Files
boshu2__agentops/cli/docs/COMMANDS.md
T

1144 lines
20 KiB
Markdown
Raw Normal View History

# ao CLI Reference
> Auto-generated by `scripts/generate-cli-reference.sh`.
> Do not edit manually. Re-run the script to update.
## Global Flags
--config string Config file (default: ~/.agentops/config.yaml)
--dry-run Show what would happen without executing
-h, --help help for ao
--json Output as JSON (shorthand for -o json)
-o, --output string Output format (json, table, yaml) (default "table")
-v, --verbose Enable verbose output
fix: critical audit findings remediation (epic soc-ab5g) (#279) * fix(session): sanitize init-step exec and correct BEADS_ACTOR Two defects in `ao session spawn` runInitSteps, from the 2026-05-16 codebase audit (epic soc-ab5g): - BEADS_ACTOR was exported as the expanded command string of the first init step instead of the session actor identity, so beads attribution for every init step was garbage. Thread tmpl.Identity.BeadsActorTemplate through runInitSteps and export the var only when non-empty. - Init steps ran via raw exec.Command("bash","-c",...) (SEC-C1). Route init-step exec through shellutil.SanitizedBashCommand and add sanitizeHostname() to strip shell metacharacters from {{hostname}}-class template vars before substitution. New regression tests: TestRunInitStepsSetsBeadsActor, TestSanitizeHostname. Refs: soc-jhxr * fix(autodev): replace vague 'validation failed' with a concrete summary outputAutodevValidateResult returned fmt.Errorf("validation failed") after already printing the detailed INVALID/ERROR lines -- a redundant, content-free wrapper. Return a summary naming the file and the validation-error count instead (COPY-C1, epic soc-ab5g). Refs: soc-mpzu * docs(eval): strip internal Day-N cadence jargon from user-facing text eval_task.go exposed internal sprint labels ("Day-2 placeholder", "Day-3 wires real launch", "Day-4 gate #4") in command Long descriptions and flag help. Reword to describe current behavior without the internal cadence (COPY-C2, epic soc-ab5g). Refs: soc-iy7p * fix(cli): reject unknown subcommands on group commands Group-parent commands (daemon, beads, codex, constraint, factory, goals, hooks, ratchet, rpi, session) had no Args validator, so an unknown subcommand printed help to stdout and exited 0 -- breaking `if ao rpi <bad>; then ...` scripting. Add Args: cobra.NoArgs to all ten; unknown subcommands now exit 1 with the error on stderr (CLI-C1, epic soc-ab5g). Refs: soc-mlqe * docs(cli): regenerate COMMANDS.md after eval-task help copy edit * fix(daemon): contain dream output_dir against path traversal DreamRunJobSpec/DreamStageJobSpec/DreamStageManifest Validate() only TrimSpace-checked output_dir, leaving the operator-supplied job payload free to redirect summary/log writes outside the intended tree. validateOutputDir now rejects ".." traversal in all three Validate() paths; outputDirContained rejects an absolute output_dir resolving outside the daemon working tree, checked in DreamExecutor.RunJob before MkdirAll. Containment checks: 1 (symlink only) → 3 (symlink + .. + abs). Closes soc-ly33 (SEC-C2, epic soc-ab5g). * fix(cli): wire ao --version flag and unify goals --json with -o rootCmd had no Version field, so `ao --version` was unsupported even though an `ao version` subcommand existed. Set rootCmd.Version = version (the ldflags-injected build var) so the standard --version flag works. goals registered its own local --json bool, disconnected from the global -o/--output flag — `ao goals measure -o json` was ignored. Drop goalsJSON; goalsJSONOutput() now reads GetOutput(), the sibling pattern used by agentopsd.go, autodev.go, codex.go and ~40 other callsites. The global --json persistent flag is inherited, so `ao goals --json` still works; output paths honored by goals: 1 (local bool) → 2 (--json + -o). Closes soc-nx1o (CLI-C2, epic soc-ab5g). * perf(cli): collapse tmux probe storm in ao rpi status checkTmuxSessionAlive forked `tmux has-session` up to 3 times per non-terminal run, each with a 2s timeout — a status scan over N runs issued 3N subprocesses and could stall ~6N seconds when tmux was slow or absent. probeTmuxSessions now runs one `tmux ls -F #{session_name}`, memoized per process behind a mutex-guarded cache; tmuxSessionAlive filters the snapshot in Go. resolveRPIToolchainDefaults collapses from per-run to once. Subprocesses per status scan: 3N → 1. Closes soc-d7v5 (PERF-C1, epic soc-ab5g). Mirrors the snapshot-then- filter shape used elsewhere for batch probes. * perf(cli): one-pass git capture + walk-once index in ao beads audit ao beads audit re-shelled git per bead (one `git log --grep` per bead, one `git log --since` per bead-path pair) and re-walked the worktree per pattern (recordAuditStaleFinding probes up to 10 patterns/bead, so up to 10N full-repo walks for N beads). captureAuditCommits now runs a single `git log --all --name-only`, parsed into auditCommit records; grepCommitsForID and fileChangesSinceCommits filter that slice in Go. repoContentCache walks the scoped roots once (lazily) and memoizes a path->content map shared across every pattern probe. git subprocesses per audit: O(beads) → 1; repo walks: O(10*beads) → 1. Mirrors the snapshot-then-filter shape just applied to ao rpi status. Closes soc-2grz (PERF-C2, epic soc-ab5g). * fix(schemas): declare schema_version const in 15 unversioned schemas 15 of 34 schemas under schemas/ carried versioned filenames (or implied a stable contract) without a machine-readable schema_version, so a consumer could not detect the version from the payload alone. Each now declares an optional schema_version integer const, mirroring the shape in schemas/bead.v1.schema.json: const 1 for every schema except skill-frontmatter.v2 (const 2). The field is intentionally left out of "required" so existing documents without it still validate — non-breaking. scenario.v1 keeps its legacy "version" field alongside. Schemas declaring schema_version: 19/34 → 34/34. Closes soc-wzgo (API-C2, epic soc-ab5g). * docs(contracts): regenerate context-map after merging main The merge of origin/main pulled a discovery SKILL.md description edit without its companion context-map regeneration, so validate-context-map-drift flagged 1 stale line. Regenerated via scripts/generate-context-map.sh. Drifted lines: 1 → 0.
2026-05-16 11:05:36 -04:00
--version version for ao
---
## Commands
### `ao init`
Create local evidence and verdict directories. This command does not
```
ao init [flags]
```
---
### `ao quick-start`
AgentOps is a small semantic evidence layer around agent work.
```
ao quick-start [flags]
```
---
### `ao capabilities`
Print the machine-readable contract for the whole ao CLI as JSON.
```
ao capabilities [flags]
```
---
### `ao constraint`
Manage constraints compiled from promoted findings.
```
ao constraint [command]
```
**Subcommands:**
#### `ao constraint activate`
Promote a precision-backed shadow constraint to active blocking
```
ao constraint activate <id> [flags]
```
#### `ao constraint list`
List all constraints with status
```
ao constraint list [flags]
```
#### `ao constraint publish`
Export the ACTIVE constraints to docs/constraints/published.json (tracked + committed),
```
ao constraint publish [flags]
```
#### `ao constraint retire`
Change constraint status from active to retired
```
ao constraint retire <id> [flags]
```
#### `ao constraint review`
List constraints compiled >90 days ago without recent citation
```
ao constraint review [flags]
```
---
### `ao doctor`
Run health checks on your AgentOps installation.
```
ao doctor [command]
```
**Flags:**
```
--dry-run With --fix: print the plan, change nothing
--explain string Expand a single finding by id
--fix Apply fixers for findings (routes through mutate())
-h, --help help for doctor
--json Output results as JSON
--online Enable network probes (default: offline-only)
--only strings Scope to a subset of detectors or subsystems
--quick Run only fast-path detectors (< 200ms)
--robot Alias for --json with structured wrapper
--robot-triage Emit the mega-command triage JSON
--severity string Minimum severity to emit (P0|P1|P2|P3) (default "P3")
--since string Diff findings against an earlier run
--skip strings Inverse of --only
```
**Subcommands:**
#### `ao doctor capabilities`
Print the machine-readable doctor contract (JSON)
```
ao doctor capabilities [flags]
```
#### `ao doctor diff`
Show what --fix would change (read-only)
```
ao doctor diff [flags]
```
#### `ao doctor explain`
Expand a single finding with full evidence
```
ao doctor explain <finding-id> [flags]
```
#### `ao doctor fix`
Run detectors, then apply fixers (backs up before every mutation)
```
ao doctor fix [flags]
```
#### `ao doctor gc`
Prune old runs (requires --yes and --before <date>)
```
ao doctor gc [flags]
```
**Flags:**
```
--before string Prune runs started before this date (YYYY-MM-DD)
-h, --help help for gc
--yes Confirm pruning (required)
```
#### `ao doctor health`
Cheap one-line liveness summary
```
ao doctor health [flags]
```
#### `ao doctor ls`
List runs in .doctor/runs/
```
ao doctor ls [flags]
```
#### `ao doctor robot-docs`
Print the paste-ready agent handbook (Markdown)
```
ao doctor robot-docs [flags]
```
#### `ao doctor undo`
Restore from .doctor/runs/<run-id>/backups/ (run-id may be 'latest')
```
ao doctor undo <run-id> [flags]
```
**Flags:**
```
--dry-run Print the restore plan; do not execute
-h, --help help for undo
--strict Refuse if any backup is missing or hash-mismatched (default true)
```
---
### `ao gate`
Run ordinary deterministic repository checks.
```
ao gate [command]
```
**Subcommands:**
#### `ao gate check`
Run the declarative deterministic check registry.
```
ao gate check [flags]
```
**Flags:**
```
--fail-fast stop after the first blocking check failure
--fast explicitly select the default fast changed-surface subset
--full run every registered deterministic check
--github-annotations emit GitHub Actions annotations for check results
-h, --help help for check
--json emit the machine-readable JSON report
--require-workflow-parity fail if the workflow references unregistered blocking scripts
--scope string changed-file scope: head|staged|worktree|upstream|range:<base>..<head> (default "head")
--workflow-coverage include workflow-to-registry coverage in the report
--workflow-path string workflow used for optional coverage comparison (default ".github/workflows/validate.yml")
feat(cli): ao gate run — 6th adapter CLI-exposed (template applied 3rd time) Cycle 150 applies the cycle-147 CLI-wiring template to a 6th adapter: productionGateRunner (cycle 115). The 3rd consecutive application of the template (148-149-150) — pattern is now demonstrably routine. New surface: ao gate run <name> Wraps productionGateRunner — invokes scripts/check-<name>.sh and emits a structured GateVerdict (Status, Reason, LogTail) as JSON. Useful as a typed alternative to 'bash scripts/check-X.sh; echo $?' for scripts wanting structured output. Live smoke (from project root): $ ao gate run compile-health {"Status":"PASS","Reason":"exit 0","LogTail":"PASS: Compile health OK (defrag 14h ago, stale=0/5)\n"} Implementation note: `gate` parent command already existed (human review gates from a different surface). cobra accepts adding a 'run' subcommand to it without conflict. The BC2 surface lives at 'ao gate run'; the prior 'ao gate ...' subcommands are unaffected. Template adherence vs cycle-147 spec: ✓ on all 5 principles. New nuance from this cycle: composing into a pre-existing parent command works as long as the verb subcommand doesn't conflict with existing subcommands under the parent. New files: - cli/cmd/ao/gate_cmd.go (96 lines) — gateRunCmd added under existing gateCmd. Standard injectable runFn for tests. - cli/cmd/ao/gate_cmd_test.go (90 lines) — 5 tests: stub returns verdict, empty name rejected, failure wrapped, UNKNOWN status for missing gate, LogTail surfaced. cli/docs/COMMANDS.md regenerated. Time: ~9 min. LOC: 191. Tests: 5. Within template band. 6 of 14 production adapters now CLI-exposed: loop history + ci latest/recent + corpus inject + operator record/list + harness status + gate run. 8 adapters remain unexposed; expose ad-hoc. Cycle 150 / template-applied CLI-wiring mode — 3rd consecutive template application. Compounding rate is steady: ~1 adapter per ~8-10 min cycle.
2026-05-12 21:32:01 -04:00
```
---
### `ao robot-docs`
Print a paste-ready, agent-targeted handbook for the whole ao CLI.
```
ao robot-docs [flags]
```
---
### `ao status`
Display the current state of AgentOps knowledge base.
```
ao status [flags]
```
---
### `ao version`
Display the version, build information, and runtime details.
```
ao version [flags]
```
---
### `ao goals`
Track, measure, and validate project fitness goals.
```
ao goals [command]
```
feat(eval): gate #2 judge_content_hash parity on outcomes ingest (ag-62g68 #gate2-hash-parity) (#627) ## What `ao eval outcomes ingest` ignored the score's `judge_content_hash` entirely — so a score graded against a **drifted rubric** would still ingest into the council verdict and feed the Knowledge Flywheel. Gate #2 (SCHEMA rc2 drift key): a stale rubric must **self-invalidate**, exactly as a stale local judge does. Adds an optional **`--expect-judge-hash`** flag: when set, ingest **refuses** (emits no verdict) if the score's `judge_content_hash` differs from the active rubric's hash. Empty (default) = parity not configured → legacy/dev flows unaffected. ## Scope Second of **ag-62g68**'s gate scenarios (gate #3 write-side refuse landed in #626). Pure guard `requireJudgeHashParity` is unit-tested; the flag is exercised end-to-end through `runEvalOutcomesIngest`. **Remaining bead slices stay open:** the rc3 Run-manifest write into the eval-verdict-compiler pipeline, the `--score/--suite/--bead` interface, and global-Dolt ledger persistence (wiring `registerOutcomesBurn` into the command). **Flag-only CLI change** — `COMMANDS.md` regenerated; the flag adds **no new `###`/`####` heading**, so the `cli-command-surface-matrix` canary counts are unchanged and the registry SKU (`cmd:ao.eval`) is unchanged (verified `generate-registry.sh --check` green). ## Evidence - `TestRequireJudgeHashParity` (match / mismatch-refuses / empty-no-op / empty-score-vs-configured) + `TestRunEvalOutcomesIngest_RefusesOnHashMismatch` (command-level: mismatch refuses & emits no verdict, match ingests, unset = no check). - `go build ./...` ✓ · `go test ./cmd/ao/` 9225 pass ✓ · `go vet` clean · gocyclo no findings · `generate-cli-reference.sh --check` up-to-date · `generate-registry.sh --check` OK. Closes-scenario: ag-62g68#gate2-judge-hash-parity Bounded-context: BC4-Evaluation Evidence: cli/cmd/ao/eval_outcomes_ingest.go
2026-05-30 07:42:46 -04:00
**Flags:**
```
--file string Path to goals file (auto-detects GOALS.md then GOALS.yaml)
-h, --help help for goals
--timeout int Check timeout in seconds (default 240)
2026-04-24 22:27:11 -04:00
```
**Subcommands:**
2026-04-24 22:27:11 -04:00
#### `ao goals measure`
Run goal checks and produce a snapshot
```
ao goals measure [flags]
```
**Aliases:**
```
measure, m
```
**Flags:**
```
--directives Output directives as JSON (skip gate checks)
--exclude-tag string Skip goals whose Tags include this value (e.g. long-cycle)
--goal string Measure a single goal by ID
-h, --help help for measure
--scenarios-only Evaluate only executable-spec scenario satisfaction; skip shell gate-command execution
--total-timeout int Overall measurement timeout in seconds (0 disables)
```
#### `ao goals validate`
feat(goals): ao scenario evaluate — the scenario-satisfaction producer (age-wedge-all-in-dyr0.10) The scenario-satisfaction layer's consumer (goalsfitness aggregator + ao goals measure --scenarios-only) and contract (scenario-results.v1 schema/loader/writer) shipped long ago, but nothing ever wrote .agents/rpi/scenario-results.json — a dead instrument reading unknown/0%-evaluated for every directive. This lands the missing producer, resolving the bead's decision rule to Option A (wire it, writer-only, no council-judge dependency in v1). ao eval scenario evaluate [--all|--directive <id>] [--json] [--timeout]: - GATE-SHAPED scenarios (acceptance_vectors carrying a mechanical "check" command; "gate:<id>" resolves through the GOALS.md Gates table) run each check via goals.MeasureOne (sanitized bash, per-check timeout, exit-77 skip convention). Score = fraction of checks passed; verdict = score vs the scenario's own satisfaction_threshold, exactly matching the aggregator's countSatisfied comparison. - JUDGMENT-SHAPED scenarios (no mechanical check) are recorded as verdict "skip" with attestation-needed evidence — the nearest ValidVerdict for "cannot mechanically evaluate"; never a fabricated pass (the anti-pattern GOALS.md's pre-production section forbids). - A check that could not run (timeout, unresolvable gate ref) yields skip, and missing/retired scenario links write NOTHING, so zero evidence stays VerdictUnknown downstream. - Results persist through the production scenarioresults.Writer.Append (latest-judged_at supersede per scenario_id; iteration = prior + 1). L2 tests prove the full producer->consumer round trip: the command writes the artifact, the production loader accepts it strict, and the real runScenariosOnly/EvaluateSatisfaction path reads back nonzero evaluated counts (pass, fail, judgment/unknown, timeout, unresolvable gate ref, supersede-on-rerun, threshold-equality lanes). Nightly cadence wiring deliberately deferred to a follow-up commit. Known: cli/docs/COMMANDS.md conformance regen deferred to landing.
2026-07-01 16:45:27 -04:00
Validate GOALS.yaml structure and wiring
feat(goals): ao scenario evaluate — the scenario-satisfaction producer (age-wedge-all-in-dyr0.10) The scenario-satisfaction layer's consumer (goalsfitness aggregator + ao goals measure --scenarios-only) and contract (scenario-results.v1 schema/loader/writer) shipped long ago, but nothing ever wrote .agents/rpi/scenario-results.json — a dead instrument reading unknown/0%-evaluated for every directive. This lands the missing producer, resolving the bead's decision rule to Option A (wire it, writer-only, no council-judge dependency in v1). ao eval scenario evaluate [--all|--directive <id>] [--json] [--timeout]: - GATE-SHAPED scenarios (acceptance_vectors carrying a mechanical "check" command; "gate:<id>" resolves through the GOALS.md Gates table) run each check via goals.MeasureOne (sanitized bash, per-check timeout, exit-77 skip convention). Score = fraction of checks passed; verdict = score vs the scenario's own satisfaction_threshold, exactly matching the aggregator's countSatisfied comparison. - JUDGMENT-SHAPED scenarios (no mechanical check) are recorded as verdict "skip" with attestation-needed evidence — the nearest ValidVerdict for "cannot mechanically evaluate"; never a fabricated pass (the anti-pattern GOALS.md's pre-production section forbids). - A check that could not run (timeout, unresolvable gate ref) yields skip, and missing/retired scenario links write NOTHING, so zero evidence stays VerdictUnknown downstream. - Results persist through the production scenarioresults.Writer.Append (latest-judged_at supersede per scenario_id; iteration = prior + 1). L2 tests prove the full producer->consumer round trip: the command writes the artifact, the production loader accepts it strict, and the real runScenariosOnly/EvaluateSatisfaction path reads back nonzero evaluated counts (pass, fail, judgment/unknown, timeout, unresolvable gate ref, supersede-on-rerun, threshold-equality lanes). Nightly cadence wiring deliberately deferred to a follow-up commit. Known: cli/docs/COMMANDS.md conformance regen deferred to landing.
2026-07-01 16:45:27 -04:00
```
ao goals validate [flags]
feat(goals): ao scenario evaluate — the scenario-satisfaction producer (age-wedge-all-in-dyr0.10) The scenario-satisfaction layer's consumer (goalsfitness aggregator + ao goals measure --scenarios-only) and contract (scenario-results.v1 schema/loader/writer) shipped long ago, but nothing ever wrote .agents/rpi/scenario-results.json — a dead instrument reading unknown/0%-evaluated for every directive. This lands the missing producer, resolving the bead's decision rule to Option A (wire it, writer-only, no council-judge dependency in v1). ao eval scenario evaluate [--all|--directive <id>] [--json] [--timeout]: - GATE-SHAPED scenarios (acceptance_vectors carrying a mechanical "check" command; "gate:<id>" resolves through the GOALS.md Gates table) run each check via goals.MeasureOne (sanitized bash, per-check timeout, exit-77 skip convention). Score = fraction of checks passed; verdict = score vs the scenario's own satisfaction_threshold, exactly matching the aggregator's countSatisfied comparison. - JUDGMENT-SHAPED scenarios (no mechanical check) are recorded as verdict "skip" with attestation-needed evidence — the nearest ValidVerdict for "cannot mechanically evaluate"; never a fabricated pass (the anti-pattern GOALS.md's pre-production section forbids). - A check that could not run (timeout, unresolvable gate ref) yields skip, and missing/retired scenario links write NOTHING, so zero evidence stays VerdictUnknown downstream. - Results persist through the production scenarioresults.Writer.Append (latest-judged_at supersede per scenario_id; iteration = prior + 1). L2 tests prove the full producer->consumer round trip: the command writes the artifact, the production loader accepts it strict, and the real runScenariosOnly/EvaluateSatisfaction path reads back nonzero evaluated counts (pass, fail, judgment/unknown, timeout, unresolvable gate ref, supersede-on-rerun, threshold-equality lanes). Nightly cadence wiring deliberately deferred to a follow-up commit. Known: cli/docs/COMMANDS.md conformance regen deferred to landing.
2026-07-01 16:45:27 -04:00
```
**Aliases:**
```
validate, v
```
#### `ao goals drift`
Compare snapshots for regressions
```
ao goals drift [flags]
```
**Aliases:**
```
drift, d
```
#### `ao goals export`
Export latest snapshot as JSON (for CI)
```
ao goals export [flags]
```
**Aliases:**
```
export, e
```
#### `ao goals history`
Show goal measurement history
```
ao goals history [flags]
```
**Aliases:**
2026-04-24 23:12:53 -04:00
```
history, h
2026-04-24 23:12:53 -04:00
```
**Flags:**
```
--goal string Filter history to a specific goal
-h, --help help for history
--since string Show entries since date (YYYY-MM-DD)
2026-04-24 23:12:53 -04:00
```
2026-07-15 00:21:02 -04:00
#### `ao goals meta`
Run and report meta-goals only
```
ao goals meta [flags]
```
#### `ao goals render`
Render the executable-spec layer as BDD/Gherkin text.
```
ao goals render [flags]
```
**Flags:**
```
-h, --help help for render
--out string Write Gherkin to this file instead of stdout
```
#### `ao goals scenarios`
2026-07-15 00:21:02 -04:00
Inspect the executable-spec scenarios linked to GOALS.md directives.
```
ao goals scenarios [flags]
```
**Flags:**
```
2026-07-15 00:21:02 -04:00
--directive int Filter by directive display number
--directive-id string Filter listing to one directive by stable Directive ID
-h, --help help for scenarios
--lint Lint the directive↔scenario link graph instead of listing
--strict With --lint, exit non-zero on warnings as well as errors
```
#### `ao goals trace`
Walk the executable-spec trace chain defined in docs/adr/ADR-0005.
```
ao goals trace [flags]
```
**Flags:**
```
--from string Render the trace lineage rooted at this directive, scenario, or bead ID
-h, --help help for trace
--orphans Audit the whole chain for broken references (errors) and missing yields (warnings)
--strict Escalate warning-class defects to a non-zero exit (ADR-0005 §4.2)
```
---
feat(wiki): port OpenKB source lifecycle — ao wiki add/remove/recompile (5qw.2) Second slice of the OpenKB→Go port epic: source management over the workspace created by `ao wiki init`. (watch is deferred to its own slice.) - `ao wiki add <file|dir>...` copies supported sources (.md/.markdown/.txt) into raw/ and records registry entries atomically (sha256, slug id); directories are walked; unsupported types (PDF/URL — adapter follow-ups) are reported+ skipped; re-add is idempotent by raw filename. - `ao wiki remove <doc> [--dry-run] [--keep-raw]` removes a registered source + its derived wiki artifacts (sources/summaries/concepts/entities/explorations/ reports) + the registry entry. --dry-run REPORTS every artifact without deleting; errors on an unregistered doc (no silent success). - `ao wiki recompile [doc] [--all] [--dry-run] [--refresh-schema]` re-runs the llmwiki ingest stage (raw/ -> wiki/sources/); --dry-run lists registered sources; --refresh-schema rewrites the workspace config. SAFETY (destructive remove): every copy AND delete is anchored at the symlink-resolved workspace root and routed through the scaffold containment guard (scaffoldSafeAbs) — within-root, no reserved (.agents/.ao) segment, and NO symlink path component. So a planted symlink derived-artifact cannot make remove delete outside the workspace (tested: TestRemoveSource_ContainmentRejectsSymlinkArtifact); dry-run mutates nothing; --keep-raw preserved. Resolves the workspace via wikiResolveWorkspace (active selection or --path). Conversion stays behind Go file handling so PageIndex/markitdown are adapters, not hidden Python deps. URL ingest + watch are sibling slices. Acceptance: - cd cli && go test ./internal/llmwiki ./cmd/ao -run 'TestWiki.*Add|TestWiki.*Remove|TestWiki.*Recompile' - destructive-safety + registry units: go test ./internal/wiki -run Source Generated docs/registry regenerated (make regen-all). Closes age-port-openkb-into-agentops-go-5qw.2
2026-06-21 03:11:14 -04:00
### `ao session`
feat(wiki): port OpenKB source lifecycle — ao wiki add/remove/recompile (5qw.2) Second slice of the OpenKB→Go port epic: source management over the workspace created by `ao wiki init`. (watch is deferred to its own slice.) - `ao wiki add <file|dir>...` copies supported sources (.md/.markdown/.txt) into raw/ and records registry entries atomically (sha256, slug id); directories are walked; unsupported types (PDF/URL — adapter follow-ups) are reported+ skipped; re-add is idempotent by raw filename. - `ao wiki remove <doc> [--dry-run] [--keep-raw]` removes a registered source + its derived wiki artifacts (sources/summaries/concepts/entities/explorations/ reports) + the registry entry. --dry-run REPORTS every artifact without deleting; errors on an unregistered doc (no silent success). - `ao wiki recompile [doc] [--all] [--dry-run] [--refresh-schema]` re-runs the llmwiki ingest stage (raw/ -> wiki/sources/); --dry-run lists registered sources; --refresh-schema rewrites the workspace config. SAFETY (destructive remove): every copy AND delete is anchored at the symlink-resolved workspace root and routed through the scaffold containment guard (scaffoldSafeAbs) — within-root, no reserved (.agents/.ao) segment, and NO symlink path component. So a planted symlink derived-artifact cannot make remove delete outside the workspace (tested: TestRemoveSource_ContainmentRejectsSymlinkArtifact); dry-run mutates nothing; --keep-raw preserved. Resolves the workspace via wikiResolveWorkspace (active selection or --path). Conversion stays behind Go file handling so PageIndex/markitdown are adapters, not hidden Python deps. URL ingest + watch are sibling slices. Acceptance: - cd cli && go test ./internal/llmwiki ./cmd/ao -run 'TestWiki.*Add|TestWiki.*Remove|TestWiki.*Recompile' - destructive-safety + registry units: go test ./internal/wiki -run Source Generated docs/registry regenerated (make regen-all). Closes age-port-openkb-into-agentops-go-5qw.2
2026-06-21 03:11:14 -04:00
Inspect or export session evidence
feat(wiki): port OpenKB source lifecycle — ao wiki add/remove/recompile (5qw.2) Second slice of the OpenKB→Go port epic: source management over the workspace created by `ao wiki init`. (watch is deferred to its own slice.) - `ao wiki add <file|dir>...` copies supported sources (.md/.markdown/.txt) into raw/ and records registry entries atomically (sha256, slug id); directories are walked; unsupported types (PDF/URL — adapter follow-ups) are reported+ skipped; re-add is idempotent by raw filename. - `ao wiki remove <doc> [--dry-run] [--keep-raw]` removes a registered source + its derived wiki artifacts (sources/summaries/concepts/entities/explorations/ reports) + the registry entry. --dry-run REPORTS every artifact without deleting; errors on an unregistered doc (no silent success). - `ao wiki recompile [doc] [--all] [--dry-run] [--refresh-schema]` re-runs the llmwiki ingest stage (raw/ -> wiki/sources/); --dry-run lists registered sources; --refresh-schema rewrites the workspace config. SAFETY (destructive remove): every copy AND delete is anchored at the symlink-resolved workspace root and routed through the scaffold containment guard (scaffoldSafeAbs) — within-root, no reserved (.agents/.ao) segment, and NO symlink path component. So a planted symlink derived-artifact cannot make remove delete outside the workspace (tested: TestRemoveSource_ContainmentRejectsSymlinkArtifact); dry-run mutates nothing; --keep-raw preserved. Resolves the workspace via wikiResolveWorkspace (active selection or --path). Conversion stays behind Go file handling so PageIndex/markitdown are adapters, not hidden Python deps. URL ingest + watch are sibling slices. Acceptance: - cd cli && go test ./internal/llmwiki ./cmd/ao -run 'TestWiki.*Add|TestWiki.*Remove|TestWiki.*Recompile' - destructive-safety + registry units: go test ./internal/wiki -run Source Generated docs/registry regenerated (make regen-all). Closes age-port-openkb-into-agentops-go-5qw.2
2026-06-21 03:11:14 -04:00
```
ao session [command]
feat(wiki): port OpenKB source lifecycle — ao wiki add/remove/recompile (5qw.2) Second slice of the OpenKB→Go port epic: source management over the workspace created by `ao wiki init`. (watch is deferred to its own slice.) - `ao wiki add <file|dir>...` copies supported sources (.md/.markdown/.txt) into raw/ and records registry entries atomically (sha256, slug id); directories are walked; unsupported types (PDF/URL — adapter follow-ups) are reported+ skipped; re-add is idempotent by raw filename. - `ao wiki remove <doc> [--dry-run] [--keep-raw]` removes a registered source + its derived wiki artifacts (sources/summaries/concepts/entities/explorations/ reports) + the registry entry. --dry-run REPORTS every artifact without deleting; errors on an unregistered doc (no silent success). - `ao wiki recompile [doc] [--all] [--dry-run] [--refresh-schema]` re-runs the llmwiki ingest stage (raw/ -> wiki/sources/); --dry-run lists registered sources; --refresh-schema rewrites the workspace config. SAFETY (destructive remove): every copy AND delete is anchored at the symlink-resolved workspace root and routed through the scaffold containment guard (scaffoldSafeAbs) — within-root, no reserved (.agents/.ao) segment, and NO symlink path component. So a planted symlink derived-artifact cannot make remove delete outside the workspace (tested: TestRemoveSource_ContainmentRejectsSymlinkArtifact); dry-run mutates nothing; --keep-raw preserved. Resolves the workspace via wikiResolveWorkspace (active selection or --path). Conversion stays behind Go file handling so PageIndex/markitdown are adapters, not hidden Python deps. URL ingest + watch are sibling slices. Acceptance: - cd cli && go test ./internal/llmwiki ./cmd/ao -run 'TestWiki.*Add|TestWiki.*Remove|TestWiki.*Recompile' - destructive-safety + registry units: go test ./internal/wiki -run Source Generated docs/registry regenerated (make regen-all). Closes age-port-openkb-into-agentops-go-5qw.2
2026-06-21 03:11:14 -04:00
```
**Subcommands:**
#### `ao session bootstrap`
Report local orientation files without starting runtimes, probing
```
ao session bootstrap [flags]
```
**Flags:**
```
-h, --help help for bootstrap
--json Emit JSON
```
#### `ao session handoff`
Write a small handoff artifact without selecting work, claiming it,
```
ao session handoff [summary] [flags]
```
**Flags:**
```
--collect Collect best-effort read-only Git observations
--continuation string Caller-supplied continuation note
--dry-run Print the artifact without writing it
--goal string Caller-supplied goal
-h, --help help for handoff
feat(wiki): port OpenKB scaffold — ao wiki init/use (age-port-openkb-...-5qw.1) First slice of the OpenKB→Go port epic (5qw): the KB scaffold/config/schema. Adds `ao wiki init [path]` and `ao wiki use <path>` in Go so a usable wiki workspace stands up without OpenKB Python. - `ao wiki init` creates the OpenKB-style layout (raw/, wiki/{sources,summaries, concepts,entities,explorations,reports}, output/{skills,decks}), seeds wiki/index.md, wiki/log.md, and a wiki/AGENTS.md schema, and writes wiki/config.yaml (model, language, entity_types, thresholds). Idempotent: existing dirs/files are preserved; config is rewritten for --model/--language. - `ao wiki use <path>` records the active workspace repo-locally (.ao/wiki/active-workspace) so later commands resolve it. - internal/wiki/scaffold.go: typed ScaffoldConfig + Scaffold/Read/Write + active-workspace state. Self-contained workspace — does NOT write into the private .agents/ corpus or the gold .ao/wiki view (preserves the raw/private vs gold/public boundary, per the bead's risk note). Validates the AUTHORED config core (model/language/entity_types/thresholds) the bead specifies; source ingestion + compilation + generation are sibling beads under the epic (kept accretive — existing wiki subcommands unchanged). Acceptance: - cd cli && go test ./cmd/ao ./internal/wiki -run 'TestWiki.*Init|Test.*Schema' - ao capabilities | grep -q 'wiki' (and ao wiki --help shows init/use) Generated artifacts regenerated (make regen-all): COMMANDS.md, cli-surface, command-surface matrix + smoke, registry.json. Closes age-port-openkb-into-agentops-go-5qw.1
2026-06-21 01:42:10 -04:00
```
#### `ao session memory`
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
Manage repo-root MEMORY.md for cross-runtime access
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
```
ao session memory [command]
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
```
##### `ao session memory sync`
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
Write recent session history to a repo-root MEMORY.md with managed block markers.
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
```
ao session memory sync [flags]
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
```
**Flags:**
```
-h, --help help for sync
--max-entries int Maximum session entries to keep (default 10)
--output-file string Output path (default: MEMORY.md in repo root)
--quiet Suppress output
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
```
#### `ao session rehydrate`
Read a handoff without consuming it, claiming work, or choosing a next action.
```
ao session rehydrate [flags]
```
**Flags:**
```
-h, --help help for rehydrate
--json Emit the stored artifact as JSON
```
---
### `ao completion`
Generate shell completion scripts for ao.
```
ao completion [bash|zsh|fish|powershell]
```
---
### `ao config`
View and manage AgentOps configuration.
```
ao config [command]
```
**Flags:**
```
-h, --help help for config
--show Show resolved configuration with sources
```
**Subcommands:**
#### `ao config models`
Display the current model cost tier settings with sources.
```
ao config models [flags]
```
**Flags:**
```
-h, --help help for models
--set-skill string Set a skill-specific tier override (e.g. council=quality)
--set-tier string Set the default model cost tier (quality, balanced, budget)
```
---
2026-07-15 00:21:02 -04:00
### `ao flywheel`
Knowledge flywheel operations and status.
```
ao flywheel [command]
```
**Subcommands:**
#### `ao flywheel compare`
Compare retrieval quality between primary and shadow namespaces.
```
ao flywheel compare [flags]
```
**Flags:**
```
-h, --help help for compare
--shadow string Shadow namespace to compare against primary (default "shadow")
```
#### `ao flywheel status`
Display comprehensive flywheel health status.
```
ao flywheel status [flags]
```
**Flags:**
```
--days int Period in days for metrics calculation (default 7)
-h, --help help for status
--namespace string Citation namespace to evaluate (primary by default) (default "primary")
```
---
### `ao claim`
Removed in the AgentOps Cathedral Cut
```
ao claim [flags]
```
---
### `ao close`
Removed in the AgentOps Cathedral Cut
```
ao close [flags]
```
---
### `ao converge`
Removed in the AgentOps Cathedral Cut
```
ao converge [flags]
```
---
### `ao crank`
Removed in the AgentOps Cathedral Cut
```
ao crank [flags]
```
---
### `ao done`
Removed in the AgentOps Cathedral Cut
```
ao done [flags]
```
---
### `ao governor`
Removed in the AgentOps Cathedral Cut
```
ao governor [flags]
```
---
### `ao help`
Help provides help for any command in the application.
```
ao help [command] [flags]
```
---
### `ao land`
Removed in the AgentOps Cathedral Cut
```
ao land [flags]
```
---
### `ao membrane`
Removed in the AgentOps Cathedral Cut
```
ao membrane [flags]
```
---
### `ao next-work`
Removed in the AgentOps Cathedral Cut
```
ao next-work [flags]
```
---
### `ao pawl`
Removed in the AgentOps Cathedral Cut
```
ao pawl [flags]
```
---
### `ao plan-pawl`
Removed in the AgentOps Cathedral Cut
```
ao plan-pawl [flags]
```
---
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
### `ao provenance`
Append-only write model for the SDLC provenance/intent graph
```
ao provenance [command]
```
**Subcommands:**
#### `ao provenance add`
Append one schema-valid, hash-chained provenance edge linking a source
```
ao provenance add <from-id> <to-id> [flags]
```
**Flags:**
```
--evidence string Optional evidence pointer (path, commit, CI run URL, event id)
--from-type string Source node type (decision|artifact|bead|...) (default "decision")
-h, --help help for add
--json Emit the sealed edge as JSON
chore(provenance): align relation enum to W3C PROV-O vocabulary (ag-lmdx.7 #prov-o-vocabulary) (#660) ## What Rename the provenance ledger relation enum from AgentOps-local `subject_verb_object` names to the standard **W3C PROV-O / PROV-DM** verbs so an external auditor recognizes the term, and document the **columns-not-JSON-paths** guard-read principle in the schema. Schema changes are single-writer on `main`. Implements ag-lmdx.7. ### Relation mapping (atomic contract change) | Prior AgentOps-local | W3C PROV-O | |---|---| | `decision_produces_artifact` | `wasGeneratedBy` | | `decision_authorizes` | `wasAssociatedWith` | | `artifact_derived_from` | `wasDerivedFrom` | | `scenario_covers_artifact` | `wasInformedBy` | | `verdict_attests_artifact` | `wasAttributedTo` | | `bead_scopes_decision` | `wasInfluencedBy` | | `commit_implements_decision` | `wasRevisionOf` | | `learning_revises_decision` | `wasInvalidatedBy` | ## Scenarios - **Relations use PROV-O vocabulary** — the enum now contains only PROV-O verbs; an edge with the colloquial `derives_from` (or the prior `artifact_derived_from`) is REJECTED in favor of `wasDerivedFrom`. Enforced by two new bats cases (accept PROV-O, reject legacy vocabulary). - **Guard-read field is a column not a JSON path** — the schema description now states that guard-read/queryable fields (`from_id`, `to_id`, `relation`, `trust_tier`, the hash-chain anchors) are first-class top-level columns, never nested JSON payload paths, because Dolt JSON-path generated-column indexing is unreliable. The `judge_id` verdict guard already reads a first-class struct field in `evidencedturn`; **no Dolt migration is invented** (no Dolt projection schema exists in this repo — the principle is encoded in the contract). ## Ripple (every merged consumer, atomic) - `schemas/agentops-sdlc-provenance.v1.schema.json` (enum + description) - `cli/internal/provenancegraph/edge.go` (`Relations` + godoc) - schema-driven validator via `tests/scripts/validate-provenance-ledger.bats` (PROV-O accept + legacy reject) - consumers: `drrebuild`, `drwitness`, `evidencedturn`, `cmd/ao/provenance_*`, `cmd/ao/turn_verify` - all hash-chained fixtures **re-sealed via the canonical hasher** (`drrebuild` ledger + frozen `expected-graph-hash.txt`, `committed-witness.jsonl`); witness dolt-rows + provenance JSON fixtures updated - generated `cli/docs/COMMANDS.md` regenerated ## Verification - `cd cli && go build ./... && go vet ./...` clean; **`go test ./...` → 11942 passed in 72 packages** - `bats validate-provenance-ledger.bats witness-dolt-jsonl-crosscheck.bats` → 20/20 - `bats provenance-orphan-fixtures.bats check-provenance-orphans.bats` → 7/7 - `scripts/check-contracts-structural-floor.sh` → PASS (45 contracts) - `docs/provenance/ledger.jsonl` does not exist (no real entries to migrate); `.agents/ao/provenance/graph.jsonl` is a separate transcript-mining graph (no `relation` field) and out of scope. Closes-scenario: ag-lmdx.7#prov-o-vocabulary Bounded-context: BC4-Factory Evidence: schemas/agentops-sdlc-provenance.v1.schema.json
2026-05-31 15:37:11 -04:00
--relation string Typed PROV-O relation (required), e.g. wasGeneratedBy
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
--to-type string Target node type (decision|artifact|bead|...) (default "artifact")
--trust-tier string Trust tier (authored|inferred|mined) (default "authored")
--ts string Override the UTC RFC3339 timestamp (defaults to now)
```
feat(provenance): ao provenance export deterministic hash-chained (ag-x31t.5 #provenance-export) (#651) ## What Adds `ao provenance export`: a deterministic, hash-chained rendering of the committed provenance ledger (`docs/provenance/ledger.jsonl`). - Reads the ledger, **canonically sorts** edges by `(ts, from_id, to_id, relation)` (with type/trust/evidence tie-breakers for a total order), then **re-seals** them into a fresh per-record hash chain. - Output is **byte-identical on re-run** regardless of the ledger's physical append order. Default = JSONL (one compact edge per line); `--json` = indented array; `--verify` = one-line OK summary, no varying body. - The re-chained export **verifies with no Dolt server** — the committed JSONL is the audit authority, and re-chaining uses only the in-process hashing in `cli/internal/provenancegraph` (same `prev_hash` discipline as the rpi ledger). No reinvented Edge/hash logic: new `CanonicalSort`/`ReChain` helpers reuse `Seal`/`VerifyChain`. ## Tests (TDD-first) - `chain_test.go`: canonical-sort ordering + stability + non-mutation, order-independent re-chain, byte-identical serialization, empty ledger, invalid-edge rejection, tamper detection. - `provenance_export_test.go`: deterministic bytes across runs, chain verifies, empty ledger (`[]` not `null`), `--verify` summary, tampered-ledger rejection. ## Derived surfaces regenerated - `cli/docs/COMMANDS.md` (cobra conformance) - `evals/agentops-core/fixtures/cli-command-surface-smoke.sh` + `cli-command-surface-matrix.json` (sub 185→186, all 259→260) - `registry.json` unchanged: it counts top-level commands only (subcommands not tracked; top-level count = 72). ## Gates `go build` / `go vet` / `go test ./...` green; gosec clean on the new files; CLI-skills-map, JSON-flag-consistency, and `generate-cli-reference.sh --check` all pass. Closes-scenario: ag-x31t.5#provenance-export Bounded-context: BC4-Factory Evidence: cli/cmd/ao/provenance_export.go
2026-05-31 13:34:45 -04:00
#### `ao provenance export`
Read docs/provenance/ledger.jsonl, canonically sort its edges by
```
ao provenance export [flags]
```
**Flags:**
```
-h, --help help for export
--json Emit a single indented JSON array instead of JSONL
--verify Verify the re-chained export and print only a one-line summary
```
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
#### `ao provenance list`
Read the provenance edges recorded in docs/provenance/ledger.jsonl, in
```
ao provenance list [flags]
```
**Flags:**
```
--from-id string Filter to edges whose from_id matches
-h, --help help for list
--json Emit machine-readable JSON
--relation string Filter to edges with this relation
```
#### `ao provenance mine-session`
Parse a Claude Code or Codex session transcript and emit the per-inference
```
ao provenance mine-session --file <session.jsonl> [flags]
```
**Flags:**
```
--file string Path to the session transcript (.jsonl) to mine (required)
-h, --help help for mine-session
--json Emit events as JSONL on stdout (default true)
--state string Path to the incremental watermark state JSON (created/updated; omit for a full one-shot mine)
```
#### `ao provenance position`
2026-07-15 00:21:02 -04:00
Report the ledger record count and latest hash without inferring lifecycle state.
```
ao provenance position [flags]
```
**Flags:**
```
-h, --help help for position
2026-07-15 00:21:02 -04:00
--json Emit machine-readable JSON
```
#### `ao provenance show`
2026-07-15 00:21:02 -04:00
Read the provenance ledger and show every edge whose from_id or to_id
```
2026-07-15 00:21:02 -04:00
ao provenance show <node-id> [flags]
```
**Flags:**
```
-h, --help help for show
2026-07-15 00:21:02 -04:00
--json Emit machine-readable JSON
```
feat(provenance): ao provenance trace --orphans --strict gate (ag-x31t.6 #provenance-orphan-gate) (#653) ## What Adds `ao provenance trace --orphans --strict`: detects provenance orphans — artifact nodes with **no inbound authored/inferred edge** — by generalizing the `goals_trace_orphans` no-inbound chain-gap detection onto the provenance graph. Wires it as a blocking CI gate. ## How - **`cli/internal/provenancegraph/orphans.go`** — `ReadGraphRecords` (parses the goalstrace `Node`/`Edge` JSONL contract that the seeded fixtures use) + `FindOrphans` (an artifact node is an orphan iff no edge's `to_id` targets it; it flips green the moment any inbound edge is added). - **`cli/cmd/ao/provenance_trace.go`** — the `trace --orphans [--strict] [--json] [--graph <path>]` subcommand. `--strict` exits non-zero when orphans exist; `--json` emits one finding per line. - **`scripts/check-provenance-orphans.sh`** + a new **blocking** step in `.github/workflows/validate.yml` (in the existing goals/spec-linkage job, right after the warn-only `ao goals trace --orphans`). The gate asserts the strict audit **catches** each seeded orphan fixture and **passes** once an inbound edge wires the artifact back to a directive — so it is deterministically green while proving the detector is wired. ## Tests (TDD-first) - `cli/cmd/ao/provenance_trace_test.go` (L2): drives the real `tests/fixtures/provenance/` fixtures against `expected-orphans.json` — `--strict` catches each of the 3 seeded orphans (`gate:scenario-hash-stability`, `artifact:scripts/pre-push-gate.sh`, `claim:65-jobs`), and a wired graph exits 0. Plus mode/flag-guard cases. - `cli/internal/provenancegraph/orphans_test.go` (L1): detection, non-artifact nodes never orphaned, deterministic sort, JSONL parsing + malformed/missing-file rejection. - `tests/scripts/check-provenance-orphans.bats`: gate-script behavior. ## Derived surfaces regenerated - `cli/docs/COMMANDS.md` (new `ao provenance trace` subcommand, cobra-conformance passes) - CLI surface smoke fixture + matrix (sub 186→187, all 260→261) - `registry.json` **unchanged** (provenance is already a top-level command; subcommands aren't counted) — timestamp-only churn reverted. ## Gates `go build ./... && go vet ./... && go test ./...` (11959 pass) · gosec clean on new files (one `#nosec G304` on the operator/CI-supplied graph path, with reason) · `scripts/validate-ci-policy-parity.sh` PASS. Closes-scenario: ag-x31t.6#provenance-orphan-gate Bounded-context: BC4-Factory Evidence: .github/workflows/validate.yml
2026-05-31 14:07:45 -04:00
#### `ao provenance trace`
Audit a provenance trace-graph for orphans: engineered artifact nodes
```
ao provenance trace [flags]
```
**Flags:**
```
--graph string Path to the JSONL trace-graph to audit (required)
-h, --help help for trace
--json Emit each finding as one JSON object per line
--orphans Audit for artifact nodes with no inbound provenance edge
--strict Exit non-zero when any orphan exists
```
feat(provenance): create the SDLC provenance ledger + ao provenance append/verify + tamper-evident gate (ag-8jf97) docs/provenance/ledger.jsonl was declared the append-only SOT in CLAUDE.md ("ledger wins on disagreement") but the file was never created and nothing verified it in place — a doctrine-level lying instrument. This pours the real slab: - Seed docs/provenance/ledger.jsonl with the genesis event (ag-8jf97 bead --wasGeneratedBy--> landing branch, trust_tier=authored). - Add `ao provenance verify`: verifies the COMMITTED chain in place (no re-sort/re-chain, unlike `export --verify`), so a tampered field, forged hash, or reordered row is caught and the offending FILE LINE is named. provenancegraph.Store.VerifyFile() is the line-accurate verifier. - Wire the gate: scripts/validate-provenance-ledger.sh --gate requires the committed ledger to exist, be schema-valid per line, and be an intact hash chain; registered as a blocking T1 CI step in validate.yml. - Tests (windshield-correctness): L1 deterministic hashing (existing), L2 intact-chain pass, L2 TAMPER (payload-flip / forged-hash / reorder all FAIL naming the line), missing-file-is-empty-intact, append-creates-genesis; plus bats coverage of the committed ledger + --gate + tamper path. Hash discipline follows the schema + existing cli/internal/rpi/ledger.go (genesis prev_hash = "", hash = sha256(payload_hash+"\n"+prev_hash)) — the brief's 64-zero/concat variant was superseded per the contracts-over-narrative precedence rule. Closes-scenario: ag-8jf97#provenance-ledger-tamper-evident Bounded-context: BC4-Factory Evidence: docs/provenance/ledger.jsonl Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 20:01:29 -04:00
#### `ao provenance verify`
Read docs/provenance/ledger.jsonl exactly as committed and verify its
```
ao provenance verify [flags]
```
**Flags:**
```
-h, --help help for verify
--json Emit the machine-readable verify result as JSON
```
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
---
### `ao reconcile`
Removed in the AgentOps Cathedral Cut
```
ao reconcile [flags]
```
---
### `ao skills`
Tooling for the skills/ source-of-truth and its skills-codex/
```
ao skills [command]
```
**Subcommands:**
#### `ao skills check`
Walk skills/ and skills-codex/, validating each skill's YAML
```
ao skills check [flags]
```
**Flags:**
```
-h, --help help for check
--json Emit machine-readable JSON
--skill string Restrict the audit to a single skill name
--strict Exit non-zero on any finding (CI mode)
```
feat(skills): queryable skill catalog JSON + ao skills (soc-vuu6.4 #skill-catalog-json) (#640) ## What Slice 2 of the skill-catalog bead (soc-vuu6.4): the **queryable surface** over the generated `skills/catalog.json`. Slice 1 (the generator, schema, drift gate, and `catalog.json` itself) landed in PR #379; this adds the `ao skills` query commands the bead's acceptance criterion calls for. - New `cli/internal/skills/catalog.go` — loads `skills/catalog.json` and a **pure, table-tested** query engine (`List`/`Consumers`/`Producers`/`Mermaid`). No SKILL.md re-parsing; reads the committed, CI-synced catalog. - New `cli/cmd/ao/skills_query.go` — four cobra subcommands: - `ao skills list [--role --produces --consumes --practice --user-invocable] [--json]` - `ao skills consumers <skill> [--json]` - `ao skills producers <output> [--json]` - `ao skills graph [--format mermaid]` - Regenerated `cli/docs/COMMANDS.md`; bumped the cli-command-surface fixtures (`sub` 179→183, `all` 252→256) for the 4 new subcommands. ## Why `registry.json` and `catalog.json` existed but had no query API — agents grepping "which skill produces X?" had to scan markdown. This turns the catalog into a queryable surface (the bead blocks `ao skill new`, which needs sibling-skill defaults). ## Acceptance > `ao skills list ... --json` returns the matching skill set in <100ms. Verified: `ao skills list --produces result.json --json` → `[beads, discovery]`; `ao skills consumers rpi` → 5 skills; `ao skills graph` emits deterministic Mermaid. Latency well under 100ms. ## Scope notes - Did **not** regenerate `skills/catalog.json` — it carries pre-existing drift on `main` (the `check-skill-catalog-drift` gate is I0/advisory). This PR only *consumes* the catalog; regenerating would sweep in unrelated drift. - The bead's illustrative `--tier judge` example does not map to the real generated schema (which has no `tier` field — it uses `hexagonal_role`, `produces`, `consumes`, `practices`). Filters implemented against the actual catalog fields. ## Tests `cli/internal/skills/catalog_test.go` (engine, exact-value table tests + load round-trip) and `cli/cmd/ao/skills_query_test.go` (JSON shape, sort invariants, flag validation, mermaid header) — all green. `go build`/`go vet`/`go test ./...` pass; conformance + command-surface smoke pass. Closes-scenario: soc-vuu6.4#skill-catalog-json Bounded-context: BC1-Corpus Evidence: cli/internal/skills/catalog.go
2026-05-31 12:36:45 -04:00
#### `ao skills consumers`
Print the skills whose consumes[] list includes <skill> — i.e. who
```
ao skills consumers <skill> [flags]
```
**Flags:**
```
-h, --help help for consumers
--json Emit machine-readable JSON
```
#### `ao skills edit`
Immune-system commands for the live skill tier.
```
ao skills edit [command]
```
##### `ao skills edit digest`
Summarize recent committed skill edits
```
ao skills edit digest [flags]
```
**Flags:**
```
--critical-policy string Critical skills policy file (default: docs/contracts/critical-skills.txt)
-h, --help help for digest
--json Emit JSON
--since string git log --since value (default "24 hours ago")
```
##### `ao skills edit seal`
Commit one live skill edit with critical-skill protection
```
ao skills edit seal [flags]
```
**Flags:**
```
--actor string Agent/operator name recorded in the commit body
--allow-critical Allow a critical skill edit; use only for human-supervised edits
--critical-policy string Critical skills policy file (default: docs/contracts/critical-skills.txt)
--dry-run Check policy and print the commit action without staging or committing
-h, --help help for seal
--message string Commit subject (default: chore(skills): update <skill> via live edit)
--skill string Skill slug under skills/<slug> to seal
```
feat(cli): ao skills find <intent> skill discovery (ag-a97 #find-ranks) (#563) ## Summary Turns the 75-skill catalog from oral tradition into a queryable surface. `ao skills find <intent>` scores every `skills/*/SKILL.md` against a free-text intent and returns the top matches (name, one-line description, score) — so an agent gets a discovery API instead of memorizing skill names. - **Scoring engine** (`cli/internal/skills/find.go`) — pure, deterministic token-overlap. A query word hitting the skill **name** counts most, a declared **trigger** next, a **description** word least, with light plural/stem tolerance (`loop` ↔ `loops`). Scores normalized to `[0,1]`; ties broken by name. No filesystem access, so it is fully table-testable. - **Loader** (`cli/internal/skills/load.go`) — reads `skills/*/SKILL.md`, parses frontmatter (`name`, `description`, best-effort top-level / `metadata` triggers). No static index file: a newly added skill is found on the next run. - **Command** (`cli/cmd/ao/skills_find.go`) — `--json` / `--limit` (default 5), stdout-as-data / stderr-as-diagnostics. An unmatched intent **exits 0** with a stderr note, not an error. Unknown-flag typo hints inherited from the root cobra config; `--limit < 1` returns a usage error naming the fix. - Regenerated `cli/docs/COMMANDS.md`. ### Notes / corrections - The bead's premise ("each SKILL.md has a populated `triggers:` array") is inaccurate — phase-1 discovery found **0/75** top-level `triggers:` arrays; intent lives as prose in `description`, with `metadata.triggers` in ~10 skills. Scoring therefore treats name+description as the primary signal and triggers as an optional boost. - Bounded context: the slice reads the **skills corpus** (SKILL.md content), so `BC1-Corpus` (the plan's draft `BC4-Practice` does not exist — BC4 is Evidence). - Deferred to follow-ups: `ao skills list --by-trigger` / `--list-triggers` (ag-0r0) and backfilling structured triggers across SKILL.md (ag-piv). ## Test plan - [x] `cd cli && go test ./internal/skills/... ./cmd/ao` (green) - [x] `cd cli && go build ./... && go vet ./internal/skills/... ./cmd/ao` - [x] `scripts/generate-cli-reference.sh` (COMMANDS.md in conformance) - [x] `bash skills/heal-skill/scripts/heal.sh --strict` (All clean) - [x] `ao autodev validate --file PROGRAM.md --json` → `valid: true` - [x] Manual smoke: `ao skills find "close the loop"`, `--json --limit 3`, unmatched intent Closes-scenario: ag-a97#find-ranks-relevant-skills Bounded-context: BC1-Corpus Evidence: cli/internal/skills/find_test.go + go test ./internal/skills/... ./cmd/ao
2026-05-28 00:15:43 -04:00
#### `ao skills find`
Score every skills/<name>/SKILL.md against a free-text intent and
```
ao skills find <intent> [flags]
```
**Flags:**
```
-h, --help help for find
--json Emit machine-readable JSON on stdout
--limit int Maximum number of results to return (default 5)
```
feat(skills): queryable skill catalog JSON + ao skills (soc-vuu6.4 #skill-catalog-json) (#640) ## What Slice 2 of the skill-catalog bead (soc-vuu6.4): the **queryable surface** over the generated `skills/catalog.json`. Slice 1 (the generator, schema, drift gate, and `catalog.json` itself) landed in PR #379; this adds the `ao skills` query commands the bead's acceptance criterion calls for. - New `cli/internal/skills/catalog.go` — loads `skills/catalog.json` and a **pure, table-tested** query engine (`List`/`Consumers`/`Producers`/`Mermaid`). No SKILL.md re-parsing; reads the committed, CI-synced catalog. - New `cli/cmd/ao/skills_query.go` — four cobra subcommands: - `ao skills list [--role --produces --consumes --practice --user-invocable] [--json]` - `ao skills consumers <skill> [--json]` - `ao skills producers <output> [--json]` - `ao skills graph [--format mermaid]` - Regenerated `cli/docs/COMMANDS.md`; bumped the cli-command-surface fixtures (`sub` 179→183, `all` 252→256) for the 4 new subcommands. ## Why `registry.json` and `catalog.json` existed but had no query API — agents grepping "which skill produces X?" had to scan markdown. This turns the catalog into a queryable surface (the bead blocks `ao skill new`, which needs sibling-skill defaults). ## Acceptance > `ao skills list ... --json` returns the matching skill set in <100ms. Verified: `ao skills list --produces result.json --json` → `[beads, discovery]`; `ao skills consumers rpi` → 5 skills; `ao skills graph` emits deterministic Mermaid. Latency well under 100ms. ## Scope notes - Did **not** regenerate `skills/catalog.json` — it carries pre-existing drift on `main` (the `check-skill-catalog-drift` gate is I0/advisory). This PR only *consumes* the catalog; regenerating would sweep in unrelated drift. - The bead's illustrative `--tier judge` example does not map to the real generated schema (which has no `tier` field — it uses `hexagonal_role`, `produces`, `consumes`, `practices`). Filters implemented against the actual catalog fields. ## Tests `cli/internal/skills/catalog_test.go` (engine, exact-value table tests + load round-trip) and `cli/cmd/ao/skills_query_test.go` (JSON shape, sort invariants, flag validation, mermaid header) — all green. `go build`/`go vet`/`go test ./...` pass; conformance + command-surface smoke pass. Closes-scenario: soc-vuu6.4#skill-catalog-json Bounded-context: BC1-Corpus Evidence: cli/internal/skills/catalog.go
2026-05-31 12:36:45 -04:00
#### `ao skills graph`
Render the skill execution/delegation graph (A --> B means A declares
feat(skills): queryable skill catalog JSON + ao skills (soc-vuu6.4 #skill-catalog-json) (#640) ## What Slice 2 of the skill-catalog bead (soc-vuu6.4): the **queryable surface** over the generated `skills/catalog.json`. Slice 1 (the generator, schema, drift gate, and `catalog.json` itself) landed in PR #379; this adds the `ao skills` query commands the bead's acceptance criterion calls for. - New `cli/internal/skills/catalog.go` — loads `skills/catalog.json` and a **pure, table-tested** query engine (`List`/`Consumers`/`Producers`/`Mermaid`). No SKILL.md re-parsing; reads the committed, CI-synced catalog. - New `cli/cmd/ao/skills_query.go` — four cobra subcommands: - `ao skills list [--role --produces --consumes --practice --user-invocable] [--json]` - `ao skills consumers <skill> [--json]` - `ao skills producers <output> [--json]` - `ao skills graph [--format mermaid]` - Regenerated `cli/docs/COMMANDS.md`; bumped the cli-command-surface fixtures (`sub` 179→183, `all` 252→256) for the 4 new subcommands. ## Why `registry.json` and `catalog.json` existed but had no query API — agents grepping "which skill produces X?" had to scan markdown. This turns the catalog into a queryable surface (the bead blocks `ao skill new`, which needs sibling-skill defaults). ## Acceptance > `ao skills list ... --json` returns the matching skill set in <100ms. Verified: `ao skills list --produces result.json --json` → `[beads, discovery]`; `ao skills consumers rpi` → 5 skills; `ao skills graph` emits deterministic Mermaid. Latency well under 100ms. ## Scope notes - Did **not** regenerate `skills/catalog.json` — it carries pre-existing drift on `main` (the `check-skill-catalog-drift` gate is I0/advisory). This PR only *consumes* the catalog; regenerating would sweep in unrelated drift. - The bead's illustrative `--tier judge` example does not map to the real generated schema (which has no `tier` field — it uses `hexagonal_role`, `produces`, `consumes`, `practices`). Filters implemented against the actual catalog fields. ## Tests `cli/internal/skills/catalog_test.go` (engine, exact-value table tests + load round-trip) and `cli/cmd/ao/skills_query_test.go` (JSON shape, sort invariants, flag validation, mermaid header) — all green. `go build`/`go vet`/`go test ./...` pass; conformance + command-surface smoke pass. Closes-scenario: soc-vuu6.4#skill-catalog-json Bounded-context: BC1-Corpus Evidence: cli/internal/skills/catalog.go
2026-05-31 12:36:45 -04:00
```
ao skills graph [flags]
```
**Flags:**
```
--format string Graph output format (mermaid|json) (default "mermaid")
feat(skills): queryable skill catalog JSON + ao skills (soc-vuu6.4 #skill-catalog-json) (#640) ## What Slice 2 of the skill-catalog bead (soc-vuu6.4): the **queryable surface** over the generated `skills/catalog.json`. Slice 1 (the generator, schema, drift gate, and `catalog.json` itself) landed in PR #379; this adds the `ao skills` query commands the bead's acceptance criterion calls for. - New `cli/internal/skills/catalog.go` — loads `skills/catalog.json` and a **pure, table-tested** query engine (`List`/`Consumers`/`Producers`/`Mermaid`). No SKILL.md re-parsing; reads the committed, CI-synced catalog. - New `cli/cmd/ao/skills_query.go` — four cobra subcommands: - `ao skills list [--role --produces --consumes --practice --user-invocable] [--json]` - `ao skills consumers <skill> [--json]` - `ao skills producers <output> [--json]` - `ao skills graph [--format mermaid]` - Regenerated `cli/docs/COMMANDS.md`; bumped the cli-command-surface fixtures (`sub` 179→183, `all` 252→256) for the 4 new subcommands. ## Why `registry.json` and `catalog.json` existed but had no query API — agents grepping "which skill produces X?" had to scan markdown. This turns the catalog into a queryable surface (the bead blocks `ao skill new`, which needs sibling-skill defaults). ## Acceptance > `ao skills list ... --json` returns the matching skill set in <100ms. Verified: `ao skills list --produces result.json --json` → `[beads, discovery]`; `ao skills consumers rpi` → 5 skills; `ao skills graph` emits deterministic Mermaid. Latency well under 100ms. ## Scope notes - Did **not** regenerate `skills/catalog.json` — it carries pre-existing drift on `main` (the `check-skill-catalog-drift` gate is I0/advisory). This PR only *consumes* the catalog; regenerating would sweep in unrelated drift. - The bead's illustrative `--tier judge` example does not map to the real generated schema (which has no `tier` field — it uses `hexagonal_role`, `produces`, `consumes`, `practices`). Filters implemented against the actual catalog fields. ## Tests `cli/internal/skills/catalog_test.go` (engine, exact-value table tests + load round-trip) and `cli/cmd/ao/skills_query_test.go` (JSON shape, sort invariants, flag validation, mermaid header) — all green. `go build`/`go vet`/`go test ./...` pass; conformance + command-surface smoke pass. Closes-scenario: soc-vuu6.4#skill-catalog-json Bounded-context: BC1-Corpus Evidence: cli/internal/skills/catalog.go
2026-05-31 12:36:45 -04:00
-h, --help help for graph
```
#### `ao skills link`
Scan skills/ and create a live-tier symlink for every skill dir that has
```
ao skills link [flags]
```
**Flags:**
```
--dest string Link into this single dir instead of the auto-detected runtimes (default: every installed runtime — ~/.claude, ~/.codex, ~/.gemini, ~/.cursor, ~/.pi)
-h, --help help for link
--json Emit machine-readable JSON
```
feat(skills): queryable skill catalog JSON + ao skills (soc-vuu6.4 #skill-catalog-json) (#640) ## What Slice 2 of the skill-catalog bead (soc-vuu6.4): the **queryable surface** over the generated `skills/catalog.json`. Slice 1 (the generator, schema, drift gate, and `catalog.json` itself) landed in PR #379; this adds the `ao skills` query commands the bead's acceptance criterion calls for. - New `cli/internal/skills/catalog.go` — loads `skills/catalog.json` and a **pure, table-tested** query engine (`List`/`Consumers`/`Producers`/`Mermaid`). No SKILL.md re-parsing; reads the committed, CI-synced catalog. - New `cli/cmd/ao/skills_query.go` — four cobra subcommands: - `ao skills list [--role --produces --consumes --practice --user-invocable] [--json]` - `ao skills consumers <skill> [--json]` - `ao skills producers <output> [--json]` - `ao skills graph [--format mermaid]` - Regenerated `cli/docs/COMMANDS.md`; bumped the cli-command-surface fixtures (`sub` 179→183, `all` 252→256) for the 4 new subcommands. ## Why `registry.json` and `catalog.json` existed but had no query API — agents grepping "which skill produces X?" had to scan markdown. This turns the catalog into a queryable surface (the bead blocks `ao skill new`, which needs sibling-skill defaults). ## Acceptance > `ao skills list ... --json` returns the matching skill set in <100ms. Verified: `ao skills list --produces result.json --json` → `[beads, discovery]`; `ao skills consumers rpi` → 5 skills; `ao skills graph` emits deterministic Mermaid. Latency well under 100ms. ## Scope notes - Did **not** regenerate `skills/catalog.json` — it carries pre-existing drift on `main` (the `check-skill-catalog-drift` gate is I0/advisory). This PR only *consumes* the catalog; regenerating would sweep in unrelated drift. - The bead's illustrative `--tier judge` example does not map to the real generated schema (which has no `tier` field — it uses `hexagonal_role`, `produces`, `consumes`, `practices`). Filters implemented against the actual catalog fields. ## Tests `cli/internal/skills/catalog_test.go` (engine, exact-value table tests + load round-trip) and `cli/cmd/ao/skills_query_test.go` (JSON shape, sort invariants, flag validation, mermaid header) — all green. `go build`/`go vet`/`go test ./...` pass; conformance + command-surface smoke pass. Closes-scenario: soc-vuu6.4#skill-catalog-json Bounded-context: BC1-Corpus Evidence: cli/internal/skills/catalog.go
2026-05-31 12:36:45 -04:00
#### `ao skills list`
Filter the generated skill catalog by hexagonal role, produced or
```
ao skills list [flags]
```
**Flags:**
```
--consumes string Filter to skills that consume this port/sibling
-h, --help help for list
--json Emit machine-readable JSON
--practice string Filter to skills that apply this practice
--produces string Filter to skills that produce this port/artifact
--role string Filter by hexagonal_role (domain, driving-adapter, ...)
--user-invocable string Filter by user-invocability (true|false)
```
#### `ao skills producers`
Print the skills whose produces[] list includes <output> — i.e. who
```
ao skills producers <output> [flags]
```
**Flags:**
```
-h, --help help for producers
--json Emit machine-readable JSON
```
feat(cli): ao skills resolve — MECE corpus audit (overlap + coverage gaps) (#841) ## What Adds `ao skills resolve` — a MECE audit of the `skills/` corpus, ported from the `control-plane/bin/skill-resolve` prototype (cp-skill-resolver-mece-dry). - **Mutually Exclusive (ME):** clusters skills by name-family stem + description-token Jaccard, surfacing overlapping/near-duplicate skills as **merge candidates** (the prune queue, cp-dkf). - **Collectively Exhaustive (CE):** flags thin / description-less `SKILL.md` files as coverage-quality gaps. Read-only; mutates nothing. ``` ao skills resolve # MECE table ao skills resolve --json # machine-readable prune queue ao skills resolve --strict # CI dedup gate: exits 1 on any ME overlap ``` ## Scope decision This ports the **MECE half** only. The deployment-DRY half (which live `~/.claude/skills` symlink backs each name, shadows, `--fix`) is an operator-runtime concern and stays in `control-plane/bin/skill-resolve`. Two tools, two scopes: product-authoring in `ao`, deployment in control-plane. ## Implementation - New `cli/internal/skillsresolve` package, reusing `skillshealth.ParseFrontmatter` (no reinvention) + cobra wiring in `cli/cmd/ao/skills.go`. - Package tests (`resolve_test.go`) + command-level tests (`skills_resolve_test.go`: registration, `--json` schema, `--strict` exit). ## Live run 171 skills, 18 ME overlaps, 0 CE gaps — mirrors the prototype (beads-br↔bv 1.0; mcp-plugins / risk-audit / test families). ## Drive-by fix (separate commit) `fix(skills): wire security-suite into SKILL-TIERS.md` — `security-suite` shipped via the image-bundle merge but was never tiered, leaving `wiring-closure` red on `main`. The HEAD-based pre-push/CI gate blocks any push while it's red, so it's repaired here. Not part of the feature. ## Verification go build ✓ · go vet ✓ · go test (resolve pkg 2/2, command 3/3) ✓ · gofmt ✓ · full pre-push gate green.
2026-06-07 21:12:24 -04:00
#### `ao skills resolve`
Walk skills/ and resolve the corpus toward MECE:
```
ao skills resolve [flags]
```
**Flags:**
```
-h, --help help for resolve
--json Emit machine-readable JSON
--strict Exit non-zero when ME overlaps are found (CI dedup gate)
```
feat(cli): add ao skills unlink — rollback inverse of skills link Add the uninstall/rollback twin for `ao skills link`: `ao skills unlink` removes exactly the live-tier symlinks link minted — those whose target resolves into this repo's skills/ tree — across every installed runtime (~/.claude, ~/.codex, ~/.gemini, ~/.cursor, ~/.pi). Idempotent and non-destructive: foreign symlinks pointing elsewhere and real directories (a foreign corpus such as jsm) are reported as foreign and never removed; stale owned links (skill since removed from the repo) are still cleaned up. Supports --dest, --dry-run (persistent), and --json, mirroring skills link. Document the uninstall path in docs/install-day2-ops.md: per-runtime plugin/ skill removal (Claude, Codex, AGY, OpenCode), `brew uninstall agentops`, `ao skills unlink` for clone-linked skills, and an explicit 'what is kept' note that .agents/ and quick-start artifacts (CLAUDE.md block, GOALS.md) are user-owned data the uninstall deliberately never touches. Regenerate the affected command-surface projections (COMMANDS.md, cli-surface .{json,md}, the eval surface matrix + smoke fixture). The matrix/smoke counts also absorb pre-existing origin/main drift (checked-in expected sub=120 vs actual tree 112); regen brings them to the truthful 113 (112 + unlink). Tests (L2 round-trip, t.TempDir): RemovesOnlyOwnLinks (foreign symlink + real dir survive), DryRunWritesNothing, Idempotent, MissingDestIsNoop, RemovesStaleOwnedLink, EmptySrcFailsClosed, ResilientAcrossDests.
2026-07-13 18:13:09 -04:00
#### `ao skills unlink`
The clean uninstall inverse of `ao skills link`. Scan each runtime's
```
ao skills unlink [flags]
```
**Flags:**
```
--dest string Sweep this single dir instead of the auto-detected runtimes (default: every installed runtime — ~/.claude, ~/.codex, ~/.gemini, ~/.cursor, ~/.pi)
-h, --help help for unlink
--json Emit machine-readable JSON
```
---
### `ao state`
Removed in the AgentOps Cathedral Cut
```
ao state [flags]
```
---
### `ao validate`
Removed in the AgentOps Cathedral Cut
```
ao validate [flags]
```
---
### `ao worktree`
Removed in the AgentOps Cathedral Cut
```
ao worktree [flags]
```
---
### `ao yield`
Removed in the AgentOps Cathedral Cut
```
ao yield [flags]
```
---