377 Commits

Author SHA1 Message Date
Boden Fuller 045eb4f0c9 feat(cli): ao citation verify — 9th adapter CLI-exposed (BC1 round-trip)
Cycle 153 applies the cycle-147 template to a 9th adapter:
productionCitationAdapter (cycle 83 — the original first wire-up
adapter from the BC ports arc). Verifies file/function/symbol
citations against HEAD.

New surface:
  ao citation verify --kind <file|function|symbol> --raw <text>

Wraps productionCitationAdapter — which in turn wraps the existing
verifyFileCitation / verifyFunctionCitation / verifySymbolCitation
helpers in beads.go. Output is JSON CitationVerdict (Status, Reason,
optional Resolved).

Live smoke verified both directions:
  $ ao citation verify --kind file --raw "cli/cmd/ao/beads.go"
  {"Status":"FRESH","Reason":"file exists at HEAD","Resolved":""}

  $ ao citation verify --kind file --raw "this/file/does/not/exist.go"
  {"Status":"STALE","Reason":"file this/file/does/not/exist.go not found at HEAD","Resolved":""}

Template adherence vs cycle-147 spec: ✓. 6 tests covering:
empty kind/raw rejected, FRESH/STALE/UNKNOWN status passthrough,
error wrapping.

New files:
- cli/cmd/ao/citation_cmd.go (107 lines) — citationCmd parent +
  citationVerifyCmd. Resolves cwd via resolveProjectDir; passes
  to the port as Cwd field.
- cli/cmd/ao/citation_cmd_test.go (104 lines) — 6 tests using
  injectable verifyFn.

cli/docs/COMMANDS.md regenerated.

9 of 14 production adapters now CLI-exposed (~64%):
  loop history/append + ci latest/recent + corpus inject/capture +
  operator record/list + harness status + gate run + citation verify.

5 remain (ClaimEvidenceBinder, FactoryAdmission, ClaimEvidence,
EventBus, FindingCompiler).

Time: ~8 min. LOC: 211. Tests: 6. Within template band.

Symbolic milestone: this exposes the FIRST production adapter that
shipped in the wire-up arc (cycle 83 productionCitationAdapter).
The cycle-122 wire-up-arc learning's named gap is now fully closed
for that pioneer adapter — typed verification reachable from the
CLI 70 cycles after the adapter shipped.

Cycle 153 / template-applied CLI-wiring 6th application.
2026-05-12 21:38:30 -04:00
Boden Fuller 186502ca02 feat(cli): ao loop append — 8th adapter; BC3 R/W pair complete on CLI
Cycle 152 applies the cycle-147 template to an 8th adapter:
productionLoopWriter (cycle 109). Closes the BC3 LoopReader+Writer
pair on the CLI side (cycle 144 already shipped 'ao loop history'
for the reader).

New surface:
  ao loop append --mode <m> --result <r> [--cycle N] [--commit C] [--milestone M]

Wraps productionLoopWriter. Required: --mode, --result. Optional:
--cycle (0 = auto-assign max+1 per port contract), --commit,
--milestone. Output: 'appended cycle=N mode="X" result="Y"'.

Template adherence vs cycle-147 spec: ✓. Pattern reused exactly
from cycle 148 (operator record) — write-side adapters with
multiple required flags + cobra MarkFlagRequired + injectable
appendFn.

New files:
- cli/cmd/ao/loop_append.go (107 lines) — loopAppendCmd added
  under existing loopCmd (cycle 144 parent). 5 flags, injectable
  appendFn, mkdir-parent for safety.
- cli/cmd/ao/loop_append_test.go (101 lines) — 5 tests: empty
  mode/result rejected, stub called with full entry, auto-assigns
  cycle when 0, error wrapped.

cli/docs/COMMANDS.md regenerated.

Pair complete:
  ao loop history  (LoopReader, cycle 144)
  ao loop append   (LoopWriter, cycle 152)

8 of 14 production adapters now CLI-exposed (~57%):
  loop history/append + ci latest/recent + corpus inject/capture +
  operator record/list + harness status + gate run.

6 adapters remain unexposed (Citation, ClaimEvidenceBinder,
FactoryAdmission, ClaimEvidence, EventBus, FindingCompiler).

Time: ~8 min. LOC: 208. Tests: 5. Squarely in template band.

5 consecutive template applications (148-149-150-151-152), 4 of
them mirroring the BC pair-completion shape (BC1 R/W in cycle 146+
151; BC3 R/W in cycle 144 + this).

