377 Commits

Author SHA1 Message Date
Boden Fuller f1b573a232 feat(state): add state memory admission gate (age-membrane-memory-arch-tz2s.2.8, age-membrane-memory-arch-tz2s.2.7.1) 2026-06-19 21:00:58 -04:00
Boden Fuller 41ded4c14b feat(plan-pawl): ao plan-pawl decide — the deterministic duel decider
The executable core of the plan-pawl duel gate (docs/contracts/pawls.md): a pure,
no-model decider that turns one round of model-family judge verdicts over a
discovery PLAN into PASS / REDO / BLOCKED, applying the quorum (no-FAIL, >=2 distinct
roster families) rule and the pawls.md circuit-breaker governance verbatim.

- internal/planpawl: Decide() — quorum + breaker precedence (judgment-flag /
  oscillation / max-attempts > FAIL > mechanical-WARN auto-apply > quorum > PASS).
- ao plan-pawl decide: --verdict family:disp[:warnclass] / --dir; exit code IS the
  decision (0 PASS, 3 REDO, 4 BLOCKED, 2 usage). Pane spawn + re-judge loop stay in
  the skill (dual-pane-atm); this is the windshield.
- Gherkin (plan-pawl.feature) + 13 unit + 7 L2 command tests; live-smoked.

Closes age-plan-pawl-9yib.2
2026-06-19 15:53:03 -04:00
Boden Fuller 35b08ca290 feat(membrane): domain-tagged findings + ao membrane recall — close the memory loop
Slices 3+4 of the membrane's event-sourced memory (rebased onto the rpi-removal
base; CLI surface regenerated fresh — code identical to the CONFIRMED review).

- Slice 3: deriveFindingFromEscape surfaces the escape's Domain + Missed in the
  finding frontmatter (escape_domain / escape_missed, independent optionals) and
  body, so a derived check is a domain-tagged "look out for this here" artifact.
- Slice 4: `ao membrane recall --domain <d> [--json]` lists past escapes in a
  domain (EscapesByDomain) — the consumption side of the self-improving membrane.
  Uses repoRootOrCwd (no subdir fail-open); --json emits [] not null.
- regen: COMMANDS.md + cli-command-surface for the new command.

Cross-family pawl CONFIRMED (codex, v2 — 3 fail-opens caught + fixed: subdir
fail-open, json null, domain/missed independence). cmd/ao green under -shuffle=1.

Closes age-membrane-memory-j9c6
2026-06-19 12:34:31 -04:00
Boden Fuller f61c5f0e71 fix(cli): remove ao rpi command surface 2026-06-19 12:22:36 -04:00
Test 695229c07d feat(worktree): ao worktree create — live-path isolated worktree command (age-r0d0 slice 2b)
Adds `ao worktree create` on the extracted cli/internal/worktree package: creates
a detached per-session worktree off the current commit and prints its path, so a
fanned-out agent gets thread-local working state (no shared mutable tree where a
concurrent reset wipes uncommitted work). Unhides the `ao worktree` group (now a
live-path verb, not just gc). L2 test creates a real git fixture + asserts a
linked worktree (.git file) — the property `ao orchestrate preflight` checks.
Regenerated cli-surface/COMMANDS/registry for the new command.

The live-path counterpart to slice 2's extraction: the worktree lib is now both
decoupled from the rpi engine AND exposed as a first-class command.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 08:54:46 -04:00
Boden Fuller 745d21f154 feat(membrane): wire escape→finding→membrane-check derivation (age-zqc)
An escape — a gate-verdict that CONFIRMED a bead which a later, higher-attempt
verdict then REFUTED — is the label that makes the membrane harder to fool. This
closes the escape→check half of the self-improving loop (epic age-cwo):

- yieldledger.DetectEscapes: pure read over the ledger; pairs the earliest
  CONFIRMED with the earliest later REFUTED per bead (v1 one-per-bead; the
  escape_rate gauge age-6ty owns finer accounting).
- ao membrane derive-checks --run <id>: detects escapes, derives a finding (the
  fresh-context re-verification check that would have caught it), and compiles it
  into a pre-mortem membrane check via the existing FindingCompilerPort. Writes
  .agents/findings/<id>.md + .agents/pre-mortem-checks/<id>.md. Deterministic id
  (escape bead + confirmed sha) → idempotent re-runs; --dry-run, --force.

The bead's "reuse hooks/finding-compiler.sh" premise was stale (that script
doesn't exist); reuses the Go finding-compiler port instead.

