feat(omp): add integration observability - #1
Open
panosAthDBX wants to merge 243 commits into
Open
Conversation
The per-harness atlas READMEs told users to run `babysitter harness:install-plugin <harness>`, which installs the BABYSITTER plugin, not atlas. Rewrote each to install the atlas plugin via the harness's real mechanism (mirrors the claude-code fix): - Published atlas npm packages -> npx/native installer: codex/genty `npx --yes @a5c-ai/atlas-<h> install`, omp `omp plugin install @a5c-ai/atlas-omp`, pi `pi install npm:@a5c-ai/atlas-pi`, github `copilot plugin marketplace add a5c-ai/atlas-github-copilot && copilot plugin install atlas`. - Plugin-only repos (no npm publish): cursor/gemini/antigravity/opencode/openclaw run the repo's bundled bin installer via `npx --yes github:a5c-ai/atlas-<repo> install`. Verified npm publish status and external repo bin/manifests for each harness. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DmHAepM1kgrjKeiph1mKAT
…json
Claude Code's marketplace schema requires a top-level `owner` object; the root
.claude-plugin/marketplace.json was missing it, so loading the `a5c.ai`
marketplace failed with "owner: Invalid input: expected object, received
undefined". Added owner {name, email} matching the other a5c marketplaces.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DmHAepM1kgrjKeiph1mKAT
Generated harness plugins (babysitter-claude et al.) write a hooks.json that
invokes the bare `adapters-hooks` binary (from @a5c-ai/hooks-adapter-cli) for
every hook event. Plugins bootstrap via `npm i -g @a5c-ai/babysitter-sdk`, but
npm only links a package's OWN bins to the global bin dir, never its
dependencies' — so nothing put `adapters-hooks` on PATH and all babysitter hooks
were dead no-ops (exit 127). @a5c-ai/hooks-adapter-cli wasn't even a dependency.
Fix: add @a5c-ai/hooks-adapter-cli as a dependency and re-export both
`adapters-hooks` and `adapters` as babysitter-sdk's own bins (thin launchers that
re-exec the dependency CLI). Now `npm i -g @a5c-ai/babysitter-sdk` puts both on
PATH. resolveDependencyBin locates each dep via node_modules + fs (bypassing the
@a5c-ai/adapters `exports` map and @a5c-ai/hooks-adapter-cli's missing `main`).
Verified: both shims re-exec the real CLIs (adapters hooks handle Stop ->
{"decision":"allow"}); 3 unit tests cover the resolver's edge cases.
NOTE: reaching published users needs an SDK version bump + republish + a plugin
versions.json bump (6.0.0 is already published, so the idempotent publisher skips
it).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DmHAepM1kgrjKeiph1mKAT
…ness build Mirror of the main-branch fix (de2d2d0): the harness build OOM-killed on the 7GB ubuntu-latest; move the job to ubuntu-latest-l like publish.yml. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DmHAepM1kgrjKeiph1mKAT
…arness build The real cause of the "Lint, Tests, Package" failures on every recent PR: the "Build babysitter-harness" / genty-core steps piped to `tee artifacts/test-lo../…` — a corrupted path (should be `artifacts/test-logs/…`). That dir doesn't exist, so `tee` fails to open it and, under `set -o pipefail`, fails the whole step with exit 1 and no TS error (the babysitter-sdk build echo comes from genty-core's own build chain, which is why it looked like an SDK/OOM failure). Fixed both paths. Kept the larger runner (matches publish.yml for this heavy build). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DmHAepM1kgrjKeiph1mKAT
…ll docs Two issues reported for codex: 1. `codex plugin marketplace add a5c-ai/babysitter-codex` failed with "marketplace root does not contain a supported manifest". The per-harness repo ships a `.codex-plugin/plugin.json` bundle but no marketplace root — only the monorepo `.agents/plugins/marketplace.json` had one (needs `--sparse`). Unlike claude, whose external repo gets a self-contained `.claude-plugin/marketplace.json` via writeRepoMarketplace (a5c-ai#955), codex repos got nothing (all targets have marketplaces:[] and the helper only handled .claude-plugin/plugin.json). Fix: writeRepoMarketplace now falls back to `.codex-plugin/plugin.json` and writes `.claude-plugin/marketplace.json` (the legacy root codex recognizes), so `codex plugin marketplace add a5c-ai/babysitter-codex` resolves without --sparse, symmetric with claude. Takes effect on the next external-repo sync. 2. Install docs were wrong/partial: the codex per-harness README and 03-babysitter-plugin-flows used `--ref staging`, contradicting codex.md's "never --ref staging" rule. Corrected to `--ref main`, clarified that the marketplace manifest lives in the monorepo (`a5c-ai/babysitter --sparse .agents/plugins`), and documented why adding `a5c-ai/babysitter-codex` failed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DmHAepM1kgrjKeiph1mKAT
…per-repo flow
Corrects the prior attempt. Per OpenAI Codex docs, `codex plugin marketplace add
owner/repo` reads `$REPO_ROOT/.agents/plugins/marketplace.json` (codex format:
`{name, version, interface.displayName, plugins:[{name, version, source:{source:
"local", path:"./"}, policy, category}]}`) — NOT a claude-format `.claude-plugin/
marketplace.json`. writeRepoMarketplace now writes the real codex manifest into
codex repos (self-sourced at ./) while keeping claude's own format, so
`codex plugin marketplace add a5c-ai/babysitter-codex` + `codex plugin add
babysitter --marketplace babysitter` works per-repo (no --sparse), symmetric with
claude. Docs (codex README, codex.md, plugin-flows) updated to the per-repo flow.
Refs OpenAI Codex plugin docs (developers.openai.com/codex/plugins/build).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DmHAepM1kgrjKeiph1mKAT
docs: changelog update 2026-07-02
…07-02 Track upstream agent CLI releases
…07-01 Track upstream agent CLI versions
…07-03 Track upstream agent CLI versions
Cryptographic policy-enforcement architecture grounded in genty trust primitives, proven, the two existing policy engines, adapters gates, and the transport proxy attestation seam. 33 numbered acceptance criteria mapped to milestones A-E; one new package (@a5c-ai/policy-adapter). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rsarial review Close all 5 blocking issues from the 62/100 adversarial security review: 1. Model-decision now binds a specific tool call: extend model-decision payload with signed toolCalls[] (toolCallId+name+argsHash); CommandAuthorization binds toolCallId (AC-34/34a; updates AC-4/§4.1, AC-12/13/15/16, AC-30). 2. Trusted-store key resolution: TrustRoot carries key material; new verifyEnvelopeTrusted wrapper resolves keys only from the trusted store, binds sha256(pubkey)==fingerprint, selects by (requiredKind, allowedFingerprints), rejects cross-kind (AC-35; updates AC-5/6/7/26). 3. Config integrity: trust-roots + policy docs signed by an out-of-agent config root-of-trust, verified before honoring; bootstrap/pin story (AC-36/37/45; updates threat model, §1.2, AC-26/33). 4. Must-be-signed is a runtime trust-boundary assertion, not a lint (AC-2/8/10). 5. Canonicalized argv command matching + per-env opt-in default-allow (AC-38/38a/38b; updates §7, AC-23). Non-blocking folds: proxy-attestation default for credential actions (AC-39), trusted credential->scope source (AC-40), quorum distinct-holder rule (AC-41), argsHash recomputed at GATE 3, evidence covers every step (AC-42), proven bridge stays human (AC-43), non-blocking-GATE-2 + passthrough denial test (AC-44). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…eview attacks
Second security review (74) confirmed Draft 2 closed the 5 original blockers
but found 3 residual blocking attacks. Draft 3 closes each precisely:
- Config rollback/downgrade: single signed config manifest with monotonic
configEpoch covering all config files together (AC-46) + off-workspace
min-epoch floor pinned beside POLICY_CONFIG_ROOT_FP (AC-47). Every gate
rejects below-floor/stale epochs; revocation can't be downgraded
independently. Revises AC-26/27/36/37/45; CommandAuthorization gains
configEpoch (AC-8/AC-10 step 10).
- Proven-bridge unsigned approved bit: bridge now asserts legacy
signedFields superset of {breakpointId,approved,responderId} before
deriving human evidence (AC-48), applying the AC-2 completeness rule to the
legacy proven answer at proven/verify.ts:60. Revises AC-3/AC-43.
- GATE 3 backstop scope: GATE 1 + genty dispatcher/session declared
load-bearing, un-bypassable for ALL covered actions with an exec-path
enumeration test (AC-49/AC-49a); GATE 3 extended to non-env credential
channels (docker -v, k8s secrets) with a bounded, warned non-goal for
IMDS/pre-existing mounts (AC-50). Revises AC-23a/33/40/44.
Folded cheaply: domain-separation payloadType constant in signedFields
(AC-51); one shared canonical argv/args serializer + conformance test
(AC-52/52a); argv wrapper allowlist (AC-38c); heterogeneous quorum
composition (AC-41a); collision-resistant credential identity, deny-on-
ambiguous (AC-40a). 65 ACs, each mapped to one milestone. No prior AC
regressed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…approval Owner approved the proof-based policy-enforcement design (score 91) at the design-approval breakpoint with the condition that the four non-blocking security-review notes become required acceptance criteria: - AC-53 argsHash proxy/gate boundary conformance + mutating-hook fail-closed (Milestone C) - AC-54 proven canonical-form hardening under the AC-48 bridge (Milestone A) - AC-55 credential-identity alias canonicalization before deny-on-ambiguous (Milestone B) - AC-56 exhaustive exec-seam registry so unregistered exec paths fail the build (Milestone D) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Frozen tests authored strictly from docs/design/proof-based-policy-enforcement.md (Milestone A — unified trust core). Cover every milestone-A acceptance criterion, each test named with its AC id, with mandatory negative/adversarial fail-closed cases. - genty-core: SignedEnvelope canonical-form determinism/stability (AC-1, AC-2 groundwork); new ModelDecisionPayload/SignedToolCall tool-call binding (AC-34/AC-34a, AC-51). - policy-adapter (new pkg, intended module paths): trusted-store verifier wrapper (AC-35, AC-2, AC-5/6/7, AC-51, AC-27); CommandAuthorization shape + verification incl. configEpoch floor (AC-8/9/10/42, AC-46/47, AC-51); config-integrity manifest + anti-rollback (AC-26/36/37/46/47); proven->SignedEnvelope bridge legacy-completeness (AC-3/43/48); chain verification extensions (AC-35g). - tasks-adapter: proven canonical-form hardening — no collision, dual-read (AC-54). Tests import from not-yet-existing implementation modules and are expected to fail to resolve until Milestone A lands; they parse and express the contract. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Implements Milestone A of proof-based policy enforcement:
- genty-core: new ModelDecisionPayload/SignedToolCall type beside
model-signing.ts binding each tool call {toolCallId,name,argsHash}
with a bound payloadType constant in signedFields (AC-34/AC-51).
- @a5c-ai/policy-adapter (new package, packages/adapters/policy):
- verifyEnvelopeTrusted: trusted-store key resolution, fingerprint
binding, (requiredKind, allowedFingerprints) selection, cross-kind
rejection, runtime signedFields completeness + payloadType, expiry
and revocation (AC-35/AC-2/AC-51/AC-27).
- verifyCommandAuthorization: full CommandAuthorization gate contract
incl. TOCTOU hash re-checks, configEpoch floor + current binding,
per-step evidence coverage (AC-8/AC-10/AC-42/AC-46/AC-47).
- verifyConfigManifest: single signed manifest, monotonic configEpoch,
off-workspace epoch floor, per-file hash + unlisted-file deny-all
(AC-36/AC-37/AC-46/AC-47).
- verifyTrustChainTrusted: wraps genty verifyTrustChain, per-link
trusted-store resolution + kind (AC-35g).
- bridgeProvenAnswer: proven -> human-approval evidence with AC-48
legacy signedFields completeness, anchored on the original human
fingerprint (AC-3/AC-43/AC-48).
- proven hardening (AC-54): length-prefixed, type-tagged canonical
signing form so distinct field assignments cannot collide; verify
dual-reads hardened + legacy so existing signatures still verify.
All fail closed: any verification/parse/config error is a deny, no
fallbacks. tsconfig references + workspace glob pick up the new package
(lockfile regeneration still required, done off-Windows).
Tests: genty-core trust 46, tasks proven 98 (full suite 1076), policy
adapter 60 -- all green. build:sdk green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Milestone-A adversarial-review defect (commit 18a73697d): the delegation-chain linkage was never verified. verifyTrustChainTrusted built links for genty verifyTrustChain WITHOUT populating parentSignature, and verifyOne validated each link in isolation, so genty's parent-linkage check (chain.ts:35) was dead code. A "chain" passed as an unordered set of individually-trusted agent envelopes with no real A->B->C delegation relationship — reordering or splicing a foreign-but-trusted envelope still passed. verifyTrustChainTrusted now verifies real delegation linkage: a chain is recognized as linked when any link (i>0) declares an in-chain delegatorFingerprint, and every link i>0 must then bind to its immediate predecessor (delegatorFingerprint == predecessor signer AND delegatorSignature == predecessor envelope signature, populated as parentSignature so genty's check re-confirms). Fails closed on reordering, missing/forged parent, or a spliced foreign envelope. A set of independent roots (no in-chain delegator declared) stays valid. Also, same trust-core guarantee: - proven verify.ts: recompute sha256(public-key DER) and bind it to the claimed publicKeyFingerprint before trusting the resolved key (the check verify-envelope-trusted enforces but proven omitted). This is the signature check behind bridgeProvenAnswer's human guarantee; deny on mismatch. - proven-bridge.ts: enforce the human trust root is valid at answeredAt (mirrors keyValidAt), so an expired human root can no longer launder proven answers into human evidence. Adds adversarial coverage (no frozen test changed): reordered links, spliced foreign envelope, forged/missing parent, valid A->B->C for the linkage fix; fingerprint-binding and expired-human-root for the proven and bridge suites. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…gn spec Frozen tests for Milestone B of proof-based policy enforcement, authored strictly from docs/design/proof-based-policy-enforcement.md (§5/§7/§9/§12/§14). Import intended @a5c-ai/policy-adapter module paths the implementation WILL provide (resolution fails now, by design — no syntax errors). Covers every Milestone-B AC: - AC-52/AC-52a shared canonicalizeArgs/canonicalizeArgv (total, loss-preserving, byte-identical across proxy + gate; conformance corpus, no-collision, AC-53 boundary) - AC-38/38a/38b/38c canonicalized argv matcher: sh -c recursion, abs-path/symlink basename, per-scope wrapper allowlist (not denylist), commandDefaultAllow opt-in; adversarial alias-evasion (npx/env-indirection/$()/backticks/eval/busybox/ interpreter-indirection/unlisted wrappers) all deny, never default-allow - AC-19/19a/38b/23c policy schema: >=2 alt chains from one doc, quorum + heterogeneous composition parseable; commandDefaultAllow default false; duplicate-fingerprint store rejection (carry-forward) - AC-9/20/41/41a/42 evaluator: aws human+opus AND 2-human quorum both evaluate; wrong-model/expired/revoked/unknown-fp/scope-miss/wrong-payloadType deny; quorum distinct-holder (one human's two keys denied); no double-use; deny>grant precedence - AC-9/42 issuer: configEpoch-bound short-lived CA, issue->gate re-verify loop; explicit requiredStepCount carry-forward (absent => fail closed); below-floor deny; delegation carry-forward (empty/single-link rejected, terminal delegatee confirmed) - AC-55/40a credential-identity alias canonicalization: two-alias-one-credential to one scope; deny-on-ambiguous/absent/agent-supplied-alias Milestone A frozen tests unchanged (67/67 pass). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…st-chain evaluator + authorization issuance) Adds the @a5c-ai/policy-adapter configurable policy component on top of the Milestone-A trust core: - canonicalize-args.ts: ONE shared, total, loss-preserving argv/args serializer (AC-52/AC-52a/AC-53) — deep-sorted object keys, preserved array order/types/bytes, explicit deny-path (throw) for non-finite numbers. - argv-matcher.ts: canonicalized argv matcher (AC-38/38a/38b/38c) — tokenize, recurse into sh/bash/zsh -c, resolve argv[0] basename, per-scope wrapper ALLOWLIST, commandDefaultAllow opt-in; all alias forms ($()/backticks/$VAR/eval/npx/busybox/ interpreter-indirection/unlisted-wrapper) fail closed instead of evading coverage. - policy-schema.ts: policy document parser/validator (AC-19/19a/38b/41/41a/23c) — requirements[] with typed steps + distinct-holder quorum, legacy steps[]/quorum: sugar normalized; plus loadTrustStore duplicate-fingerprint rejection. - policy-evaluator.ts: trust-chain evaluator (AC-9/20/22/41/41a/42) — verifies every envelope via verifyEnvelopeTrusted/verifyTrustChainTrusted, condition sugar compiled to base operators, deny>grant precedence, no-double-use, delegation carry-forward hardening (reject single-link non-delegation, confirm terminal delegatee), fail closed. - authorization-issuer.ts: short-lived configEpoch-bound CommandAuthorization issuance (AC-9/42/47) — explicit requiredStepCount required, fail closed on unverified evidence / below-floor epoch / missing step coverage. - credential-identity.ts: alias canonicalization + deny-on-ambiguous (AC-55/40a). Reuses the two existing engines' condition operators + precedence (AC-22); no third engine. All 146 policy-adapter tests pass (67 frozen Milestone-A + 79 Milestone-B). Adds `yaml` dependency (already at repo root) — lockfile regeneration needed on CI. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ld-ins Adversarial review (score 46) found the Milestone-B policy engine passed only happy-path (theatrical) tests. Fix at root cause and add the missing adversarial assertions: 1. AC-34a/AC-30 model-decision tool-call binding: evidenceSatisfiesStep now requires the verified attestation's signed toolCalls[] to contain an entry whose toolCallId===context.toolCallId AND argsHash===context.argsHash (shared canonicalize-args bytes); mismatched id/argsHash or empty toolCalls => deny. 2. AC-38/38a/38c argv anti-evasion: the evaluator now routes action matching through the canonicalized matchArgv (shell -c recursion, per-scope wrapper allowlist, deny-on-unresolvable) instead of naive basename matching. Disguised covered commands (sh -c, nested sh, npx, A=aws;$A, $(...), backticks, eval, busybox, python/node -c) resolve to the covered program and DENY. 3. AC-41 quorum distinctness: humanIdentity resolves the RESOLVED trusted-store identity (TrustRoot identityId/label) instead of the attacker-signed payload approvedBy; two keys owned by one trusted identity count as ONE. 4. Anchor unanchored regexes (modelIdMatches, subcommandMatches x2) as ^(?:x)$. Folded-in security fixes: 5. AC-17/39 requireProxyAttestation enforced: defaults to true for any credentialScope-touching action; an in-process (agent-held) attestation is rejected unless the policy explicitly opts out (producer:'proxy' marker). 6. Issuer grant gate: new issueFromDecision consumes the evaluator's PolicyDecision (granted===true) and binds the EXACT granted action (toolName/commandHash/argsHash/credentialScope/toolCallId/configEpoch). Also add the empty-requirements/requiredStepCount===0 => unsatisfied guard. Fixtures corrected (not weakened): proxy engine roots marked producer:'proxy' so the AC-39 credential-scope default is satisfied for a valid fixture. 170 policy tests pass (was 146; +24 adversarial). 67 frozen Milestone-A tests unchanged and green. build:sdk green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rt, incident-management, contract-lifecycle, full-cycle-hiring Owner-steered enrichment run 01KY6X5FN64XTQT6V21B84WG1N: four full end-to-end work workflows, all passed adversarial executed-evidence gates on attempt 1. - customer-support/ (NEW specialization): ticket-lifecycle.js — triage, parallel investigation, adversarial resolution gate, policy-gated reply/refund/KB-publish. - incident-management/ (NEW specialization): incident-lifecycle.js — consolidates devops-sre incident-response, itil-incident-management, observability lifecycle; severity-routed policy gates, postmortem completeness gate. - legal/contract-lifecycle-workflow.js: supersedes contract-lifecycle-management.js (deprecated in place); redline gate with executed coverage check, per-round negotiation approvals, gated send/accept/sign. - human-resources/full-cycle-hiring-workflow.js: supersedes full-cycle-recruiting.js; JD + panel-calibration bias gates, comp approval hard pre-gate of offers. All declare policyGatedActions (breakpointId=actionId, adapters/policy-ready evidence), reuse routed-gate-combinators, and kip recall/assert per domain. Plan updated with owner throughput decision (auto-slates, two ~12-item batches next). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…partially closes D-61) A learned graph retained a superseded design-choice edge as status:"current", so kip ask presented a superseded choice as present-tense. Fix (owner-chosen retrieval locus; proj UNTOUCHED, getNode unchanged): a supersedes edge convention (edgeKind:"supersedes", from=new, to=old — an ordinary signed fact) surfaced in graph-QA. A node reached as the LIVE (D-68 edgeExistenceFactId) to of a supersedes edge is historical: its status:"current" is OVERRIDDEN to "superseded" (not just flagged — the D-60 lesson) on the node and its outgoing claim edges, plus superseded/supersededBy markers and the citable supersedes edge. A retracted supersedes reverts to current. Adversarial round (critic 72 -> fixed): the first cut leaked — supersession was keyed by literal eid and NOT expanded across the same_as class, so a superseded decision described across two same_as-merged documents leaked status:"current" under the alias eid (getNode redirects to canonical; §3a reads alias cells) in BOTH directions — the same D-60-class masking. Corrected by expanding supersession across repo.sameAsClass (every member mapped to the min live supersedes factId). Independently re-verified: zero "current" leaks for any class member, both directions. The D-60 composition (conflicted AND superseded) applies the same override; overclaim removed. Honest scope (PARTIALLY ADDRESSED): deterministic retrieval surfacing shipped; model extraction of supersession is KIP_LEARN_LIVE-gated + nondeterministic; getNode-direct projection and true bitemporal validTo (learn validFrom is 0) are documented follow-ons. proj UNTOUCHED, deterministic, INV-A1/read-only, N5, zero deps. ADR-B16. Suite 974 passed | 8 skipped (+8, incl. both same_as directions). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…herent, no clean fix ships Investigated D-58's three suggested levers and found none applies, so recording the grounded finding rather than shipping cosmetic code that would overclaim a determinism the model path cannot provide: - Pin temperature/seed: NOT AVAILABLE — claude CLI v2.1.195 exposes no --temperature/--seed/--top-p/sampling flag (verified via --help); no seam to pin. - Canonical AssertInput ordering: MOOT — proj projection is set-pure/order-independent, so ordering the compiled array does not change the resulting graph (cosmetic). - Deterministic slug re-derivation: REJECTED — folds genuinely-distinct entities that normalize to one slug (cross-entity collision), needs model-coupled identity detection, churns frozen eids. The core node/edge DECOMPOSITION variance is intrinsic to the accelerator-class model encode. The cross-run eid-instability CONSEQUENCE is mitigable downstream via the entity resolver's same_as linking (ADR-B11/B12; read-reversible since D-68). Status: Open/INHERENT, honestly documented as accelerator-class, not a determinism guarantee. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…s 12 domains Auto-slate enrichment run 01KY78D4SQ0WX1C73HHEWKXJ8W (owner throughput authorization): all 12 passed adversarial executed-evidence gates on attempt 1. NEW specializations: release-engineering (release-lifecycle.js), data-privacy-compliance (dsar-lifecycle.js, statutory-clock deadline routing), procurement (procurement-lifecycle.js, spend-threshold routing). New flagships in existing domains: research-publication, marketing-campaign, sales-deal (supersedes pipeline-review-forecast), finance-month-end-close (supersedes financial-statement-preparation), product-lifecycle-e2e, multi-audience-announcement (+ communication README). First 3 implemented methodology compositions: legacy-modernization, regulated-greenfield, startup-mvp. All declare policyGatedActions (adapters/policy-ready routed breakpoints, fail-closed executors), reuse routed-gate-combinators, kip recall/assert per domain kind. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rl) — closes D-67 remote half via safe design kip ingest-rdf --url <https-url> fetches N-Triples from an explicit host allowlist and feeds the bytes VERBATIM to the existing rdfToAcquisition -> runAcquisition path, so the D-67 untrusted-data guards (reserved-channel forge refusal, malformed strict-fail, INV-A1) already apply to fetched content. The fetch layer only ACQUIRES bytes; it never parses or authors. Safe by design: opt-in gate KIP_RDF_FETCH (comma-separated host allowlist; unset => DISABLED, the default — no network call in the CLI or the whole suite; gate-off / non-allowlisted host => exit 7 before any network call); EXACT case-insensitive hostname match (no suffix/subdomain — evil-dbpedia.org != dbpedia.org, fails closed on trailing-dot/IDN-homograph); HTTPS-only; embedded credentials refused; GET-only, no cookies/auth/added-query, fixed Accept; redirects refused outright (redirect:manual); hard caps (5 MiB STREAMED byte count — Content-Length not trusted — + AbortController timeout); injectable fetchImpl so the suite hits NO real network. Zero new deps (Node global fetch). Security review (score 85 -> fixed): every bypass fails closed (userinfo-SSRF caught by the credentials check first; redirect refusal covers 3xx + undici opaqueredirect before the body read; streamed cap with reader cancel). The one finding was an HONESTY gap — the private-IP/metadata SSRF residual was real but undisclosed. Fixed two ways: (1) DEFENSE-IN-DEPTH — loopback/link-local/metadata IP LITERALS (127/8, 169.254/16 incl. 169.254.169.254, 0/8, IPv6 ::1, fe80::/10) refused BEFORE the allowlist, even when allowlisted (verified: metadata/loopback/[::1]/[fe80::1] all refused, no network hit; public 8.8.8.8 still fetches); (2) DISCLOSURE — ADR-B14 + DEBTS now state the residual: an allowlisted HOSTNAME resolving to an internal IP IS fetched (only IP-literals are blocked); bounded (no rebinding TOCTOU; body parsed locally, never returned — internal-probe/data-poison, not exfiltration); per-host opt-in + https + no-redirect. A private-range/DNS SSRF block is deferred. Still deferred: open/arbitrary-URL fetch, SPARQL, Turtle/JSON-LD, auth'd endpoints. ADR-B14 addendum. Suite 1010 passed | 8 skipped (+36 fetch tests, all injected). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…query, dep-free fuzzy default + real-embedder seam (D-57 semantic half) Owner-approved N2/N5 stance lift: kip now embeds the query itself and drives the existing vector half of recall (the matching machinery + corpus-embedding seam already existed; the stance was the only blocker). - defaultEmbed (src/embed/default-embedder.ts): dep-free 1024-dim L2-normalized signed-feature-hashed vector over stemmed tokens + char-3-grams. FUZZY character/ token OVERLAP, explicitly NOT learned semantics (header: 'Do NOT call this semantic'). Boundary pinned: revenue-recognition vs booking-settlement cos=0.0000. - computeRecall embeds q.text when q.semantic===true and no q.embedding — via the INJECTED embedding microagent if wired, ELSE defaultEmbed (branched on hasInjectedDispatch AVAILABILITY, NOT a try/catch — a failed injected embedder throws loud, N5; 'fallbacks are evil'). Query + corpus embedded SYMMETRICALLY by the same embedder, never mixed. - Opt-in via RecallQuery.semantic (kip ask/recall --semantic, KIP_ASK_EMBED), resolved outside computeRecall (stays pure). Default recall BYTE-IDENTICAL — the m4 'kip NEVER embeds the query text' test stays green, now guarding the off path. HONEST (no overclaim): the dep-free default is fuzzy overlap, NOT synonymy — the canonical revenue-recognition==booking-settlement case is still not matched. TRUE synonymy needs an INJECTED real embedding model via the §5.3 seam (proven by a scripted synonym-aware dispatch test); kip stays zero-dep (claude CLI has no embeddings API). §5.3 boundary intact (embeddings outside proj; INV-A1), N5/§6.1b anchoring preserved (subject-absent node still abstains), deterministic. Adversarial critic 93/100. Two disclosed nits: --semantic mode-gate name; sim>0 fuzzy noise floor (follow-on). ADR-B17. Suite 1021 passed | 8 skipped (+11). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…c CLI surface was unreachable)
An end-to-end live scenario caught that 'kip ask --semantic' and 'kip recall
--semantic' both exit 2 'unknown option --semantic': --semantic was never added to
BOOLEAN_FLAGS in cli/args.ts, even though cmdAsk/cmdRecall read flagBool(flags,
'semantic'). So the entire D-57 semantic CLI surface was unreachable, while the SDK
recall({semantic:true}) path worked — which is exactly why the mock/SDK-level tests
missed it (same class as the D-69 --force gap). Fix: register 'semantic' in
BOOLEAN_FLAGS. Add CLI-parser tests asserting kip recall/ask --semantic parses to
flags.semantic===true (boolean, positional not swallowed) so the registration can't
silently regress again.
Suite 1023 passed | 8 skipped.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ith getNode/edgeEids (E2E-caught)
The end-to-end scenario surfaced that edge valid-time was read inconsistently:
- plain getEdge did NOT gate on the edge's OWN validity, while getNode DID
(nodeLiveVisibleAt) and edgeEids DID (edgeExistenceFactId(_, null)) — so a
finite-validTo edge read 'present' from getEdge but was dropped by edgeEids (two
reads disagreeing at the same instant; asymmetric with the node side);
- asOf({validTime}).getEdge applied only the prop-segment lens and never gated edge
existence, so it returned an edge OUTSIDE its own [validFrom, validTo) interval
(a validFrom:2024 edge read live at validTime:2023, an expired edge read live 'now').
Fix: both getEdge paths now gate on the edge's OWN validity via edgeValidAt(eid,
instant) — the exact analogue of getNode's nodeLiveVisibleAt gate — while STILL not
gating on endpoint-node existence (an edge is its own entity). Reuses the same
edgeValidAt authority the D-68 fold uses; the proj-INTERNAL getEdge that fold calls
is a different function and is unaffected (it already gates on edgeValidAt first).
Verified: getEdge/edgeEids now AGREE on a finite-validTo edge (both absent) and
match the node side; asOf({validTime}).getEdge reads a bounded edge present ONLY
inside its interval (null before validFrom, null after validTo). Zero regression —
full suite 1023->1029 passed | 8 skipped (all D-68/D-66/traverse/bitemporal tests
still green). Localized to the two KipRepo.getEdge read wrappers.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… facts + validate in proj as a quarantine (opt-in), never a write gate (ADR-B18)
Closes the DECLARATION + current-version validation half of the docs/21 §3 ontology
gap (previously designed-not-built). Architecturally correct per the spec: a
signature is the SOLE write gate, so a schema violation is NEVER a write-time reject
(that would break set-union CRDT convergence) — it is a proj-time QUARANTINE.
- registerSchema(def: NodeKindDef) authors ONE signed { kind:'schema',
ontologyRef:'kip:node-kind/<kind>' } fact (orchestrator-signed channel, INV-A1);
validFrom from the repo clock so it is bitemporal. getSchema(kind, asOf?) reads the
orderKey-winner back, as-of-queryable. NodeKindDef/EdgeKindDef/PropSchema ported to
types.ts; NodeView.schemaViolations?: string[] added.
- proj folds the declared ontology once (collectDeclaredNodeKinds, pure over facts)
and validates each node of a declared kind (validateNodeAgainstSchema): a missing
required prop or a wrong-typeof prop surfaces kip:schema-violation. Node/props never
dropped, value never invented (N5). Kind preserved (not overwritten).
- OPT-IN / non-breaking: an undeclared kind is validated against nothing → projected
exactly as before. Grow-only: a schema declared later re-projects existing nodes.
Deterministic: pure fold, orderKey-winner selection, sorted messages.
Convergence critic 92/100. Fixes applied: (a) determinism guard — a schema fact is
applied only when its ontologyRef matches its own payload kind, so a ref/payload
mismatch can't make winner-selection Map-ingest-order-dependent (proj determinism no
longer relies on writer discipline); (b) a disputed kip:conflict node drops
schemaViolations (uniform with the tie path); (c) +3 hardening tests (retracted
required prop → 'missing' no-phantom; same_as alias validates against the canonical
kind; re-declared stricter schema's orderKey-winner supersedes). Known Slice-1 limit
(blob-backed prop typed 'object') documented.
DEFERRED as follow-on slices (no overclaim): per-fact-version upcasters / migration /
rename / deprecate; EdgeKindDef depth; cardinality / inverse; per-kind cellReducer +
identity; and the reusable importable schema LIBRARY.
proj UNTOUCHED for write-gating; NUL count preserved (7); LF; zero new deps; lockfile
untouched. Suite 1045 passed | 8 skipped. ADR-B18.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…(registerSchemaLibrary/get/list), manifest as versioned fact, orderKey-convergent (ADR-B19) Packages Slice-1 node-kind defs into a named, versioned SchemaLibrary manifest that imports as facts and re-declares its member kinds (proj re-validates nodes against the new winning def, grow-only). Selection is maxByOrderKey(...).winner so a colliding-declared-id manifest tie resolves by the same content tiebreak as getSchema — convergent across replicas, never a write-time gate. Honest limits documented (ADR-B19 + types): version is last-write-wins by orderKey (descriptive, not a monotonicity guard — a lower version registered later still supersedes); member kinds share the global kip:node-kind/<kind> namespace (two libs declaring the same kind resolve to one shared winning def); list echoes the declared manifest kinds while get hydrates the currently-resolvable subset; retracting a member kind does not un-declare it (Slice-3 evolution work). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…neage + deprecation advisory), applied at proj-time as a read-time view (ADR-B20) NodeKindDef gains `renames` (a prop-rename lineage: old and new name are the SAME slot, so old-named data satisfies a new-named requirement, resolved transitively + cycle-safe, type-checked against the current type) and `deprecated` (a node still carrying a deprecated prop surfaces a `kip:schema-deprecated` advisory on the new SEPARATE NodeView.schemaDeprecations field — never a schemaViolations entry, never a drop). Both serialize through the same registerSchema channel (getSchema + library re-hydration round-trip them), parse all-or-nothing (present-but-malformed => def declares nothing), and are rejected up front by the Slice-2 strict library validator. Pure, convergent, no write gate: everything is a read-time VIEW over unchanged facts, a deterministic function of the single winning schema fact. A renames-free def validates byte-identically to Slice 1. Arbitrary per-fact-version CODE upcasters are documented as architecturally impossible in a convergent fold (retired, not deferred); schema retraction + required-with-default stay named follow-ons. Adversarial convergence/determinism critic found NO MAJOR issues; its minors applied: reserved kip:conflict kind is never validated, the dead `?? [spec.name]` fallback removed (repo no-fallback rule), duplicate deprecated names deduped, and two critic-requested tests added (disputed node drops schemaDeprecations; multi-alias wrong-typed message is stable across authoring orders). Full kip suite green: 1084 passed | 8 skipped. proj.ts NUL sentinel count intact. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-snapshot, idempotent, parent-chained) sharing txn()'s exact tree recipe (ADR-B21) commit(message?) was a throwing stub. It now flushes the repo's auto-batched, already-durably-ingested content facts (assert/retract/supersede/re-attest — so schema facts and retracts publish too) as a new parent-chained git commit and advances the CommitTipStore tip, returning the commit CID. Recipe parity, no drift: the combined writeFactsTreeAndCommit was split into writeFactsTree + writeCommitForTree (a mechanical, byte-identical extraction, so txn() is unchanged), and commit() reuses writeFactsTree with the SAME orderKey->compareByContent sort txn uses. A txn() commit followed by commit() over the identical fact set is a no-op returning the txn's own oid — proving both build the same tree. Idempotent no-op (tree unchanged => return the existing tip, never an empty-delta chain; always correct since currentFacts() is append-only). Loud on empty (ERR_MALFORMED_INPUT, N5 — no honest CID for an empty publish). Advances only the COMMIT tip; seq/hlc were already persisted per-fact by the ordinary ingest path. Adversarial critic found one MAJOR (M1): commit() bypassed the txn single-flight guard — a mid-txn commit() would publish a stale snapshot and clobber the tip. Fixed: commit() now rejects ERR_TXN_ALREADY_ACTIVE while a txn() is in flight. Its other axes (txn byte-identity, recipe parity, idempotency, N5, durability) came back clean; its test-gap asks (G1 multi-fact parity, G4 no-op-after-reopen) are added. Full kip suite green: 1094 passed | 8 skipped. proj.ts untouched. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ions now implemented Final auto-slate enrichment run 01KY7W26BV6M3BVHNGCQJF4FJ9: 12 authored, all passed adversarial executed-evidence gates (9 attempt-1, 3 after one scoped fix round each). - New/built-out specializations: observability (slo-lifecycle.js + incident-lifecycle deprecation pointer), accessibility (supersedes web-development seed), internationalization, mlops, developer-relations. - New flagships: customer-onboarding-e2e (customer-support), supply-chain-fulfillment-e2e. - business/sourcing vestigial dirs folded with deprecation pointers. - Composition methodology Examples 1/5/6/7 implemented — all 7 now done. Gates caught 3 real defects (JSDoc gap, ingredient-shape bug, siloed kip kind), fixed+re-verified. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ce at the channel ref
The documented_install codex lane was red on staging: it ran the monorepo
sparse form (`codex plugin marketplace add a5c-ai/babysitter --ref staging
--sparse .agents/plugins`), which reads the committed
`.agents/plugins/marketplace.json`. That manifest pins `source.ref: main` /
`6.0.2` (set for the 6.0.2 main release), so codex resolved babysitter-codex@main
= 6.0.2 while the staging channel publishes 6.0.3-staging.bf012dbb7bff — a
STALE-plugin assertion failure.
The docs already disavow that exact command ("never `--ref staging`" for the
monorepo form) and document the per-repo marketplace as the primary path.
babysitter-codex is synced per branch and its root
`.agents/plugins/marketplace.json` is channel-correct, so switch the lane to
`codex plugin marketplace add a5c-ai/babysitter-codex --ref <channel>`,
mirroring what the claude-code lane already does with `@<channel>`.
Adds a guard test that the codex commands never regress to the sparse form,
and documents the prerelease `--ref <channel>` form in the codex harness guide.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@
…mains and the classic-methodology bar retrofit Fifth batch of the process-library enrichment epic, run through meta/library-enrichment. All 12 items cleared adversarial executed-evidence gates (5 on attempt 1; 7 after one scoped fix round, each a real defect). Flagship workflows (each declares policyGatedActions on routed breakpoints, composes point processes BY NAME, and carries kip recall/assert): - domains/science/biomedical-engineering: medical-device-tplc - domains/science/civil-engineering: design-to-construction - domains/social-sciences-humanities/social-sciences: empirical-study-lifecycle (first flagship in that tier) - domains/social-sciences-humanities/healthcare: clinical-safety-quality - domains/business/knowledge-management: knowledge-lifecycle - domains/business/project-management: program-delivery - domains/business/venture-capital: investment-lifecycle - security-compliance: security-attestation - data-engineering-analytics: data-product-lifecycle - qa-testing-automation: release-quality-assurance Classic-methodology bar retrofit: scrum, kanban, xp-process, waterfall, v-model, shape-up, domain-driven-design and atdd-tdd gain routed breakpoints, adversarial gates and kip touchpoints without homogenizing their domain semantics (9 distinct gateIds, 18 distinct critics, zero shared ironLaw sentences); adds methodologies/production-contract. Structural hygiene: READMEs for authoring/, collaboration/, media/; two SKILL.md; batch-4's half-applied fold repaired — sourcing/ and business/ now hold header-only @deprecated aliases and the canonical files are tracked. release-quality-assurance namespaces defineTask ids across 13 sibling qa-testing-automation files: defineTask registers into a globalThis-pinned singleton, so co-importing the point processes threw DuplicateTaskIdError at module 4 of 19. Id-strings only; no exported binding, task body or schema changed, and the ids had no external referents. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… installs All three vanilla lanes of live-stack-published have failed since 2026-07-03 at the very first install command: npm error 404 '@a5c-ai/policy-adapter@6.0.3-staging.bf012dbb7bff' is not in this registry. packages/adapters/policy was `private: true`, but the policy Milestone C/D work (15f6e38, 5ed5f6a) made it a runtime dependency of three published packages — comm-adapter, tools-adapter and transport-adapter. @a5c-ai/adapters pulls in transport-adapter, so `npm install -g @a5c-ai/adapters` 404s for every user, not just CI. @a5c-ai/trust-core is private for the same reason and sits one layer below policy-adapter, so both have to ship. Drops `private: true` from both, adds publishConfig.access, registers them as public surfaces in the docs-coverage manifest (with the README that check-package-metadata requires), and wires build+publish steps into both publish workflows — trust-core in the foundation group, policy-adapter in its own sequential step between the foundation and its consumers. Verified: verify:metadata passes, guard-package-integrity passes, npm pack produces both tarballs, trust-core 46 tests and policy-adapter 230 tests green. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…lished install With the policy-adapter E404 fixed, the vanilla published lanes got one command further and hit the next break: npm error code EEXIST npm error File exists: /opt/hostedtoolcache/node/22.23.1/x64/bin/adapters @a5c-ai/babysitter-sdk re-exports `adapters` and `adapters-hooks` as its own bins (bd11c5b, 2026-07-01) so a standalone SDK install still puts them on PATH. @a5c-ai/adapters and @a5c-ai/hooks-adapter-cli own those names, so installing both globally is impossible in either order — npm refuses to overwrite an existing bin. The E404 masked this since it landed. Installs the SDK first, then lets the canonical owners reclaim their bins with --force. Order matters: the SDK's dependency range is ^6.0.0, which does not match a 6.0.x-<channel>.* prerelease under semver, so leaving the shim in place would silently exercise the last RELEASED adapters instead of the channel build. The edit is inside the &published_steps anchor, so all four published lanes get it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
zod ^4.4.3runtime compatibility and OMP peer range>=16.5.2 <17The combined upstream PR a5c-ai#1582 now contains this exact integration commit and supersedes the underlying driver PR a5c-ai#1580. Companion OMP API PR: can1357/oh-my-pi#6522.
Compatibility / risk notes:
>=16.5.2 <17.zod ^4.4.3; a packed strict nested install compiled and imported the driver without installing the optional OMP peer./varversus/private/varpath baseline failure; 67 focused SDK tests passed and the SDK build passed.@tailwindcss/oxide-darwin-arm64optional-binding baseline failure; Observer CLI build and 70 focused tests passed.Testing
npm test(not run; focused matrix below)npm run test:ci(not run; focused matrix below)(cd packages/adapters/extensions && npm exec -- vitest run src/__tests__/ompDeterministicDriver.regression.test.ts src/__tests__/e2e.test.ts)— 40 passed, 0 failed(cd packages/observer-dashboard && npm exec -- vitest run src/lib/__tests__/parser.test.ts src/lib/__tests__/omp-checkpoint.test.ts src/components/details/__tests__/agent-panel.test.tsx)— 70 passed, 0 failed(cd packages/babysitter-sdk && npm exec -- vitest run src/runtime/__tests__/progressTracking.test.ts src/harness/__tests__/sessionMarker.test.ts src/harness/__tests__/sessionResolutionPrecedence.test.ts src/cli/commands/session/__tests__/iterationMessage.test.ts src/cli/commands/session/__tests__/resume.test.ts src/cli/commands/session/__tests__/lifecycle.test.ts)— 67 passed; 2 unrelated canonical-path baseline failures(cd packages/babysitter-sdk && npm exec -- vitest run src/cli/commands/session/__tests__/resume.test.ts --no-file-parallelism)— reproduced exactly the 2 unrelated baseline failures with 6 passednpm run verify:omp-extension-types— passed against installed OMP 16.5.2npm ls @oh-my-pi/pi-coding-agent --depth=0— resolved 16.5.2npm run build --workspace=@a5c-ai/extensions-adapter— passednpm ci --ignore-scripts --dry-runandnpm ci --ignore-scripts --dry-run --omit=optional— passednpm ci --ignore-scriptsinstalled 3281 packages from the lock; generated strict pack/install/compile/import regression passednpm run verify:metadata— passedDocs impact
README.mdandAGENTS.mdDEMO.mdSECURITY.mdCONTRIBUTING.mdScreenshots / GIFs (if UI changes)
No screenshot: the Observer change adds derived checkpoint/status presentation covered by parser, checkpoint, and component regressions; it does not introduce a new interaction flow.