Cycle 152 / template-applied CLI-wiring 5th application.
2026-05-12 21:36:18 -04:00
Boden Fuller 4c91c7cd9f feat(cli): ao corpus capture — 7th adapter CLI-exposed; BC1 R/W pair complete on CLI
Cycle 151 applies the cycle-147 template to a 7th adapter:
productionCorpusWriter (cycle 113). Closes the BC1 CorpusReader+
Writer pair on the CLI side (cycle 146 already shipped 'ao corpus
inject' for the reader).

New surface:
  ao corpus capture --path <relpath> --body "..." [--meta k=v ...]
  ao corpus capture --path x --body-file f.md
  echo "..." | ao corpus capture --path x --body-stdin

Wraps productionCorpusWriter. Three body-source options
(--body, --body-file, --body-stdin) are mutually exclusive — the
helper rejects multiple sources to force one explicit choice.
Metadata via --meta key=value (repeatable). Path safety inherited
from the production adapter (rejects absolute paths and parent
traversal).

Live smoke (round-trip):
  $ ao corpus capture --root /tmp --path smoke.md --body "hello"
  created /tmp/smoke.md
  $ cat /tmp/smoke.md
  hello from cycle 151

New nuance from this cycle: 'body source' validation. The template
previously didn't model "one of N alternatives required" inputs.
Solved with a small corpusCaptureResolveBody helper that counts
sources and errors clearly. Future cycles applying the template to
adapters with mutually-exclusive input modes can copy this pattern.

New files:
- cli/cmd/ao/corpus_capture.go (172 lines) — corpusCaptureCmd
  added under existing corpusCmd. Three body sources + metadata +
  injectable captureFn. Compile-time port wiring via
  productionCorpusWriter.
- cli/cmd/ao/corpus_capture_test.go (165 lines) — 8 tests:
  empty path rejected, body required, multiple-sources rejected,
  inline body to stub, stdin body, meta parsed, malformed meta
  rejected, --body-file reads content, stub error wrapped.

cli/docs/COMMANDS.md regenerated.

7 of 14 production adapters now CLI-exposed (50%!):
  loop history + ci latest/recent + corpus inject + corpus capture
  + operator record/list + harness status + gate run.

7 adapters remain unexposed. Exposing all 14 is now a deterministic
path; expose ad-hoc as needs surface.

Time: ~10 min. LOC: 337. Tests: 8. Slightly above template band
because of the body-source-resolution helper — accounted for in
the new nuance documented above.

Cycle 151 / template-applied CLI-wiring 4th application.
BC1 R/W pair now complete on the CLI side.
2026-05-12 21:34:14 -04:00
Boden Fuller 12961cb7aa 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
Boden Fuller b59b72ac5e feat(cli): ao harness status — 5th adapter CLI-exposed (template-applied)
Cycle 149 applies the cycle-147 template to a 5th adapter:
productionHarness (cycle 111). Mirrors cycle 148's operator surface
exactly — second consecutive validation of the template's
predictive value.

New surface:
  ao harness status [--skill <name>] [--out-of-sync-only]

Wraps productionHarness — emits one HarnessSkillSync per
(skill, harness) pair (claude vs codex), each with SHA-256 content
hash and OutOfSync flag. Typed alternative to parsing
scripts/audit-codex-parity.sh output.

Live smoke verified: 'ao harness status --out-of-sync-only' returns
empty against the repo's current state (all skills in sync), and
'ao harness status --skill evolve' returns both claude+codex entries
for the evolve skill.

Template adherence vs cycle-147 spec: ✓ on all 5 principles + the
post-filter pattern proven (--out-of-sync-only filters AFTER the
port call, not as a port arg — keeps the port narrow).

New files:
- cli/cmd/ao/harness_cmd.go (108 lines) — harnessCmd + status
  subcommand + 2 flags + injectable statusFn.
- cli/cmd/ao/harness_cmd_test.go (107 lines) — 5 tests: emits all,
  --out-of-sync-only filters, empty results → 0 bytes, all-in-sync
  with filter → 0 bytes, error wrapping.

cli/docs/COMMANDS.md regenerated.

5 of 14 production adapters now CLI-exposed (loop history + ci
latest/recent + corpus inject + operator record/list + harness
status). 9 adapters remain unexposed — expose ad-hoc as needs
arise.

Time: ~8 min. LOC: 215. Tests: 5. Squarely within template band.

Cycle 149 / template-applied CLI-wiring mode (cycle 148 + 149 are
the 2-cycle proof that the template works for arbitrary adapters).
2026-05-12 21:29:50 -04:00
Boden Fuller 51224cefcf feat(cli): ao operator record/list — 4th adapter exposed (template-applied)
Cycle 148 ships the 4th CLI surface using the cycle-147 template
captured immediately after the 3-cycle slice arc (144-146). First
test of the template's predictive value: a new adapter exposure in
~10 min using the documented pattern without re-deriving the shape.

New surface:
  ao operator record --kind <kind> [--subject S] [--note N]
  ao operator list

Wraps productionOperator (cycle 110) — writes/reads OperatorIntent
records to .agents/operator/intents.jsonl. Useful as a durable
operator-decision ledger: halt, rescope, handoff records survive
session boundaries.

Template adherence (vs cycle-147 spec):
- ✓ Parent noun (operator) + verb subcommands (record, list)
- ✓ Injectable function fields (recordFn + listFn) on options bag
- ✓ Line-delimited JSON output for list
- ✓ Error wrapping with command name
- ✓ Build + smoke verification (ao operator --help renders)
- New nuance: --kind marked required via cobra's MarkFlagRequired
  (per port contract that rejects empty Kind)
- New nuance: operatorIntentsPath helper centralizes the
  .agents/operator/intents.jsonl path resolution + mkdir-parent

New files:
- cli/cmd/ao/operator_cmd.go (149 lines) — operatorCmd parent +
  operatorRecordCmd + operatorListCmd + 4 helper functions.
- cli/cmd/ao/operator_cmd_test.go (107 lines) — 6 tests covering
  empty-kind rejection, stub-called, error-wrapped, list emits
  intents, empty list, error wrap on list.

Total: 256 LOC + 6 tests — within the cycle-147 spec's 250-335 LOC
band. Time: ~9 min. Template predicts costs accurately.

cli/docs/COMMANDS.md regenerated.

soc-y5vh-style follow-up: this exposes the 4th of 14 production
adapters via CLI. 10 remain (Citation, Harness, ClaimEvidenceBinder,
GateRunner, FactoryAdmission, ClaimEvidence, EventBus,
CorpusWriter, LoopWriter, FindingCompiler). None are blocking any
queued bd; expose them as ad-hoc needs arise.

Cycle 148 / template-applied CLI-wiring mode (cycle-147 spec
validated on first real use).
2026-05-12 21:27:34 -04:00
Boden Fuller b567bdd20c feat(cli): ao corpus inject — soc-y5vh.5 COMPLETE (all 3 slices)
Cycle 146 ships slice 3 of soc-y5vh.5. The 3-slice prerequisite work
(cycles 144 + 145 + this) is now complete — 3 production adapters
exposed via the operator-facing CLI:

  ao loop history    — productionLoopReader (cycle 108)
  ao ci latest       — productionCIStatus (cycle 117)
  ao corpus inject   — productionCorpusReader (cycle 112)  ← THIS

This unblocks soc-y5vh.1 (Step 0 prior-failure injection),
soc-y5vh.2 (Step 1.5 healing classifier), and soc-y5vh.4 (script
wrapper) — each can now consume the typed adapter without
re-implementing the file walk / gh shellout / jsonl scan.

New files:
- cli/cmd/ao/corpus_inject.go (114 lines) — corpusInjectCmd added
  as subcommand under existing 'ao corpus'. Flags: --query, --root
  (default .agents/learnings/), --limit (default 10).
  corpusInjectOptions struct with injectable injectFn (mirrors
  cycle 144 historyFn + cycle 145 statusFn patterns).
- cli/cmd/ao/corpus_inject_test.go (5 tests) — stub-based +
  live-root walk + limit-respected + empty-results + error-wrap.

cli/docs/COMMANDS.md regenerated.

End-to-end smoke verified:
  $ ao corpus inject --root docs/learnings --query "wire-up" --limit 2
  {"Path":"docs/learnings/2026-05-13-bc-ports-wire-up-arc.md",...}
The cycle-122 wire-up-arc learning IS the top match for "wire-up",
which is the right ranking outcome.

soc-y5vh.5 epic prerequisite COMPLETE. Tree status:
  ✓ soc-y5vh.5 (this commit closes)
  ○ soc-y5vh.1/.2/.4 (now unblocked)
  ○ soc-y5vh.3 (separate scope — Hypothesis + Convergence ports)

3-cycle slice arc summary:
  Cycle 144: ao loop history     (~10 min / 335 LOC / 6 tests)
  Cycle 145: ao ci latest+recent (~ 8 min / 258 LOC / 4 tests)
  Cycle 146: ao corpus inject    (~ 8 min / ~230 LOC / 5 tests)

The repeated cycle-shape across 3 unrelated adapters proves the
CLI-wiring pattern is broadly applicable. Future production
adapters just need to follow the same parent-noun + verb-subcommand +
injectable-fn shape.

Cycle 146 / soc-y5vh.5 slice-3-of-3 + EPIC-CLOSE mode.
2026-05-12 21:23:44 -04:00
Boden Fuller 4307f533a7 feat(cli): ao ci latest/recent — slice 2 of soc-y5vh.5 (productionCIStatus exposed)
Cycle 145 ships the second slice of soc-y5vh.5: 'ao ci' command
group with two subcommands wired through productionCIStatus
(cycle 117 adapter). Mirrors cycle 144's 'ao loop history' shape.

New subcommands:
- ao ci latest <sha>   — most recent CI run for the given commit;
                          emits empty when no run exists
- ao ci recent --limit N — last N runs (any sha; default 10, cap 50)

Wraps the cycle-117 adapter which itself wraps 'gh run list --json
...'. Output is line-delimited JSON, one CIRun per line — composable
with jq, awk, grep.

New files:
- cli/cmd/ao/ci.go (138 lines) — ciCmd parent + ciLatestCmd +
  ciRecentCmd; ciStatusOptions struct with injectable statusFn
  for tests (mirrors cycle 117's runGH pattern and cycle 144's
  historyFn).
- cli/cmd/ao/ci_test.go (4 tests) — stub-based: latest emits 1
  run, latest empty emits 0 lines, recent emits multiple, errors
  wrapped with "ci status:" prefix.

cli/docs/COMMANDS.md regenerated.

Pattern reused from cycle 144:
- Parent cmd as a noun (loop, ci); subcommands as verbs (history,
  latest/recent)
- Injectable function field for test stubs (so tests don't need
  real gh or temp dirs)
- Line-delimited JSON output for shell-script composability

soc-y5vh.5 progress: 2 of 3 slices shipped (LoopReader + CIStatus).
Remaining: ao corpus inject via productionCorpusReader (cycle 112).
After slice 3 closes, soc-y5vh.1/.2/.4 unblock.

Cycle 145 / soc-y5vh.5 slice-2-of-3 mode.
2026-05-12 21:21:13 -04:00
Boden Fuller ce291d4bf7 feat(cli): ao loop history — first ao subcommand wired through a production adapter (soc-y5vh.5 slice 1)
Cycle 144 ships the first slice of soc-y5vh.5: the new 'ao loop'
command group with 'ao loop history' as its first subcommand. This
is the first cobra command that exposes a production port adapter
(productionLoopReader, cycle 108) to the operator surface.

Why this matters: cycle 143 audit found that all 14 production
adapters were internal-only — no CLI surface invoked them outside
tests. This was the latent-value problem from cycle 122's wire-up
learning. soc-y5vh.5 (cycle 143 filed) was the operator surface
that closes that loop. This commit ships the first 1 of 3 planned
subcommands.

New files:
- cli/cmd/ao/loop.go (130 lines) — loopCmd + loopHistoryCmd. Three
  ways to query the history:
    --latest             emit only the most recent entry
    --limit N            emit at most N most-recent
    --start S --end E    emit cycles S..E inclusive
  Output is line-delimited JSON (one CycleEntry per line). Wired
  through productionLoopReader (cycle 108) reading
  .agents/evolve/cycle-history.jsonl.
- cli/cmd/ao/loop_test.go (6 tests) — temp-dir fixtures, latest +
  limit + range slicing, missing-file empty output, injectable
  historyFn for test stubs, error wrapping.

Verified end-to-end against this session's actual cycle-history.jsonl:
  $ cli/bin/ao loop history --latest
  {"Number":143,"Mode":"prerequisite-audit-and-bd-decomposition",
   "Result":"improved",...}

cli/docs/COMMANDS.md regenerated via scripts/generate-cli-reference.sh.

Anti-pattern caught (cycle-126 lesson, applied to a name collision):
- Initial helper named `loadCycleHistory` collided with an existing
  function of the same name in cli/cmd/ao/metrics_health.go. go vet
  caught it; renamed mine to `loadCycleHistoryViaPort`. Grep BEFORE
  naming helpers in cli/cmd/ao/ — the package is large and
  collisions are easy.

Future slices of soc-y5vh.5:
- ao corpus inject (productionCorpusReader, cycle 112)
- ao ci latest <sha> (productionCIStatus, cycle 117)
- Each is a separate cycle; same shape as this one (cobra add +
  thin wrapper + tests + COMMANDS.md regen).

Cycle 144 / soc-y5vh.5 slice-1-of-3 mode.
2026-05-12 21:18:59 -04:00
Boden Fuller 7358ec62bd feat(corpus): snapshot/restore + freshness gate (D11)
Closes soc-ymph.11 — Directive D11 (Corpus durability snapshot/restore).

Why
- Routine cleanup periodically wipes most of .agents/. Without a
  durable copy, the corpus moat claim becomes fragile every time the
  operator runs maintenance. soc-rv5p documented the 2026-05-07
  incident that motivated this work.

What
- cli/cmd/ao/corpus_snapshot.go: two new subcommands.
  * ao corpus snapshot — tar.gz the .agents/ tree into
    $AGENTOPS_CORPUS_SNAPSHOT_DIR (default ~/.agentops/corpus-snapshots),
    write a sidecar .manifest.json with file_count, total_bytes,
    sha256, RFC3339 created_at. Atomic via tmp+rename.
  * ao corpus restore — extract a snapshot tarball, with path-
    traversal defense, --from/--latest source resolution, --into
    destination (default .agents), --overwrite gate that moves the
    existing tree to .agents.bak-<ts>/ before extracting and only
    removes the backup after a successful extract.
- scripts/check-corpus-freshness.sh: structural freshness gate.
  Fails when the newest tarball in the snapshot dir is older than
  AGENTOPS_CORPUS_FRESHNESS_DAYS (default 7). Skips cleanly when
  no snapshot dir or no tarballs (greenfield boxes); honors
  AGENTOPS_CORPUS_FRESHNESS_SKIP=1.
- GOALS.md: new gate row corpus-freshness, weight 4.
- .github/workflows/validate.yml: new validate-corpus-freshness job
  (always-on; sets the SKIP env on CI runners since they don't carry
  a snapshot dir). Registered in summary.needs[] and summary echo
  per validate-ci-policy-parity contract.
- scripts/pre-push-gate.sh: new always-on check 22g. Fast (<100ms)
  in the SKIP path; real teeth on operator boxes with a snapshot
  dir.
- AGENTS.md: CI Jobs row for validate-corpus-freshness.
- tests/scripts/pre-push-gate.bats: stub for the new gate script.
- cli/docs/COMMANDS.md: regenerated to include corpus snapshot/restore
  (cobra-conformance test would fail otherwise).

Round-trip smoke
- Snapshot of a 2-file .agents/ tree round-trips byte-identical
  through tar.gz + sha256 manifest.
- check-corpus-freshness.sh: SKIP (no dir) → SKIP (env) → PASS
  (fresh) → FAIL (10d old > 7d threshold). All four paths.
- bats: 51/51 ok.
- go test ./cmd/ao/... -run "TestCorpus |TestCobra" : 165 pass.
- validate-ci-policy-parity: PASS (53 jobs, 7 non-blocking).
- pre-push --fast (PRE_PUSH_SKIP_EVAL=1 for the soc-l4yt canary flake):
  both passes green with "ok corpus freshness".

Companion bead: soc-rv5p (closed) — original incident.
2026-05-11 17:31:59 -04:00
Boden Fuller 3e374d842d feat(product): codify AgentOps 3 launch path 2026-05-10 23:22:14 -04:00
Boden Fuller 28da44fc5d feat(daemon): wire skill schedules 2026-05-09 09:34:23 -04:00
Boden Fuller cca4dd7f6d docs(positioning): substrate-leads thesis + lineage cleanup (epic soc-sx99 W1.3)
Propagate the council-consolidated positioning thesis across the doc tree.
8/8 cross-vendor council verdict (.agents/council/2026-05-07-validate-positioning-thesis-report.md)
identified the substrate-leads framing as the durable 24-month thesis;
plugin-not-API was a 12-month wedge that contradicted the existing strategic
bet ("Knowledge is the moat. AgentOps isn't.").

Canonical thesis (now propagated):

  AgentOps is a context compiler — the substrate the supermodel plugs into.
  It encodes the DevOps SDLC as the CDLC, plus the operating practices of
  multi-agent work: isolated context, stigmergic coordination, planner/
  implementer/validator separation. Validation gates, the knowledge flywheel,
  and the schedulable dream daemon are outputs of the compiler, not peer
  products. The bet is sovereignty, not features.

Surface changes:

- PRODUCT.md: Mission section (sub​strate-leads thesis); "What the Product
  Actually Is" reframed as "one substrate, three surfaces / three outputs";
  Strategic Bet expanded with sovereignty answer (cross-runtime corpus,
  local sovereignty, operator workflow encoding); new dedicated Lineage
  section (Knowledge OS → Olympus → AgentOps → Mt. Olympus); compound-
  engineering / software-factories / Greenfield 2003 named lineage; 12-factor
  parallel-not-derived callout; Meadows promoted from footnote.
- README.md: hero replaced with substrate-leads framing; scheduling
  reference link surfaced.
- AGENTS.md: top-level positioning blurb updated.
- CLAUDE.md: new "What this is" preamble with one-sentence thesis.
- cli/docs/HOOKS.md: CASS clarified as AgentOps-internal terminology
  (not external prior art); inspired by Olympus.
- docs/strategic-direction.md: lineage hierarchy spine added under the
  consolidation decision; industry parallels named as convergent.
- docs/cdlc.md: Meadows leverage-point hierarchy was already integrated;
  no edit needed (worker verified existing prose covers it).

Constraints honored (per pre-mortem R1, R2, council verdict):
- No new docs/comparisons/ files created (existing vs-compound-engineer.md
  referenced by link only).
- Factory's Missions / Luke / Factory AI not cited explicitly (operator
  decision: internalize the planner/implementer/validator framing, don't
  attribute).