Tests: L1 escape detection (run-scoped, control cases) + L2 command (writes,
idempotency, dry-run, required-run) — fixtures built via the production writer.
Live-smoke verified end-to-end against the built binary.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 18:38:56 -04:00
Boden Fuller daf5c4fdd3 feat(orchestrate): Phase 1 instrument lane + profiles contract (age-ueu)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-17 16:48:21 -04:00
Boden Fuller cb13158e62 feat(claim): add changed-claim proof cards 2026-06-17 11:57:15 -04:00
Boden Fuller cebc43e98e feat(eval): age-6sg scenario-ab control-only slice
Add --control-only for applied-OOD ceiling checks, CI validate headroom hook, and workflow coverage wiring so ceiling violations fail before live campaign spend.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-17 10:45:32 -04:00
Boden Fuller 9ec993288c chore(forge): regen derived changed-scope artifacts for --typed flag (age-2jf) 2026-06-17 09:34:37 -04:00
Boden Fuller 00fc9858eb feat(eval): moat claim surface hard-rejects ineligible scorecards (age-sb0)
Add ao eval scenario-moat aggregation with fail-closed rejection of
moat_eligible=false plumbing scorecards before any moat verdict is rendered.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-17 08:38:20 -04:00
Boden Fuller e445d6ac82 chore(regen): sync changed-scope after age-wp1 cli edits
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-17 07:59:12 -04:00
Boden Fuller c160918ada feat(orchestration): wire live /discovery to stamp orchestration_decision via ValidateShape (age-aqu #s-wire)
The orchestration-shape record (age-gwa) and ValidateShape (age-nep) landed but
had no live consumer: writeExecutionPacketSeed runs only in the retired rpi_*
engine, and the live skill-driven /discovery (dag.md) hand-compiles the packet
without ever stamping orchestration_decision. ValidateShape had zero callers.
(Reachability gap, post-mortem age-gud / .agents/learnings/2026-06-16-reachability-not-unit-green.md.)

Wire it with a focused command the live path invokes:

- `ao rpi stamp-shape` reads .agents/rpi/execution-packet.json, gathers
  observable ground truth (am robot agents --active count + per-lane reservation
  write-sets grouped from `am robot reservations`), the unattended/durability
  signal, and the packet's own proposed shape, runs orchestration.ValidateShape,
  and stamps a well-formed orchestration_decision (chosen_shape, predicates_fired
  always present, rationale, ts) back onto the packet — preserving every other
  field. am failures degrade to the single-agent floor; never hangs (4s timeout)
  or errors the live path.
- /discovery STEP 6 (skills + skills-codex twin) now invokes it after the packet
  write — ValidateShape's first live caller.

Acceptance: running stamp-shape on a live packet produces a validated
orchestration_decision; --unattended fires durability:unattended and overrides a
single-agent proposal to atm-only (live smoke verified). 8 new tests cover
am-output parsing, write-set grouping, round-trip field preservation,
predicates_fired-always-present, and the contention-override wire.

Closes-scenario: age-aqu#s-wire
Bounded-context: BC6-Orchestration
Evidence: cli/cmd/ao/rpi_stamp_shape_test.go

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 14:01:27 -04:00
Boden Fuller c7189017e0 feat(eval): ao eval scenario-ab — RunScenarioAB knowledge A/B with deterministic gate (age-kf-s1-close-loop-0ly.2 #kf-b-runscenarioab)
New RunScenarioAB adapter (cli/internal/eval/scenario_ab.go) runs a scenario.v1
holdout WITH vs WITHOUT the gold pull through injectable runner+judge seams,
emits a ScenarioDeltaScorecard, and applies a DETERMINISTIC gate over the
machine-readable (cross-family) judge output: fail-loud on delta<=0 (the
ADR-0002 spray returning), on the treatment missing the satisfaction threshold,
or on summed token cost over budget. The ao eval scenario-ab command wires a
thin codex-exec default (Law 0) behind the seam; tests inject fakes (no live
models, no hangs). Adds scenario.Load (the production reader). Live proof is KF-C.

Closes-scenario: age-kf-s1-close-loop-0ly.2#kf-b-runscenarioab
Bounded-context: BC4-evaluation
Evidence: .agents/plans/2026-06-16-knowledge-field-ab-runner.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 12:46:50 -04:00
Boden Fuller a04b6d51fc feat(lookup): ao lookup --gold retrieves from the OKF gold wiki
Slice D from IMPROVE-DISCOVERY (re-baselined to a source switch, not a
subsystem rebuild — and targeting the CANONICAL retrieval command: ao inject is
deprecated, ao lookup is its successor).

- ao lookup --gold reads .ao/wiki/{learnings,patterns,findings} via the existing
  scorers (collectLocalLearnings/rankLearnings, collectPatternsFromDir,
  collectFindingsFromDir); no global/canon merge (gold is already curated).
- goldDocFiles excludes OKF reserved catalog files (index.md/log.md) so they're
  never surfaced as knowledge.
- citation recording unchanged (--cite retrieved/applied still works → feeds the
  existing reward loop, the seam Slice B will use).

Proven by TestGoldDocFiles_ExcludesReserved + TestCollectGoldKnowledge_SkipsCatalogFiles
+ live e2e (ao lookup --gold --query ratchet returns gold docs, no catalog noise).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 07:45:22 -04:00
Boden Fuller 3dfe75abe4 docs(cli): regenerate COMMANDS.md for ao wiki gold + --gold flags
Restores TestCobraConformance: the wiki-okf-gold work added 'ao wiki gold',
--gold on wiki index/search, and --gold on compile; the generated CLI
reference now matches the live Cobra tree.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 02:10:10 -04:00
Boden Fuller 5b657ff0d3 feat(corpus): field-level learning seam schema + classify migration (ag-2srq1 #field-level-seam)
S3 of epic ag-k7tq9 (corpus private/public separation). Formalize the
promote-time, field-level seam from the cross-family council verdict: the
corpus is lossless and private-by-default; only an abstracted lesson crosses
into the public wiki, gated by two fail-closed frontmatter fields.

- schemas/learning.v1.schema.json: +sensitivity (enum unknown/private/public,
  default unknown) +publishable (bool, default false) — allowlist ceiling
- docs/contracts/corpus-learning-seam.md: field-boundary SOT (lesson crosses;
  evidence/provenance/source_session never do); cites the council verdict
- ao corpus classify: dry-run-by-default annotator; operates on the YAML fence
  textually (never parses the body) so one junk record can't abort; idempotent;
  skips meta docs (CORPUS-POLICY.md, README.md, ...)
- L1 + L2 tests for the annotator, the dir walk, and the command

Applied to the private corpus (boshu2/agentops-corpus): 342 learnings annotated
with safe defaults, 1 meta doc skipped, idempotent. Boundary verified — 0
.agents/learnings changes in the public repo.

Closes-scenario: ag-2srq1#field-level-seam
Bounded-context: BC1-Corpus
Evidence: docs/contracts/corpus-learning-seam.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 16:08:03 -04:00
Boden Fuller 5e4f890909 feat(corpus): ao corpus scan — fail-closed deny/PII leak detector (ag-b0x50) 2026-06-15 14:55:35 -04:00
Boden Fuller c2aed76df9 feat(rehydrate): ao rehydrate — the read-side of handoff→clear→rehydrate (ag-7k2g2)
S1 of epic ag-2jp7l (self-healing context loop), the read-side complement to S0.
After /clear, a lane (or a peer that just cleared this pane) runs 'ao rehydrate'
to restore the working thread from the latest handoff artifact — the primitive
S3 (peer-control) will call after clearing a peer.

Composes S0's artifact (does not duplicate): reads the most-recent
.agents/handoff/*.json, renders a dense re-bootstrap brief (goal, active bead +
'br show', reservations to re-acquire, next action, recent commits), points at
'ao session bootstrap' for full orientation, and marks the handoff consumed (the
consumed/consumed_at hook = the mine→measure→improve compounding feed). --peek
reads without consuming; --json emits the raw artifact.

Pure helpers (pickLatestHandoff, renderRehydrateBrief) unit-tested; the brief
omits fields the handoff lacks (never invents a bead/next-action). DOGFOODED:
ran against the real handoff written earlier this session — rendered a complete,
usable brief (charter + comms topology + next action), closing handoff→rehydrate
end-to-end on real data.

Closes-scenario: ag-7k2g2#rehydrate-readside
Bounded-context: BC5-runtime
Evidence: cli/cmd/ao/rehydrate_test.go

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 12:18:27 -04:00
Boden Fuller 49ad7d48aa feat(provenance): ao provenance position — navigator's where-am-I read surface (ag-cuhdj)
Read-only command that reports the navigator's current position by reading
the provenance ledger for landed bead→commit edges (wasGeneratedBy). Degrades
gracefully on an empty/genesis-only ledger. Agent-ergonomic --json output.

Closes-scenario: ag-cuhdj#position-reports-recent-landed-arc
Closes-scenario: ag-cuhdj#position-degrades-gracefully-empty-ledger
Bounded-context: BC1-corpus
Evidence: cli/cmd/ao/provenance_position_test.go

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-15 07:34:13 -04:00
Boden Fuller aaa9901f68 feat(provenance): verdict→commit emitter — feed the milestone-1 SENSOR verdict half (ag-cm8nd)
ao provenance emit-verdict --file <verdict.json> parses bead_id, head_sha,
disposition from a pawl-verdict artifact and appends a schema-valid,
hash-chained edge (verdict --wasDerivedFrom--> commit) to the provenance
ledger. Verdict node id = <bead_id>@<sha[:7]>, trust_tier=inferred.

Wired non-blocking into scripts/pawl-verdict.sh write (after atomic rename,
|| true). Idempotent, honest, same discipline as emit-landed (ag-62jrm).

Tests: registration + L2 store (ledger grows, chain verifies, re-emit
is idempotent) + pure parser + pure edge builder.

Closes: ag-cm8nd

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-15 07:31:08 -04:00
Boden Fuller e17d68b9ec feat(provenance): wire landed-bead emitters — feed the milestone-1 SENSOR (ag-62jrm)
GOALS milestone 1 (position signal) was 'floor poured, unfed': ag-8jf97 built
docs/provenance/ledger.jsonl + ao provenance add/verify + the tamper gate, but
nothing auto-emitted — only the genesis row existed. This plugs the sensor in.

New: ao provenance emit-landed. For the commit(s) being landed, it appends a
schema-valid, hash-chained 'bead --wasGeneratedBy--> commit' edge per bead the
commit cites (Closes/Closes-scenario trailer or the parenthesized PR-title
convention). Honest trust tier 'inferred' (a deterministic read of the commit,
never a self-grade); idempotent (re-emit is a no-op). The bead-close mapping is
honest: in push-to-main, a bead closes when its arc lands on main, so emit-on-
landed-commit IS emit-on-close.

Wired automated + human-free at the land path: the pre-push gate (both the live
Go-gate dispatcher scripts/hooks/pre-push.local and the bash escape-hatch
scripts/pre-push-gate.sh) runs scripts/emit-landed-provenance.sh AFTER a PASS,
which emits for origin/main..HEAD and commits the ledger growth as a trailing
sensor commit (one-push lag). Non-blocking by construction (always exits 0,
slice-0 graceful-degrade), skippable via AGENTOPS_PROVENANCE_EMIT_SKIP=1, and
self-terminating (the provenance commit cites no bead → no further emission).

Smoke-caught + fixed: the conventional-commit scope 'feat(cc-hooks):' was
mis-read as a bead id; the title-parens matcher now requires start/whitespace
before '(' so scopes are excluded.

Tests: pure extractor (6 cases incl. scope-exclusion + no-false-positive),
edge-shape, L2 ledger-grows-and-stays-intact through the real store, wrapper
bats (skip/happy/no-op/non-blocking). Gate green 23/23; full cli suite green;
pre-push-gate self-test 40/40. CLI surface regenerated.

Closes-scenario: ag-62jrm#emits-edge-on-land
Closes-scenario: ag-62jrm#ledger-grows-beyond-genesis
Bounded-context: BC1-corpus
Evidence: cli/cmd/ao/provenance_emit_test.go

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 22:43:59 -04:00
Boden Fuller e4fcd05a61 feat(dynamo): ag-qzinh — compute yield gauges + shadow-mode actuation hypotheses
Q first-pass-yield numerator now requires the accept to be authorized by the
attempt-1 gate-verdict specifically: a bead counts as clean-first-pass ONLY IF
its attempt==1 gate-verdict is CONFIRMED AND an accept event references that
attempt-1 verdict's head_sha (same bead). A bead REFUTED on attempt 1 and only
later CONFIRMED — whose accept is bound to a later attempt's head_sha — no longer
inflates Q. Denominator unchanged (distinct attempted beads, difficulty-weighted).

Fixes the codex check-7 BLOCKING bug (loose accept↔verdict match) and adds the
missed test cases: late-confirm-not-clean, clean-first-pass positive, and the
loose-match regression guard. E test now also exercises HOLD (E counts ESCALATE
and HOLD). Re-dogfood still prints Q=0 for the dynamo run (both beads attempt-1
REFUTED).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 21:17:09 -04:00
Boden Fuller aa6a623277 feat(dynamo): ag-grcz3 — yieldledger durable per-bead event stream
Append-only JSONL yield ledger (yieldledger-event.v1): a durable,
bead-keyed operational event stream (accept | gate-verdict | usage) so
an agent factory's per-bead yield (A, R, A/R, Q, E, L) is computable
from DATA, not prose. Read by ag-qzinh (the gauges).

Rework addressing cross-family codex REFUTE of the prior commit:
- B1 Writer is now concurrent-append-safe: O_APPEND JSONL (one event
  per line), no read-modify-write, no shared tmp — fungible lanes can
  merge concurrently without lost/collided events.
- B2 codec enforces the closed schema (DisallowUnknownFields on the
  envelope AND every typed body) — an unknown field is a REJECT.
- B3 reconcile-pr.sh emits a gate-verdict for ALL dispositions
  (CONFIRMED/REFUTED/ESCALATE/HOLD) right after the gate verdict,
  before exit-5 — Q's denominator + E are now computable.
- B4 reconcile-pr.sh emits a usage event at close (R/A-R/L source).
- B5 accept emit stays strictly post-MERGED; post-decision emits
  backgrounded so a slow emit can never delay the merge/close path.
- B6 tests for the real risks: concurrent-append (-race), closed-schema
  rejection, REFUTED/HOLD round-trip.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 20:50:45 -04:00
Boden Fuller 23ddcf29b9 merge: ag-8jfp0 recover stale claims through br (not retired bd)
Cross-family gate (orchestrator sole-merge): claude review of codex-authored work,
author!=reviewer. Evidence: beads_recovery_test.go green, bd->br re-point + BEADS_DIR
handling verified in beads_resume.go/beads_stale.go.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 16:38:42 -04:00
Boden Fuller bf8837bd39 fix(beads): recover stale claims through br (ag-8jfp0) 2026-06-14 16:34:33 -04:00
Boden Fuller d7ae725ffa fix(rpi): default phased runtime to codex (ag-nbh9i) 2026-06-14 16:28:37 -04:00
Boden Fuller 479891017e feat(provenance): create the SDLC provenance ledger + ao provenance append/verify + tamper-evident gate (ag-8jf97)
docs/provenance/ledger.jsonl was declared the append-only SOT in CLAUDE.md
("ledger wins on disagreement") but the file was never created and nothing
verified it in place — a doctrine-level lying instrument. This pours the
real slab:

- Seed docs/provenance/ledger.jsonl with the genesis event
  (ag-8jf97 bead --wasGeneratedBy--> landing branch, trust_tier=authored).
- Add `ao provenance verify`: verifies the COMMITTED chain in place (no
  re-sort/re-chain, unlike `export --verify`), so a tampered field, forged
  hash, or reordered row is caught and the offending FILE LINE is named.
  provenancegraph.Store.VerifyFile() is the line-accurate verifier.
- Wire the gate: scripts/validate-provenance-ledger.sh --gate requires the
  committed ledger to exist, be schema-valid per line, and be an intact hash
  chain; registered as a blocking T1 CI step in validate.yml.
- Tests (windshield-correctness): L1 deterministic hashing (existing), L2
  intact-chain pass, L2 TAMPER (payload-flip / forged-hash / reorder all FAIL
  naming the line), missing-file-is-empty-intact, append-creates-genesis;
  plus bats coverage of the committed ledger + --gate + tamper path.

Hash discipline follows the schema + existing cli/internal/rpi/ledger.go
(genesis prev_hash = "", hash = sha256(payload_hash+"\n"+prev_hash)) — the
brief's 64-zero/concat variant was superseded per the contracts-over-narrative
precedence rule.

Closes-scenario: ag-8jf97#provenance-ledger-tamper-evident
Bounded-context: BC4-Factory
Evidence: docs/provenance/ledger.jsonl

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 20:05:54 -04:00
Boden Fuller afb3535dcd fix(converge): harden context-quorum from pre-land refuter findings (ag-converge-hardening-wof1r)
Cross-vendor pre-land refuters (fresh Claude + read-only Codex, 2026-06-13)
found real residual on the landed converge feature. Fixes:

P1: converge.go RunE now exercises the kernel (resolve LAW-0 transport, build
the non-mutating author_neq_validator judge packet, derive the bounded-loop
config) and emits a real plan instead of a vacuous print — the primitives are
reachable from the command, not dead code. (+kill-dir flag.)

P2 (security): CanonicalizeContextID (trim + casefold + unicode/whitespace
collapse via strings.Fields) is applied before context dedup in BOTH
CheckSignificantActionDetailed and tickCouncilGate, so a single agent cannot
forge >=2 'distinct contexts' via 'ctx-1'/'CTX-1'/'ctx-1 ' variants.

P3: belt-and-suspenders author exclusion — an ACK whose AgentID==ActorID is
dropped even when ActorContextID is empty (author can't count its own ACK).

#8: convergeEvaluateRound takes an optional minContexts (variadic, preserves the
frozen single-arg acceptance call) so it cannot silently disagree with
convergeRunBounded's cfg.MinContexts.

All 30 frozen acceptance scenarios still green; new L1 tests for canonicalization
collapse, AgentID author-exclusion, RunE-exercises-kernel, evaluateRound floor.
(Refuter P0 'not on main' was a stale-checkout artifact — all slices are on
origin/main; dismissed.)

Closes-scenario: ag-converge-hardening-wof1r#refuter-residual
Bounded-context: BC5-Runtime

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 14:32:17 -04:00
Boden Fuller 16a67c1d41 feat(converge): ao converge bounded judge-panel convergence loop (ag-slice2-converge-orchestration-028l1)
New cli/cmd/ao/converge.go composing existing AgentOps Go into the fix->re-run
judge-panel loop:
- convergeJudgeAgreement: vote-agreement criterion (>=N distinct PASS contexts,
  zero FAIL); reasons name the PASS/FAIL split
- convergeFailTracker: 3-CONSECUTIVE-fail BLOCK (resets on a passing round)
- convergeResolveTransport: Claude->codex-dispatch, Codex->pane-delegation;
  UsesClaudePrint hard-wired false in EVERY branch (LAW 0)
- convergeBuildJudgePacket + codexTaskPacket.AuthorID() + convergeVerifyReceipt:
  non-mutating judge packet + author_neq_validator (the fix is the orchestrator's,
  never the dispatched judge's)
- convergeRunBounded: max-rounds + .agents/rpi/KILL switch (rpi_loop convention)
- convergeEvaluateRound: fail-closed on empty (nil/empty) verdicts — never a
  vacuous PASS
- converge cobra command (--max-rounds/--min-contexts/--require-cross-family) +
  make regen-all (COMMANDS.md / cli-surface / registry.json)

Closes-scenario: ag-slice2-converge-orchestration-028l1#S2.1-S2.11
Bounded-context: BC5-Runtime

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 13:40:30 -04:00
Boden Fuller e936314e90 feat(skills): ao skills retire <slug> --into <target> — deterministic retire operation (ag-48ybr)
Five phases: validate (phantom/critical/carve-out/--into refusals), remove
trees (skills/, skills-codex/, skills-codex-overrides/, images/*/skills/),
non-lossy text-targeted dispositions ledger flip (active row -> historical,
comments preserved), ordered regen via injectable runner, and a table-driven
ripple scan that exits non-zero while unresolved references remain.
--dry-run plans everything with zero mutations; --json emits a
machine-readable report. No git commands inside the command — the operator
lands; mutations are git-recoverable.

Closes-scenario: ag-48ybr#skills-retire
Bounded-context: BC4-factory
Evidence: cli/cmd/ao/skills_retire_test.go

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 17:05:05 -04:00
Boden Fuller cf8084d227 fix(codex): per-check timeouts + slow-check reporting in image-health (ag-7ixm9)
Each image-health check now runs under a per-check timeout budget
(default 30s, --check-timeout to override). A check exceeding its
budget is killed and reported as FAIL with timed_out/slow flags and
its duration; remaining checks still run. Summary counts slow checks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 15:59:15 -04:00
Boden Fuller a466e0d9ec feat(codex): add image health doctor 2026-06-12 12:50:47 -04:00
Boden Fuller b57bd973f1 feat(codex): add dispatch receipts
Implements ag-codex-runtime-enhancement-o0nds.2.
2026-06-12 12:07:39 -04:00
Boden Fuller 40ee1c34fa chore(skills)!: skill-prune Phase 2 — execute disposition ledger remainder (ag-if7p)
9 remaining ledger rows (49 of 58 already landed via Phase 1 5e4f7e58a):
5 codebase-* skills folded into codebase-audit (references/REPORT-MODES.md,
context_rel adopted), 4 retired. 114 -> 105 skills (97 user-facing + 8
internal). Registry regen: SKILL-TIERS 166->105 (clears Phase 1 backlog),
sync-skill-counts (12 files), codex overrides catalog 114->105, manifest
180->171, context/domain maps, skill catalog. Repairs two validators that
were red on main: validate-agy-plugin.sh (10 stale core_skills + bundle
prune to 17 + drift resync) and validate-skill-flow.sh (5 orphans -> 0;
codebase-audit wired supplier-to plan/validate, handoff allowlisted,
cross-vendor-trust-gate consumes converted-skill). Pre-cull tree archived
at archive/skill-prune-phase2-20260611.

Closes-scenario: ag-if7p#phase2-execute-ledger
Bounded-context: BC1-corpus
Evidence: evidence/skill-prune-phase2.md
2026-06-11 08:39:45 -04:00
Boden Fuller 9c13986717 feat(skills): seal live skill edits
cp-jyi.2
2026-06-08 00:38:35 -04:00
Bo c9c3e27067 feat(cli): ao skills resolve — MECE corpus audit (overlap + coverage gaps) (#841)
## What

Adds `ao skills resolve` — a MECE audit of the `skills/` corpus, ported
from the `control-plane/bin/skill-resolve` prototype
(cp-skill-resolver-mece-dry).

- **Mutually Exclusive (ME):** clusters skills by name-family stem +
description-token Jaccard, surfacing overlapping/near-duplicate skills
as **merge candidates** (the prune queue, cp-dkf).
- **Collectively Exhaustive (CE):** flags thin / description-less
`SKILL.md` files as coverage-quality gaps.

Read-only; mutates nothing.

```
ao skills resolve            # MECE table
ao skills resolve --json     # machine-readable prune queue
ao skills resolve --strict   # CI dedup gate: exits 1 on any ME overlap
```

## Scope decision

This ports the **MECE half** only. The deployment-DRY half (which live
`~/.claude/skills` symlink backs each name, shadows, `--fix`) is an
operator-runtime concern and stays in `control-plane/bin/skill-resolve`.
Two tools, two scopes: product-authoring in `ao`, deployment in
control-plane.

## Implementation

- New `cli/internal/skillsresolve` package, reusing
`skillshealth.ParseFrontmatter` (no reinvention) + cobra wiring in
`cli/cmd/ao/skills.go`.
- Package tests (`resolve_test.go`) + command-level tests
(`skills_resolve_test.go`: registration, `--json` schema, `--strict`
exit).

## Live run

171 skills, 18 ME overlaps, 0 CE gaps — mirrors the prototype
(beads-br↔bv 1.0; mcp-plugins / risk-audit / test families).

## Drive-by fix (separate commit)

`fix(skills): wire security-suite into SKILL-TIERS.md` —
`security-suite` shipped via the image-bundle merge but was never
tiered, leaving `wiring-closure` red on `main`. The HEAD-based
pre-push/CI gate blocks any push while it's red, so it's repaired here.
Not part of the feature.

## Verification

go build ✓ · go vet ✓ · go test (resolve pkg 2/2, command 3/3) ✓ · gofmt
✓ · full pre-push gate green.
2026-06-07 21:12:24 -04:00
Bo 390695b65e ci: report Go gate workflow coverage
Adds Go-gate workflow coverage reporting so ao gate check exposes validate.yml parity instead of hiding the remaining bash orchestration gap.\n\nValidation: GitHub Actions validate workflow passed; local go test ./internal/gates ./cmd/ao passed; regen-all --check passed; ao gate check --full --json --workflow-coverage reports 66 workflow scripts / 45 registered / 40 missing.
2026-06-07 18:52:05 -04:00
Boden Fuller cba058c6ab feat(refinery): ao refinery backstop daemon (ag-qidx P2.1-2.4,2.6)
The bushido continuous-validation backstop: watch main -> full gate on each new
commit -> classify deterministic-vs-flaky (re-run N=3; the 18-30% flake rate
makes naive escalation noise) -> on deterministic blocking FAIL: poison beacon
(.refinery-poison + git note) + fix-bead (bd create) + alert. NEVER reverts
(P2.5 quorum-gated revert deferred to ag-k99u). Backstop-not-gatekeeper: down =
merges still succeed; resumes from .refinery-state. Injectable ports (git/bd/
gates adapters); core tested with fakes (deterministic escalates, flaky doesn't,
green clears, never-reverts). ao refinery once|run; systemd unit + runbook for
bushido. go test green. ag-qidx.
2026-06-07 10:57:08 -04:00
Boden Fuller efbcf7e90a feat(gates): wire ao gate check into the pre-push hook (opt-in) (ag-qidx.20)
GA6: pre-push.local routes through 'ao gate check --fast' when AGENTOPS_GATE_GO=1,
with the from-source bootstrap (go build ./... first — block on the build error
if broken — then build a fresh ao and exec it; pre-mortem BLOCKER-3, no stale
binary). Default stays the bash gate: the Go registry is a 12-check subset until
Phase B reaches parity, and flipping the default early would regress coverage on
the only pre-merge wall. Adds explicit --fast flag. Proven: AGENTOPS_GATE_GO=1
push path = 12/12 PASS via from-source ao. ag-qidx.
2026-06-07 10:36:09 -04:00
Boden Fuller 1c0b3af425 feat(gates): ao gate check command — fast/full/json/fail-fast (ag-qidx.18)
GA4: orchestrated gate surface wiring the BC2 registry + productionGateRunner +
git ChangedFilesPort. Mode is the only variable the 3 consumers pass (hook=--fast,
CI=--full, refinery=--full --json) -> local≡CI on one binary. Exit code = verdict
via the existing gateExitError (0 pass / 1 blocking-fail / 2 internal). Distinct
from 'ao gate run <name>' (single check). Smoke + cmd tests green. ag-qidx.
2026-06-07 10:26:25 -04:00
Bo 3db57964ad refactor(ao): route cron self-adjust to MTO
Routes the old ao cron self-adjust CronCreate renderer/history writer behind the mto-fleet boundary while preserving a machine-readable compatibility shim. Updates reduction accounting to KEEP 453 / RELOCATE 143, regenerates COMMANDS.md and registry.json, and keeps rpi_* deferred. Local targeted Go tests, regen checks, command-surface check, diff check, and fast pre-push passed; GitHub Actions passed/skipped, Cursor Bugbot was pending and bypassed under operator instruction.
2026-06-07 03:17:59 -04:00
Bo 113e737ac8 chore(ao): retire legacy pool migration command
Retires the archived pool migrate-legacy surface while preserving legacy capture ingestion through pool ingest. Partial cp-cd9 slice; RELOCATE seam remains.
2026-06-07 02:41:21 -04:00
Bo bb8d747d3a feat(ao): add harness-neutral bead ports (#810)
## Summary
- add harness-neutral BR/git ports: `ao ready`, `ao close ...`, and bare
`ao claim <id>` while preserving `ao claim bind/list`
- keep top-level gate commands from #809 as the shared gate surface; `ao
close` reuses the typed commit-persist close path and returns success
when the ledger already proves the bead is closed
- regenerate command docs, command surface inventory, matrix counts, and
registry metadata

## Validation
- `go test ./cmd/ao -run TestTick -count=1`
- `bash scripts/regen-all.sh && bash scripts/regen-all.sh --check`
- `go test ./cmd/ao -count=1`
- `go vet ./...`
- `go test ./... -count=1 -short`
- `git diff --check`
- `/tmp/ao-cp-ljp ready` from `/Users/bo/dev/control-plane` returned
`state_source=br`, `ready_count=20`, and counts `{ready:20, open:30,
in_progress:1, closed:19}`
- `/tmp/ao-cp-ljp claim cp-ljp` from `/Users/bo/dev/control-plane`
succeeded and did not dirty the Git ledger
- `PRE_PUSH_SKIP_MKDOCS=1 bash scripts/pre-push-gate.sh --fast` passed;
warning-only executable-spec drift remains pre-existing (`scenarios
--lint`, `trace --orphans`)

BR: cp-ljp
2026-06-07 02:03:39 -04:00
Bo a617df3028 feat(ao): expose membrane gate aliases (#809)
## Summary
- expose the membrane gate surfaces as top-level `ao` aliases:
`verdict-gate`, `council-gate`, `install-guards`, `guard-status`, and
`chaos-test`
- keep the existing `ao tick ...` implementation as the shared backend,
so the shell-oracle port and public aliases cannot drift
- regenerate CLI command docs, surface inventory, matrix counts, and
registry metadata

## Validation
- `go test ./cmd/ao -run TestTick -count=1`
- `bash scripts/check-cmdao-surface-parity.sh --write-surface`
- `bash scripts/regen-all.sh --check`
- `go test ./cmd/ao -count=1`
- `go vet ./...`
- `go test ./... -count=1 -short`
- `/tmp/ao-cp-ltj chaos-test` from `/Users/bo/dev/control-plane` =>
`SMOKE PASS`
- `./tick.sh smoke` from `/Users/bo/dev/control-plane` => `SMOKE PASS`
- top-level alias exit matrix from `/Users/bo/dev/control-plane`:
`council-gate` mixed => 8, unverified => 6
- `PRE_PUSH_SKIP_MKDOCS=1 bash scripts/pre-push-gate.sh --fast` passed;
warning-only executable-spec drift remains pre-existing (`scenarios
--lint`, `trace --orphans`)

BR: cp-ltj
2026-06-07 01:45:16 -04:00
Bo 9ddffab410 feat(ao): add typed tick oracle port (#808)
## Summary
- add `ao tick` as a typed Go port of the control-plane tick oracle
- preserve BR/git boundaries for next/status/claim/reopen/close and port
verdict/council/guard/smoke behavior
- update generated command inventory, registry, CLI docs, and
command-surface fixtures

## Validation
- cd cli && go test ./cmd/ao -run TestTick -count=1
- cd cli && go test ./cmd/ao -count=1
- cd cli && go vet ./...
- cd cli && go test ./... -count=1 -short
- bash scripts/check-cmdao-surface-parity.sh
- bash scripts/regen-all.sh --check
- git diff --check
- PRE_PUSH_SKIP_MKDOCS=1 bash scripts/pre-push-gate.sh --fast
- built /tmp/ao-cp7k6 and compared against
/Users/bo/dev/control-plane/tick.sh for verdict-gate, council-gate,
next; `ao tick smoke` returned SMOKE PASS

Note: fast pre-push gate still reports existing warn-only
executable-spec drift for scenarios --lint and trace --orphans.
2026-06-07 01:26:56 -04:00
Bo f4162649b8 fix(agentops): remove api-print worker paths (#804)
## Summary
- replace AgentOps headless Claude print worker paths with Codex exec or
non-CLI providers
- switch compile auto-detect/default headless CLI runtime from
claude-cli to codex-cli
- fix two shellcheck blockers from the merged skill corpus and refresh
generated docs/hash metadata

## Validation
- bash /Users/bo/acfs/skill-pipeline/scripts/no-api-print-scan.sh
/Users/bo/dev/agentops/skills /Users/bo/dev/agentops/scripts
/Users/bo/dev/agentops/hooks
- shellcheck --severity=error skills/compile/scripts/compile.sh
scripts/eval-agent-harness.sh scripts/run-rpi-phases.sh
skills/agy-rules-workflows/scripts/close-guard.sh
skills/rch/scripts/mine_rch_history.sh
- cd cli && go test ./cmd/ao -run
'TestResolveCompileRuntime|TestPreflightCompileRuntime|TestCompileScriptOptionsPassesBatchFlags|TestRunCompile_EndToEnd_FixtureCorpus'
-count=1
- bash scripts/regen-all.sh --check
- PRE_PUSH_SKIP_MKDOCS=1 bash scripts/pre-push-gate.sh --fast

Note: unscoped
/Users/bo/acfs/skill-pipeline/scripts/no-api-print-scan.sh still flags
ACFS conformance-selftest fixture strings outside this repo; AgentOps
scoped roots are clean.
2026-06-07 00:08:59 -04:00
Bo bc9a846dbd feat(eval): ao eval outcomes ingest --manifest-out emits eval-run.v1 manifest (ag-fy6e #manifest-out-eval-run) (#774)
## What

Adds `--manifest-out <dir>` (+ `--run-id`) to `ao eval outcomes ingest`.
When set, ingest **also** writes `<dir>/<run-id>/manifest.json`
conforming to `schemas/eval-run.v1.schema.json`, so the existing verdict
pipeline (`docs/contracts/eval-verdict-pipeline.md`) can pick it up and
feed the Knowledge Flywheel — closing the **Outcomes→Flywheel loop** for
the eval-run.v1 surface. Bead: **ag-fy6e**.

## How

- New file `cli/cmd/ao/eval_outcomes_manifest.go` (diversifies off
`eval_outcomes_ingest.go`); ingest.go only wires the thin flag.
- Reuses the existing `eval.RunRecord` struct rather than hand-rolling
the schema shape.
- Band mapping: `PASS→{status:pass, verdict:pass}`, `FAIL→{fail, fail}`,
`WARN→{inconclusive, advisory}`.
- `dimension_scores` filtered to the 7 schema-permitted keys (foreign
criterion dropped; `minProperties:1` guarded by synthesizing
`correctness=aggregate`).
- Out-of-process grade → honest schema-valid stubs for
`git`/`runtime`/`environment` + a `notes` provenance entry.

## Deviation from bead text (source-of-truth precedence)

The bead said `status=complete`, but that value belongs to the **other**
SCHEMA.md run-manifest. eval-run.v1's `status` enum is
`pass/fail/error/skipped/inconclusive` — no `complete` member — so this
follows the schema (per CLAUDE.md precedence: executable contracts >
narrative).

## Scope boundary (honest)

This delivers **only** the eval-run.v1 emission named in the bead's
ACCEPTANCE CRITERIA. The downstream `eval-verdict-compiler.sh` /
SCHEMA.md run-manifest path (rc3 struct verdict + holdout-sensitive
`ground_truth_ref/hash`) remains **BLOCKED** on the external compiler
contract + a holdout-safety decision, per the bead's own 2026-05-30
SCOUT CORRECTION. eval-run.v1 carries no holdout-sensitive fields, so
that blocker does not apply to this slice. Bead left open for the
compiler-path follow-up.

## Verification

- `go build ./... && go vet ./cmd/ao/` clean
- 77 eval/outcomes tests pass (`go test ./cmd/ao/ -run 'Eval|Outcomes'`)
- Real CLI run writes a manifest that validates against
`eval-run.v1.schema.json` via python `jsonschema`
- `cli/docs/COMMANDS.md` regenerated for the two new flags

Closes-scenario: ag-fy6e#manifest-out-eval-run
Bounded-context: BC2-Validation
Evidence: cli/cmd/ao/eval_outcomes_manifest_test.go
2026-06-06 10:17:25 -04:00
Bo 8611b71f0f feat(corpus): auto-snapshot before destructive defrag prune (ag-32xk #defrag-autosnapshot) (#771)
## What

`ao defrag` now takes an **automatic, recoverable corpus snapshot**
before it applies a destructive `--prune` (anything that deletes from
`.agents/`). It reuses the same tar.gz machinery as `ao corpus
snapshot`, so an over-aggressive cleanup is always rehydratable via `ao
corpus restore`.

## Why (ag-32xk — moat durability)

The corpus moat is switching-cost / data-gravity, not tech — and it is
one accidental delete away from losing its receipts. Directive #11
history: routine maintenance wiped `.agents/` subdirs, counts went to
~0. A moat you can lose to routine cleanup doesn't feel like a moat.
This closes the most common loss path (the destructive defrag) first.

## Behavior

- **Apply-mode prune** → snapshot first, then prune.
- **Safe-by-default**: a snapshot failure *aborts* the prune — we refuse
to delete files we couldn't first back up.
- **No-op** for: dry-runs (nothing deleted), dedup-only runs (flags,
never deletes), and `--no-snapshot` (new escape hatch).

## Changes

- `corpus_snapshot.go`: extract `createCorpusSnapshot()` as the shared
engine behind both the `ao corpus snapshot` command and the defrag
auto-snapshot (no behavior change to the command).
- `defrag.go`: `autoSnapshotBeforeDefrag()` + `--no-snapshot` flag +
help text.
- `defrag_autosnapshot_test.go`: 6 tests (apply-prune snapshots;
dry-run/no-snapshot/dedup-only skip; missing-corpus aborts; L2
`runDefrag` leaves a recoverable tarball).
- `cli/docs/COMMANDS.md`: regenerated for the new flag (passes
`generate-cli-reference.sh --check`).

## Scope

Slice of ag-32xk. **Remaining (bead stays open):** `ao curate`
auto-snapshot + a canon/promoted-entry delete guard.

## Verification

- `cd cli && go build ./... && go vet ./cmd/ao/` — clean
- `go test ./cmd/ao/` — 9315 pass
- `scripts/pre-push-gate.sh --fast` — passed (CLI docs parity green)

Closes-scenario: ag-32xk#defrag-autosnapshot
Bounded-context: BC1-Corpus
Evidence: cli/cmd/ao/defrag_autosnapshot_test.go
2026-06-06 09:05:37 -04:00
Bo 466842d9bd feat(memory): add citation outcome taxonomy (#741)
## Summary

Implements `ag-rbx8` W3.1 citation outcome taxonomy and reviewer
identity plumbing for memory feedback.

- Adds canonical citation types: `retrieved`, `used-in-final-artifact`,
`helpful`, `harmful`, `refuted`, while preserving legacy `applied`,
`reference`, and `skill_loaded`.
- Extends citation events with `artifact_author_id`,
`cited_by_agent_id`, and `cited_by_model_family`.
- Parses legacy identity aliases in citation JSONL (`author_id`,
`reviewer_id`, `judge_id`, `model_family`).
- Updates `ao metrics cite` with non-author identity flags and rejects
self-authored outcome judgments.
- Teaches citation pipeline and feedback-loop logic that retrieved-only
is exposure, helpful/final-artifact/applied are rewardable, and
harmful/refuted are explicit non-reward outcomes.
- Regenerates CLI command docs and `registry.json`.

## Validation

Focused tests after rebase over #737 (`origin/main` @ `7bbc6569`):

- `go test ./internal/types ./internal/ratchet ./internal/quality
./internal/lifecycle`
- `go test ./cmd/ao -run
'TestMetricsCite|TestProcessCitationFeedback|TestCitationConfidenceBuckets|TestValidateFeedbackCitationType|TestFlagCompletions_Registered|TestComputeCitationPipeline|TestCanonicalCitationType'`
- `go test ./cmd/ao`
- `git diff --check`

Required regen/gate:

- `bash scripts/regen-all.sh` completed generated artifact updates, then
exited on known CMDAO surface parity red (`wiki query`; 30 uncovered
commands).
- `PRE_PUSH_FAIL_FAST=false bash scripts/pre-push-gate.sh` completed
with 5 known non-diff failures:
  - test-fixture parity: `scripts/gc-stale-worktrees.sh`
  - worktree disposition: canonical root dirty/untracked operator state
  - goals validate: local `GOALS.md` lookup red
  - corpus freshness: newest local snapshot over threshold
- contract canaries: known `agentops-core.pre-push-gate-governance`
failure

Diff-owned checks passed in the gate, including go build, go vet,
changed-scope race tests, command/test pairing, registry drift, CLI docs
parity, mkdocs strict build, contract compatibility, CI policy parity,
context-map drift, shellcheck, skill citation parity, and
executable-spec link integrity.

## Review Gate

No self-grade: requesting cross-model review from WindyCastle and
RubyMoose before merge.

Bead: `ag-rbx8`
2026-06-05 02:00:10 -04:00