Files

1219 lines
30 KiB
Markdown
Raw Permalink 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: ~/.agents/ao/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 demo`
Default to native execution and report independently accepted work (#1129) ## Change Make native coding-agent execution the default AgentOps entry path with zero mandatory skills. Preserve full bundles and add repeatable `ao skills link --skill NAME` selection, validating the entire selection before writes. Align product, installation, architecture and generated command documentation. Extend the existing trial readout to separate endpoint test results, execution state and independently accepted work. Bind supplied judgments to exact content, acceptance and native evidence. Reject empty implementation subjects and require the caller's complete criterion ID set before reporting acceptance. Preserve genuine nonempty and deletion-only subjects, valid failures and missing-proof outcomes. ## Validation - Native onboarding from empty home/consumer directories produces no setup files; selective/full linking and failure boundaries are covered. - Actual RED/GREEN regressions cover empty subjects and the partial-criterion omission found by independent review. - Full Go build, vet and race/shuffle tests; affected Go lint; 88 Python readout/statistics tests passed. - All 73 gates, generated projections, strict documentation build and local aggregate passed (10 passed; one documented optional absence). - All nine PR checks succeeded at `7df0d42b12f35ffc22008cc10a40339afcfbb6a0`. - Fresh author-distinct review passed all six acceptance criteria over all 59 changed paths, with no findings or unchecked scope, after repairing the criterion-coverage finding. ## Evidence limits The real native coding repair demonstrates usability, not comparative skill uplift. The strict live-session machine replay remains NOT_PROVEN where execution/identity observations are unavailable; the source review PASS is retained separately. Existing cohort limits and the historical aggregate-enforcement gap remain unwaived. No new comparative cohort, scheduler, skill-corpus deletion, memory migration or global installation is included.
2026-09-10 16:28:22 -04:00
Show a native coding-agent change from accepted behavior through checks,
```
ao demo [flags]
```
**Flags:**
```
--concepts explain the product boundary
-h, --help help for demo
Default to native execution and report independently accepted work (#1129) ## Change Make native coding-agent execution the default AgentOps entry path with zero mandatory skills. Preserve full bundles and add repeatable `ao skills link --skill NAME` selection, validating the entire selection before writes. Align product, installation, architecture and generated command documentation. Extend the existing trial readout to separate endpoint test results, execution state and independently accepted work. Bind supplied judgments to exact content, acceptance and native evidence. Reject empty implementation subjects and require the caller's complete criterion ID set before reporting acceptance. Preserve genuine nonempty and deletion-only subjects, valid failures and missing-proof outcomes. ## Validation - Native onboarding from empty home/consumer directories produces no setup files; selective/full linking and failure boundaries are covered. - Actual RED/GREEN regressions cover empty subjects and the partial-criterion omission found by independent review. - Full Go build, vet and race/shuffle tests; affected Go lint; 88 Python readout/statistics tests passed. - All 73 gates, generated projections, strict documentation build and local aggregate passed (10 passed; one documented optional absence). - All nine PR checks succeeded at `7df0d42b12f35ffc22008cc10a40339afcfbb6a0`. - Fresh author-distinct review passed all six acceptance criteria over all 59 changed paths, with no findings or unchecked scope, after repairing the criterion-coverage finding. ## Evidence limits The real native coding repair demonstrates usability, not comparative skill uplift. The strict live-session machine replay remains NOT_PROVEN where execution/identity observations are unavailable; the source review PASS is retained separately. Existing cohort limits and the historical aggregate-enforcement gap remain unwaived. No new comparative cohort, scheduler, skill-corpus deletion, memory migration or global installation is included.
2026-09-10 16:28:22 -04:00
--quick show the compact native example (the default)
--rpi show the optional full RPI workflow
```
---
### `ao init`
Default to native execution and report independently accepted work (#1129) ## Change Make native coding-agent execution the default AgentOps entry path with zero mandatory skills. Preserve full bundles and add repeatable `ao skills link --skill NAME` selection, validating the entire selection before writes. Align product, installation, architecture and generated command documentation. Extend the existing trial readout to separate endpoint test results, execution state and independently accepted work. Bind supplied judgments to exact content, acceptance and native evidence. Reject empty implementation subjects and require the caller's complete criterion ID set before reporting acceptance. Preserve genuine nonempty and deletion-only subjects, valid failures and missing-proof outcomes. ## Validation - Native onboarding from empty home/consumer directories produces no setup files; selective/full linking and failure boundaries are covered. - Actual RED/GREEN regressions cover empty subjects and the partial-criterion omission found by independent review. - Full Go build, vet and race/shuffle tests; affected Go lint; 88 Python readout/statistics tests passed. - All 73 gates, generated projections, strict documentation build and local aggregate passed (10 passed; one documented optional absence). - All nine PR checks succeeded at `7df0d42b12f35ffc22008cc10a40339afcfbb6a0`. - Fresh author-distinct review passed all six acceptance criteria over all 59 changed paths, with no findings or unchecked scope, after repairing the criterion-coverage finding. ## Evidence limits The real native coding repair demonstrates usability, not comparative skill uplift. The strict live-session machine replay remains NOT_PROVEN where execution/identity observations are unavailable; the source review PASS is retained separately. Existing cohort limits and the historical aggregate-enforcement gap remain unwaived. No new comparative cohort, scheduler, skill-corpus deletion, memory migration or global installation is included.
2026-09-10 16:28:22 -04:00
Optional local evidence setup; native execution needs no init, skills or
```
ao init [flags]
```
---
### `ao quick-start`
Default to native execution and report independently accepted work (#1129) ## Change Make native coding-agent execution the default AgentOps entry path with zero mandatory skills. Preserve full bundles and add repeatable `ao skills link --skill NAME` selection, validating the entire selection before writes. Align product, installation, architecture and generated command documentation. Extend the existing trial readout to separate endpoint test results, execution state and independently accepted work. Bind supplied judgments to exact content, acceptance and native evidence. Reject empty implementation subjects and require the caller's complete criterion ID set before reporting acceptance. Preserve genuine nonempty and deletion-only subjects, valid failures and missing-proof outcomes. ## Validation - Native onboarding from empty home/consumer directories produces no setup files; selective/full linking and failure boundaries are covered. - Actual RED/GREEN regressions cover empty subjects and the partial-criterion omission found by independent review. - Full Go build, vet and race/shuffle tests; affected Go lint; 88 Python readout/statistics tests passed. - All 73 gates, generated projections, strict documentation build and local aggregate passed (10 passed; one documented optional absence). - All nine PR checks succeeded at `7df0d42b12f35ffc22008cc10a40339afcfbb6a0`. - Fresh author-distinct review passed all six acceptance criteria over all 59 changed paths, with no findings or unchecked scope, after repairing the criterion-coverage finding. ## Evidence limits The real native coding repair demonstrates usability, not comparative skill uplift. The strict live-session machine replay remains NOT_PROVEN where execution/identity observations are unavailable; the source review PASS is retained separately. Existing cohort limits and the historical aggregate-enforcement gap remain unwaived. No new comparative cohort, scheduler, skill-corpus deletion, memory migration or global installation is included.
2026-09-10 16:28:22 -04:00
Use your native coding agent and shell to complete the accepted work.
```
ao quick-start [flags]
```
---
### `ao capabilities`
Print the machine-readable contract for the whole ao CLI as JSON.
```
ao capabilities [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]
```
fix(cli): residue wave — doctor dev-version coherence, diff --only, config-models removal, dual-root stragglers (#944) Wave 4 (residue) of the new-user happy-path arc. Three scoped implementer lanes + fresh adversarial verifier (4 RESOLVED; 1 INCOMPLETE = stale generated projections, closed in integration). **Doctor**: the dev-version detector now reuses the Binary Freshness resolution — a from-source build matching its checkout is healthy (a novice building from source can finally see `ao doctor` exit 0); findings fire only on genuine drift, shadowed duplicate `ao` binaries, or an informational from-source note outside any checkout. `ao doctor diff` gains `--only` so the fix-plan preview can be scoped the way remediation text implies. **Config**: the dead `ao config models` surface is removed end-to-end (lane re-verified zero consumers before deleting; `--show` proven byte-identical before/after; removed-child hint + MIGRATION row; existing `models:` config sections still parse and are ignored). **Dual-root stragglers**: learning-coherence gate globs, `quality.CountConstraints`, and the eval sandbox corpus deny-list now cover canonical `.agents/ao/<section>` alongside legacy roots. **Doc-link hygiene**: the strict docs-link backstop's allowlist was 100% stale (53/53 entries referenced Cathedral-Cut-deleted docs) — refreshed to 10 verified accepted-class entries; ROADMAP dead links fixed; documentation-index generator emits GitHub URLs for repo-root targets; doc-skill references instruct only shipped scripts; codex twins + CLI-surface projections + surface-count fixture regenerated. **Deferred by design**: the `3.3.0-rc` fallback version bump belongs inside the v3.3.0 tag-cut commit. **Verified**: full suite 61/61 pkgs (2825 tests); golangci-lint clean; `ao gate check --full` 67/67 over this range; Test-Removal-Reason trailer covers the 6 deliberately deleted models tests.
2026-07-20 19:05:57 -04:00
**Flags:**
```
-h, --help help for diff
--only strings Scope the fix-plan preview to finding ids or subsystems (comma-separated), mirroring --fix --only
```
#### `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 content-addressed intent and verdict evidence stored by AgentOps.
```
ao status [flags]
```
Improve CLI checkpoint recovery, evidence status, and skill search (#1120) A failed mining-checkpoint write could truncate the saved watermark and cause retry to replay older events. The CLI also wrote evidence to external roots that status could not inspect. This batch fixes those behaviors and removes duplicate normalization from skill search. - Mining checkpoints use the existing atomic storage writer. A real partial-write regression test proves old bytes survive and retry retains stable event IDs. Existing mode bits are preserved; new checkpoints use 0600. Symlink and special-file destinations are rejected before reading. Before replacement, an empty same-directory probe checks ownership and permission metadata, including ACLs and inherited permissions. Unverifiable or different metadata returns an error and leaves the prior checkpoint intact. This is a conservative refusal, not ACL migration. A directory-sync error after rename can leave the new state visible. - `ao status --evidence-root PATH` inspects an explicit existing non-Git store, with matching text/JSON/YAML reports, no fallback on invalid roots, and no reads through evidence symlinks. Omitted-flag behavior remains unchanged. - Skill-query normalization has one implementation, preserving repetition versus first-occurrence semantics. Nine fixed shipped-catalog queries remain byte-identical against a source-pinned baseline. Validation: Go build, vet, tests, race/shuffle with atomic coverage, repository Bats and aggregate suites, regeneration, applicable gates and lint passed. Final Linux and Windows correctness CI and all required checks passed. A fresh author-distinct review verified every acceptance criterion across all 23 changed paths with no unchecked scope. Nine production-query outputs match the source-pinned baseline. The first CI attempt exposed a test-child coverage flush under its temporary file-size limit; the test now restores that limit before exit. Fresh review then exposed ACL loss despite green CI. The permission guard and native regression tests repair that defect while preserving the original access requirement. The failure cases and repair costs are retained in the evaluation.
2026-09-09 18:48:58 -04:00
**Flags:**
```
--evidence-root string Existing explicit non-Git evidence directory (default: working directory's .agents/ao)
-h, --help help for status
```
---
### `ao version`
Display the version, build information, and runtime details.
```
ao version [flags]
```
---
feat(gc): port gc-maintainer-ops into the ao gc command family (#1016) ## What Ports `scripts/gc-maintainer-ops.sh` (425 lines of bash: prepare / check / recover-affinity for stock Gas City rigs) into the Go CLI as **`ao gc prepare|check|recover-affinity`**, per ADR-0016 (skill logic ships in Go via `ao`; shell stays thin glue). **Why:** skills ship via plugin/npx as SKILL.md only — a user without a repo checkout could not run the commands the shipped `using-gc` skill teaches. The skill said "From an AgentOps checkout", which was disclosed but weak. ## Changes - **`cli/internal/gcmaintainer`** — full port: rig/import pin verification, bundled pack-cache resolution, PyYAML-capable python selection, atomic runtime staging, managed check wrappers, skill links into city/rig Codex sinks, macOS LaunchAgent + doctor/status health checks, bounded affinity recovery. Output and refusal-message parity with the shell script (incl. refuse-before-mutation ordering). - **`cli/internal/commands/gc` + `cmd/ao/gc_composition.go`** — cobra module on the shared `clicontract.HostOptions` seam; global `--dry-run` always overrides `--apply`. - **Skills source resolution without a checkout**: `--skills-source` > enclosing agentops checkout > installed skills root (`~/.agents/skills`, `~/.claude/skills`). Existing rigs stay recognized: the `managed-by: agentops gc-maintainer-ops` wrapper marker is unchanged. - **Tests migrated**: `tests/python/test_gc_maintainer_ops.py` (7 cases) → Go L2 tests in `cli/internal/gcmaintainer` with the same fake-`gc` harness, plus module wiring tests. `scripts/check-gc-executor.sh` no longer runs the python suite. - **`scripts/gc-maintainer-ops.sh`** reduced to a thin wrapper exec'ing `ao gc`, pinning `--skills-source` to its checkout to preserve historical semantics (`--ao-bin` now selects the ao binary). - **Docs/projections**: `skills/using-gc/SKILL.md` now teaches `ao gc ...`; codex, gemini, and executor-pack projections regenerated via their owning generators; spine/COMMANDS.md/surface artifacts regenerated. ## Verification - `go build ./... && go vet ./... && go test ./...` — 2923 passed, 73 packages - `golangci-lint run` on new/touched packages — clean - `shellcheck -S warning` on wrapper + gate script — clean - `bash scripts/check-gc-executor.sh` — OK - Smoke: built `ao`, ran wrapper → `ao gc` delegation end-to-end
2026-07-30 13:16:53 -04:00
### `ao gc`
Prepare and qualify the stock Gas City maintainer pack without owning a pack.
```
ao gc [command]
```
**Subcommands:**
#### `ao gc check`
Verify a prepared maintainer runtime read-only
```
ao gc check [flags]
```
**Flags:**
```
--city string Gas City root directory (required)
feat(gc): pre-seed Codex trust for materialized Gas City homes (#1031) ## Defect Gas City materializes Codex session homes with project-local hooks. The first Codex process in an untrusted home can stop at the interactive workspace/hook trust dialog, leaving the agent pane alive but unable to take dispatched work. Codex persists two independent decisions in `$CODEX_HOME/config.toml`: 1. workspace trust under `[projects."<dir>"]` 2. one content hash per hook under `[hooks.state."<hook-key>"]` Trusting a parent directory does not trust a session home, and the hook digest input is intentionally owned by Codex rather than reimplemented here. ## Change `ao gc prepare` now discovers the Gas City directories that exist when it runs (city and rig roots, materialized agent homes, and materialized rig worktrees) and pre-seeds both trust layers for those exact targets. - Hook identities and current hashes come from Codex's `hooks/list` app-server method. - Returned hooks are restricted to the discovered targets; user- or plugin-level hooks are never granted trust by this command. - Explicit operator decisions are preserved. An untrusted workspace, modified hook, disabled hook, unusable hash, malformed response, or malformed TOML fails loudly rather than being rewritten or accepted as complete. - The merged TOML is validated in memory and installed with the CLI's durable atomic writer while preserving existing permissions. - `ao gc check` verifies the same values from local files only. It starts no Codex subprocess and writes nothing. ## Deliberate boundary Discovery is filesystem-based. A home Gas City creates *after* `prepare` is not pre-seeded by an earlier invocation. `prepare` compares configured agent identities with materialized homes and warns about missing homes, including the real dotted-name shape (`gastown.mayor` → `.gc/agents/mayor`). The operational rule is documented explicitly: ```text prepare → start the city → prepare again → dispatch ``` This PR does not claim that one pre-start invocation covers future homes or that every future pane can never encounter a prompt. ## Evidence Automated tests cover: - value-based workspace and hook trust, including `enabled = false` - malformed/unexpected `hooks/list` responses - regular local `hooks.json` files that derive zero hook identities (`{}`, `{"hooks":null}`, and `{"hooks":{}}`), keeping `prepare` and `check` aligned - real TOML spellings, invalid merges, idempotence, and mode preservation - target filtering and derived hook-key fidelity - subprocess-free `check` - missing-home identity reporting for nested and dotted qualified names - operation with no Codex binary - package-wide HOME isolation An isolated real-Codex smoke on a disposable Gas City home established the behavioral differential: with the home's trust entries removed, Codex rendered the trust dialog; after seeding the same home, it reached the composer without the prompt. This proves the existing-home mechanism, not future-home timing. Final recovery checks on commit `a4b52b2354b9f96e5e10e07b2916339c87190bfc`: ```text go test -count=1 ./internal/gcmaintainer ok github.com/boshu2/agentops/cli/internal/gcmaintainer 11.943s go test -race -shuffle=on -count=2 ./internal/gcmaintainer PASS go test -count=1 ./internal/testsupport PASS go vet ./internal/gcmaintainer ./internal/testsupport PASS scripts/check-test-home-isolation.sh PASS scripts/check-test-isolation.sh PASS (raw os.Setenv remains at the 10/10 baseline) GOCACHE=/private/tmp/agentops-gocache \ GOLANGCI_LINT_CACHE=/private/tmp/agentops-golangci-cache \ WORKTREE_DISPOSITION_CI_SKIP=1 \ ./bin/ao gate check --full --workflow-coverage --require-workflow-parity PASS (68/68 full/head checks) GOCACHE=/private/tmp/agentops-gocache bash scripts/regen-all.sh --check PASS git diff --check PASS ``` Recovery fixed the prior CI findings with `storage.AtomicWriteFile`, package-wide HOME isolation, and `json.Encoder.Encode`. The first repaired CI replay exposed one further ratchet: raw `os.Setenv` calls in the new `_test.go` TestMain raised the repository baseline from 10 to 12. The final commit moves that one-time setup into the existing shared test-support boundary, keeps environment changes outside `m.Run`, and teaches the HOME-isolation gate only the exact safe helper shape. CI will rerun on the exact pushed commit.
2026-08-03 09:51:53 -04:00
--codex-bin string Codex CLI used to resolve hook trust identities (default: codex on PATH)
feat(gc): port gc-maintainer-ops into the ao gc command family (#1016) ## What Ports `scripts/gc-maintainer-ops.sh` (425 lines of bash: prepare / check / recover-affinity for stock Gas City rigs) into the Go CLI as **`ao gc prepare|check|recover-affinity`**, per ADR-0016 (skill logic ships in Go via `ao`; shell stays thin glue). **Why:** skills ship via plugin/npx as SKILL.md only — a user without a repo checkout could not run the commands the shipped `using-gc` skill teaches. The skill said "From an AgentOps checkout", which was disclosed but weak. ## Changes - **`cli/internal/gcmaintainer`** — full port: rig/import pin verification, bundled pack-cache resolution, PyYAML-capable python selection, atomic runtime staging, managed check wrappers, skill links into city/rig Codex sinks, macOS LaunchAgent + doctor/status health checks, bounded affinity recovery. Output and refusal-message parity with the shell script (incl. refuse-before-mutation ordering). - **`cli/internal/commands/gc` + `cmd/ao/gc_composition.go`** — cobra module on the shared `clicontract.HostOptions` seam; global `--dry-run` always overrides `--apply`. - **Skills source resolution without a checkout**: `--skills-source` > enclosing agentops checkout > installed skills root (`~/.agents/skills`, `~/.claude/skills`). Existing rigs stay recognized: the `managed-by: agentops gc-maintainer-ops` wrapper marker is unchanged. - **Tests migrated**: `tests/python/test_gc_maintainer_ops.py` (7 cases) → Go L2 tests in `cli/internal/gcmaintainer` with the same fake-`gc` harness, plus module wiring tests. `scripts/check-gc-executor.sh` no longer runs the python suite. - **`scripts/gc-maintainer-ops.sh`** reduced to a thin wrapper exec'ing `ao gc`, pinning `--skills-source` to its checkout to preserve historical semantics (`--ao-bin` now selects the ao binary). - **Docs/projections**: `skills/using-gc/SKILL.md` now teaches `ao gc ...`; codex, gemini, and executor-pack projections regenerated via their owning generators; spine/COMMANDS.md/surface artifacts regenerated. ## Verification - `go build ./... && go vet ./... && go test ./...` — 2923 passed, 73 packages - `golangci-lint run` on new/touched packages — clean - `shellcheck -S warning` on wrapper + gate script — clean - `bash scripts/check-gc-executor.sh` — OK - Smoke: built `ao`, ran wrapper → `ao gc` delegation end-to-end
2026-07-30 13:16:53 -04:00
--gc-bin string Gas City 1.4 binary (default: gc on PATH)
-h, --help help for check
--pack-dir string resolved official gascity pack root (normally auto-detected)
--rig string rig directory inside the city (required)
--skills-source string AgentOps skills directory to link from (default: enclosing checkout, then installed skills root)
```
#### `ao gc prepare`
feat(gc): pre-seed Codex trust for materialized Gas City homes (#1031) ## Defect Gas City materializes Codex session homes with project-local hooks. The first Codex process in an untrusted home can stop at the interactive workspace/hook trust dialog, leaving the agent pane alive but unable to take dispatched work. Codex persists two independent decisions in `$CODEX_HOME/config.toml`: 1. workspace trust under `[projects."<dir>"]` 2. one content hash per hook under `[hooks.state."<hook-key>"]` Trusting a parent directory does not trust a session home, and the hook digest input is intentionally owned by Codex rather than reimplemented here. ## Change `ao gc prepare` now discovers the Gas City directories that exist when it runs (city and rig roots, materialized agent homes, and materialized rig worktrees) and pre-seeds both trust layers for those exact targets. - Hook identities and current hashes come from Codex's `hooks/list` app-server method. - Returned hooks are restricted to the discovered targets; user- or plugin-level hooks are never granted trust by this command. - Explicit operator decisions are preserved. An untrusted workspace, modified hook, disabled hook, unusable hash, malformed response, or malformed TOML fails loudly rather than being rewritten or accepted as complete. - The merged TOML is validated in memory and installed with the CLI's durable atomic writer while preserving existing permissions. - `ao gc check` verifies the same values from local files only. It starts no Codex subprocess and writes nothing. ## Deliberate boundary Discovery is filesystem-based. A home Gas City creates *after* `prepare` is not pre-seeded by an earlier invocation. `prepare` compares configured agent identities with materialized homes and warns about missing homes, including the real dotted-name shape (`gastown.mayor` → `.gc/agents/mayor`). The operational rule is documented explicitly: ```text prepare → start the city → prepare again → dispatch ``` This PR does not claim that one pre-start invocation covers future homes or that every future pane can never encounter a prompt. ## Evidence Automated tests cover: - value-based workspace and hook trust, including `enabled = false` - malformed/unexpected `hooks/list` responses - regular local `hooks.json` files that derive zero hook identities (`{}`, `{"hooks":null}`, and `{"hooks":{}}`), keeping `prepare` and `check` aligned - real TOML spellings, invalid merges, idempotence, and mode preservation - target filtering and derived hook-key fidelity - subprocess-free `check` - missing-home identity reporting for nested and dotted qualified names - operation with no Codex binary - package-wide HOME isolation An isolated real-Codex smoke on a disposable Gas City home established the behavioral differential: with the home's trust entries removed, Codex rendered the trust dialog; after seeding the same home, it reached the composer without the prompt. This proves the existing-home mechanism, not future-home timing. Final recovery checks on commit `a4b52b2354b9f96e5e10e07b2916339c87190bfc`: ```text go test -count=1 ./internal/gcmaintainer ok github.com/boshu2/agentops/cli/internal/gcmaintainer 11.943s go test -race -shuffle=on -count=2 ./internal/gcmaintainer PASS go test -count=1 ./internal/testsupport PASS go vet ./internal/gcmaintainer ./internal/testsupport PASS scripts/check-test-home-isolation.sh PASS scripts/check-test-isolation.sh PASS (raw os.Setenv remains at the 10/10 baseline) GOCACHE=/private/tmp/agentops-gocache \ GOLANGCI_LINT_CACHE=/private/tmp/agentops-golangci-cache \ WORKTREE_DISPOSITION_CI_SKIP=1 \ ./bin/ao gate check --full --workflow-coverage --require-workflow-parity PASS (68/68 full/head checks) GOCACHE=/private/tmp/agentops-gocache bash scripts/regen-all.sh --check PASS git diff --check PASS ``` Recovery fixed the prior CI findings with `storage.AtomicWriteFile`, package-wide HOME isolation, and `json.Encoder.Encode`. The first repaired CI replay exposed one further ratchet: raw `os.Setenv` calls in the new `_test.go` TestMain raised the repository baseline from 10 to 12. The final commit moves that one-time setup into the existing shared test-support boundary, keeps environment changes outside `m.Run`, and teaches the HOME-isolation gate only the exact safe helper shape. CI will rerun on the exact pushed commit.
2026-08-03 09:51:53 -04:00
Stage the contained maintainer runtime, skill links, and codex trust for a rig
feat(gc): port gc-maintainer-ops into the ao gc command family (#1016) ## What Ports `scripts/gc-maintainer-ops.sh` (425 lines of bash: prepare / check / recover-affinity for stock Gas City rigs) into the Go CLI as **`ao gc prepare|check|recover-affinity`**, per ADR-0016 (skill logic ships in Go via `ao`; shell stays thin glue). **Why:** skills ship via plugin/npx as SKILL.md only — a user without a repo checkout could not run the commands the shipped `using-gc` skill teaches. The skill said "From an AgentOps checkout", which was disclosed but weak. ## Changes - **`cli/internal/gcmaintainer`** — full port: rig/import pin verification, bundled pack-cache resolution, PyYAML-capable python selection, atomic runtime staging, managed check wrappers, skill links into city/rig Codex sinks, macOS LaunchAgent + doctor/status health checks, bounded affinity recovery. Output and refusal-message parity with the shell script (incl. refuse-before-mutation ordering). - **`cli/internal/commands/gc` + `cmd/ao/gc_composition.go`** — cobra module on the shared `clicontract.HostOptions` seam; global `--dry-run` always overrides `--apply`. - **Skills source resolution without a checkout**: `--skills-source` > enclosing agentops checkout > installed skills root (`~/.agents/skills`, `~/.claude/skills`). Existing rigs stay recognized: the `managed-by: agentops gc-maintainer-ops` wrapper marker is unchanged. - **Tests migrated**: `tests/python/test_gc_maintainer_ops.py` (7 cases) → Go L2 tests in `cli/internal/gcmaintainer` with the same fake-`gc` harness, plus module wiring tests. `scripts/check-gc-executor.sh` no longer runs the python suite. - **`scripts/gc-maintainer-ops.sh`** reduced to a thin wrapper exec'ing `ao gc`, pinning `--skills-source` to its checkout to preserve historical semantics (`--ao-bin` now selects the ao binary). - **Docs/projections**: `skills/using-gc/SKILL.md` now teaches `ao gc ...`; codex, gemini, and executor-pack projections regenerated via their owning generators; spine/COMMANDS.md/surface artifacts regenerated. ## Verification - `go build ./... && go vet ./... && go test ./...` — 2923 passed, 73 packages - `golangci-lint run` on new/touched packages — clean - `shellcheck -S warning` on wrapper + gate script — clean - `bash scripts/check-gc-executor.sh` — OK - Smoke: built `ao`, ran wrapper → `ao gc` delegation end-to-end
2026-07-30 13:16:53 -04:00
```
ao gc prepare [flags]
```
**Flags:**
```
--city string Gas City root directory (required)
feat(gc): pre-seed Codex trust for materialized Gas City homes (#1031) ## Defect Gas City materializes Codex session homes with project-local hooks. The first Codex process in an untrusted home can stop at the interactive workspace/hook trust dialog, leaving the agent pane alive but unable to take dispatched work. Codex persists two independent decisions in `$CODEX_HOME/config.toml`: 1. workspace trust under `[projects."<dir>"]` 2. one content hash per hook under `[hooks.state."<hook-key>"]` Trusting a parent directory does not trust a session home, and the hook digest input is intentionally owned by Codex rather than reimplemented here. ## Change `ao gc prepare` now discovers the Gas City directories that exist when it runs (city and rig roots, materialized agent homes, and materialized rig worktrees) and pre-seeds both trust layers for those exact targets. - Hook identities and current hashes come from Codex's `hooks/list` app-server method. - Returned hooks are restricted to the discovered targets; user- or plugin-level hooks are never granted trust by this command. - Explicit operator decisions are preserved. An untrusted workspace, modified hook, disabled hook, unusable hash, malformed response, or malformed TOML fails loudly rather than being rewritten or accepted as complete. - The merged TOML is validated in memory and installed with the CLI's durable atomic writer while preserving existing permissions. - `ao gc check` verifies the same values from local files only. It starts no Codex subprocess and writes nothing. ## Deliberate boundary Discovery is filesystem-based. A home Gas City creates *after* `prepare` is not pre-seeded by an earlier invocation. `prepare` compares configured agent identities with materialized homes and warns about missing homes, including the real dotted-name shape (`gastown.mayor` → `.gc/agents/mayor`). The operational rule is documented explicitly: ```text prepare → start the city → prepare again → dispatch ``` This PR does not claim that one pre-start invocation covers future homes or that every future pane can never encounter a prompt. ## Evidence Automated tests cover: - value-based workspace and hook trust, including `enabled = false` - malformed/unexpected `hooks/list` responses - regular local `hooks.json` files that derive zero hook identities (`{}`, `{"hooks":null}`, and `{"hooks":{}}`), keeping `prepare` and `check` aligned - real TOML spellings, invalid merges, idempotence, and mode preservation - target filtering and derived hook-key fidelity - subprocess-free `check` - missing-home identity reporting for nested and dotted qualified names - operation with no Codex binary - package-wide HOME isolation An isolated real-Codex smoke on a disposable Gas City home established the behavioral differential: with the home's trust entries removed, Codex rendered the trust dialog; after seeding the same home, it reached the composer without the prompt. This proves the existing-home mechanism, not future-home timing. Final recovery checks on commit `a4b52b2354b9f96e5e10e07b2916339c87190bfc`: ```text go test -count=1 ./internal/gcmaintainer ok github.com/boshu2/agentops/cli/internal/gcmaintainer 11.943s go test -race -shuffle=on -count=2 ./internal/gcmaintainer PASS go test -count=1 ./internal/testsupport PASS go vet ./internal/gcmaintainer ./internal/testsupport PASS scripts/check-test-home-isolation.sh PASS scripts/check-test-isolation.sh PASS (raw os.Setenv remains at the 10/10 baseline) GOCACHE=/private/tmp/agentops-gocache \ GOLANGCI_LINT_CACHE=/private/tmp/agentops-golangci-cache \ WORKTREE_DISPOSITION_CI_SKIP=1 \ ./bin/ao gate check --full --workflow-coverage --require-workflow-parity PASS (68/68 full/head checks) GOCACHE=/private/tmp/agentops-gocache bash scripts/regen-all.sh --check PASS git diff --check PASS ``` Recovery fixed the prior CI findings with `storage.AtomicWriteFile`, package-wide HOME isolation, and `json.Encoder.Encode`. The first repaired CI replay exposed one further ratchet: raw `os.Setenv` calls in the new `_test.go` TestMain raised the repository baseline from 10 to 12. The final commit moves that one-time setup into the existing shared test-support boundary, keeps environment changes outside `m.Run`, and teaches the HOME-isolation gate only the exact safe helper shape. CI will rerun on the exact pushed commit.
2026-08-03 09:51:53 -04:00
--codex-bin string Codex CLI used to resolve hook trust identities (default: codex on PATH)
feat(gc): port gc-maintainer-ops into the ao gc command family (#1016) ## What Ports `scripts/gc-maintainer-ops.sh` (425 lines of bash: prepare / check / recover-affinity for stock Gas City rigs) into the Go CLI as **`ao gc prepare|check|recover-affinity`**, per ADR-0016 (skill logic ships in Go via `ao`; shell stays thin glue). **Why:** skills ship via plugin/npx as SKILL.md only — a user without a repo checkout could not run the commands the shipped `using-gc` skill teaches. The skill said "From an AgentOps checkout", which was disclosed but weak. ## Changes - **`cli/internal/gcmaintainer`** — full port: rig/import pin verification, bundled pack-cache resolution, PyYAML-capable python selection, atomic runtime staging, managed check wrappers, skill links into city/rig Codex sinks, macOS LaunchAgent + doctor/status health checks, bounded affinity recovery. Output and refusal-message parity with the shell script (incl. refuse-before-mutation ordering). - **`cli/internal/commands/gc` + `cmd/ao/gc_composition.go`** — cobra module on the shared `clicontract.HostOptions` seam; global `--dry-run` always overrides `--apply`. - **Skills source resolution without a checkout**: `--skills-source` > enclosing agentops checkout > installed skills root (`~/.agents/skills`, `~/.claude/skills`). Existing rigs stay recognized: the `managed-by: agentops gc-maintainer-ops` wrapper marker is unchanged. - **Tests migrated**: `tests/python/test_gc_maintainer_ops.py` (7 cases) → Go L2 tests in `cli/internal/gcmaintainer` with the same fake-`gc` harness, plus module wiring tests. `scripts/check-gc-executor.sh` no longer runs the python suite. - **`scripts/gc-maintainer-ops.sh`** reduced to a thin wrapper exec'ing `ao gc`, pinning `--skills-source` to its checkout to preserve historical semantics (`--ao-bin` now selects the ao binary). - **Docs/projections**: `skills/using-gc/SKILL.md` now teaches `ao gc ...`; codex, gemini, and executor-pack projections regenerated via their owning generators; spine/COMMANDS.md/surface artifacts regenerated. ## Verification - `go build ./... && go vet ./... && go test ./...` — 2923 passed, 73 packages - `golangci-lint run` on new/touched packages — clean - `shellcheck -S warning` on wrapper + gate script — clean - `bash scripts/check-gc-executor.sh` — OK - Smoke: built `ao`, ran wrapper → `ao gc` delegation end-to-end
2026-07-30 13:16:53 -04:00
--gc-bin string Gas City 1.4 binary (default: gc on PATH)
-h, --help help for prepare
--pack-dir string resolved official gascity pack root (normally auto-detected)
--rig string rig directory inside the city (required)
--skills-source string AgentOps skills directory to link from (default: enclosing checkout, then installed skills root)
```
#### `ao gc recover-affinity`
Clear stale required session-affinity assignments (dry-run by default)
```
ao gc recover-affinity [flags]
```
**Flags:**
```
--apply apply the recovery; the default is a read-only dry run
--city string Gas City root directory (required)
--gc-bin string Gas City 1.4 binary (default: gc on PATH)
-h, --help help for recover-affinity
--pack-dir string resolved official gascity pack root (normally auto-detected)
--rig string rig directory inside the city (required)
```
---
### `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
```
---
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 session evidence and maintain .agents artifacts
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 prune-agents`
Apply .agents retention policies (dry-run by default)
```
ao session prune-agents [flags]
```
**Flags:**
```
--execute Delete the selected artifacts; the default is a read-only dry run
-h, --help help for prune-agents
--quiet Suppress per-path output and print only the summary
```
#### `ao session read-source`
Read one explicit regular source file under independently selected T05 context
```
ao session read-source [flags]
```
**Flags:**
```
--access-policy-ref string Independently selected T05 access policy JSON (required)
--allow-oversize Explicitly bypass serialized profile size bound; host delivery remains unverified
--consumer-root string Existing consumer checkout for T05 route verification (required)
--destination-ref string Expected destination identity (required)
--expect-file-identity string Expected prior file_before.identity, for replacement checks across calls
--expect-prefix-sha256 string Expected SHA-256 of all bytes before through-byte
--file string Exact absolute source file path (required)
-h, --help help for read-source
--json Emit JSON (also the default; no text-only coverage view)
--max-bytes int Positive maximum returned source bytes (required)
--model-ref string Expected model/provider identity (required)
--native-directory string Explicit directory for native BD source verification (required)
--owner-scope string Independently expected owner scope (required)
--project-id string Expected native project identity (required)
--source-id string Expected canonical native beads_dir (required)
--start-byte int First byte of the returned half-open range (required)
--task-ref string Expected caller task identity (required)
--through-byte int Frozen exclusive prefix boundary, paired with expect-prefix-sha256
```
#### `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.
```
Restore private context routes and verify native judgment receipts (#1112) Add explicit, recoverable private context routing through `ao config context`, binding native source, owner, task, model and destination to existing policy and external storage. Recovery reads the original Beads maintenance anchor; configuration reports native access enforcement as unattested. Add `ao provenance verify-judgments` to check required review profiles against exact native transcript receipts, independent subject and acceptance, distinct contexts, completion and permitted providers. Requested identity and unreported effort do not count as runtime evidence. The verdict schema is unchanged. Repair the existing cleanup test: a 0.3-second budget could expire during preparation before either fixture process started. A separate controlled-delay test now proves preparation cannot renew that deadline. The running-cleanup case requires parent/child readiness, preserved partial output, the postlaunch cleanup result and both processes stopped within its existing four-second bound. Production timeout behavior is unchanged. Validation: fresh author-distinct review passed the exact 55-path final subject and all T05/T21 acceptance. The complete local Bats run passed (1,333 passed, two existing skips), as did Go build/vet/test/race, all 72 full-mode gates, the aggregate and generated-output checks. Ubuntu/Windows CI, security and both installation jobs passed on the final commit. The final evidence scan found no new orphaned bindings; 73 historical bindings remain preserved. Earlier failed results and private evidence remain outside the PR.
2026-09-08 18:57:08 -04:00
ao config [command]
```
**Flags:**
```
-h, --help help for config
--show Show resolved configuration with sources
```
Restore private context routes and verify native judgment receipts (#1112) Add explicit, recoverable private context routing through `ao config context`, binding native source, owner, task, model and destination to existing policy and external storage. Recovery reads the original Beads maintenance anchor; configuration reports native access enforcement as unattested. Add `ao provenance verify-judgments` to check required review profiles against exact native transcript receipts, independent subject and acceptance, distinct contexts, completion and permitted providers. Requested identity and unreported effort do not count as runtime evidence. The verdict schema is unchanged. Repair the existing cleanup test: a 0.3-second budget could expire during preparation before either fixture process started. A separate controlled-delay test now proves preparation cannot renew that deadline. The running-cleanup case requires parent/child readiness, preserved partial output, the postlaunch cleanup result and both processes stopped within its existing four-second bound. Production timeout behavior is unchanged. Validation: fresh author-distinct review passed the exact 55-path final subject and all T05/T21 acceptance. The complete local Bats run passed (1,333 passed, two existing skips), as did Go build/vet/test/race, all 72 full-mode gates, the aggregate and generated-output checks. Ubuntu/Windows CI, security and both installation jobs passed on the final commit. The final evidence scan found no new orphaned bindings; 73 historical bindings remain preserved. Earlier failed results and private evidence remain outside the PR.
2026-09-08 18:57:08 -04:00
**Subcommands:**
#### `ao config context`
Resolve caller/home CDLC routes and read the selected native maintenance anchor.
```
ao config context [flags]
```
**Flags:**
```
--access-policy-ref string Existing caller-owned access policy JSON
--bundle-root string Selected existing external bundle
--consumer-root string Existing consumer checkout to exclude
--destination-ref string Caller destination identity
--evidence-root string Selected existing protected non-Git evidence
--field string Emit one checked root for its caller-owned consumer
-h, --help help for context
--maintenance-work-ref string Known native maintenance anchor
--model-ref string Caller model/provider identity
--native-directory string Explicit native BD source directory
--owner-scope string Expected separately authorized owner scope
--project-id string Expected native project ID
--recover Recover the same route from its native maintenance anchor
--source-id string Expected canonical native beads_dir
--staging-root string Selected existing protected non-Git staging
--task-ref string Caller task identity
```
---
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 and inspect generic, evidence-backed relationships between
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 [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 (for example decision, artifact, or observation) (default "decision")
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
-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
--to-type string Target node type (for example decision, artifact, or observation) (default "artifact")
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
--trust-tier string Trust tier (authored|inferred|mined) (default "authored")
--ts string Override the UTC RFC3339 timestamp (defaults to now)
```
#### `ao provenance check-okf`
Check one explicitly selected Markdown concept against agentops-okf-v0.2/v1,
```
ao provenance check-okf [flags]
```
**Flags:**
```
--file string Explicit Markdown concept file (required; at most 1 MiB)
-h, --help help for check-okf
--json Emit JSON (the default)
--profile string Exact supported structural profile version (default "agentops-okf-v0.2/v1")
```
2026-09-08 16:06:33 -04:00
#### `ao provenance digest`
Hash a strict JSON object in canonical form.
```
ao provenance digest <json-file> [flags]
```
**Flags:**
```
-h, --help help for digest
--helper-version string Require evidence helper version; incompatibility fails before mutation (default "1")
--json Emit JSON (the default for evidence operations except digest)
```
#### `ao provenance evidence-orphans`
Read the established scorecard, fixture-set and capture-contract bindings
```
ao provenance evidence-orphans [flags]
```
**Flags:**
```
--changed stringArray Changed bound path; repeat to preserve input order
-h, --help help for evidence-orphans
--root string Explicit repository root to scan
```
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
```
2026-09-08 16:06:33 -04:00
#### `ao provenance manifest`
Compute subject-manifest.v1 from declared filesystem paths.
```
ao provenance manifest [flags]
```
**Flags:**
```
--base-manifest string Base manifest for deletions
--evidence-root string Existing non-Git directory required with --out
--exclude stringArray Excluded path or fnmatch pattern (repeatable)
--exclude-git-root stringArray Caller-known existing Git storage root to exclude (repeatable); unresolved roots fail before writes
--git-metadata-json string Descriptive string/null metadata object; excluded from identity
-h, --help help for manifest
--helper-version string Require evidence helper version; incompatibility fails before mutation (default "1")
--include stringArray Declared relative path (repeatable)
--json Emit JSON (the default for evidence operations except digest)
--out string Optional relative output path inside evidence root
--root string Explicit subject directory
```
#### `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:**
```
Extract bounded session evidence for instruction improvement (#1130) ## What Extend `ao provenance mine-session` with `--view excerpts` and an explicit instruction target. Native agents can inspect bounded Codex/Claude records with literal text, JSON field pointers, exact byte spans and SHA-256 identities, then propose a supported skill, AGENTS.md or task-prompt edit. Existing event JSONL and checkpoint behavior stay the default. ## Why Instruction improvement needs precise session evidence. The existing normalized parser truncates long text and does not provide bounded, directly citable extraction. This view supplies the deterministic reading step; native agents retain interpretation and review. ## How I tested - Focused application and command regressions passed, including legacy checkpoints, native message/tool forms, long Unicode text, malformed data, continuation, limits and writer errors. - Source-built AO extracted nine selected records from real AgentOps sessions. All selected range hashes matched; analysis produced one candidate prompt clarification and one justified no-change finding. Private source material and proposals remain outside Git. This demonstrates usability, not causal uplift. - Go build/vet/race-shuffle passed. Full gates: 73/73 passed, including lint. Aggregate: 10 passed, one optional absence. Generated projections passed. All seven GitHub checks passed at `31c128015a2e48a2a787b165e02966938381cf65`, including Linux, Windows and security. - A fresh author-distinct reviewer verified all eight changed paths, exact source ranges and targets, the private proposal/no-change support, and the clean-commit demo binary; no implementation or support findings. The command reads explicit authorized files and writes JSON to stdout. It runs no model, creates no index or checkpoint in excerpt mode, and automatically edits or publishes nothing. It does not enforce restricted-source isolation or redact output. ## Checklist - [x] Required Go build, vet and tests pass - [x] No private session content or credentials added to this diff - [x] Existing event interface preserved; new flags documented
2026-09-10 17:25:45 -04:00
--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)
--max-bytes int Excerpts only: maximum source-window bytes (default 65536)
--max-output-bytes int Excerpts only: maximum serialized JSON bytes, including newline (default 131072)
--max-records int Excerpts only: maximum emitted records (default 20)
--start-byte int Excerpts only: zero-based record-aligned source offset
--state string Path to the incremental watermark state JSON (created/updated; omit for a full one-shot mine)
--target string Excerpts only: explicit instruction file, at most 64 KiB
--view string Output view: events (legacy JSONL) or excerpts (one bounded JSON document) (default "events")
```
#### `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
```
2026-09-08 16:06:33 -04:00
#### `ao provenance snapshot-intent`
Store exact immutable intent bytes in an explicit non-Git evidence root.
```
ao provenance snapshot-intent [flags]
```
**Flags:**
```
--evidence-root string Existing explicit non-Git evidence directory
--exclude-git-root stringArray Caller-known existing Git storage root to exclude (repeatable); unresolved roots fail before writes
-h, --help help for snapshot-intent
--helper-version string Require evidence helper version; incompatibility fails before mutation (default "1")
--json Emit JSON (the default for evidence operations except digest)
--source string Intent file, or - for stdin
```
#### `ao provenance store-verdict`
Verify and atomically store a supplied verdict.v2 with runtime facts.
```
ao provenance store-verdict [flags]
```
**Flags:**
```
--author-context-id string Runtime author identity
--base-manifest string Base manifest for deletions
--draft string Fresh judge's supplied draft JSON
--evidence-root string Existing explicit non-Git evidence directory
--exclude-git-root stringArray Caller-known existing Git storage root to exclude (repeatable); unresolved roots fail before writes
--freshness-attester-id string Freshness attester identity
--freshness-source string runtime or caller
-h, --help help for store-verdict
--helper-version string Require evidence helper version; incompatibility fails before mutation (default "1")
--intent-source string Independently supplied immutable intent file
--json Emit JSON (the default for evidence operations except digest)
--root string Explicit subject directory
--scope-result string Runtime-derived PASS, FAIL or NOT_PROVEN scope fact
--subject-manifest string Runtime-derived manifest
--validator-context-id string Fresh validator identity
```
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
```
Restore private context routes and verify native judgment receipts (#1112) Add explicit, recoverable private context routing through `ao config context`, binding native source, owner, task, model and destination to existing policy and external storage. Recovery reads the original Beads maintenance anchor; configuration reports native access enforcement as unattested. Add `ao provenance verify-judgments` to check required review profiles against exact native transcript receipts, independent subject and acceptance, distinct contexts, completion and permitted providers. Requested identity and unreported effort do not count as runtime evidence. The verdict schema is unchanged. Repair the existing cleanup test: a 0.3-second budget could expire during preparation before either fixture process started. A separate controlled-delay test now proves preparation cannot renew that deadline. The running-cleanup case requires parent/child readiness, preserved partial output, the postlaunch cleanup result and both processes stopped within its existing four-second bound. Production timeout behavior is unchanged. Validation: fresh author-distinct review passed the exact 55-path final subject and all T05/T21 acceptance. The complete local Bats run passed (1,333 passed, two existing skips), as did Go build/vet/test/race, all 72 full-mode gates, the aggregate and generated-output checks. Ubuntu/Windows CI, security and both installation jobs passed on the final commit. The final evidence scan found no new orphaned bindings; 73 historical bindings remain preserved. Earlier failed results and private evidence remain outside the PR.
2026-09-08 18:57:08 -04:00
#### `ao provenance verify-judgments`
Check caller-selected required judgment legs using existing verdict.v2 evidence_refs.
```
ao provenance verify-judgments [flags]
```
**Flags:**
```
--allowed-provider stringArray Independently authorized provider: openai or anthropic (repeatable)
--author-context-id string Independent native author context identity
--base-manifest string Base manifest for deletions
--evidence-root string Explicit private non-Git root for receipts, transcripts and verdicts
-h, --help help for verify-judgments
--helper-version string Required evidence helper version (default "1")
--intent string Independent expected immutable acceptance file
--json Emit JSON (the default)
--manifest string Expected subject-manifest.v1 file
--required-profiles string Independent JSON object containing the required profiles array
--root string Explicit subject directory
--verdict stringArray Content-addressed verdict.v2 file inside evidence root (repeatable)
```
2026-09-08 16:06:33 -04:00
#### `ao provenance verify-manifest`
Recompute and compare exact subject identity.
```
ao provenance verify-manifest [flags]
```
**Flags:**
```
--base-manifest string Base manifest required for deletion identity
-h, --help help for verify-manifest
--helper-version string Require evidence helper version; incompatibility fails before mutation (default "1")
--json Emit JSON (the default for evidence operations except digest)
--manifest string subject-manifest.v1 file
--root string Explicit subject directory
```
#### `ao provenance verify-subject`
Check a supplied PASS against exact content and independent expected intent.
```
ao provenance verify-subject [flags]
```
**Flags:**
```
--base-manifest string Base manifest required for deletion identity
-h, --help help for verify-subject
--helper-version string Require evidence helper version; incompatibility fails before mutation (default "1")
--intent string Independent expected immutable acceptance file
--json Emit JSON (the default for evidence operations except digest)
--manifest string subject-manifest.v1 file
--root string Explicit subject directory
--verdict string Content-addressed supplied verdict.v2 PASS
```
#### `ao provenance verify-verdict`
Structurally verify a content-addressed verdict.v2.
```
ao provenance verify-verdict [flags]
```
**Flags:**
```
-h, --help help for verify-verdict
--helper-version string Require evidence helper version; incompatibility fails before mutation (default "1")
--json Emit JSON (the default for evidence operations except digest)
--verdict string Content-addressed verdict.v2 file
```
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 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
```
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`
Default to native execution and report independently accepted work (#1129) ## Change Make native coding-agent execution the default AgentOps entry path with zero mandatory skills. Preserve full bundles and add repeatable `ao skills link --skill NAME` selection, validating the entire selection before writes. Align product, installation, architecture and generated command documentation. Extend the existing trial readout to separate endpoint test results, execution state and independently accepted work. Bind supplied judgments to exact content, acceptance and native evidence. Reject empty implementation subjects and require the caller's complete criterion ID set before reporting acceptance. Preserve genuine nonempty and deletion-only subjects, valid failures and missing-proof outcomes. ## Validation - Native onboarding from empty home/consumer directories produces no setup files; selective/full linking and failure boundaries are covered. - Actual RED/GREEN regressions cover empty subjects and the partial-criterion omission found by independent review. - Full Go build, vet and race/shuffle tests; affected Go lint; 88 Python readout/statistics tests passed. - All 73 gates, generated projections, strict documentation build and local aggregate passed (10 passed; one documented optional absence). - All nine PR checks succeeded at `7df0d42b12f35ffc22008cc10a40339afcfbb6a0`. - Fresh author-distinct review passed all six acceptance criteria over all 59 changed paths, with no findings or unchecked scope, after repairing the criterion-coverage finding. ## Evidence limits The real native coding repair demonstrates usability, not comparative skill uplift. The strict live-session machine replay remains NOT_PROVEN where execution/identity observations are unavailable; the source review PASS is retained separately. Existing cohort limits and the historical aggregate-enforcement gap remain unwaived. No new comparative cohort, scheduler, skill-corpus deletion, memory migration or global installation is included.
2026-09-10 16:28:22 -04:00
Optionally install skills from a source checkout. Native execution needs no
```
ao skills link [flags]
```
**Flags:**
```
Default to native execution and report independently accepted work (#1129) ## Change Make native coding-agent execution the default AgentOps entry path with zero mandatory skills. Preserve full bundles and add repeatable `ao skills link --skill NAME` selection, validating the entire selection before writes. Align product, installation, architecture and generated command documentation. Extend the existing trial readout to separate endpoint test results, execution state and independently accepted work. Bind supplied judgments to exact content, acceptance and native evidence. Reject empty implementation subjects and require the caller's complete criterion ID set before reporting acceptance. Preserve genuine nonempty and deletion-only subjects, valid failures and missing-proof outcomes. ## Validation - Native onboarding from empty home/consumer directories produces no setup files; selective/full linking and failure boundaries are covered. - Actual RED/GREEN regressions cover empty subjects and the partial-criterion omission found by independent review. - Full Go build, vet and race/shuffle tests; affected Go lint; 88 Python readout/statistics tests passed. - All 73 gates, generated projections, strict documentation build and local aggregate passed (10 passed; one documented optional absence). - All nine PR checks succeeded at `7df0d42b12f35ffc22008cc10a40339afcfbb6a0`. - Fresh author-distinct review passed all six acceptance criteria over all 59 changed paths, with no findings or unchecked scope, after repairing the criterion-coverage finding. ## Evidence limits The real native coding repair demonstrates usability, not comparative skill uplift. The strict live-session machine replay remains NOT_PROVEN where execution/identity observations are unavailable; the source review PASS is retained separately. Existing cohort limits and the historical aggregate-enforcement gap remain unwaived. No new comparative cohort, scheduler, skill-corpus deletion, memory migration or global installation is included.
2026-09-10 16:28:22 -04:00
--dest string Link into this single dir instead of the auto-detected roots (default: ~/.agents plus every installed runtime)
-h, --help help for link
--json Emit machine-readable JSON
--skill stringArray Install only this skill; repeat for more names (default: all skills)
```
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 roots (default: ~/.agents plus every installed runtime)
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
-h, --help help for unlink
--json Emit machine-readable JSON
```
---
feat(cli): workflows are canonical product artifacts — workflows/ + ao workflows link (#945) Workflows get the skills treatment (operator decision): canonical source in the product tree, installed by a product verb, Claude-only labeled as such. **What moves:** all seven Claude workflow scripts + README migrate from force-added exceptions inside the gitignored `.claude/` to a tracked top-level `workflows/` (sibling of `skills/`) — the four existing conveyors plus `audit-dimensions`, `verify-fixes`, `implement-wave`: three thin, args-parameterized orchestration conveyors extracted from this session's hand-rolled waves, contract-reviewed, and smoke-proven through the real Workflow runtime (the smoke caught two contract gaps static review could not: an `export default` wrapper the runtime never invokes, and args arriving as a JSON string — both fixed, string-args tolerance now built in). **New verb:** `ao workflows link` / `unlink` mirror `ao skills link` semantics — dry-run `--json`, refuse to replace real files or foreign links, unlink only checkout-owned links — targeting the project-local `.claude/workflows/` where Claude Code resolves named workflows (`--into` overrides). Checkout identity reuses the skillsapp marker discipline, fail-closed. Claude-only runtime adapter, same doctrine as the Codex-only `skills-codex/`. **Legacy surfaces repointed:** `install-workflows.sh` (user-global $HOME installer), `check-workflow-drift.sh` + gate comment, `check-bdd-foundry-markers.sh`; spine allowlist + YAML-probe excuse + go-cli.md spine region gain the workflows group; COMMANDS.md, cli-surface projections, and surface-count fixture regenerated; new tests carry per-command git-env scrubbing (test-isolation ratchet back at baseline). **Built BY the workflow being canonized** — `implement-wave` orchestrated its own canonization: two disjoint-ownership lanes plus a seam-checking verifier that ran the real binary's link → resolve → unlink cycle in the live tree (both lanes RESOLVED). The lanes correctly *refused* to self-approve their command into the spine invariants and handed integration three flagged edits instead. **Expected local gate note:** `workflow.install-drift` correctly FAILS on machines whose user-global `~/.claude/workflows` links still point at the old location — that is the transition it exists to catch. CI stays green (absent→skip). **Post-merge operator step:** `cd ~/dev/agentops && git pull && bash scripts/install-workflows.sh`. **Verified:** full suite 63/63 pkgs; golangci-lint clean; `gate check --full` over this range = 66/67 with only the documented install-drift environment finding; workflows smoke-run evidence in session logs.
2026-07-20 19:39:16 -04:00
### `ao workflows`
Tooling for the top-level workflows/ source-of-truth: the Claude-harness
```
ao workflows [command]
```
**Subcommands:**
#### `ao workflows link`
Scan the agentops checkout's workflows/ directory and create a symlink in
```
ao workflows link [flags]
```
**Flags:**
```
-h, --help help for link
--into string Link into this single dir instead of <cwd-git-root>/.claude/workflows
--json Emit machine-readable JSON
```
#### `ao workflows unlink`
The clean uninstall inverse of `ao workflows link`. Sweep the target
```
ao workflows unlink [flags]
```
**Flags:**
```
-h, --help help for unlink
--into string Sweep this single dir instead of <cwd-git-root>/.claude/workflows
--json Emit machine-readable JSON
```
---
### `ao help`
Help provides help for any command in the application.
```
ao help [command] [flags]
```
---