- No fabricated corpus stats (sx99.9 owns that slice).

Closes soc-sx99.3.
2026-05-07 12:03:22 -04:00
Boden Fuller c1d5159c2a fix(harvest): idempotent pattern promotion + ao patterns repair-filenames (epic soc-sx99 W3.2)
Audit found 128/136 patterns (94%) on disk with malformed recursive-doubled
filenames like 2026-04-29-pend-2026-04-19-6a97752-19-2026-04-19-6a97752-19-…md.
Root cause: cli/internal/harvest/catalog.go promotionDestinationName
unconditionally re-prepended <rig>- on every promotion pass, even when the
source filename already started with <rig>-.

- Fix: strip pre-existing <rig>- prefixes (in a loop) before re-prefixing,
  making promotion idempotent for both already-canonical and pre-corrupted
  inputs.
- Regression tests: TestPromote_DoesNotDoubleRigPrefix, …TripleRigPrefix,
  …RepeatedPromotionIsIdempotent. Each FAILS pre-fix, PASSES post-fix.
- New: ao patterns repair-filenames — one-shot migration. Default dry-run
  (lists proposals, exits 0). --apply performs renames idempotently
  (running twice = no-op). Frontmatter name field updated. Collisions
  resolved by appending a suffix.
- Real-corpus dry-run on this repo: 82 of 136 patterns flagged for repair.
  --apply NOT run by the agent; left for operator review.
