mirror of
https://github.com/boshu2/agentops.git
synced 2026-09-14 15:08:13 +08:00
4226b9b395
26-cycle structural milestone deserves a durable learning so future
/evolve cycles can find it via `ao lookup` / docs/learnings/
browsing and not re-discover the same shape patterns.
New file: docs/learnings/2026-05-13-bc-ports-wire-up-arc.md.
(First attempt wrote to .agents/learnings/ which is gitignored —
moved to the tracked docs/learnings/ home that sibling learnings
2026-05-11-* and 2026-05-12-* live in.)
Captures:
1. What the arc proved — repeatable file triplet (~250 LOC + ~10
tests per cycle), 8 distinct adapter shapes that all worked
under the same triplet, reader+writer pair tests prove on-disk
format compatibility, two valid subprocess-test shapes (fake-
script vs pluggable func field).
2. Anti-patterns observed — fileExists collision caught by go vet
(cycle 115), cap shadowing (cycle 117), assuming wrong adapter
shape until re-reading port contract (cycle 116). All three
have actionable preventions ("grep before util", "rename when
shadowing builtins", "read port doc-comment first").
3. What the arc did NOT do — no call-site migration, no cross-
process EventBus. Names the per-BC follow-up bds tracking that
work and the operator transport-choice still deferred.
4. WHY the arc stopped at 12 adapters instead of migrating callers
— intra-package routing (cli/cmd/ao → cli/cmd/ao) adds layers
without semantic gain because the port surface only matters at
a package boundary. The genuine value comes from cross-package
callers or test substitution. Documents the next-phase target
explicitly so cycle 123+ doesn't pick a manufactured migration.
5. Cycle-history pointers — scaffold arc 78-106, wire-up arc
83+108-118, doc reconciliation 119-121, total 26 cycles across
the BC ports surface.
Why this is a cycle-worth-doing: the cycle 122 selection ladder had
no fresh signal post-wire-up. Capturing the structural milestone
preserves the lessons for future operators and gives docs/learnings/
something concrete to surface when "ports", "wire-up", or
"hexagonal" comes up in a future session.
Cycle 122 / soc-2klg knowledge-capture mode.
4.4 KiB
4.4 KiB
title, date, tags, source, maturity
| title | date | tags | source | maturity | |||||
|---|---|---|---|---|---|---|---|---|---|
| BC ports wire-up arc — 12 production adapters in 11 consecutive cycles | 2026-05-13 |
|
.agents/evolve/cycle-history.jsonl cycles 83+108-118 | lessons-learned |
BC ports wire-up arc
11 consecutive /evolve cycles (108-118), preceded by cycle 83's
first-mover productionCitationAdapter, delivered 12 production
adapters covering all 5 DDD bounded contexts (BC1-BC5). The arc is
the canonical compound-by-repetition demonstration in the cycle
history. Cycles 119-121 reconciled doc-narrative drift after the
arc completed.
What the arc proved
- A repeatable file shape ships fast. Every adapter followed the
same triplet:
<port>_adapter.goincli/cmd/ao/, paired<port>_adapter_test.go, compile-timevar _ XPort = (*productionX)(nil)assertion. Average cycle: ~250 LOC + ~10 tests in ~10 minutes wall-clock. - 8 distinct adapter shapes all worked under the same triplet: CLI wrapper (Citation), JSONL append/read (Loop R/W, Operator, ClaimEvidenceBinder w/ upgrade-only rule), tree-walk + hash join (Harness), tree-walk + ranker (CorpusReader), idempotent file write + frontmatter (CorpusWriter), pure-Go transform (FindingCompiler), subprocess bash wrapper (GateRunner), external CLI + pluggable runner (CIStatus), sync in-memory pubsub (EventBus).
- Reader+writer pair tests work. Both BC1 (CorpusReader+Writer cycles 112-113) and BC3 (LoopReader+Writer cycles 108-109) shipped round-trip tests in the writer's suite — proves the on-disk format is shared end-to-end.
- Subprocess testing has two valid shapes. Cycle 115's
GateRunner used a fake-bash-script-in-temp-repo harness;
cycle 117's CIStatus refined to a pluggable
runGHfunc field that lets tests substitute canned bytes without writing a script. Both are valid; the func-field shape is faster and platform- independent (use it when the adapter's interesting logic is the parser, not the subprocess invocation).
Anti-patterns observed during the arc
- Naming collisions caught by
go vet. Cycle 115 introduced a localfileExistshelper that collided withdoctor.go's existing one.go vetcaught it; fix was to reuse doctor's helper rather than rename. Lesson: before writing a small util in an adapter,grep -n "func <name>" cli/cmd/ao/first. - Shadowing builtins. Cycle 117 wrote
cap := limitwhich shadowedcap().go vetdidn't fail (it's legal) but it's a readability trap. Renamed topageSize. - Assuming the wrong adapter shape. Cycle 116 (ClaimEvidenceBinder) initially looked like a bd-CLI wrapper (cycle 83 Citation precedent), but re-reading the port contract showed it's a JSONL adapter (the binding ledger lives on disk, not in bd). Lesson: always read the port doc-comment first; the adapter shape is constrained by the port's persistence model.
What the arc did NOT do
- No call-site migration. Production callers in
cli/cmd/aostill invoke the leaf helpers (e.g.beads.go:227still callsverifyCitationInPlacedirectly, not via theproductionCitationAdapter). The adapters are reachable but latent. The per-BC follow-up bds (soc-pm5tfor BC1.1, etc.) track the migration work. - No cross-process EventBus.
productionEventBusis sync in-process; the adapter doc explicitly names the swap path (event_bus_nats.goor similar) for when the factory goes distributed. Operator transport-choice is deferred.
Why I stopped at 12 instead of migrating callers
A migration cycle inside cli/cmd/ao adds a layer
(verifyCitationInPlace → productionCitationAdapter →
verifyFileCitation) without semantic gain because both endpoints
are in the same package — the port surface only matters at a
package boundary. The genuine call-site value comes when:
- a non-
cli/cmd/aopackage consumes one of these adapters, or - a test substitutes the InMemoryX adapter to exercise a code path without real I/O.
Future cycle should pursue the former (create or migrate a cross-package caller) rather than manufacture intra-package routing.
Cycle-history pointers
- Scaffold arc: cycles 78-106 (12 port interfaces + InMemoryX
adapters, captured in
docs/contracts/bc-ports-inventory.md) - Wire-up arc: cycle 83 + cycles 108-118 (12 production adapters)
- Doc reconciliation arc: cycles 119-121 (3 doc files updated to reflect actual state)
- Total: 26 cycles across the BC ports surface