## 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)
## What
New CI gate `validate-skill-body-refs` (T1) that scans the **inline-code
prose** of every `SKILL.md` + `references/*.md` (under `skills/` and
`skills-codex/`) for `` `ao <command>` `` / `` `ao <command> --flag` ``
tokens and validates each against the **live `ao` help tree**.
This is the systemic fix for oracle gap #3:
`validate-skill-cli-snippets.sh` only inspects fenced/`ao`-leading
snippets, so a stale command/flag named inside an inline code span
mid-sentence (e.g. `` `ao schedule` `` , `` `ao context assemble` ``)
regenerated after every CLI rename. This gate is the **complement** of
the snippet gate — together they cover both fenced snippets and prose.
## How the gate works
- Builds a robust live command tree: `ao capabilities` (authoritative
top-level) + recursive grouped-help subcommand parse (handles `ao
goals`' category-grouped help that the standard "Available Commands:"
parser misses) + command aliases (`quickstart` → `quick-start`) +
per-command flags.
- Only validates `ao` refs inside inline `` `code` `` spans — bare-prose
English ("if ao available", "ao not installed") is never treated as a
command, eliminating false positives while still catching the genuine
(always backtick-quoted) stale refs.
- Justified historical refs skip via an inline marker (`Superseded` /
`Historical` / `removed in` / `retained for history` / `(historical)`)
on the line/file, or `scripts/skill-body-refs-allowlist.txt`.
## Prose sweep (what made main pass)
The gate detected genuine stale refs on main; swept them to keep the
gate green:
- `ao context assemble` → `ao lookup` (8 sites — the command was never
built; `ao lookup` is the real co-cited replacement)
- `ao cite` → `ao metrics cite`
- `ao worktree gc` → `git worktree prune` (4 sites — `ao worktree` never
existed)
- `ao hooks` removal note → reworded to "removed in 3.0" (matches the
`removed in` historical marker)
## Allowlist contents
- `skills/standards/references/cli-wireup-template.md` — illustrative
naming template (deliberately names `ao loop-history` / `ao loop write`
/ `ao loop tail` as good/bad examples + future placeholders)
- `skills/release/references/release-notes.md`,
`skills-codex/release/references/release-notes.md` — historical
changelog prose (e.g. `ao daemon status` from the daemon era)
## Wiring
- `.github/workflows/validate.yml` — new T1 job + `summary.needs` +
`validate-pr-evidence-claims.needs` + summary echo (65 jobs)
- `docs/contracts/ci-jobs.yaml` — manifest entry (keeps
`validate-ci-policy-parity` green)
- `AGENTS-CI.md` — regenerated via `scripts/generate-ci-jobs-table.sh
--write`
- `tests/scripts/validate-skill-body-refs.bats` — 6 cases (clean pass,
stale-cmd fail, stale-flag fail, historical-marker skip, bare-prose
ignore, committed-tree pass)
## Verification (local, green)
- `bash scripts/validate-skill-body-refs.sh` → exit 0
- `scripts/validate-ci-policy-parity.sh` → PASS (65 rows)
- `scripts/validate-skill-cli-snippets.sh` → passed (no regression)
- `scripts/check-codex-parity-drift.sh` +
`validate-codex-generated-artifacts.sh --scope worktree` → passed (codex
hashes regenerated for the 6 edited skills only)
- `bats tests/scripts/validate-skill-body-refs.bats` → 6/6 ok
- `shellcheck scripts/validate-skill-body-refs.sh` → clean
- `markdownlint` on changed docs → clean
Closes-scenario: ag-4x8#body-ref-gate
Bounded-context: BC1-Corpus
Evidence: scripts/validate-skill-body-refs.sh
## What
Sweep 16 stale CLI snippets across `skills/` and `skills-codex/` that
referenced commands/flags removed from the `ao` CLI. Unblocks the
release `skill-cli-snippet` gate —
`scripts/validate-skill-cli-snippets.sh` now reports **0 failures** (was
16).
## Three fix patterns (verified against the built `ao` binary)
1. **`ao init --hooks`** — the `--hooks` flag is gone (hooks removed).
`ao init` is hookless (only `--stealth`). Fixed snippets to `ao init`
and reframed surrounding prose: hooks are opt-in / author-it-yourself
via the `hooks-authoring` skill, not an `ao` command/flag.
2. **`ao hooks install --force` / `--full` / `ao hooks test`** — the `ao
hooks` command is gone entirely (`unknown command`). Removed the broken
snippets and reframed the quickstart troubleshooting "Optional Hooks"
sections to hookless (CI is the authoritative gate).
3. **`ao inject --query`** — wrong: `ao inject` uses `--context`; the
corpus-query command is **`ao corpus inject --query`**. Fixed
`using-gc/reference-city.md` (canonical + codex). For
`domain/context-compiler.md` the line also carries `--apply-decay
--max-tokens` (which live on `ao inject`, NOT `ao corpus inject`), so
the surgical fix there was `--query` → `--context` on the existing `ao
inject` command.
## Sites fixed (canonical + codex twins in lockstep)
- bootstrap: `SKILL.md` Step 6 + `references/related-runbooks.md` (×2
trees)
- quickstart: `SKILL.md` Hook-activation row +
`references/troubleshooting.md` (×2 trees)
- domain: `references/context-compiler.md` (canonical only — no codex
twin)
- using-gc: `references/reference-city.md` (×2 trees)
`regen-codex-hashes.sh` refreshed the affected
`.agentops-generated.json` + manifest.
## Gate results (all green)
- `scripts/validate-skill-cli-snippets.sh` → **passed, 0 failures**
- `tests/scripts/test-skill-cli-snippets.sh` → 4 PASS / 0 FAIL
- `skills/heal-skill/scripts/heal.sh --strict` → All clean
- `scripts/audit-codex-parity.sh --skill
{bootstrap,quickstart,using-gc,domain}` → all passed
- `scripts/regen-codex-hashes.sh --check` → All hashes up to date
- `cd cli && make build` → green
- markdownlint (cli2) on all changed `.md` → clean
Closes-scenario: ag-d0t#snippet-sweep
Bounded-context: BC1-Corpus
Evidence: scripts/validate-skill-cli-snippets.sh
Wave 5 of 5 (the finale) of the orchestration-substrate retirement
(soc-2rtm0). AgentOps stops being the orchestration substrate; GC is the
substrate. The always-on out-of-session supervisor (the daemon) is
deleted; GC's controller replaces it. Features that ran AS daemon jobs
(wiki build, llmwiki loop) keep their BUILDER CORE (in-process /
GC-callable) but lose the daemon-job-executor wrapper.
## Deleted
- `cli/internal/daemon/` — the whole package (71 .go files + testdata +
AGENTS.md).
- `cli/cmd/ao/`: `agentopsd.go`, `daemon_jobs.go`, `daemon_soak.go`,
`daemon_fake_policy.go`, `rpi_phased_daemon.go` (+ their tests).
- Daemon-only tests: `rpi_status_daemon_test.go`,
`rpi_integration_test.go`, `doctor_product_runtime_test.go`.
- `internal/doctor/fix_daemon.go` (+test) + the daemon
runtime/ledger-health/telemetry/openclaw-consumer checks and the
`--product-runtime` flag in `doctor.go` (the `ao doctor` command itself
is KEPT).
- The `ao daemon`/`agentopsd` command registration (went with
`agentopsd.go`).
- Daemon test scripts: `scripts/validate-daemon-product-e2e.sh`,
`tests/scripts/test-daemon-product-e2e.sh`.
No daemon CI gates existed in `validate.yml` / `ci-jobs.yaml` to remove
(prior waves had already cleared them).
## Severed (KEEP features — builders stay, daemon-job-executor wrappers
removed)
- **wiki** (`internal/wiki/pipeline.go`): removed the
`daemon.JobExecutor` impl
(`JobTypes`/`RunJob`/`PipelineJobSpec`/`parsePipelineJobSpec`/`jobResultFromOutcome`)
+ the daemon import. The builder core — `WikiPipeline`, `RunStage`,
`SelectStage`, the ingest/query/lint runners — is untouched; `ao wiki
lint/query/promote` run in-process.
- **llmwiki** (`internal/llmwiki/executor.go`): removed
`LLMWikiLoopExecutor` + `LoopJobSpec` + the daemon import. KEPT the leaf
builder core in the same file (`Stage`, stage constants, `StageHandler`,
`StageResult`, `DefaultLintIntervalHours`, `SelectStage`,
`rawHasNewerFiles`, `lintIsStale`) — `stages.go` (the real handlers) and
`internal/scope` depend on these. No new package needed; the shared
types already lived in this leaf file.
- **rpi status** (`cmd/ao/rpi_status.go`): severed the
`--daemon`/`--daemon-url`/`--daemon-fallback` read path. `ao rpi status`
now reads only the local run registry (`.agents/rpi/runs/`) — a KEEP
feature. Relocated the tiny `cobraContext` helper here (it lived in the
deleted `agentopsd.go`, only consumer is this file).
- **rpi phased** (`cmd/ao/rpi_phased.go`, `rpi_phased_context.go`):
removed the `--daemon-submit` short-circuit + flags + the
`DaemonSubmit/URL/Token/Fallback` opts fields (only consumer was the
deleted submit path).
## Lost capabilities (intentional, daemon-only)
- `ao rpi status --daemon` (read RPI job state from agentopsd) and `ao
rpi phased --daemon-submit` (queue an RPI run to agentopsd).
- llmwiki `LoopJobSpec.AllowPlaceholderOutputs` opt-in gating (the
placeholder-output-disabled skip) — that gate lived in the removed
daemon-job wrapper, not the stage handlers.
- `ao doctor` daemon runtime/ledger-health/telemetry/openclaw-consumer
checks + `--product-runtime`.
## Verification (all green)
- `gofmt -l` clean (my files), `go build ./...`, `go vet ./...`, `go
test ./...` → 11920 passed, 0 failed, 65 packages.
- `scripts/release-smoke-test.sh` → 108 pass / 0 fail (EXPECTED_COMMANDS
never listed daemon; no scrub needed).
- `tests/windows/test-windows-smoke.ps1` → `Invoke-GoTest` list has no
`./internal/daemon` ref (nothing to scrub).
- `internal/quality/stale_refs.go` → no daemon/agentopsd
deprecated-command entries (`TestDoctorStaleReplacementsExist` passes).
- `tests/smoke-test.sh`, `tests/cli/test-json-flag-consistency.sh`
(15/0), `scripts/test-agentops-contract-canaries.sh` (failures=0 after
fixing the cli-command-surface heading-count fixture/eval 68/179/247 →
67/172/239 and the `ao daemon` refs in `skills/dream` +
`skills-codex/dream`).
- Regenerated `cli/docs/COMMANDS.md` + `registry.json`;
`regen-codex-hashes.sh --check` clean; `validate-ci-policy-parity.sh`
PASS; doc link/learning-ref checks pass; `heal.sh --strict` clean.
Diff stat: 113 files changed, 95 insertions, 34,978 deletions.
Closes-scenario: soc-2rtm0#cascade-rip
Bounded-context: BC5-Runtime
Evidence: .agents/discovery/2026-05-24-rip-caller-map.md
Skill-dir edits across #503-#508 (.feature additions, SKILL.md links,
heal.sh) changed source dirs but the regenerated codex source_hashes
were never committed; CI codex gate is --scope-head so cross-PR
accumulation slipped through. `regen-codex-hashes.sh` → 'All hashes up
to date'. 9 files, hash strings only.
NOTE: claude-review infra-red (weekly limit) — operator-authorized
bypass when sole red.
Closes-scenario: soc-z5mbz#regen-8-codex-hashes
Bounded-context: BC1-Corpus
Evidence: skills-codex/.agentops-manifest.json
#275's billboard refactor thinned process-skill SKILL.md files and moved
detail into references/, but the validate contracts still grepped SKILL.md.
skill-lint + smoke-test: relax content-presence checks in crank/implement/
post-mortem/swarm validate.sh to scan the skill as a unit (SKILL.md +
references/); structural/identity checks stay SKILL.md-only. test-first-smoke
updated to match relocated SPEC/TEST WAVE + Step 0/4 headings.
skill-lint line caps: trim flywheel 310 -> 286 (cap 300), using-agentops
261 -> 239 (cap 250) by removing redundant prose, no content lost.
skill-integrity: link 3 orphaned references (crank/branch-isolation,
validation/flags + release-readiness-gates).
codex parity: regenerate stale skills-codex source hashes (77 skills).
Local: run-all.sh PASS, heal.sh --strict clean, smoke-test PASS.
Operator polish on top of the just-shipped substrate-leads thesis. Tightens
voice and adds an Assurance Posture section that names the operating
discipline without overclaiming certifications.
Headline:
- "AgentOps is a context compiler that feeds your software factory" →
"AgentOps compiles and compounds the context that feeds your software
factory" (verb-led, more active; "the substrate the supermodel plugs
into" relegated from headline to body).
Body:
- New value-prop paragraph: "the highest-leverage input to coding agents
is context: what the system knows, what it has tried, what failed, what
the codebase decided, and what gates must hold."
- "One substrate, four surfaces" → "One substrate, three operator surfaces,
one enforcement layer" (cleaner separation: surfaces are for humans,
hooks are policy).
- "TSMC-efficiency for code" → "factory-grade throughput for code"
(accessible, not brand-specific).
- "Humans drop in or out" → "Humans choose the posture" (more deliberate).
- Lineage demoted with note: "users do not need that vocabulary to
understand the product."
NEW: Assurance Posture section (PRODUCT.md) — names the constrained-
environment habits (local-first control, context as a boundary, evidence
by default, policy gates over advice, variable autonomy, constrained-
network fit) WITHOUT making certification claims. Explicit caveat:
"Formal deployment into classified, export-controlled, or safety-critical
environments still requires the local authority's security controls,
model approvals, supply-chain process, and accreditation work."
Also tracked as a Known Product Gap: "High-assurance profile is not yet
formalized." Honest framing: posture exists, accreditation surface does
not.
Mirrored across:
- AGENTS.md, CLAUDE.md preamble: matching one-paragraph form
- README.md hero: matching headline
- docs/strategic-direction.md: lineage spine matched
- skills/quickstart/SKILL.md, skills-codex/quickstart/SKILL.md (parity sync;
hashes regenerated via scripts/regen-codex-hashes.sh)
The /quickstart and ao demo "Always-on lane" snippets used the wrong CLI form:
- 'ao schedule add ./path' → should be 'ao schedule add --file ./path' (CLI requires --file flag)
- 'ao daemon' → should be 'ao daemon run' (parent command needs subcommand)
Found by /council --mixed --deep validation of soc-sx99 positioning thesis (8/8
WARN, operator-clarity perspective): the recipe pack docs/scheduling.md got the
flags right, but the same-session quickstart edit shipped the wrong form. Both
shipped commits would have failed at runtime on first user attempt.
- skills/quickstart/SKILL.md: corrected always-on lane snippet
- skills-codex/quickstart/SKILL.md: parity sync
- cli/cmd/ao/demo.go: corrected step 6 command in quickDemo
- skills-codex hashes regenerated via scripts/regen-codex-hashes.sh
Verified: cli/docs/COMMANDS.md:1031,3630-3645 confirms canonical form is
'ao daemon run' and 'ao schedule add --file <path>'. docs/scheduling.md:24-32
already used the right form.
The 5-minute quickstart path didn't mention scheduling, but the user's actual
flagship usage is the always-on dream daemon. This adds scheduling co-equally
with compiler+gates in the basic surface.
- skills/quickstart/SKILL.md: new "Schedule a nightly dream (always-on lane)"
step in the 5-minute path with `ao schedule add ./examples/schedules/dream-nightly.yaml`
and the one-sentence note that `ao daemon` is the always-on lane
- skills-codex/quickstart/SKILL.md: parallel sync (PreToolUse hook required)
with `$skill` prefix in place of `/skill`
- skills-codex/.agentops-manifest.json + .agentops-generated.json: regenerated
via scripts/regen-codex-hashes.sh
- cli/cmd/ao/demo.go: 6th step "Schedule a recurring job (always-on lane)"
added to quickDemo's step deck
Note: the original issue mentioned skills/init/ and skills/quick-start/ —
neither exists in the repo; the only quickstart skill is skills/quickstart/.
Closes soc-sx99.5.
Adds a 2400-char aggregate budget for skills-codex/*/SKILL.md `description:`
fields in tests/skills/test-token-budgets.sh, then trims each skill's description
to fit (catalog now 2146/2400). Both Claude and Codex SKILL.md descriptions
are kept in sync; codex .agentops-generated.json hashes regenerated.
Adds --repair-shape to scripts/audit-codex-hooks.sh: when ~/.codex/hooks.json
is missing or in legacy-flat shape, rewrites it from hooks/codex-hooks.json
with the active plugin_root (read from .agentops-codex-install.json) and
backs up any prior file. Covered by new test_repairs_legacy_flat_shape.
Memory decay (4 .agents/ files) bumped by the SessionStart inject hook.
* docs: add go cli quality discovery plan
* fix(cli): harden gc bridge version parsing
* docs(go): align complexity policy with gates
* docs(cli): classify command surface
* fix(cli): enforce json output contracts
* feat(cli): expand completion coverage
* refactor(cli): pilot badge options writer
* refactor(cli): inject contradict output writer
* refactor(cli): inject notebook update writer
* fix(cli): enable gc runtime smoke coverage
* fix(cli): align gc bridge with gascity v1
* Release v2.39.0
* fix(tests): align next-work schema test with widened type enum
Commit ed35c47f added `docs` and `chore` to the script's VALID_TYPES,
but tests/scripts/check-next-work-schema-rows.bats:42 still used
`type:"docs"` as its supposed-to-be-rejected example, so the test
now passes through the validator — `bats-tests` has been red on
main since.
Switch the rejected-type example to `finding`, which is still
outside the enum and is also the canonical example cited in the
script's own header comment ("type=finding ... caught at push time").
Local: 11/11 in tests/scripts/check-next-work-schema-rows.bats pass.
* docs: capture finding generator postmortem (#157)
* fix(rpi): sort verdicts deterministically in context and status helpers (#158)
BuildPhaseContext and JoinVerdicts iterated the verdicts map directly,
producing non-deterministic output across runs. Sort keys before
rendering so prompt injection and status logs are reproducible.
Closes council finding W-7 (context-orchestration-leverage batch). The
related buildHandoffContext path was already fixed to delegate to
FormatVerdicts (which sorts); this completes the remaining helpers.
- cli/internal/rpi/status.go: sort keys in JoinVerdicts
- cli/internal/rpi/phased_context.go: sort keys in BuildPhaseContext
- tests: replace "ordering not deterministic" waivers with exact-order
asserts and add a 50-run stability check
https://claude.ai/code/session_01Qw4bZvXUNuLs8Rp1j1homB
Co-authored-by: Claude <noreply@anthropic.com>
* fix(codex): audit noisy hook injections (#159)
* docs: add competitive radar (#160)
* feat(agents): harden operator control plane (#161)
* docs(discovery): plan agents control plane hardening
* feat(agents): harden operator control plane
* Release v2.39.0
* fix(tests): align next-work schema test with widened type enum
Commit ed35c47f added `docs` and `chore` to the script's VALID_TYPES,
but tests/scripts/check-next-work-schema-rows.bats:42 still used
`type:"docs"` as its supposed-to-be-rejected example, so the test
now passes through the validator — `bats-tests` has been red on
main since.
Switch the rejected-type example to `finding`, which is still
outside the enum and is also the canonical example cited in the
script's own header comment ("type=finding ... caught at push time").
Local: 11/11 in tests/scripts/check-next-work-schema-rows.bats pass.
* docs: capture finding generator postmortem (#157)
* fix(rpi): sort verdicts deterministically in context and status helpers (#158)
BuildPhaseContext and JoinVerdicts iterated the verdicts map directly,
producing non-deterministic output across runs. Sort keys before
rendering so prompt injection and status logs are reproducible.
Closes council finding W-7 (context-orchestration-leverage batch). The
related buildHandoffContext path was already fixed to delegate to
FormatVerdicts (which sorts); this completes the remaining helpers.
- cli/internal/rpi/status.go: sort keys in JoinVerdicts
- cli/internal/rpi/phased_context.go: sort keys in BuildPhaseContext
- tests: replace "ordering not deterministic" waivers with exact-order
asserts and add a 50-run stability check
https://claude.ai/code/session_01Qw4bZvXUNuLs8Rp1j1homB
Co-authored-by: Claude <noreply@anthropic.com>
* fix(codex): audit noisy hook injections (#159)
* docs: add competitive radar (#160)
* fix(merge): drop unused AgentsDoctorError ref and prune allowlist entries without production refs
---------
Co-authored-by: Claude <noreply@anthropic.com>
* fix(merge): resolve conflicts by taking PR's refactored contradict/codex_runtime, main's overnight test schema
---------
Co-authored-by: Claude <noreply@anthropic.com>
Unblocks CI on this PR. Both were pre-existing drift on main:
- cli/embedded/.../test-pyramid.md: re-ran `cd cli && make sync-hooks`
to match source under skills/standards/references/. Fixes the
embedded-sync and go-build `Verify embedded hooks in sync` gates.
- skills-codex/{crank,quickstart,standards}/.agentops-generated.json
and skills-codex/.agentops-manifest.json: re-ran
`scripts/regen-codex-hashes.sh`. Fixes the codex-runtime-sections
`Validate Codex generated artifacts` gate.
https://claude.ai/code/session_01W5b6kSdX9wEDgXfVGCXTZa
skills-codex/compile/SKILL.md: dropped claude-cli and claude rows from
the AGENTOPS_COMPILE_RUNTIME backend table; rewrote the 'When unset'
paragraph to describe CLI auto-detect without referencing the claude
binary. These were inconsistent with the skill's description field
which already scopes Codex users to ollama|api backends, and the
codex-runtime lint (validate-codex-runtime-sections.sh) rejects them.
skills-codex/quickstart/SKILL.md:50: swapped the
GIT=false + AO=true + GLOBAL_AGENTS=true branch hint from
AGENTOPS_COMPILE_RUNTIME=claude-cli to ollama/openai.
Hash regen also absorbs the swarm-skill hash drift from d8ea5c12
(worker-prompt template update).
Resolves the 2 pre-existing gate failures tracked in
.agents/rpi/next-work.jsonl under source_epic swarm-2026-04-15-8-issue.
Ref: .agents/learnings/2026-04-15-codex-mirror-runtime-string-lint.md
Fixes three onboarding defects that surfaced on 2026-04-15 when running
against a global ~/.agents corpus from a non-git home directory:
1. `ao compile --full` failed in the installed bundle with
"open skills/compile/scripts/compile.sh: file does not exist". The
Makefile's sync-hooks target never copied compile.sh into
cli/embedded/skills/, so the //go:embed all:skills fallback had
nothing to fall back to. Fix: sync-hooks now seeds the script and a
regression test (TestMaterializeCompileScriptFallsBackToEmbedded)
asserts the embedded copy resolves when no local skills/ exists.
2. Headless compile implicitly required OLLAMA_HOST / OPENAI_API_KEY /
ANTHROPIC_API_KEY with no actionable error when none were set, and
ignored a locally installed `claude` CLI. Fix: resolveCompileRuntime
auto-detects the `claude` binary and selects claude-cli runtime (no
API key needed — inherits Claude Code auth). preflightCompileRuntime
fails fast with an actionable error naming the exact env var to set.
compile.sh gains a matching claude-cli backend and a --preflight flag.
3. The headless compiler concatenated all changed files into one LLM
prompt, which is unworkable on 2000+ file corpora. Fix: compile.sh
batches by --batch-size (default 25) and --max-batches (default
unlimited); ao compile propagates both flags.
Onboarding gaps:
- $quickstart now detects a global ~/.agents corpus (GLOBAL_AGENTS=true)
and, when GIT=false + AO=true, surfaces a harvest → compile →
knowledge-activation path instead of only suggesting `git init`.
- Harvest SKILL.md clarifies that promotion writes to ~/.agents/learnings/
(not ~/.agents) and adds a "which skill do I need?" decision table.
- Compile SKILL.md documents the claude-cli runtime and batching flags.
- skills-codex/compile/scripts/compile.sh wrapper now falls back through
multiple candidate paths and finally delegates to `ao compile`, so an
installed bundle without a sibling skills/ checkout still works.
Tests added:
- TestMaterializeCompileScriptFallsBackToEmbedded
- TestResolveCompileRuntime
- TestPreflightCompileRuntimeErrors (5 subtests)
- TestPreflightCompileRuntimeSuccess
- TestCompileScriptOptionsPassesBatchFlags
- TestQuickstartSkillCoversGlobalCorpus (both parity surfaces)
Verification:
cd cli && go vet ./... && go test ./... # all green
bash skills/heal-skill/scripts/heal.sh --strict # clean
bash tests/docs/validate-doc-release.sh # PASS
bash scripts/check-contract-compatibility.sh # 0 failures
bash scripts/regen-codex-hashes.sh # 3 skills rehashed
bash scripts/generate-cli-reference.sh # COMMANDS.md regenerated
Reference .md files in skills-codex/ were copied verbatim from source,
bypassing all converter rewrite rules. Now .md files in references/,
scripts/, and other subdirs are processed through codex_rewrite_text()
during passthrough copy.
Empirically validated: Codex agent confirms 0 Claude primitives in
converted reference files (was 107). Remaining gap: crank/swarm
orchestration patterns need full Codex-native rewrites (not converter
fixes) — tracked separately.
Validated with: codex exec -s read-only (gpt-5.4)
1. ao flywheel status (14 files) → ao metrics flywheel status
`ao flywheel` only has `close-loop` subcommand. Status lives under
`ao metrics flywheel status` (metrics_flywheel.go).
2. ao settings notebook update (skills-codex/retro) → ao notebook update
`ao settings` namespace was removed in 4fd2512c; top-level `ao notebook`
is the correct form.
3. ao start seed / ao start init (skills-codex/quickstart) → ao seed / ao init
`ao start` namespace was removed in 4fd2512c; seed and init are top-level.
The CLI namespace was flattened in 4fd2512c (remove know.go, work.go,
quality.go), but skills-codex/ was never updated. Replace all stale
two-token prefixes with their flat equivalents across 17 SKILL.md files:
ao know forge → ao forge
ao know inject → ao inject
ao know search → ao search
ao know lookup → ao lookup
ao know temper → ao temper
ao quality flywheel → ao flywheel
ao quality pool → ao pool
ao quality metrics → ao metrics
ao quality maturity → ao maturity
ao quality badge → ao badge
ao quality constraint → ao constraint
ao quality contradict → ao contradict
ao quality dedup → ao dedup
ao quality curate → ao curate
71 occurrences fixed. Codex agents following these skills will no longer
invoke commands that return "unknown command".