Commit Graph

161 Commits

Author SHA1 Message Date
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 6d5d111faf feat(skills): land four-vendor skill corpus (#803)
## Summary
- Lands the AgentOps skill corpus across source and Codex wrappers,
including Gemini image targets.
- Integrates the skill branch onto current origin/main and refreshes
generated manifests/catalogs.
- Normalizes local next-work queue enum drift and fixes shellcheck in
alias-collision validation.

## Validation
- bash scripts/regen-all.sh --check
- bash scripts/validate-skill-schema.sh
- bash tests/skills/test-token-budgets.sh
- bash tests/skills/run-all.sh
- bash scripts/audit-codex-parity.sh && bash
scripts/validate-codex-override-coverage.sh && bash
scripts/validate-codex-generated-artifacts.sh --scope worktree && bash
scripts/validate-codex-api-conformance.sh && bash
scripts/validate-codex-runtime-sections.sh && bash
scripts/lint-codex-native.sh
- bash skills/heal-skill/scripts/heal.sh --strict
- PRE_PUSH_SKIP_MKDOCS=1 bash scripts/pre-push-gate.sh --fast

MkDocs strict remains skipped locally via the documented
PRE_PUSH_SKIP_MKDOCS=1 override because the repo currently emits
repo-wide strict-link warnings unrelated to this landing; CI remains
authoritative.
2026-06-06 23:44:42 -04:00
Bo bdd62816ea docs(skills): add trigger markers to judgment-tier skills (ag-okfu #judgment-wave) (#767)
## What

Wave 1 of **ag-okfu** — adds an explicit `Use when:` discovery trigger
clause to the 8 **judgment-tier** skills: `council`, `design`,
`post-mortem`, `pre-mortem`, `red-team`, `review`, `validate`, `vibe`.

`scan_descriptions.py` flagged 73/81 skills with no trigger marker — a
silent skill-selection risk since runtime discovery is pure LLM
reasoning over the `description` field. The judgment tier ships first
because mis-selection there (e.g. grabbing `review` when you needed
`validate`) is the most costly.

## Why this slice

The bead says *"wave by metadata.tier."* This is one coherent wave = one
PR with a single rollback semantic. Remaining tiers (execution 22,
knowledge 8, meta 8, session 6, background 5, product 5, contribute 4,
cross-vendor 3, library 3, orchestration 1) ship as follow-on waves.

## Evidence

- Corpus missing-trigger count: **73 → 65** (the 8 judgment skills now
pass).
- `python3 skills/skill-builder/scripts/scan_descriptions.py skills
--strict` — all 8 judgment skills report `has_trigger=True`.
- `bash scripts/generate-registry.sh --check` → `OK: registry.json is up
to date` (regenerated, descriptions embedded).
- `markdownlint` clean on all 8 changed SKILL.md files.

## Notes

- Does **not** close ag-okfu — the `--strict` gate stays red until all
tiers are done. Advances the bead; unblocks nothing yet (ag-cx7d ratchet
waits on full corpus clean).

Bounded-context: BC1-Corpus
Evidence: skill-domain-map golden gate
2026-06-06 11:33:18 -04:00
Bo b84dcf3ca2 docs(hookless): close cold-start orientation drift (soc-qh2g1 #cold-start-orientation-coherence) (#795)
## Summary

Close the hookless cold-start orientation gap for `soc-qh2g1` by making
the live startup docs and skills point at explicit `ao session
bootstrap` plus pulled context (`ao inject` / `ao lookup`) instead of
hidden SessionStart behavior.

## Changes

- Reframes live docs that still implied automatic startup/handoff
injection to the hookless explicit-command path.
- Updates source and Codex skill mirrors for `quickstart`, `inject`,
`using-agentops`, `recover`, `bug-hunt`, and `session-bootstrap`.
- Expands the cold-start and docs drift gates so `SessionStart hook`,
`startup hooks`, and `auto-inject ... hook` promises fail unless
explicitly hedged as opt-in, removed, or historical.
- Refreshes scoped Codex skill hashes for the touched mirrors.

## Test plan

- [x] `bash scripts/check-hookless-cold-start.sh`
- [x] `bash scripts/check-doc-hooks-drift.sh`
- [x] `bats tests/scripts/check-hookless-cold-start.bats
tests/scripts/check-doc-hooks-drift.bats`
- [x] `shellcheck scripts/check-hookless-cold-start.sh
scripts/check-doc-hooks-drift.sh`
- [x] `bash scripts/regen-codex-hashes.sh --check --only
session-bootstrap,quickstart,inject,using-agentops,recover,bug-hunt`
- [x] `bash scripts/validate-codex-generated-artifacts.sh`
- [x] `bash scripts/validate-codex-lifecycle-guards.sh`
- [x] `bash scripts/validate-agents-split.sh`
- [x] `git diff --check`
- [x] `bash scripts/validate-skill-runtime-parity.sh`
- [x] `bash scripts/lint-codex-native.sh`

Closes-scenario: soc-qh2g1#cold-start-orientation-coherence
Bounded-context: BC1-Corpus
Evidence: scripts/check-hookless-cold-start.sh
2026-06-06 11:23:56 -04:00
Bo 2dbc575ea3 docs(agent-native): add Claude + Codex/NTM runtime reference recipes (ag-ok755 #agent-native-runtime-refs) (#789)
## What

Completes ag-ok755's remaining acceptance: the `agent-native` skill
shipped doctrine-only, missing the two runtime how-to references the
bead requires (linked from SKILL.md per the heal `--strict` rule).

- `references/managed-agents-runtime.md` — **Claude path**: Anthropic
Managed Agents + Agent SDK + self-hosted sandbox. Carries the
three-phase recipe (bundle → expose `ao` → CI-gate), the
planned-mechanism status for `ao agent bundle` (ag-jspr) / `ao mcp
serve` (ag-higd), and the ZDR / no-fork / CI-is-the-gate boundaries.
- `references/codex-ntm-runtime.md` — **Codex/NTM path**: tmux pane
swarms + agent-mail + direct `ao` shell calls (no Managed Agents API),
with the Claude→Codex primitive substitution table.
- Both linked from `SKILL.md` (runtime-recipes pointer + See Also).
- Regenerated derived artifacts: skills-codex source-hash
manifest/marker (source tree changed) and `registry.json`
reference_count (1→3).

## Scope decision

Catalog treatment for `agent-native` stays **`parity_only`** — the codex
artifact is manual-maintained and already tailored (it has a dedicated
Codex/NTM section), and the bespoke override-dir flip is a deliberate
operator TODO in `skills-codex-overrides/catalog.json`. Not
auto-flipping that here (operator judgment).

## Gates run (all green, in-worktree)

- `heal.sh --strict skills/agent-native` — all references linked
- All 7 codex-parity checks: parity audit, generated-artifacts (`--scope
head`), backbone-prompts, override-coverage, runtime-sections,
lifecycle-guards, parity-drift
- `generate-registry.sh --check` — up to date
- `markdownlint-cli2` on all changed/new files — 0 errors

Closes-scenario: ag-ok755#agent-native-runtime-refs
Bounded-context: BC5-Runtime
Evidence: skills/agent-native/SKILL.md
2026-06-06 10:45:10 -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 b008e22f9b feat(domain): name silent-contract-violation + verdict.v1 finding taxonomy (ag-twl8 #verdict-category-taxonomy) (#759)
## What

First slice of the RubricRefine integration epic (**ag-5elx**). Moves
the paper's sharpest idea into the verification membrane — and it's the
dependency that **blocks the flagship** pre-execution gate (ag-rjvf).

- **`skills/domain/references/silent-contract-violation.md`** — new
draft anti-pattern entry. Names the failure class the whole membrane
exists to catch: tool-use code that **runs clean, raises no exception,
and is still wrong** (wrong routing, mismatched output shape, broken
argument provenance). Full Signature / Cost / Cause / Refusal + `bd`
incident citation, indexed in `INDEX.md` under a new "Verification
membrane concepts" section.
- **`schemas/verdict.v1.schema.json`** — adds RubricRefine's 4-category
contract-check taxonomy as an **optional** `category` enum on findings:
`tool-choice | output-contract | call-signature | data-provenance`.
Backward compatible — existing uncategorized findings stay valid
(`additionalProperties:false` preserved), an unknown category is
rejected so the taxonomy can't drift.
- **`tests/scripts/check-verdict-category-taxonomy.bats`** — behavioral
schema tests via python `jsonschema` (valid accepted · all four accepted
· omit valid · unknown rejected · enum exact). Written test-first:
confirmed failing against the unmodified schema, then green.
- **`registry.json`** — regenerated (domain `reference_count` 18→19;
scope-only diff).

## Why

RubricRefine (Anduril, arxiv 2605.09730v3) formalizes the failure
AgentOps' no-self-grade membrane targets, but AgentOps had no name for
it and no shared bucket vocabulary for findings. This slice supplies
both, so every downstream gate (and the pre-execution gate ag-rjvf) can
categorize and ablate contract violations.

## Verification

- `bats tests/scripts/check-verdict-category-taxonomy.bats` → 5/5 (CI
runs it via the bats job; surfaces changed: schemas/skills/docs/bats).
- `scripts/generate-registry.sh --check` → up to date.
- `scripts/check-bead-scenario-coverage.sh --run` → PASS (1/1 scenario
covered & passing).
- Full `pre-push-gate.sh --fast`: green except `corpus-freshness`
(env-local snapshot 8d old; CI sets `AGENTOPS_CORPUS_FRESHNESS_SKIP=1` —
not a PR blocker).

Closes-scenario: ag-twl8#verdict-category-taxonomy
Bounded-context: BC1-Corpus
Evidence: schemas/verdict.v1.schema.json
2026-06-06 08:33:38 -04:00
Bo 57ec8f3290 docs(memory): remove legacy bd-memory guidance
Implements ag-i788 W4.3. Cross-model ACKs recorded in Agent Mail: RubyMoose #214 and WindyCastle #213. Required checks green; merge proceeds under the recorded Cursor Bugbot non-required instability exception.
2026-06-05 04:06:57 -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
Bo 7bbc6569c4 feat(liveness): enforce author-judge quorum gate (ag-xdrw) (#737)
## Summary

Implements `ag-xdrw` independent-verification gates for claim-evidence
and significant orchestration actions.

- Adds `author_id` / `judge_id` metadata to claim-evidence bindings.
- Rejects self-graded bindings at the ClaimEvidenceBinder port.
- Requires non-empty, distinct author/judge metadata for high-assurance
PG3/PG4 evidence while preserving legacy anonymous PG1/PG2 behavior.
- Carries reviewer metadata through in-memory + production
claim-evidence derive paths and durable JSONL binding records.
- Adds `liveness.CheckSignificantAction` for orchestration-tier
significant actions requiring two distinct non-actor ACKs across at
least two model families.
- Regenerates CLI docs/surface/registry after adding `ao claim bind
--author-id/--judge-id` flags.

## Validation

Current head: `e4456538d89660c954ca12d347a186bd1cf68edf` rebased over
#740 (`853d781e`).

Focused checks after rebase:

- `go test ./internal/liveness ./internal/ports`
- `go test ./cmd/ao -run
'TestProductionClaimEvidenceBinder|TestClaimBind|TestClaimList|TestProductionClaimEvidence|TestClaim'`

Required regen after rebase:

- `bash scripts/regen-all.sh` regenerated artifacts, then exited nonzero
on the known CMDAO surface parity red: `wiki query` / 30 uncovered
commands.

Required pre-push after rebase:

- `PRE_PUSH_FAIL_FAST=false bash scripts/pre-push-gate.sh` completed
with 4 known non-diff failures:
  - test-fixture parity: `scripts/gc-stale-worktrees.sh`
  - worktree disposition: canonical root dirty/untracked operator state
  - corpus freshness: newest local snapshot older than threshold
- contract canaries: known `agentops-core.pre-push-gate-governance` Bats
failure

Diff-relevant gates passed in the pre-push run, including changed-scope
build/vet/race, command/test pairing, `goals validate`, registry drift,
CLI docs parity, command-surface matrix canary, shellcheck, mkdocs,
contract compatibility, CI policy parity, and context-map drift.

## Review Gate

No self-grade: cross-model ACKs are recorded in Agent Mail.

- WindyCastle re-confirmed ACK on `547eb36f` and then explicitly called
to rebase once more over #740 and merge this keystone next (#134).
- RubyMoose re-confirmed ACK on `547eb36f`; current `e4456538` is the
same reviewed semantic diff rebased over #740 plus regenerated registry
timestamp.

Review attacks covered:

- PG3/PG4 anonymous reviewer metadata rejects; PG1/PG2 anonymous legacy
remains allowed.
- `AuthorID == JudgeID` rejects.
- Significant-action actor ACK does not count toward quorum.
- Two same-family ACKs do not satisfy quorum.
- Non-quorum path returns `NeedsAdmission`, never `Allowed`.

Bead: `ag-xdrw`
Evidence: TestProductionClaimEvidenceBinder_SelfGradeRejected
Evidence:
TestProductionClaimEvidenceBinder_HighAssuranceWithoutReviewersRejected
Evidence: TestCheckSignificantActionTwoCrossModelACKsAllowed
Evidence: TestCheckSignificantActionActorACKDoesNotCount
2026-06-05 04:05:51 +00:00
Bo 853d781e66 feat(memory): inject canon memory during session bootstrap (#740)
## Summary

Implements ag-11bi W2.3 canon-gated T2 bootstrap memory for `ao session
bootstrap`.

- Selects only canon-promoted established learnings plus high/critical
severity canon anti-patterns from `.agents/canon/learnings`.
- Ranks by `utility * confidence * freshness`, caps selection at 1200
estimated tokens, and warns on stderr when eligible canon memory exceeds
the cap.
- Computes reach through the existing search reach helper, so
established canon memory surfaces as `reach=always` without author-set
reach.
- Emits the memory payload in JSON/robot output and prints selected
memory in the default human bootstrap output.
- Extends `schemas/session-bootstrap.v1.schema.json` and tests the
filter, budget, warning, and human-output paths.

## Validation

Focused checks:

- `go test ./cmd/ao -run 'TestSessionBootstrap'`
- `go test ./internal/search ./internal/types`
- `git diff --check`
- `python3 -m json.tool schemas/session-bootstrap.v1.schema.json`

Required regen:

- `bash scripts/regen-all.sh` regenerated artifacts but exited on the
known CMDAO `wiki query` parity red.

Required pre-push after rebase:

- `PRE_PUSH_FAIL_FAST=false bash scripts/pre-push-gate.sh` completed
with 4 known non-diff failures:
  - test-fixture parity: `scripts/gc-stale-worktrees.sh`
  - worktree disposition: canonical root dirty/untracked operator state
  - corpus freshness: newest local snapshot older than threshold
- contract canaries: known `agentops-core.pre-push-gate-governance` Bats
failure

Diff-relevant gates passed in the pre-push run, including changed-scope
Go race tests, command/test pairing, goals validate, registry drift, CLI
docs parity, command-surface matrix canary, schema checks, CI policy
parity, and shellcheck.

## Review Ask

Requesting cross-model ACK/AMEND/BLOCK before merge. Primary attacks to
run:

- Does any non-canon or candidate/provisional learning enter bootstrap
memory?
- Can the 1200-token cap be bypassed or hidden from callers?
- Does the default human path actually expose the selected memory, not
just JSON?
- Is the generated CLI-surface drift acceptable as regen output on this
branch?

No self-grade for merge.
2026-06-04 23:31:05 -04:00
Bo 0e5ace2eda docs(evolve): backport pre-push fail-fast lever + ao-command surfaces (ag-ro1i #evolve-backport) (#735)
## Summary

Backports two deltas validated on the LIVE plugin-cache evolve skill
(`~/.claude/plugins/cache/agentops-marketplace/agentops/3.0.1/skills/evolve/SKILL.md`)
into the repo source `skills/evolve/`, so they survive a plugin
reinstall. Based on current `origin/main` (post-#724), preserving the
`ao loop` refs — this PR only ADDs the missing lever/surface guidance.

**1. Pre-push fail-fast lever.** Pre-release checklist step 2 →
`PRE_PUSH_FAIL_FAST=false bash scripts/pre-push-gate.sh`, with
rationale: default fail-fast stops at a PRE-EXISTING failure (e.g.
corpus-freshness) and masks the loop's own regressions by ending the run
early. The full no-fail-fast gate surfaces every red.

**2. AO-command surfaces.** Pre-release checklist step 1 →
`scripts/regen-all.sh` and names the two surfaces `regen-all` only WARNS
about when ADDING an `ao` command: cobra `expectedCmds` (x2 lists in
`cobra_commands_test.go`) + the `cli-command-surface` heading counts
(smoke fixture + `matrix.json`). New reference
`references/ao-command-landing.md` documents the full command-landing
procedure, parallel to `new-skill-landing.md` (the skills axis).

## Regen / scope

- `registry.json` reference_count 26→27 (new reference file) +
`skills-codex/*` source_hash for the SKILL.md prose edit — genuine
consequences of the skill touch.
- Pre-existing `docs/cli-surface.*` drift (unrelated `ao loop` coverage
recategorization) was REVERTED — out of scope.
- `regen-all.sh --check` clean across all skill/codex/registry drift
validators.

## Note (install-lag)

The live v3.0.1 plugin-cache evolve skill was ALSO stale vs repo
(pre-#724 `ao evolve` refs, missing the "six derived surfaces" note) —
flagging the install-lag per the bead.

Closes-scenario: ag-ro1i#evolve-backport
Bounded-context: BC4-Factory
Evidence: skills/evolve/SKILL.md
2026-06-04 22:40:57 -04:00
Bo 2a09d29a0e ci(ci): wire skill-eval as T1 changed-files-scoped CI job + pinned ms install (ag-ktjb #skill-eval) (#731)
Wire the existing `scripts/skill-eval.sh` (#726) as a **T1 (≤5min)
changed-files-scoped** CI job in `.github/workflows/validate.yml`.

## What
- New `skill-eval` job (T1, `timeout-minutes: 5`), gated on
`skills`/`ci` path changes.
- **Setup installs PINNED `ms` v0.1.2** (`git+meta_skill@b0bb6bd541…`)
and **gates on `ms --version` + exact-0.1.2 check BEFORE running**. A
failed install or version mismatch **HARD-FAILS the job (red)** — never
green-skips. This is deliberate: the silent-skip-on-absent-ms
anti-pattern recreates the exact "no skill evaluation" gap this gate
exists to close (the same contract `skill-eval.sh` enforces internally).
- **Changed-files scoping** reuses the repo's existing `eval`-job
`skilldelta` convention (`git diff --name-only` against the PR merge
base), kept to `skills/<id>/**` so `ms` runs **only** for skills the PR
touched (`_fixtures`/`_scaffolding` excluded).
- Reports as its own check in `gh pr checks`: added to `summary.needs`,
the parity-gated `docs/contracts/ci-jobs.yaml` manifest, and the
regenerated `AGENTS-CI.md` table.

## Verification (local)
- `scripts/generate-ci-jobs-table.sh --check` → parity PASS (manifest ↔
summary.needs).
- `tests/scripts/generate-ci-jobs-table.bats`,
`test-ci-policy-parity.sh`, `test-pathfilter-gate-coverage.bats` → all
green.
- `validate.yml` parses as valid YAML; both embedded `run:` scripts are
`shellcheck -S warning` clean.
- `markdownlint AGENTS-CI.md` clean.
- `scripts/skill-eval.sh` smoke against the installed `ms 0.1.2`: bad
fixture → non-zero (names no-secrets/required-metadata), good fixture →
0.

Closes-scenario: ag-ktjb#skill-eval
Bounded-context: BC4-Validation
Evidence: docs/contracts/ci-jobs.yaml
2026-06-05 02:24:12 +00:00
Bo 8ad6747913 chore(ao): delete the ao evolve CLI surface (ag-llni slice 1) (#724)
**Slice 1 of ag-llni** — retire `ao rpi`/`ao evolve` (orchestration is
no longer an in-CLI engine). This PR removes the **`ao evolve`** half;
the `rpi*.go` + phased web is slice 2.

**Architecture (operator-confirmed 2026-06-04):** orchestration is
two-tier — *inner loop* (one session) = skills/CLIs/native-subagents +
**Workflows** (`.claude/workflows/operating-loop.js` + `bead-crank.js` —
the Claude encoding of inner-orchestration that was mis-shaped as
`rpi`/`evolve`); *outer loop* (many sessions) = **NTM +
mcp-agent-mail**. Codex inner-loop = NTM + agent-mail for now. Leaf CLIs
(`corpus`/`goals`/flywheel/knowledge loops = BC1 corpus), NTM, and
agent-mail all stay.

### Changes
- Deleted `ao evolve` + 4 subcommands (`config`, `next-work`, `blocked`,
`write-stop-marker`) — 10 files.
- Relocated the one non-evolve coupling, `countCronHistoryRows`, into
its sole consumer `cron_self_adjust.go`.
- Removed `evolve` from the `cobra_commands_test.go` golden
`expectedCmds` list (2 sites).
- Regenerated `cli/docs/COMMANDS.md` (−125 lines) +
`docs/cli-skills-map.md`.

### Verification
- `go build ./...` green · `go vet ./cmd/ao` clean · **`go test
./cmd/ao` = 9251 pass**.
- Net: 13 files, −2192 LOC.

Bounded-context: BC5-Runtime
Closes-scenario: ag-llni#delete-evolve-cli
Evidence: cli/cmd/ao/cron_self_adjust.go
Test-Removal-Reason: ao evolve CLI surface retired (ag-llni) —
orchestration moved to .claude/workflows + NTM; the 5 deleted
evolve_*_test.go covered now-deleted command code, not kept behavior.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-06-05 00:21:53 +00:00
Bo 6c8cb223ea feat(corpus): add reach blast-radius tier {bead|pull|always} (ag-bsf6 #reach-field) (#721)
W2.1 of epic ag-lhu0 (memory-system re-architecture). Adds the **reach**
blast-radius axis, orthogonal to maturity, per the locked duel
architecture.

- `reach {bead|pull|always}` on FrontMatter + Learning; `reach:`
frontmatter round-trips.
- `SanitizeReach` normalizes + defaults absent/invalid → `pull`, and
**never** promotes to `always` (the computed-not-authored invariant —
`always` is derived from maturity==established ∩ canon in ag-oqha).
- `learning.v1.schema.json`: reach enum + default pull; domain vocab
`skills/domain/references/reach.md`.
- Tests: SanitizeReach + frontmatter round-trip/default (88 search-pkg
tests green).

Closes-scenario: ag-bsf6#reach-field
Bounded-context: BC1-Corpus
Evidence: cli/internal/search/learnings.go
2026-06-04 16:52:33 -04:00
Bo 7e8197ba93 ci(skills): consolidate live skill gates into one required skill-gates job (ag-87sv #skill-gates-job) (#723)
Consolidates the live skill-authoring CI gates into one named, required
`skill-gates` job (pure regroup of already-live gates — no behavior
change). Replaces the phantom `scenario-hash-stability` reference in
`CLAUDE.md` with the real `check-scenario-test-linkage` gate now grouped
under `skill-gates`. Adds the `skill-gates` row to the CI-policy-parity
manifest (`docs/contracts/ci-jobs.yaml` + `AGENTS-CI.md`) and the
`gate:skill-gates` SKU to `registry.json` (11→12 gates). New
`tests/scripts/skill-gates.bats` (12 tests) locks the job's structure,
required-check wiring, and drift-sweep behavior.

Part of epic ag-czzf.

Closes-scenario: ag-87sv#skill-gates-job
Bounded-context: BC2-Validation
Evidence: .github/workflows/validate.yml

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-06-04 16:16:04 -04:00
Bo 3d99d4bf69 fix(corpus): unify secret redaction + compile/CI git-safety (ag-sz3h ag-zi90 ag-y2xy #w1-git-safety) (#720)
Completes the **W1 git-safety arc** of epic ag-lhu0 (memory-system
re-architecture) — three beads, one coherent surface, after #719 wired
scrub-on-write into corpus_fs.

- **ag-zi90 (dedup):** `redactContent` (`ao context assemble`) now runs
canonical `llm.Redact` first — a single source of truth for credential
patterns (AWS / GitHub / GitLab / Slack / GCP / PEM, previously
uncovered in this path) — then keeps the supplements `llm.Redact` does
*not* cover: 2-segment app JWTs, sensitive env-var assignments,
high-entropy strings.
- **ag-sz3h (compile chokepoint):** new `ao redact` (stdin→stdout
canonical scrub) bridges the shell compile path; `compile.sh` pipes
every rendered article through it before `os.WriteFile` (loud fallback
if `ao` absent).
- **ag-y2xy (CI backstop):** `check-corpus-secret-scan.sh` scans
**git-tracked** (committed/allowlisted) `.agents` corpus + canon only —
repo-root `.agents` is local-only by policy, so scrub-on-write (#719 +
`ao redact`) is the primary defense and this is the backstop. Wired into
`validate.yml`; bats covers clean / leak-with-file:line /
untracked-not-scanned.

Scrub-on-write is primary; CI is the backstop. Verified: go
build/vet/test (incl. `TestRunRedact`, JWT-dedup regression test green),
bats 3/3, shellcheck clean, conformance regenerated.

Closes-scenario: ag-sz3h#compile-render-scrub
Closes-scenario: ag-zi90#dedup-redactor
Closes-scenario: ag-y2xy#ci-secret-scan
Bounded-context: BC1-Corpus
Evidence: scripts/check-corpus-secret-scan.sh

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-06-04 14:11:55 -04:00
Bo 0c635274e4 docs(skills): reframe /evolve + domain/rpi dispatch as skill-not-CLI (ag-wb6k #skills-dispatch-narration) (#700)
## What
**iowf Wave 1** (ag-wb6k): bring the CLAUDE skills in line with the
codex stance the `validate-codex-rpi-contract.sh` gate already enforces
— `ao evolve`/`ao rpi` are terminal **wrappers**, not the runtime
default; the loop runs as the skill.

- **skills/evolve/SKILL.md** — the "V2 command surface" para framed `ao
evolve` as *the* entry. Reframed: the loop runs as the `/evolve` skill
(chaining `/rpi --auto` cycles); `ao evolve` / `ao rpi loop
--supervisor` are terminal-native wrapper commands for humans/non-skill
runtimes (being retired — ag-iowf).
- **skills/domain/references/rpi.md** — "a substrate dispatches `ao rpi`
as one unit" → "dispatches the `/rpi` loop (an agent running the skill)
as one unit" (matches the ag-88y5 doctrine reframe).

**Left as-is (legitimate, not misframings):** autodev's skill-first "use
`/evolve` or `ao evolve`" listing; ralph-loop-contract's accurate `ao
rpi phased` backend references.

## Verification
Six derived surfaces regenerated. Gates green: **codex-rpi-contract**
(the coupled gate — the codex side already had the correct stance, so no
twin edit needed), regen-all --check, embedded-sync, heal --strict,
registry-drift, body-refs.

## Scope
This is Wave 1 (docs/skills narration) of ag-iowf. The actual `ao
evolve`/`ao rpi` CLI removal is W2–W4 (ag-kbh0/ayst/zoa1, blocked on
soc-1gbpz + live-automation migration).

Closes-scenario: ag-wb6k#skills-dispatch-narration
Bounded-context: BC3-Loop
Evidence: skills/evolve/SKILL.md
2026-06-03 16:09:50 +00:00
Bo 6072dceac5 docs(substrate): reconcile doctrine — skill-dispatch + drop Gas City reference (ag-88y5 #docs-skills-dispatch-reframe) (#696)
## What
Two bounded doctrine-reconciliation slices (one coherent arc):

**ag-88y5** — the out-of-session dispatch unit is the `/rpi`·`/evolve`
**skill**, not the `ao rpi`/`ao evolve` CLI. Per the 3.0
skills-are-the-runtime thesis (using-ntm #693 already frames it this
way), re-narrate the **live** doctrine surfaces so the substrate spawns
an agent that *runs the /rpi skill* over a bead:
- docs/3.0.md, docs/architecture/canonical-loop-model.md,
docs/runbooks/nightly-evolution.md
- skills/using-agentops, skills/agent-native,
skills/domain/references/factory.md

Historical surfaces (MIGRATION-3.0, ADR-0009, release notes) +
CLI-reference left as-is; the actual `ao rpi`/`ao evolve` CLI removal is
the **ag-iowf** epic (live automation callers — overnight-evolve,
release-smoke — must migrate first).

**ag-ogp5** — drop the 4 docs still asserting Gas City as THE reference
substrate → NTM+MCP+managed-agents:
- docs/ARCHITECTURE.md, docs/SCHEMAS.md,
docs/contracts/agents-write-surfaces.md,
docs/patterns/completion-notifications.md (Pattern C)

The ~37 historical/illustrative GC refs are intentionally retained (per
ag-ogp5 scope).

## Verification
regen-all --check, embedded-sync, heal --strict, registry-drift,
codex-rpi-contract, codex-artifacts --scope head — all green.

Closes-scenario: ag-88y5#docs-skills-dispatch-reframe
Bounded-context: BC4-Factory
Evidence: docs/3.0.md
2026-06-03 12:11:23 +00:00
Bo 59b2391b6d feat(skills): add AgentOps-owned using-ntm substrate-orchestration skill (ag-zaoj #using-ntm-skill) (#693)
## What

Adds an **AgentOps-owned, shippable `using-ntm` skill** — the missing
NTM leg of the `NTM + MCP + managed-agents` substrate doctrine
(**ag-zaoj**). Until now `automation-shape-routing` pointed **by name**
at the *proprietary* `ntm`/`vibing-with-ntm` skills, which AgentOps
can't ship — a dangling pointer for standalone users. This is original
content modeled on (not copied from) those.

## The seam: skills are the runtime, not the CLI

The skill teaches driving the open `ntm` CLI as the out-of-session
substrate: **NTM spawns Claude/Codex panes that run the `/rpi` and
`/evolve` *skills*** over a bead queue. It explicitly does **not** use
`ao rpi`/`ao evolve` CLI subprocesses — those terminal wrappers are
retired; the substrate dispatches the whole loop as one invocable skill.

## What lands (15 files, +~440)

- `skills/using-ntm/SKILL.md` + `skills-codex/using-ntm/SKILL.md` (twin)
— the new skill.
- `automation-shape-routing` (+ codex twin) — dangling
`ntm`/`vibing-with-ntm` pointers now route to the owned `/using-ntm`;
`ntm` stays as the CLI tool.
- Six derived surfaces regenerated: `registry.json`, skill-domain-map,
SKU catalog, codex hashes/manifest, context-map; + skill-disposition row
and skill-count bumps (80 → 81) in PRODUCT / ARCHITECTURE / SKILLS /
domain-map / BDD-Gherkin.

## E2E verification (against the real `ntm` CLI)

Per the directive (no `ao rpi`/`ao evolve`): verified every `ntm`
subcommand the skill cites exists
(`spawn/send/activity/attach/doctor/deps/kill/health`) and **fixed the
documented flag to the real `--pane=N` syntax** (it had `--pane N`).
`ntm doctor` runs (bv ✓ / bd ✓ / am ⚠). `docs/cli-surface.*` drift
excluded (pre-existing, unrelated).

## Follow-up (not in this PR)

`ao rpi`/`ao evolve` CLI are slated for retirement; `docs/3.0.md` + the
recent Gas City-prune PRs still reference `ao rpi <bead>` as the
dispatch unit and need a skills-not-CLI reconciliation pass.

## Verification

- `regen-all.sh --check` ALL GREEN · registry-drift PASS · codex parity
PASS · skill-isolation/size PASS · markdownlint 0.

Closes-scenario: ag-zaoj#using-ntm-skill
Bounded-context: BC4-Factory
Evidence: skills/using-ntm/SKILL.md

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-06-03 00:19:22 +00:00
Bo 6685eac0c9 feat(skills): bd-first memory migration — Phase 2 migrate (ag-5u50 #phase2-migrate) (#692)
## Phase 2 — migrate salvaged memory onto bd (epic `ag-5u50`)

**Stacked on #691 (Phase 1).** Review/merge that first; this PR's diff
is Phase-2-only.

Second arc of the **bd-first-memory-migration** skill: take the Gate-A
keepers and stand up bd as the single source of truth — typed memories
with provenance, decay-ranked recall, a generated MEMORY.md cache, and
one unified write path.

### What's in it (beads ag-5u50.10–.14)
- **`.11` `mem.py`** — typed wrapper over bd keys (fenced `<!--mem-->`
header), injectable `BdStore`/`FakeStore` adapter, `parse`/`render` +
**decay-rank** per DATA-MODEL.
- **`.12` `recall.py`** — decay-ranked, token-budgeted recall; bumps
`access_count` (the read signal feeding utility/promotion).
- **`.14` `gen_memory_md.py`** — regenerate the thin, read-only
MEMORY.md cache from bd (permanently fixes the bloat mode).
- **`.13` `remember.py`** — unified write entrypoint (all harnesses →
bd).
- **`.10` `import_memories.py`** — idempotent salvage import with
provenance + import-ledger, **write-paced** (bd auto-commit OOM guard),
`--dry-run`.

### Verification
- **11 hermetic L2 tests** (`tests/test_phase2_migrate.py`), no
`bd`/`ao` dependency — round-trip, decay ordering, supersede exclusion,
episodic-vs-feedback decay, access bump, idempotent import, dry-run,
write-path provenance — all green (17 total with Phase 1).
- **7 Gherkin scenarios** (`references/migrate.feature`).
- Scripts 100-col clean; codex twin hashes refreshed; full local gate
sweep green (skill-lint, codex artifacts/coverage, registry,
context-map, counts, three-gap).

> **CI note:** opened on **local-green** — GitHub Actions stopped
dispatching workflow runs repo-wide ~20:20 (a GitHub-side outage/quota
issue, not this code). All gates verified locally; cloud CI will run
once dispatch recovers.

### Scope guardrails
Writes to bd only — no Phase-3 GC/retire here (that's gated behind the
rollback test). The destructive dogfood on the live box stays
human-gated (Gate C).

Closes-scenario: ag-5u50#phase2-migrate
Bounded-context: BC1-Corpus
Evidence: skills/bd-first-memory-migration/tests/test_phase2_migrate.py

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-06-02 19:07:05 -04:00
Bo b830d163c4 feat(skills): bd-first memory migration — Phase 1 audit (ag-5u50 #phase1-audit) (#691)
## Phase 1 — read-only memory-layer audit (the first arc of epic
`ag-5u50`)

First slice of the **bd-first-memory-migration** skill: a generic,
3-phase AgentOps skill that consolidates fragmented agent-memory layers
(Claude `MEMORY.md`, ao/flywheel, `.agents/*`, openclaw) onto **bd** as
the single source of truth, then GC/retires the rest. This PR ships the
**read-only audit half** — it cannot mutate anything; it produces the
Gate A manifest a human approves before any later migration.

### What's in it (beads ag-5u50.5–.9)
- **`.5` scaffold** — `SKILL.md` (trigger-matched) + references +
`scripts/`.
- **`.6` data model** — `references/DATA-MODEL.md`: type taxonomy
(fact/feedback/project/episodic/procedural), per-memory fields,
decay/utility formula, maturity ladder **wired to eviction** (the fix
for ao's 99%-provisional stall).
- **`.7` scanner** — `scripts/audit_scan.py`: read-only inventory of
every layer (counts, bytes, dup-rate, maturity), `--json`/`--human`.
- **`.8` classifier** — `scripts/classify.py`: keep/drop manifest
(authored=keep, `-pend-`/dups=drop, bloated `MEMORY.md`=drop), dry-run.
- **`.9` Gate A report** — `scripts/audit_report.py`: current-state
table + manifest summary + **reversibility plan naming every later
destructive action and its rollback**.

### Verification
- **6 hermetic L2 tests** (`tests/test_phase1_audit.py`), no `bd`/`ao`
CLI dependency — all green.
- **5 Gherkin scenarios** (`references/audit.feature`).
- Scripts are 100-col clean and `py_compile`-verified.
- **Live-validated** against a real fragmented box: the scanner
auto-found 2 bloated `MEMORY.md` indexes + the 62k-file /
99%-provisional / dup-pile signals.
- Context-map regenerated; drift gate green.

### Scope guardrails
Read-only only. No Phase-2/3 (migrate / GC / retire) code here — those
are gated behind Gate A and ship in later PRs. The destructive dogfood
on the live box stays human-gated (Gate C).

Closes-scenario: ag-5u50#phase1-audit
Bounded-context: BC1-Corpus
Evidence: skills/bd-first-memory-migration/tests/test_phase1_audit.py
2026-06-02 17:10:17 -04:00
Bo d4b3b38422 docs(skills): re-narrate residual live Gas City framing in skills/ (ag-r6g1 #skills-slice) (#686)
## What

Round-3 Gas City doctrine sweep — **skills/ slice** (**ag-r6g1**). Five
skill surfaces still framed Gas City as THE live out-of-session
substrate; re-narrated to **NTM + MCP + managed-agents** per
[`docs/3.0.md`](docs/3.0.md).

## Surfaces (5 source + 6 regenerated derived, +20 −20)

- `skills/compile/SKILL.md` + `skills-codex/compile` twin — "run it on
Gas City" → the out-of-session substrate (NTM + MCP + managed-agents).
- `skills/discovery/references/best-practices.md` +
`skills/validation/references/best-practices.md` — magic-compounding
anti-pattern row's "Gas City for out-of-session" → "the out-of-session
substrate: NTM + MCP + managed-agents".
- `skills/swarm/references/shared-checkout-discipline.md` — "`ao evolve`
via Gas City" → "`ao evolve` on the substrate".
- Regenerated: `registry.json` + codex `.agentops-generated.json`
hashes/manifest for the 4 edited skills.

## Scope

Triaged each ref — only **present-tense live-substrate** framing was
changed; already-correct historical/reference mentions were left alone.
**ag-r6g1 stays OPEN**: the docs/ narrative slice (~30 refs) is deferred
to a later tick. `docs/cli-surface.*` drift excluded (pre-existing,
unrelated to this change).

## Verification (full gate, pre-push)

- `generate-registry.sh --check` OK · codex parity audit passed ·
`regen-all.sh --check` ALL GREEN · markdownlint 0 errors ·
skill-isolation/size clean.

Closes-scenario: ag-r6g1#skills-slice
Bounded-context: BC1-Corpus
Evidence: skills/compile/SKILL.md
2026-06-02 15:16:32 -04:00
Bo 0d82c6e20c docs(skills): re-narrate live Gas City substrate framing to NTM+MCP+managed-agents (ag-94vu #live-substrate-renarration) (#684)
## What

Round-2 Gas City doctrine sweep (**ag-94vu**). Re-narrates the **5 named
skill surfaces** that still framed Gas City as THE live reference
substrate (present-tense operator instructions) to the canonical
substrate trio — **NTM (tmux swarm) + MCP (`ao mcp serve`) +
managed-agents (`ao agent`)** — matching [`docs/3.0.md`](docs/3.0.md).
Driver: post-mortem checkpoint #6 Judge-3 FAIL ("the repo does not yet
speak one doctrine").

## Surfaces (9 insertions / 9 deletions, 5 files)

- `skills/domain/references/factory.md` — "Gas City is the reference
substrate" → the NTM/MCP/managed-agents trio; "Mayor-driven / `gc
sling`" → **swarm-driven** dispatch.
- `skills/scope/SKILL.md` — cron-cadence orchestration reference.
- `skills/session-bootstrap/SKILL.md` — substrate submit reference.
- `skills/SKILL-TIERS.md` — dream retired-pointer note.
- `skills-codex/using-agentops/SKILL.md` — **codex-twin parity**:
dropped the stale `gc` runtime-mode row for the canonical `substrate`
row (the Claude twin was already correct; this one slipped in #679).

## Bounded by design

This PR is the coherent **"live skill operator-instructions speak one
doctrine"** slice. A repo-wide grep shows ~35 more refs across other
skills + `docs/` narrative; bundling them would reproduce the #682
mega-PR that was rejected for sprawl. Deferred to tracked follow-ups:

- **ag-r6g1** — round-3 narrative sweep (remaining skills/ + docs/ ~35
refs; many docs already frame GC correctly as "the reference" — triage
required).
- **ag-82pv** — remove orphaned
`GasCityPhaseEvidence*`/`GasCityTranscript*` dead types in
`cli/internal/rpi/artifacts.go`.

## Verification (local, green)

- codex-parity-drift: PASS · registry-drift: PASS (80) ·
skill-catalog-drift: up-to-date · skill-isolation: PASS · skill-size:
0/0 · markdownlint: 0 errors.
- Residual live-substrate grep over the 5 surfaces: clean.

Closes-scenario: ag-94vu#live-substrate-renarration
Bounded-context: BC1-Corpus
Evidence: skills/domain/references/factory.md
2026-06-02 14:41:43 -04:00
Bo 7455382416 refactor(gc): strip Gas City coupling; adopt NTM+MCP+managed-agents (ag-124p) (#679)
## What

Operator-authorized (Bo, 2026-06-02). Strips the remaining **Gas City**
(`gastown`) coupling from AgentOps and reconciles the **split-doctrine
state** on `main` that the #672–#676 post-mortem flagged: canonical docs
(#676) said NTM+MCP+managed-agents while user-facing docs still
described Gas City as the reference substrate.

The out-of-session substrate is now uniformly **NTM** (local tmux swarm)
+ **MCP** (`ao mcp serve`, shipped) + **managed-agents** (`ao agent`).
AgentOps adopts a substrate; it owns none. Closes **ag-124p** (and
resolves **ag-h93p** — the claude.json gc-hook decouple).

## Deleted (load-bearing surfaces, per the bead's verified scope)

- `packs/agentops/` (the reference City) + root `city.toml`
- `skills/using-gc` + `skills-codex/using-gc` (+
`tests/scripts/using-gc-skill.bats`)
- `gc prime/nudge/mail/hook` wiring in `cli/hooks/claude.json` → now
hookless, matching 3.0 doctrine

## Doc sweep (the split-doctrine fix the post-mortem required)

- **README.md, docs/MIGRATION-3.0.md, docs/dependencies.md,
docs/activation-profiles.md** re-narrated to the substrate trio (the
four files the verdict named)
- AGENTS.md / CLAUDE.md substrate bullets; `dream` skill (+codex twin)
retirement pointer; `shared` / `agent-native` / `using-agentops`
cross-refs; skill-dispositions, context-map, sku-catalog, google-sre
convergence map

## Regenerated derived surfaces

Skill counts (81→80), `registry.json`, `skills/catalog.json`,
context-map, skill-domain-map, codex hashes (14) + manifest, SKILL-TIERS
— all via the generators, validated drift-free.

## Scope boundaries / follow-ups

- **`cli/internal/doctor/fix_bridges.go`** still carries a gc-bridge
detector/fixer subsystem. Out of the bead's verified scope; degrades
gracefully (stat-checks, returns empty when `gc`/`city.toml` absent);
removing it is a test-backed Go change → **follow-up bead**.
- **CLAUDE.md "Gas City bridge — REMOVED"** note kept intentionally:
it's an anti-re-coupling record, not substrate-framing.
- The local-only **bd-closeout** pre-push check (not in CI) is a
pre-existing gap on `main` (its AGENTS.md has no `bd dolt push` line) —
untouched here.
- `thesis-stability` gate FAIL, if present, is the pre-existing
README/PRODUCT/GOALS tagline drift, unrelated to this PR (my
README/PRODUCT edits are the dependency table + skill-count numbers, not
the tagline).

## Verification

`go build ./...` + `go vet` green · skill schema (80/80) + integrity
(heal --strict clean) + lint suite (0 fail) + codex parity green ·
sku-catalog & context-map drift gates green · zero broken markdown links
to deleted paths.

Closes-scenario: ag-124p#gc-coupling-strip
Bounded-context: BC5-Runtime
Evidence: docs/MIGRATION-3.0.md
2026-06-02 09:06:41 -04:00
Bo 3702761e75 feat(canon): earned-promotion team-knowledge tier (ag-bw5s #earned-promotion-gate) (#672)
## What

A team-knowledge **canon**: learnings *earned* into a shared trusted
set, not self-asserted. Adapts Doug Dan's warmind (#671) to the
post-ACFS direction — moat = knowledge earned by verification, not
self-certification.

Promotion requires **two independent, self-guarded signals**:
- **citation** — another engineer/agent USED it (proves useful)
- **verification** — another engineer/agent CHECKED it (proves true;
receipt-bearing)

An independent refutation hard-blocks. The anti-self-certification guard
is generalized to *all* promotion signals: the factory may not grade its
own homework.

## Slices (3 commits, one coherent arc)
1. **Earned-promotion gate** — `internal/canon` (identity guard,
citation + verification JSONL ledgers, gate); `ao canon
cite/verify/status/promote`.
2. **Inject trusted tier** — `collectLearnings` surfaces
`.agents/canon/learnings/` deduped + boosted 1.15× over equal-utility
local; flagged `Canon`.
3. **IdentityResolver port** — `--as` > `AGENTOPS_ACTOR` env > git. Env
tier is the seam to Agent Mail (`whois`) with **no MCP coupling** — `ao`
stays portable. Makes the cross-actor guard hold for humans AND agents.

## Deliberately dropped from #671
Resurrected `hooks/` + session-end auto-sync (hookless regression), the
"Gas City Dispatch (CRITICAL)" doctrine (contradicts
prune-the-coordination-plane), the parallel scoring/maturity engine
(duplicated inject primitives), and the "warmind" name.

## Verification
- `go build`/`vet` clean, gofmt clean
- 9,388 tests green (`cmd/ao` + `internal/canon` + `internal/search`)
- e2e: apollo self-attesting excluded; witness (distinct agent via
`AGENTOPS_ACTOR`) earns promotion; `ao inject` ranks canon first at
equal utility

## Deferred (next)
Wire `verify` → `ao verify`/council (currently operator-attested — the
load-bearing gap); tier-aware gate (heuristics earn citation, not
verification).

Closes-scenario: ag-bw5s#earned-promotion-gate
Closes-scenario: ag-bw5s#inject-trusted-tier
Closes-scenario: ag-bw5s#agent-identity-resolver
Bounded-context: BC1-Corpus
Evidence: cli/internal/canon/promote.go
2026-06-01 00:57:12 -04:00
Bo 20a4e2d393 docs(domain): add Primitive Selection ubiquitous-language entry (ag-1aav #trivial) (#632)
Adds the DDD ubiquitous-language entry for **when to use which behavior
primitive** — Skill (judgment) vs CLI subcommand (deterministic core) vs
Hook (local/bypassable trigger) vs CI gate (authoritative trigger). The
CLI subcommand is the reusable core; hook + CI-gate are trigger surfaces
that call it.

Per operator rule (2026-05-30): CLI for deterministic/repeated logic;
skills are instructions; AgentOps 3.0 is hookless-first (CI is the
authoritative gate).

New `skills/domain/references/primitive-selection.md` (status: draft),
linked in SKILL.md + INDEX.md.

Closes ag-1aav
Bounded-context: BC1-Corpus
Evidence: skills/domain/references/primitive-selection.md
2026-05-31 23:15:03 -04:00
Bo a5a0cdcb0b feat(skills): encode external skill-authoring standard + corpus trigger scanner (ag-vb3q #authoring-standard-trigger-scan) (#663)
## What

RPI cycle on **mining how AgentOps makes skills** (bead `ag-vb3q`),
using the external `meta_skill` best-practices doc as the scoring lens
(methodology only — no Rust `ms` build).

**Research:** codebase-archaeology over the 83-skill corpus + the skill
factory
(`skill-builder`/`skill-auditor`/`heal-skill`/`converter`/`forge`,
`SKILL-TIERS`, `score_agentops_skill.py`, CI gates). The corpus is
structurally excellent: **100% frontmatter conformance, 100% Codex
parity, ~94% references usage**.

**The one finding that matters:** skill selection is pure LLM reasoning
over the `description` field, yet **73 of 81 skills (90%) carry no
trigger marker**. The auditor *has* the checks
(`description-has-triggers`, `trigger-clarity`) but they were downgraded
**FAIL→WARN**, so the gap accumulated silently — a textbook
doctrine-vs-enforcement drift.

## This PR (Implement)

- **`references/skill-authoring-standard.md`** — clean-room distillation
of the external standard, cross-walked to AgentOps's *actual* enforced
rules (best-practice → gate → severity table).
- **`scripts/scan_descriptions.py`** — corpus-wide trigger scanner that
mirrors `audit.sh`'s exact three-form detection (so it never contradicts
the per-skill auditor) and adds the prioritized remediation backlog + a
suggested `Triggers:` stub the auditor never produced. `--json` robot
mode, `--strict` exit code.
- **`tests/python/test_scan_descriptions.py`** — 11 behavioral tests
(all three forms, suggestion quality, CLI exit codes, live-corpus
smoke).
- **`skill-builder/SKILL.md`** — "Corpus authoring health" section +
reference link (194/250 lines).
- Regenerated `registry.json`; patched `catalog.json` reference count.

## Plan (follow-on beads filed)

- `ag-okfu` — add trigger markers to the 73 flagged skills (wave by
tier; acceptance = scanner `--strict` exits 0)
- `ag-cx7d` — ratchet `trigger-clarity`/`description-has-triggers`
WARN→FAIL once the corpus is clean (blocked by `ag-okfu`)
- `ag-mm6q` — fix `generate-skill-catalog.sh` BSD-awk incompatibility

## Evidence

\`\`\`
python3 skills/skill-builder/scripts/scan_descriptions.py skills #
scanned 81, missing 73 (90%)
python3 -m unittest tests.python.test_scan_descriptions # 11 ok
bash scripts/check-registry-drift.sh # PASS — no drift
bash scripts/validate-context-map-drift.sh # exit 0
heal --strict skills/skill-builder # All clean
\`\`\`

Closes-scenario: ag-vb3q#authoring-standard-trigger-scan
Bounded-context: BC4-Factory
Evidence: .agents/audits/meta-skill-archaeology.md
2026-05-31 20:16:38 +00:00
Bo d81ebe3e7d feat(skills): blind sub-agent judge in /vibe + /validation (ag-9jle.5 #blind-judge) (#662)
## What

Adds the concrete **blind sub-agent judge** spawn mechanism in `/vibe`
and `/validation`, building on ag-lmdx.4 (#658) which added the
author!=validator refusal contract + `ao turn verify --allow-self`.

Per operator mechanism (Bo 2026-05-30): validation MAY run in the
authoring session, but the JUDGE must be a fresh-context sub-agent
acting as if it has no authoring context. lmdx.4 supplied the
invariant/refusal + the CLI guard; this bead supplies the actual spawn
instruction.

## Changes

- **`skills/vibe/SKILL.md` Step 4.5** — adds the MANDATORY blind
sub-agent judge spawn: when validating in the authoring session, spawn
the acceptance judge via Agent/Task tool, hand it ONLY the diff/artifact
+ acceptance scenarios + verdict contract (never the authoring
conversation), use its verdict, record `judge_id` != `author_id`. Keeps
lmdx.4's refusal + `--allow-self` escape + `ao turn verify` enforcement.
- **`skills/validation/SKILL.md`** — new "Blind Sub-Agent Judge" section
+ **`references/dag.md` STEP 1** guard that refuses to certify
acceptance (`<promise>DONE</promise>`) when `judge_id == author_id`.
- **`vibe.feature` + `validation.feature`** — testable scenarios
matching the bead acceptance (self-validation still gets an independent
judge; missing blind judge is refused).
- **Codex twins** mirrored verbatim (no symlinks); manifest hashes
spliced to vibe+validation only (8 pre-existing codex drifts left
untouched).

## Gates

- `tests/skills/run-all.sh`: PASS (87/0/0)
- `scripts/audit-codex-parity.sh --skill {vibe,validation}`: PASS
- `scripts/check-codex-parity-drift.sh`: PASS
- `scripts/validate-codex-generated-manifest.sh`: OK (81 skills)
- `scripts/check-scenario-test-linkage.sh`: PASS (both .feature files
allowlisted doc-only)
- No Go touched.

Closes-scenario: ag-9jle.5#blind-judge
Bounded-context: BC2-Validation
Evidence: skills/vibe/SKILL.md
2026-05-31 15:55:18 -04:00
Bo 554eb8c306 feat(turn): enforce author!=validator no-self-grading invariant (ag-lmdx.4 #author-validator-guard) (#658)
## What

Enforce the no-self-grading invariant (`ag-lmdx.4`): a Turn graded by
its own author is autocorrelated, so an Evidenced Turn is not done
unless an independent judge context produced the acceptance verdict.

- **`cli/internal/evidencedturn`** — new `author_neq_validator`
predicate + `AuthorID`/`JudgeID`/`AllowSelf` fields on `Input`. The
predicate FAILS when `judge_id == author_id` (self-graded) or when no
judge identity was recorded (independence that was never recorded cannot
be asserted); the documented, default-OFF `--allow-self` waives it for
the inline fallback. This fills the `TODO(ag-lmdx.4)` extension point
the #657 author left.
- **`cli/cmd/ao/turn verify`** — `--allow-self` flag +
`author_id`/`judge_id` on the turn-input file, wired into the DoD
predicate so a self-graded verdict fails the `validated->closed` guard.
- **`/pre-mortem` + `/vibe` SKILL.md** (and `skills-codex` twins) —
refuse a self-graded PASS verdict; require the judge to be a blind,
context-isolated sub-agent (`judge_id != author_id`); document
`--allow-self` as the default-OFF escape and point at `ao turn verify`
as the enforcement predicate.

## Tests (TDD-first)

`evidencedturn`: self-graded refused / independent accepted /
`--allow-self` waives / missing-judge refused. `cmd/ao`: `turn verify`
self-graded exits non-zero, `--allow-self` passes.

## Gates

`go build ./...` + `go vet` + `go test ./...` green (11845 pass). gosec:
0 new findings in touched files. Codex parity audit +
generated-manifest/artifacts validators pass. `tests/skills/run-all.sh`:
87/87. COMMANDS.md regenerated (the one `--allow-self` line); codex
manifest spliced to pre-mortem+vibe only (no drift-sweep).

## Dedup note (ag-9jle.5)

This bead is the **invariant/guard** (data shape + predicate + skill
refusal). The skill text states the blind-sub-agent requirement, but the
actual blind-judge SPAWNING MECHANISM in `/vibe` + `/validation`
(ag-9jle.5) is NOT implemented here. Partial overlap on the skill
contract; the runtime mechanism remains for ag-9jle.5.

Closes-scenario: ag-lmdx.4#author-validator-guard
Bounded-context: BC2-Validation
Evidence: cli/internal/evidencedturn/evidencedturn.go
2026-05-31 15:05:06 -04:00
Bo 486cb99be5 feat(turn): ao turn verify Evidenced-Turn DoD predicate (ag-lmdx.5 #ao-turn-verify) (#657)
## What

Adds `ao turn verify <bead>` — a legible Definition-of-Done predicate
for an **Evidenced Turn** (ag-lmdx.5). Where the live AP#7 gate checks
Evidence *presence*, this checks turn *sufficiency*: one verdict
answering "can this bead legally transition validated->closed?" with a
clear pass/fail per predicate and a reason for every gap (`--json` too).

## Definition of "Evidenced Turn"

A turn is DONE iff all six predicates pass:

| predicate | meaning |
|---|---|
| `chain_intact` | the bead's state_transition log hash-verifies and
folds (turnstate `FoldVerified`) |
| `terminal_state` | the folded lifecycle state is at the
validated->closed boundary |
| `scenarios_covered` | every Closes-scenario claim has a passing test |
| `evidence_resolves` | every Evidence line resolves to a gate log that
exercised THAT scenario (presence->sufficiency) |
| `provenance_event` | a provenance edge in the ledger references the
bead |
| `no_orphan` | no artifact in the turn's trace-graph is a provenance
orphan |

## How

- New pure, in-memory predicate core `cli/internal/evidencedturn` (no
Dolt / no shell-out) — the testable kernel that defines what "done"
MEANS.
- Builds directly on **#654** `cli/internal/turnstate`
(`Seal/Append/Fold/FoldVerified/VerifyChain`) and
`cli/internal/provenancegraph` (edges + `FindOrphans`).
- `cli/cmd/ao/turn_verify.go` wires `--input` (turn-input JSON: state
log + scenario coverage), `--ledger` (provenance EDGE ledger), and
`--graph` (optional trace-graph for orphan audit). Non-zero exit on
not-done makes it usable as a transition guard.

## Scope note (ag-lmdx.4)

The author!=validator guard is a **separate** concern and is NOT
implemented. It is left as a documented extension point (TODO on
`Evaluate`); the verdict shape already accommodates an extra predicate
row without a reshape.

## Tests

`cli/internal/evidencedturn` (14 cases: complete-turn-done, each missing
predicate fails with a legible reason, multi-gap, blank-bead error) +
`cli/cmd/ao/turn_verify_test.go`
(complete/incomplete/json/orphan/no-graph/missing-input/bead-mismatch).
`go build ./...`, `go vet`, full `cmd/ao`+`evidencedturn` suites (9288)
green.

## Derived surfaces regenerated

COMMANDS.md, cobra `expectedCmds`, command-surface smoke (top=75 sub=188
all=263) + matrix.json, registry.json (cli_commands 72->73),
cli-skills-map.

Closes-scenario: ag-lmdx.5#ao-turn-verify
Bounded-context: BC4-Factory
Evidence: cli/internal/evidencedturn/evidencedturn.go
2026-05-31 14:40:05 -04:00
Bo 427c25b248 feat(provenance): provenance_edges write-model + ao provenance add (ag-x31t.4 #provenance-write-model) (#649)
## What

Builds the WRITE side of the SDLC provenance/intent graph (ag-x31t slice
1). Adds `ao provenance add` / `ao provenance list` plus a new
`cli/internal/provenancegraph` package that seals typed, evidence-backed
edges onto the per-record hash-chained ledger at
`docs/provenance/ledger.jsonl`.

Consumes the schema merged in #637
(`schemas/agentops-sdlc-provenance.v1.schema.json`). Does not touch the
schema (.2), export (.5), or gate (.6).

## CQRS doctrine

Per CLAUDE.md and the council architecture, the committed JSONL ledger
is the **audit authority and source of truth**; any Dolt
`provenance_edges` table is a rebuildable projection that loses on
disagreement. So this command appends the JSONL ledger directly. Hashing
reuses the `cli/internal/rpi/ledger.go` discipline: `payload_hash =
sha256(canonical payload)`, `hash = sha256(payload_hash + "\n" +
prev_hash)`, genesis `prev_hash=""`.

## Behavior

- `ao provenance add <from-id> <to-id> --relation ... [--from-type
--to-type --trust-tier --evidence --ts --json]` — seals + appends one
schema-valid edge. **Idempotent** on edge identity
(endpoints+relation+evidence+trust-tier), so a re-run with a different
timestamp is a no-op.
- `ao provenance list [--json --from-id --relation]` — reads edges back
in chain order.

## Tests (TDD, table-driven, exact-value asserts)

- `edge_test.go`: field/enum validation, deterministic hash chain,
schema-version forcing, tamper + chain-link detection, identity
stability, JSON field-name parity with the v1 schema.
- `store_test.go`: append→read round-trip + persisted-chain verify,
idempotency, reject-invalid-before-write (no file created), corrupt-line
rejection, and **validation of emitted edges against the merged schema
via `scripts/validate-provenance-ledger.sh`**.
- `provenance_add_test.go`: add produces a schema-valid sealed edge +
list reads it back, idempotent no-op, invalid-relation error, list
filters.

## Gates

- `cd cli && go build ./... && go vet ./... && go test ./...` — all
green (11949 pass).
- Command-surface bumped: regenerated `cli/docs/COMMANDS.md`, updated
`cli-command-surface-smoke.sh` + `cli-command-surface-matrix.json` (top
73→74, sub 183→185, all 256→259), added `provenance` to cobra
expectedCmds; `validate-cli-skills-map.sh` PASS.

Closes-scenario: ag-x31t.4#provenance-write-model
Bounded-context: BC4-Factory
Evidence: cli/cmd/ao/provenance_add.go
2026-05-31 13:02:55 -04:00
Bo 4131e7c720 feat(rpi): materialize harvested next-work into durable beads (ag-9jle.3 #lessons-to-beads) (#633)
## What

Closes the missing half of the BDD-Gherkin-wave loop — **lessons →
beads**. Harvested follow-ups landed in `.agents/rpi/next-work.jsonl` as
a queue but never became durable beads, so the flywheel executed without
compounding into the tracker.

New **`ao next-work materialize`**:
- Reads unmaterialized items from `next-work.jsonl` and `bd create`s one
durable bead each.
- Carries `source_epic` + `proof_ref` on **bd's native `--metadata`** —
*not* a forked provenance format. The real provenance graph edge is
deferred to `ag-x31t.4`'s future `ao provenance add`.
- **Idempotent** via the existing per-item `bead_id` back-reference.
Re-runs skip already-materialized / consumed / held-for-review items.
- Flags: `--file`, `--dry-run`, `--json`, `--source-epic`,
`--materialized-by`.
- `skills/post-mortem/references/harvest-next-work.md` now invokes it
after the queue-write (CLI owns the deterministic core; the skill just
calls it).

## First failing test (Gherkin contract)

> Given a completed wave with a harvested follow-up · When materialize
runs · Then a durable bead exists via `bd create` carrying
`source_epic`/`proof_ref`, not only a `next-work.jsonl` queue line.

`TestNextWorkMaterialize_CreatesDurableBeadWithProvenance` + 6 more
(idempotency, skips-consumed/held, dry-run-no-mutation, source-epic
filter, 2 mapping tables) — all green.

## Compass-not-maps pivots vs the locked plan

Verifying each premise before executing (the W1-reconciliation
overstated-scope lesson) caught two beats that were **already done**:
1. The schema fields `source_epic`/`proof_ref` already exist in
`next-work-{item,batch}.v1.schema.json` — dropped the "add fields" beat.
2. The idempotency anchor `NextWorkItem.BeadID` already exists — no new
field invented.

## Boundary

Zero `ag-x31t` files touched; `validate.yml` untouched (parked per
handoff). `ao next-work` is collision-free (distinct from the existing
`ao evolve next-work` ladder recommender).

## Validation

- `cli/cmd/ao` package: all tests green except pre-existing
`TestCronSelfAdjust_RoundTrip` (macOS-only `/tmp` vs `/private/tmp` path
bug — fails identically on clean `main`, passes on CI Linux).
- `TestCobraConformance` + `TestCobraExpectedCmdsMatchRegistration`
updated for the new command; `COMMANDS.md` regenerated.
- `go vet` + `gofmt` clean.

Closes-scenario: ag-9jle.3#lessons-to-beads
Bounded-context: BC3-Loop
Evidence: cli/cmd/ao/next_work_materialize_test.go
2026-05-30 13:55:39 -04:00
Bo d10975314d docs(agent-native): optional SDK PreToolUse/Stop hook adapter reference (ag-50m3 #sdk-adapter) (#620)
## What

**5th and final epic deliverable of ag-7s9fo.** New
`skills/agent-native/references/sdk-hook-adapter.md` — a
clearly-**OPTIONAL** Agent SDK `PreToolUse`/`Stop` adapter (TypeScript +
Python samples) that shells `ao validate --gate` for teams wanting
*in-loop* interception.

The framing is hammered throughout (header + boundaries section):
- **CI (`agent-output-validate.yml`, ag-mptr) is the authoritative
gate.** This adapter is convenience, **not** a dependency, **not** a
hook revival, wired into **no runtime by default**.
- Advisory-only — never hard-block on it; CI is the merge boundary.
- Never inline holdout/eval corpus (Managed Agents are NOT ZDR).

Linked from SKILL.md's existing "Optional: SDK hook adapter" section
(heal --strict ref-linked).

## Acceptance (doc-shaped bead — gates are the verification)

- ✅ Adapter documented as OPTIONAL with explicit "CI is the default, not
this" framing.
- ✅ Shells to `ao validate` / the `standards` checklist.
- ✅ No claim that hooks are required; no always-on hook registered.
- ✅ Example adapter (TS + Py).

## Skill-modification regen (surgical)

Editing the skill shifts its content hash, so: `registry.json`
content-hash + `skills-codex/agent-native` source_hash + the manifest's
agent-native entry. The 6 pre-existing-main codex drifts
(deps/provenance/red-team/release/scenario/trace) were **reverted to
origin/main** (not swept in). Evidence: heal --strict exit 0 ·
codex-artifacts `--scope worktree` PASS · registry-drift PASS · parity
PASS · skill audit WARN(exit 0). Scope-only diff (5 files).

Closes-scenario: ag-50m3#sdk-adapter
Bounded-context: BC5-Runtime
Evidence: skills/agent-native/references/sdk-hook-adapter.md
2026-05-30 02:05:34 -04:00
Bo c4552483be feat(cli): ao mcp serve --print-tools — curated MCP tool-descriptor surface (ag-h1mk #mcp-print-tools) (#619)
## What

New `ao mcp` noun + `serve` verb exposing **`--print-tools --json`** —
the curated, read-mostly MCP tool surface a hosted/SDK Claude loop uses
to orient and self-check. It's the descriptor `ao agent bundle --runtime
managed` (#618) already references. **Claude-only** (Codex shells `ao`
directly).

**Slice 1 of ag-3ucpd** (split per the evolve scope filter — the full
MCP server is genuinely oversized: a from-scratch JSON-RPC stdio
transport + live integration test, no MCP library vendored). This ships
the deterministic, high-value, fully-testable descriptor surface now;
the live transport + transport-round-trip integration test is carved to
the **ag-3ucpd** umbrella for a fresh context.

- `mcpToolDescriptors()` — 6 curated tools (`session_bootstrap`,
`inject`, `corpus_inject`, `standards`, `validate`, `goals_measure`)
with name + description + input_schema + holdout-sensitive flag.
- `mcpToolDenied()` — deterministic **NOT-ZDR holdout refusal**: a tool
call whose args reference `holdout` / `ground_truth` / `.agents/evals`
is denied (cloud MCP surface; eval substrate LOCKED;
`AGENTOPS_HOLDOUT_EVALUATOR` does **not** unlock the cloud surface).
- Bare `ao mcp serve` (no `--print-tools`) errors loudly pointing at the
ag-3ucpd live-transport follow-up — never a silent no-op.

## Tests (TDD-first)

`cli/cmd/ao/mcp_serve_test.go` — 6 cases: curated surface (6 tools,
schemas present), holdout refusal (query + path-escape), clean-call
allowed, `--print-tools` JSON shape, live-transport-not-yet error. `go
vet` clean, gocyclo < 15, full `cmd/ao` suite **9210 pass**.

## New-`ao`-command surfaces (all 5 regenerated up-front)

The corpus-encoded checklist from #618's three-round discovery — applied
in one shot, expecting one-shot-green:
1. `expectedCmds` ×2 (`mcp` inserted alphabetically) ·
2. `cli/docs/COMMANDS.md` (TestCobraConformance) ·
3. `registry.json` (69→70 commands, 164→165 SKU) ·
4. `cli-command-surface-matrix` eval fixtures (71/177/248 → 72/178/250;
smoke PASS) ·
5. `docs/cli-surface.md`+`.json` (`ao mcp serve` covered).

Scope-only diff (10 files, all mcp-attributable; no unrelated drift).

Closes-scenario: ag-h1mk#mcp-print-tools
Bounded-context: BC5-Runtime
Evidence: cli/cmd/ao/mcp_serve_test.go
2026-05-30 01:51:19 -04:00
Bo 7fc46eb76e feat(cli): ao agent bundle — emit runtime-specific AgentOps-native Agent definitions (ag-eguw0 #agent-bundle) (#618)
## What

New `ao agent` cobra noun + `bundle` verb — emits a **runtime-specific
Agent definition** that stitches the AgentOps skill set + the `ao` tool
surface so an out-of-session loop (Managed Agent / Codex-NTM swarm) runs
under the same guardrails. Third child of epic **ag-7s9fo** (after
ag-2wln skill #616, ag-mptr CI gate #617).

- `--runtime managed` → Managed Agents JSON (model + stitched
instructions + `skills[]` + `ao` MCP tool descriptor;
self-hosted-sandbox block on `--sandbox self-hosted`).
- `--runtime codex-ntm` → NTM bundle (skills-codex/agent-native ref +
pane bootstrap running `ao session bootstrap` + `ao inject`); no MCP —
Codex shells `ao` directly.
- Default skills: `session-bootstrap, standards, validation,
provenance`. Flags: `--skills`, `--sandbox`, `--out`, `--json`.

## Security — HARD REFUSAL (NOT-ZDR)

Managed Agents are **not** ZDR. `buildAgentBundle` refuses (non-zero
exit + explicit message) if any selected skill **names/paths a
holdout/eval surface** or its `SKILL.md` body carries a holdout marker
(`private_holdout` / `ground_truth` / `holdout target`).
`AGENTOPS_HOLDOUT_EVALUATOR` does **not** authorize leaking holdout to a
cloud agent. The eval substrate stays LOCKED (no relitigation of
`~/.agents/evals/SCHEMA.md`). Fails closed.

## Tests (TDD-first)

`cli/cmd/ao/agent_bundle_test.go` — 7 cases on the pure
`buildAgentBundle` seam: managed defaults + `ao` MCP descriptor;
self-hosted sandbox block; codex-ntm shape (bootstrap + reference, no
MCP); **holdout refusal**; unknown runtime; default-skill set; managed
JSON required-keys (= the schema contract). All funcs CC < 15 (budget
25). `go vet` clean; full `cmd/ao` suite 9204 pass.

## Gates handled

- Added `agent` to **both** `expectedCmds` lists
(TestCobraExpectedCmdsMatchRegistration).
- Regenerated `cli/docs/COMMANDS.md` (TestCobraConformance) +
`docs/cli-skills-map.md`.
- `ao agent bundle` reads as `public-tested`/`covered`.
`docs/cli-surface.md` left at its standing tolerated state (non-blocking
inventory; reverted to avoid sweeping in unrelated #613 eval-outcomes
drift).

## Notes for review

- **Naming**: `ao agent` (singular, new) sits beside `ao agents`
(plural, AGENTS.md doctor/lint) — different domains, but the
singular/plural proximity is a UX smell. Proceeded per epic spec;
trivial rename if you'd prefer (e.g. `ao agentdef bundle`).
- **Schema follow-up**: the managed-output structural contract is
test-enforced (required-keys); a formal
`schemas/agent-definition.schema.json` + validator wiring can land later
if a downstream consumer needs strict validation. Kept out to bound this
PR.
- Instructions are stitched as skill **names + preamble**, not full
bodies — bounded payload + the agent loads full skills at runtime via
the `ao` tool surface (also avoids over-inlining).

Closes-scenario: ag-eguw0#agent-bundle
Bounded-context: BC5-Runtime
Evidence: cli/cmd/ao/agent_bundle_test.go
2026-05-30 01:28:41 -04:00
Bo 03d2aaa8d7 feat(skills): add /agent-native — make out-of-session agents AgentOps-native, hooklessly (ag-2wln #agent-native) (#616)
## What

First child of **ag-7s9fo** (Make Managed/SDK agents AgentOps-native).
Adds the **/agent-native** dual-runtime skill documenting the **hookless
reframe** of the retired "port the ~50 hooks" idea.

An out-of-session Claude (Managed Agent / Agent SDK loop / self-hosted
sandbox) becomes AgentOps-native via three things — **never hooks**:
1. **Bundle AgentOps skills** into the Agent definition (same `skills/`
files, no fork).
2. **Expose the `ao` CLI as a callable tool** (MCP/shell-tool) so the
loop self-bootstraps + self-validates.
3. **Gate outputs through the SAME CI** as interactive work.

Extends `standards` + `converter`. The SDK hooks become an *optional
thin adapter*, never the enforcement boundary. Managed Agents are NOT
ZDR → no holdout/PII in the agent definition.

## How

Built through the hardened scaffold (ag-cw2y → ag-ekyq → ag-j4l1) — all
6 derived surfaces regenerated in one shot (registry, domain-map,
context-map, counts, codex twin+manifest+marker, dispositions
BC5-Runtime, SKILL-TIERS, using-agentops catalog, embedded sync).
Reverted the swept-in pre-existing drift (6 codex hashes + cli-surface)
per the changed-files-scoped triage.

Caught + fixed an `INVALID_AO_CMD` heal finding: `ao standards` isn't a
command — `standards` is a loaded checklist enforced via `ao validate` +
CI (corrected the references).

## Scope note

The skill documents the *intended* `ao agent bundle` / `ao mcp serve` /
`agent-output-validate.yml` surfaces — those are the sibling child beads
(ag-jspr, ag-higd, ag-mptr). This PR is the skill-doc slice only.

## Evidence

- `heal.sh --strict skills/agent-native` → clean
- `audit-codex-parity.sh --skill agent-native` → pass
- `validate-codex-generated-artifacts.sh --scope worktree` → pass
- `generate-{registry,skill-domain-map}.sh --check` → clean;
`check-registry-drift.sh` → no drift

Closes-scenario: ag-2wln#agent-native
Bounded-context: BC5-Runtime
Evidence: skills/agent-native/SKILL.md
2026-05-29 23:28:11 -04:00
Bo 8a4e78f01c docs(evolve): bake fix-and-repush discipline into the /evolve skill (ag-j4l1 #evolve-discipline-references) (#615)
## What

Promotes this session's hard-won fix-and-repush discipline — which lived
only in the **session-only cron prompt** (expires in 7 days) — into the
**durable `/evolve` skill**, so every future autonomous run inherits it.

## How

- **NEW** `skills/evolve/references/new-skill-landing.md` — the **six
derived surfaces** a new/modified skill must regenerate in one shot
(registry.json being the most-missed; it trips `contracts-sync` +
`correctness(ubuntu)` together), with the `regen-all.sh` shortcut and
the manual codex-twin / `SKILL-TIERS.md` steps.
- `gate-hygiene.md` **+2 subsections**: pre-push **diff-scope check**
(catches half-staged commits like #612 + conflict-resolution collateral
deletions like #600) and **pre-existing-vs-mine red triage**
(mkdocs-strict + the 7 codex `.agentops-generated.json` drifts).
- `SKILL.md` links both from Step 4.5 + the References list.

## Dog-fooding

Built one-shot through its own documented discipline: codex twin hash
refreshed for `evolve`, the 7 pre-existing codex drifts reverted,
manifest surgically rebuilt to the `evolve` delta only. No
inventory/count files touched (correct — adds references, not a skill).

## Evidence

- `tests/scripts/evolve-discipline-references.bats` → **4/4** (locks
both reference links + the two new gate-hygiene subsections)
- `heal.sh --strict skills/evolve` → clean
- `validate-codex-generated-artifacts.sh --scope worktree` → pass

(Companion: ag-cw2y wired the skill-builder *scaffold*; ag-ekyq added
the registry surface; this bakes the operator-side *runtime guidance*
into /evolve.)

Closes-scenario: ag-j4l1#evolve-discipline-references
Bounded-context: BC2-Validation
Evidence: skills/evolve/references/new-skill-landing.md
2026-05-29 22:29:31 -04:00
Bo 79a4558902 feat(skills): add /eval-outcomes — Outcomes as a holdout-safe projection of the locked eval substrate (ag-hdqu0.8 #eval-outcomes-skill) (#613)
## What

Adds the **/eval-outcomes** dual-runtime skill — the user-facing
documentation wrapper for the already-merged `ao eval outcomes
compile/ingest` capability (the Outcomes epic ag-hdqu0, capability beads
.1/.2/.4/.5/.6/.7/.9 all merged). This is the final ag-hdqu0 child.

eval-outcomes documents Outcomes as a **grading transport** that EXTENDS
`validation` + `ratchet` — a *projection* of the locked eval substrate
(`SCHEMA.md`), never an alternate bar. Holdout `target`/`ground_truth`
never leaves the boundary (Managed Agents are not ZDR).

## How

Built through the ag-cw2y scaffold + the 6-surface new-skill discipline
in one shot:
- `skills/eval-outcomes/SKILL.md` + `skills-codex/eval-outcomes/`
(parity_only twin + prompt.md)
- override catalog + manifest/marker (`register-new-codex-skill.sh`)
- dispositions row (BC2 Validation) + SKILL-TIERS row + using-agentops
catalog
- registry.json SKU catalog + domain-map + context-map + narrative
counts + embedded sync

Reverted pre-existing-main drift swept in by generators (6 unrelated
codex artifact hashes, cli-surface.*) per the changed-files-scoped
triage.

## Evidence

- `audit-codex-parity.sh --skill eval-outcomes` → pass
- `heal.sh --strict skills/eval-outcomes` → clean
- `validate-codex-override-coverage.sh` → 80 skills pass
- `validate-codex-generated-artifacts.sh --scope worktree` → pass
- `generate-{registry,skill-domain-map,context-map}.sh --check` → clean;
`check-registry-drift.sh` → no drift

(Local fast pre-push gate references a missing
`scripts/audit-codex-hooks.sh` — pre-existing gate-infra drift absent on
main, not this PR; CI is the authoritative gate.)

Closes-scenario: ag-hdqu0.8#eval-outcomes-skill
Bounded-context: BC2-Validation
Evidence: skills/eval-outcomes/SKILL.md
2026-05-29 21:35:17 -04:00
Bo 606ae03b84 feat(skills): add /burndown — bounded epic-completion loop (ag-3yl8 #burndown-skill) (#600)
## What
Adds **`/burndown`** — the bounded, finite-end counterpart to open-ended
`/evolve`. Drives a finite target (epic / set of epics / explicit bead
list) to *every in-scope bead merged on main* via bounded `/rpi` cycles,
then **STOPS**.

## Why (the gap it fills)
| Command | Shape |
|---|---|
| `/evolve` | open-ended compounding loop — goes dormant, never
*completes* |
| `/crank` | parallel-**wave** one-shot fan-out |
| `/autodev` | contract layer only (not a loop) |
| **`/burndown`** | **serial, resumable, finite-end drive-to-merge
loop** |

## Per-cycle (idempotent — cron / ScheduleWakeup / in-session)
reconcile one outstanding tick-PR (CI-green→merge, pending→skip,
red→fix) → completion-check (all in-scope merged → DONE/STOP) → pick ONE
in-scope ready bead → drive in a worktree → PR with trailers → loop.
Finite stops: target merged · `--max-cycles=N` · operator
STOP/`--hold-merges` · genuine blocker.

This is the generalized, named form of the cron loop we validated
landing PR #599.

## Dual-runtime + gates
- `skills/burndown/SKILL.md` (canonical) +
`skills-codex/burndown/SKILL.md` (Codex-native).
- `audit-codex-parity.sh --skill burndown` **PASS**; `heal.sh --strict`
**PASS**.
- Skill counts synced 76→77 (SKILL-TIERS, PRODUCT, docs/SKILLS,
docs/ARCHITECTURE, using-agentops catalog); `context-map.md`
regenerated; embedded skills synced; `go build ./...` success.

Closes-scenario: ag-3yl8#burndown-skill
Bounded-context: BC5-Runtime
Evidence: skills/burndown/SKILL.md
2026-05-29 21:06:19 -04:00
Bo e4e32a3374 feat(orchestration): dual-runtime OrchestrationPort foundation (ag-nk67 #orchestration-foundation) (#598)
## What

The **dual-runtime OrchestrationPort foundation** — the seam that gates
the
`[EPIC] AgentOps × Claude Managed Agents integration (dual-runtime)`
application epics.
Implements the 3-category model (Claude Workflow / NTM swarm / plain
skill) behind a
single `OrchestrationPort` with safe degradation **NTM → Claude-native →
beads floor**
and a global `AGENTOPS_ORCHESTRATION=off` opt-out.

Derived from a live 3-legged spike (`~/dev/agentops-3cat-spike/`): safe
degradation is
solvable at the selection layer; parallel buys quality/independence not
wall-clock at
small N; NTM is a multi-vendor control plane that runs Claude/Codex as
panes.

## What's in it (10 slices, agent-team driven)

- **Port + adapters** — `cli/internal/ports/orchestration.go` (idiomatic
to existing ports pattern) + new `cli/internal/orchestration/` pkg:
`Selector`, `ntm_probe` (capability detection via `ntm
--robot-capabilities`, not `command -v`), `beads_floor` +
`OrchestrationResult` parity type, degradation-conformance test.
- **Live CLI** — `ao orchestrate select` (`--pin`/`--opt-out`/`--json`);
COMMANDS.md regenerated.
- **Contracts** — `schemas/orchestration-{backend,result}.v1` + paired
`docs/contracts/` docs (structural-floor gated: 41 contracts).
- **Prose** — swarm/shared/crank rewritten NTM>native>beads; **gc
demoted** (soc-2rtm0); `rpi_phased_stream.go` doc-comment fixed.
- **Skills** — `automation-shape-routing` (the 3-category router) +
`workflow-builder` + meta-skill authoring chain wired (`context_rel`);
skill counts synced.
- `lib/orchestrate-select.sh` selector seam.

## Verification (local)

`go build ./...` clean · `go vet` clean · **56 Go tests pass**
(orchestration 31, ports 10, cmd/ao orchestrate 15) · structural-floor
PASS (41) · `lib/orchestrate-select.sh --self-test` 6/6 · live command:
`--json`→claude (NTM absent), `--opt-out`→beads, `--pin claude`→claude.

## Notes

- Bundles the foundation + the routing/authoring skills as one coherent
dual-runtime arc.
- NTM/Claude executors are stubs (the parity contract is real); concrete
executors land in the application epics this gates.
- Two-ladders distinction preserved (spawn-backend ladder A vs CLI
phase-executor ladder B) — see `docs/contracts/orchestration-ports.md`.

Closes-scenario: ag-nk67#orchestration-foundation
Bounded-context: BC5-Runtime
Evidence: cli/internal/orchestration/conformance_test.go
2026-05-29 18:42:45 +00:00
Bo 4107bbed1c refactor(ci): rebuild validate.yml — 67 jobs → 10 purpose-grouped (ag-877 #gate-rebuild) (#592)
## What

First-principles rebuild of `.github/workflows/validate.yml` (ag-877 /
epic ag-5ck, no strangler). Collapses the **67-job** orchestration into
**9 purpose-grouped jobs** (+ `changes` + `summary` = 12 total). All
**59** `scripts/{check,validate}-*` are preserved verbatim — the checks
are the safety logic; the 67-way job fan-out was accretion slop.

Design: `spec/teardown-2026-05-28/gate-rebuild-first-principles.md`

## How

Each purpose job runs its script family as **path-gated steps**
(per-step `if: needs.changes.outputs.X`), with advisory checks marked
`continue-on-error: true` at the **step** level (no whole-job
non-blocking). Notable structural moves:

- **correctness** = matrix `[ubuntu, windows]` — folds `windows-smoke`
in as a Windows leg (it runs `tests/windows/*.ps1`, no `scripts/`
family) instead of a standalone job.
- **doctrine-proof** = the doctrine/GOALS proofs **+ spec-linkage**
(executable-spec link, scenario↔test linkage, AGENTS split,
docs↔learning) — both prove the GOALS/spec apparatus is consistent and
share the Go+ao+Python setup (10→9).
- **summary** absorbs **AP#7** Evidence verification (was
`validate-pr-evidence-claims`) — it needs every sibling job's logs, so
it must run last, not in a parallel group.

## Acceptance (ag-877)

- **ac-gr.1 coverage-proof empty** — `comm -23` of old-vs-new
`scripts/*` invocations is empty (no script dropped). ✅
- **ac-gr.2 job count ≤12** — `grep -cE '^  [a-z][a-z0-9-]+:$'` = 12. ✅
- **ac-gr.3 self-CI green** — this PR runs the new `validate.yml`
against itself (changes `.github/**` → all paths trigger). ⏳ this run.

Coupled job-name contract projections updated in lockstep:
`docs/contracts/ci-jobs.yaml` manifest (64→9), regenerated
`AGENTS-CI.md` table + `registry.json` (gate SKUs 66→11; skills/cli/ref
untouched), and 3 structural bats tests re-anchored to the grouped jobs.
Local: `validate-ci-policy-parity`, `registry-check`,
`validate-sku-catalog-drift`, `check-wiring-closure` all PASS; full bats
suite **740 tests, 0 failures**.

## ⚠️ Operator-gated cutover (do NOT auto-merge)

Branch protection still lists the **64 old** required-check names. This
PR **cannot auto-merge** until an admin swaps them for the new ~10
(**ag-7hpl**), then verifies a no-op PR is gated by exactly the new set
(**ag-1eqi**). Both are repo-admin, repo-wide blast radius →
operator-coordinated.

Closes-scenario: ag-877#uniform-gates-consolidated
Closes-scenario: ag-877#heterogeneous-setup-ported
Closes-scenario: ag-877#changes-preserved-summary-rewired
Closes-scenario: ag-877#coverage-proof-empty-ci-green
Bounded-context: BC2-Validation
Evidence: CI_JOBS_TABLE: PASS
2026-05-29 00:16:47 -04:00
Bo de0699a493 feat(skills): operating-loop-workflow skill ships the workflow to plugin users (agentops-7m7a #plugin-deliver-operating-loop) (#595)
## What
Adds a `operating-loop-workflow` skill that delivers the
`operating-loop` Workflow-tool script to **installed plugin users** and
invokes it.

## Why
Claude Code plugins do **not** load `.claude/workflows/*.js` (recognized
components are `skills/`, `commands/`, `agents/`, `hooks/`, …). PR #594
force-added the script so it *ships in the plugin cache*, but an
installed user still wouldn't see `/operating-loop`. This skill is the
delivery vehicle.

## How
On `/operating-loop-workflow`, the skill:
1. Idempotently copies
`${CLAUDE_PLUGIN_ROOT}/.claude/workflows/operating-loop.js` →
`~/.claude/workflows/operating-loop.js` (copy-if-newer; never clobbers
user edits).
2. Invokes `Workflow({name:'operating-loop', args})` (supports
`{mode:'plan'}` for the plan-only half).

Named `operating-loop-workflow` (not `operating-loop`) to avoid
colliding with the workflow's own auto-surfaced `/operating-loop` in the
dev repo.

## Registries updated
- `skills/SKILL-TIERS.md` row + `sync-skill-counts.sh` (→ 76 total, 66
user-facing)
- `docs/contracts/skill-dispositions.yaml` + regenerated
`docs/reference/agentops-skill-domain-map.md` (76/76)
- `docs/contracts/context-map.md`,
`docs/reference/agentops-domain-evolution-bdd.md` count

## Validation
- `scripts/pre-push-gate.sh --fast` passed (registry-drift,
skill-domain-map golden gate, domain-evolution plan all green)
- `generate-skill-domain-map.sh`: 76 skills, 76 dispositions, clean

Closes-scenario: agentops-7m7a#plugin-deliver-operating-loop
Bounded-context: BC3-Loop
Evidence: docs/reference/agentops-skill-domain-map.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-05-29 02:30:09 +00:00
Bo 450f06f62f docs(skills): autodev reads as config not loop (soc-ozoqh #autodev-config) (#572)
## Summary

Reposition the `/autodev` skill so it reads as **config, not a loop**,
per the canonical vocabulary rule
`skills/domain/references/autodev.md:9,13` — autodev is the
config/intent layer the loop reads each tick, and its description must
never lead with "bounded autonomous dev loops".

- `skills/autodev/SKILL.md`: new `description:` leads with managing the
PROGRAM.md/AUTODEV.md contract and names autodev as the config layer
Evolve and Factory read; "Loop position" prose reframed so the drivers
run the loop, autodev does not.
- `skills-codex/autodev/SKILL.md`: codex mirror description synced.
- Regenerated derived artifacts: `skills/catalog.json`, `registry.json`,
`docs/contracts/context-map.md`, codex hash manifest/marker (autodev
only).
- No command logic changes. Scenario 2 (factory-noun de-collision)
re-sliced to `ag-0qz` (premise drifted — no `ao factory` command
exists).

## Test plan

- [x] `bats tests/scripts/autodev-skill-positioning.bats` (new gate, 6/6
— pins the description + body + derived catalogs + codex mirror to the
config-not-loop rule; written failing-first)
- [x] `scripts/validate-codex-generated-artifacts.sh --scope head`
(parity + manifest)
- [x] `scripts/validate-context-map-drift.sh`,
`scripts/check-skill-catalog-drift.sh`,
`scripts/check-registry-drift.sh`
- [x] `skills/heal-skill/scripts/heal.sh --strict` (autodev clean)

Closes-scenario: soc-ozoqh#autodev-reads-as-config-not-loop
Bounded-context: BC1-Corpus
Evidence: bats tests/scripts/autodev-skill-positioning.bats;
skills/domain/references/autodev.md:13
2026-05-28 06:34:13 -04:00
Bo 39f0850640 ci(validation): test-count non-regression gate for cli/internal (ag-h2z #test-count-noregress) (#562)
## Summary

Adds a blocking T1 CI gate that ratchets test coverage in
`cli/internal/` packages: once tests are added, a PR cannot delete them
without a deliberate, recorded justification. Motivated by PR #558–#561,
which added 248 tests across 6 internal packages with nothing preventing
a future PR from silently removing them.

- `scripts/check-test-count-regression.sh` — for each
`cli/internal/<pkg>` with a changed `_test.go` file between the PR base
and HEAD, sums `^func Test` declarations per package at both refs. A net
per-package decrease fails the gate **unless** a `Test-Removal-Reason:`
trailer is present in a commit body in the range. Counts are summed per
package (not per file), so moving a test between files in the same
package is net-zero. Emergency bypass:
`AGENTOPS_TEST_COUNT_NOREGRESS=skip` (logged). Fail-open when the base
ref is unresolvable (shallow clone), fail-closed only on a verifiable
decrease.
- `tests/scripts/check-test-count-regression.bats` — 8 scenarios (add /
remove-no-trailer / remove-with-trailer / rename / skip-bypass / no-op /
unresolvable-base / cross-file move) driven by throwaway git repos.
Auto-discovered by the `bats-tests` job.
- Wired as blocking `validate-test-count-noregress` (T1): job block +
`summary.needs` + `validate-pr-evidence-claims.needs` in
`.github/workflows/validate.yml`, manifest entry in
`docs/contracts/ci-jobs.yaml`, and regenerated `AGENTS-CI.md` (parity
gate green, 66 rows). `fetch-depth: 0` so the base ref resolves for the
before/after diff.

Green by construction on this PR: it changes no
`cli/internal/**/_test.go`, so the gate is a no-op PASS.

## Acceptance scenarios (from ag-h2z)

- PR adds tests to `cli/internal/X` → gate passes (count up or stable).
✅ bats #1
- PR removes a test without a trailer → gate fails, naming the test +
pkg. ✅ bats #2
- PR removes a test **with** `Test-Removal-Reason:` trailer → gate
passes. ✅ bats #3
- PR renames a test (`Test_X` → `TestX`) → net count stable → gate
passes. ✅ bats #4

## Test plan

- `bats tests/scripts/check-test-count-regression.bats` — 8/8 green
- `shellcheck scripts/check-test-count-regression.sh` — clean
- `bash scripts/validate-ci-policy-parity.sh` — PASS (66 rows)

## Follow-ups (out of scope, immutable)

- Promoting `validate-test-count-noregress` to a GitHub
branch-protection *required status* is repo-admin (immutable scope) —
not done here. The job is blocking via `summary.needs`.

Closes-scenario: ag-h2z#test-count-noregress
Bounded-context: BC2-Validation
Evidence: PASS: no cli/internal/*_test.go changes
2026-05-27 23:22:53 -04:00
Bo c640ef2379 fix(ops): route work selection through reconciliation
Route status/quickstart/release/beads through ao reconcile before backlog selection or release-health claims. Correct release-tag CI skip docs, regenerate registry, and clarify the reconcile release-tag next action.
2026-05-26 19:07:42 -04:00
Bo 3f4b67be49 feat(cli): add reconciliation report (#550)
## Summary
- add `ao reconcile` for a read-only git/GitHub release/beads/.agents
decision report
- emit both human and `--json` output with ranked findings and next
actions
- anchor external checks at the git root and disable bd Dolt auto-start
for this read-only scan
- update generated CLI docs and JSON flag consistency coverage

## Validation
- `cd cli && go test ./cmd/ao -run 'TestReconcile|TestCapabilities'`\n-
`cd cli && make build`\n- `cd cli && bin/ao reconcile --json | jq ...`
(live run detected green main Validate plus failed `v3.0.1` tag
Validate)\n- `bash tests/cli/test-json-flag-consistency.sh`\n- `bash
scripts/validate-ci-policy-parity.sh`\n-
`./scripts/generate-cli-reference.sh --check`\n- `git diff --check`\n-
`scripts/pre-push-gate.sh --fast` (passes; existing warn-only
executable-spec warnings for `scenarios --lint` and `trace
--orphans`)\n\nNote: a broad local `go test ./cmd/ao` run was stopped
after it appeared hung with no child test process; the focused command
tests and build passed, and CI should provide the full-package signal.
2026-05-26 17:03:27 -04:00
Bo 3a829779c6 fix(ci): restore validate parity gates
Restore CI policy parity generation and related skill/registry drift so Validate can run green on main.
2026-05-26 11:41:38 -04:00