- All 9 added tests PASS; cli build/vet/test green.

Why it matters: without clean filenames, pattern→rule promotion can never
run reliably (the 0-rules corpus is partially explained by this upstream
break).

Closes soc-sx99.7.
2026-05-07 12:03:22 -04:00
Boden Fuller b27e527f1c feat(cli): add ao session spawn command for template-driven session launch
Reads a TOML session template, expands variables (date, hostname,
session_name), runs init steps sequentially, and creates a tmux session
with configured panes. Supports --dry-run and --no-tmux modes.

Adds github.com/BurntSushi/toml dependency for template parsing.
Regenerates CLI docs for cobra conformance.

Phase 1 of soc-y8b.7 (session-template launcher).
2026-05-05 18:03:10 -04:00
Boden Fuller e3a0dff442 fix: resolve merge conflicts with main (types.go, templates README) 2026-05-05 08:51:37 -04:00
Boden Fuller 3f90737501 feat(daemon): execute factory admission jobs 2026-05-04 21:56:00 -04:00
Boden Fuller 951ed9d5c3 feat: Phase 2 unified registry — job type, CLI, CI gate
Add skill.invoke generic daemon job type for scheduling skill
executions without dedicated executors. Build `ao registry list`
CLI command that reads registry.json with --type filtering and
--json output. Wire registry staleness check into CI via
scripts/generate-registry.sh --check.

- cli/internal/daemon/types.go: add JobTypeSkillInvoke constant
- cli/cmd/ao/registry.go: new ao registry list [--type X] command
- cli/cmd/ao/registry_test.go: 9 tests covering filter, JSON, errors
- .github/workflows/validate.yml: registry-check job + summary wiring
- registry.json: regenerated (12 job types, 144 CLI commands)
2026-05-04 21:43:07 -04:00
Boden Fuller 1022c7413c feat(daemon): register eval and planning job types, regen CLI docs
Add JobTypePlansProjection, JobTypeLLMWikiLoop, JobTypeEvalSuite, and
JobTypeEvalSkillDelta to the known daemon job types. Regenerate
COMMANDS.md to match. Extend TestValidateSubmitJobTypeAcceptsKnown to
cover the new types.
2026-05-04 15:39:47 -04:00
Boden Fuller dbbe159d2d feat(eval): add agent harness script and wire live runtime into eval CLI
Phase 1: scripts/eval-agent-harness.sh wraps setup → agent CLI → score
for any workbench task. Supports --dry-run, --hooks-disabled for A/B,
--timeout, and agent-not-found graceful handling.

Phase 2: extend parseEvalRuntime() to accept claude/codex alongside
static/mock/shell. Update flag help and shell completion. Add table-
driven test covering all 5 runtime values plus empty and unknown.

Closes soc-egdg, soc-eiy4.
2026-05-04 13:27:26 -04:00
Boden Fuller 4ea208afb5 feat(factory): add bounded cloud frontier pilot plan
Refs soc-dpci.8
2026-05-03 21:05:12 -04:00
Boden Fuller 43a5217621 feat: add agentopsd routing policy guardrails 2026-05-03 19:16:06 -04:00
Boden Fuller e5da4c06d6 feat(eval): add context packet ab canary 2026-05-03 10:15:12 -04:00
Bo b7d11812bd feat(eval): LID baseline-A/B primitive — Wave 1 (soc-x5yz) (#212)
* feat(eval): plumb DisableHooks toggle for LID baseline-A/B (W1.1)

Wire SuiteEnvironment.DisableHooks (suite-declared) and
LiveRuntimeOptions.OverrideDisableHooks (caller-toggled) through
liveEnvironmentRecord, liveRuntimeEnv, and liveRuntimePrompt via the
new effectiveDisableHooks helper. When effective:
- liveEnvironmentRecord populates the existing HooksDisabled placeholder
- liveRuntimeEnv appends AGENTOPS_HOOKS_DISABLED=1 (already honored at
  hooks/session-start.sh:7)
- liveRuntimePrompt appends a "do not load skills" constraint sentence

Round-trip JSON snapshot tests for SuiteEnvironment + EnvironmentRecord
per f-2026-04-26-001. Internal helpers for the prompt/env wiring.

Issue: soc-x5yz / W1.1
Plan: .agents/plans/2026-05-02-lid-primitives-eval-integration.md

* feat(eval): --baseline-mode flag + DeltaScorecard runner (W1.2)

Add `ao eval run --baseline-mode={skill-on,skill-off,both}`. When `both`,
runs the suite twice (skill-on, then skill-off via OverrideDisableHooks)
and synthesises a DeltaScorecard with per-case pass/fail delta + aggregate
score delta. cobra ValidArgs reject invalid mode values. New `--delta-out`
writes the scorecard JSON. Per-leg run records get `-skill-on`/`-skill-off`
suffixed paths and run-ids when caller supplies --out / --run-id, so the
two leg artifacts are preserved alongside the scorecard.

Wires OverrideDisableHooks through RunOptions → environmentRecord so the
deterministic SIL path mirrors the live path's HooksDisabled provenance
(W1.1 wired the live path; this commit completes the deterministic side).

Tests: AllBaselineModes/IsValidBaselineMode, deltaSign triad, computeDelta
with mixed pass/fail/missing cases, appendBaselineSuffix path-mangling.

Issue: soc-x5yz / W1.2
Plan: .agents/plans/2026-05-02-lid-primitives-eval-integration.md

* feat(eval): wire DisableHooks into deterministic engine + LID demo fixture (W1.3)

Engine: when OverrideDisableHooks is set, mutate the local suite copy so
runtimeRecord, environmentRecord, and the case command env all see the same
effective DisableHooks state. Inject AGENTOPS_HOOKS_DISABLED=1 into the case
command env (parallels the live-runtime path from W1.1) so SIL fixtures can
gate behavior on the kill-switch.

Demo fixture: evals/agentops-core/lid-primitives-demo.json — two shell cases
that produce the smallest measurable delta proving the baseline-A/B wiring
works end-to-end. Smoke run reports +0.5 aggregate delta:

  ao eval run evals/agentops-core/lid-primitives-demo.json --baseline-mode=both
  → skill-on=1.0000 (pass) skill-off=0.5000 (fail) delta=+0.5000 cases=2

Issue: soc-x5yz / W1.3
Plan: .agents/plans/2026-05-02-lid-primitives-eval-integration.md

* docs(eval): contract + code-map for LID baseline-A/B (W1.4)

- docs/contracts/eval-baseline-ab.md: --baseline-mode semantics, what
  skill suppression actually disables (and what it doesn't), DeltaScorecard
  schema, when to use which mode, SIL vs HIL/VIL scope (HIL/VIL deferred),
  backward-compat guarantees, regression guards.
- docs/code-map/eval-lid-primitives.md: file inventory of every Wave 1
  surface, test coverage map, live smoke recipe, recipe for adding new
  baseline-A/B-eligible suites, open follow-ups (Wave 2 anchor namespace,
  HIL/VIL extension, release-readiness gate promotion).

Hook audit confirmed only hooks/session-start.sh:7 auto-honors
AGENTOPS_HOOKS_DISABLED today; future skill-loading hooks must honor it
or future baseline-A/B measurements will under-report.

Issue: soc-x5yz / W1.4
Plan: .agents/plans/2026-05-02-lid-primitives-eval-integration.md

* fix(daemon): Wave A durability — fsync prop, orphan-tmp sweep, snapshot dir-fsync

Three audit follow-ups from .agents/research/2026-05-02-bug-daemon-audit-and-chaos.md:

- W-A-04 (soc-58q5.1): AppendLedgerEvent fsync error propagation. Audit was
  STALE — code already returned wrapped Sync error at store.go:211. Added
  L2 regression test TestAppendLedgerEvent_SyncErrorPropagates via a
  test-only ledgerSyncFn function-variable seam. Caught by reverting line
  211 and observing the new test fail.

- W-A-09 (soc-58q5.2): rotateLedger orphan-tmp cleanup. Sweeps
  ledger.*.jsonl.gz.tmp files older than 5 min at rotation start (grace
  prevents racing concurrent in-flight gzip work). Cleanup failures log at
  warn and do not fail rotation. L2 test TestRotation_CleansOrphanedGzTmp
  pre-seeds stale + fresh tmps via os.Chtimes, asserts only stale removed.

- W-A-21 (soc-58q5.3): WriteProjectionSnapshot syncDir after rename.
  Adds private syncDir helper; calls it after os.Rename(tmp, dst).
  syncDir failure DOES fail the function (durability contract). L2 test
  TestWriteProjectionSnapshot_SyncsParentDir confirms happy-path remains
  green; injection-based negative test deferred (would require interface
  threading that costs more than defense-in-depth value).

go test -race -count=1 ./internal/daemon/... green (26.7s).

* fix(ci): close out PR #212 CI failures (W1.x parity + pre-mortem ref link)

- skills/pre-mortem/SKILL.md: add the missing scope-predicate-positive-
  negative-cases.md to References (fixes go-build TestSkillContract_
  ReferencesLinkedInSKILLMD failure that's been carrying forward from
  commit 12fa13b4).
- docs/documentation-index.md: register docs/contracts/eval-baseline-ab.md
  (fixes contract-compatibility-gate orphan-contract failure).
- cli/docs/COMMANDS.md: regenerate to capture --baseline-mode and
  --delta-out flags added in W1.2 (fixes cli-docs-parity diff failure).
- AGENTS.md: add the hook-output-schema-lint job introduced by 12fa13b4
  to the CI jobs table (fixes validate-ci-policy-parity drift).

Local: 11899 tests pass. heal-skill --strict clean. validate-ci-policy-
parity PASS.

Issue: soc-x5yz / W1 CI closure
2026-05-02 23:51:32 -04:00
Boden Fuller 39477a9533 feat(onboarding): unify repo seed golden path 2026-05-02 22:19:23 -04:00
Boden Fuller 15f2a3ef71 merge: evolve 2026-05-01 unbounded
# Conflicts:
#	cli/cmd/ao/daemon_jobs.go
#	cli/cmd/ao/eval_cleanup.go
#	cli/cmd/ao/retrieval_search_eval.go
#	cli/cmd/ao/retrieval_search_eval_test.go
#	cli/cmd/ao/testdata/retrieval-bench/search-eval-manifest.json
#	docs/cli-skills-map.md
#	docs/contracts/agents-write-surfaces.md
#	hooks/session-end-maintenance.sh
#	scripts/check-retrieval-quality-ratchet.sh
2026-05-02 12:29:59 -04:00
Boden Fuller 1a2ba1d56a fix: bound goals measurement runtime 2026-05-02 12:15:11 -04:00
Boden Fuller 3366baa14b Merge remote-tracking branch 'origin/fix/daemon-jobs-submit-cli' into codex/rpi-branch-cleanup-followup-20260502 2026-05-02 10:44:08 -04:00
Boden Fuller 7031c463fe feat: add optional llama rerank backend 2026-05-02 10:35:31 -04:00
Boden Fuller 00731d13ff feat: add file-backed search eval backends 2026-05-02 10:26:37 -04:00
Boden Fuller 832b6ed239 feat: add backend-aware search eval reports 2026-05-02 10:17:23 -04:00
Boden Fuller 0d1abe3b04 chore(cli-docs): regen COMMANDS.md after rebase to include upstream eval subcommands
Upstream commits f2053294, 3597ff77, c954643f added `ao eval cleanup`,
`ao eval suite`, `ao eval task` (+ subcommands) but didn't regen the docs.
TestCobraConformance now passes again with the regenerated reference.
2026-05-02 08:20:17 -04:00
Boden Fuller 41b31d087e chore: sync generated artifacts after Wave 1 (COMMANDS.md, embedded hooks, skill counts, cobra registration)
Orchestrator post-wave step. Mechanical updates triggered by Wave 1
landings (soc-irg1.1 through .3):

- cli/cmd/ao/cobra_commands_test.go: add 'scope' and 'skills' to both
  expectedCmds lists (TestCobraCommandTreeRegistration +
  TestCobraExpectedCmdsMatchRegistration), so the cobra registration
  conformance test passes with the new ao subcommands.
- cli/docs/COMMANDS.md: regenerated by scripts/generate-cli-reference.sh
  to include ao scope and ao skills subcommands.
- cli/embedded/hooks/{hooks.json,edit-scope-guard.sh}: re-synced via
  cd cli && make sync-hooks (per CLAUDE.md sync-hooks rule). Wave 2 (I5)
  pre-mortem amendment will re-verify embedded copies after the mass
  refactor.
- skills/SKILL-TIERS.md: add /scope row under Primitives table.
- docs/SKILLS.md, docs/ARCHITECTURE.md, PRODUCT.md: skill counts synced
  by scripts/sync-skill-counts.sh from 69 → 70 (and user-facing 60 → 61).

All Wave 1 issues now closeable. Codex parity audit passes. Full
go test ./... green.
2026-05-02 08:15:51 -04:00
Boden Fuller bf21153dcc fix: standardize daemon CLI token resolution 2026-05-01 23:01:40 -04:00
Boden Fuller 6f2e08e1bb fix: clear E5 CLI hygiene blockers 2026-05-01 22:39:44 -04:00
Boden Fuller c221348c16 fix(cli): register ao schedule in cobra conformance lists + regen COMMANDS.md (soc-8inr.10 follow-up) 2026-05-01 17:55:10 -04:00
Boden Fuller 82e9cacc2a Merge branch 'evolve/prep-2026-04-30' into main
# Conflicts:
#	.agents/ao/last-processed
#	.agents/findings/registry.jsonl
#	.agents/learnings/2026-04-07-v2.35.0-release-postmortem.md
#	.agents/learnings/2026-04-19-orchestrator-compression-anti-pattern.md
#	.agents/learnings/2026-04-27-ci-contract-scanners-need-syntax-parity.md
#	.agents/patterns/pre-tag-ci-validation.md
#	.agents/rpi/execution-packet.json
#	.agents/rpi/next-work.jsonl
#	PRODUCT.md
#	README.md
#	docs/index.md
#	skills-codex/.agentops-manifest.json
#	skills-codex/crank/.agentops-generated.json
#	skills-codex/evolve/.agentops-generated.json
#	skills-codex/implement/.agentops-generated.json
#	skills-codex/plan/.agentops-generated.json
#	skills-codex/rpi/.agentops-generated.json
#	skills-codex/swarm/.agentops-generated.json
#	skills/plan/references/plan-document-template.md
2026-05-01 12:52:56 -04:00
Boden Fuller 7ded7c2c74 feat(pool): add ao pool reindex to backfill promoted-index from disk
Worker E (swarm). Closes council action item from
.agents/council/2026-05-01-evolution-cycle-council.md.
2026-05-01 10:30:52 -04:00
Boden Fuller ea40e5fded feat(dedup): write archive manifest + threshold-pause for --merge
Worker D (swarm). Closes council action item from
.agents/council/2026-05-01-evolution-cycle-council.md.
2026-05-01 10:30:51 -04:00
Boden Fuller c2099fc364 fix(codex): make closeout dirty-safe 2026-05-01 09:01:35 -04:00
Bo a85e734851 feat: add daemon watch and telemetry histograms (#198)
* feat: add daemon watch and telemetry histograms

* docs: sync CLI skills map count for watch
2026-04-30 17:04:58 -04:00
Bo 56e93ef5ce feat: isolate cli fallback workers (#199) 2026-04-30 16:30:05 -04:00
Bo d391039a21 fix: complete GasCity wiki forge workers (#193) 2026-04-30 11:08:22 -04:00
Boden Fuller 45d2d4fd10 feat(daemon): add ao daemon jobs submit subcommand
Mac, phone, and any future non-CLI client of agentopsd previously had to
hand-roll curl POSTs to /v1/jobs. The runbooks documenting that path were
correct (X-AgentOps-Daemon-Token header, AllowedPaths /v1/jobs) but every
operator hit the same papercuts: header-name typos, non-JSON payloads, and
silently mistyped job_type strings that the daemon would queue without an
executor.

This adds `ao daemon jobs submit --type <known-type> --payload <inline|@file|@->`
sibling to the existing show/list/wait/cancel commands. Behavior:

- POSTs SubmitJobRequest{job_type, payload} to <url>/v1/jobs with the
  canonical X-AgentOps-Daemon-Token header (DefaultMutationTokenHeader from
  cli/internal/daemon/auth.go).
- Validates --type against the JobType enum (cli/internal/daemon/types.go).
  Unknown types exit 2 with the full known-type list — scripts and the
  /evolve loop can branch on the exit code without parsing stderr.
- Reads --payload as inline JSON, '@-' for stdin, or '@path' for a file.
- Outputs submitDaemonJobResponse (Accepted/JobID/JobType/Status/RequestID/
  LastEventID/ProjectionStatus) in table or json format, suitable for
  shell pipelining via `--json | jq -r .job_id`.

Tests in cli/cmd/ao/daemon_jobs_test.go cover:
- Happy path: real httptest fixture submits openclaw.snapshot, asserts
  daemon queue contains the returned job_id (L2 integration via the same
  fixture as cancel/wait tests).
- Enum validation: known/unknown/error-message coverage (L1 unit).
- Payload reading: inline, @file, empty/whitespace, and non-JSON rejection.

CLI docs regenerated via scripts/generate-cli-reference.sh; TestCobraConformance
passes.

Closes-after-validation: soc-5of.11
2026-04-30 08:20:06 -04:00
Boden Fuller 1ec75aaa21 feat(eval): classify evidence and audit baselines 2026-04-29 17:10:57 -04:00
Boden Fuller ae37125a34 feat(daemon): add product soak proof 2026-04-29 14:35:24 -04:00
Boden Fuller 4b3ee6c75a fix(daemon): execute dream runs through supervisor 2026-04-29 14:35:24 -04:00
Boden Fuller 8c784f0036 fix(daemon): run wiki forge through supervisor 2026-04-29 14:35:24 -04:00
Boden Fuller feb941b251 fix(daemon): add operator job commands 2026-04-29 14:35:23 -04:00
Boden Fuller 7f05992535 fix(daemon): add foreground worker supervisor 2026-04-29 13:01:03 -04:00