crickets composition - alexherrero/crickets GitHub Wiki
Note
LAUNCHED (lifted 2026-06-24, AG Phase 3; originally approved 2026-06-22) ยท locked 2026-06-28 (final AG design sweep). child-design โ the composition mechanics, parent crickets HLD: how capabilities combine with each other, lean on agentm's opinions, and compose onto the person. The parent stays high-level; this holds the wiring. status: launched (lifted into tracked wiki/designs/ 2026-06-24, AG Phase 3). Points up at the crickets HLD.
Crickets is a box of stateless tools, yet the work it does holds together โ /release knows the plan /work built, code-review sharpens what /review runs. This design specifies the mechanism behind that coherence: composition โ how tools combine by capability-name, resolved at load, with every dependence pointing one way.
Three kinds of composition meet here: capability with capability, capability with an agentm opinion, and the whole toolbox with the person (agentm). All three are by name and one-way โ a unit names the capability it wants, the runtime wires it at load, and dependence points up the stack. A tool reaches another tool's surface, or an opinion, or the substrate, by asking the resolver for it; each plugin's code stays in its own plugin (the soft-composition rule, established for the developer suite and now held here).
The target shape is thirteen plugin-capabilities, and thirteen plugins ship today (the sets differ). The target renames developer-workflows โ development-lifecycle (the spine, now owning the feature's whole arc โ launch / deprecate / retire included), folds testing-conventions + releasing-conventions โ conventions and status-line-meter โ token-audit, and adds the two new research / diagnostics. The graph below is that target shape:
Dashed green = soft enhances:; solid = hard requires:. Dimmed nodes (research, diagnostics) are the new capabilities, not yet shipping โ their precise depends/enhances land in their per-capability sub-designs (crickets-research, crickets-diagnostics, to be authored). development-lifecycle (the spine โ the renamed developer-workflows, now owning the feature's whole arc including launch / deprecate / retire) is the base most build on; code-review, developer-safety, and wiki enhance it; github-projects, maintenance, conventions, and design require it; token-audit, obsidian-vault, and privacy rest directly on the substrate. Everything rests, directly or through the spine, on the agentm substrate. Today the thirteen ship under current names (developer-workflows, github-ci, design-docs, wiki-maintenance, pii, the two *-conventions, status-line-meter); the renames + merges land in Phase-1/3 build. One line on what each capability is: the HLD's sub-designs table.
A capability names two kinds of relationship to another, by capability name:
-
requires:โ a hard dependency: it will not run without the target (e.g.github-projectsrequiresdeveloper-workflows). -
enhances:โ a soft dependency: it works alone, and does more when the target is present (e.g.code-reviewenhancesdeveloper-workflows's/review).
At load time agentm's resolver (capability_resolver.py) matches names to installed capabilities, and the crickets bridge (agentm_bridge.py's capability verb) reaches it. These links arise where a primitive is shared across capabilities, or one capability builds on another's surface.
How enhances: resolves. The relationship is asymmetric and order-free: the enhancer names the target, the target knows nothing of its enhancers, and the resolver matches at load regardless of install order โ installing the enhancer before or after the enhancee gives the same result. A soft match that finds nothing resolves to a quiet absence, so any subset of crickets installs and runs. The declared edges also drive discovery surfaces: suggest_enhancers.py (governed here) lets bootstrap suggest installing an enhancer ("you have development-lifecycle; install code-review for the full experience"), and the marketplace render carries the same "works better with โฆ" links.
The honesty lints (in the generator's lint_src.py) keep the graph sound: the named target must exist, nothing enhances itself, enhances: and requires: cannot name the same capability, and a named target must be declared in some plugin's capabilities:. A capability declares the names it provides in capabilities:; those are what others may target. All thirteen shipping plugins declare capabilities: today.
Version matching โ capability_version_match.py (a single-range semver check: >=, >, <=, <, ==, !=, ~=, degrading to a non-match on malformed input rather than raising) exists in agentm. [PENDING-IMPL] (wiring only) โ crickets does not yet wire it in: the Enhance dataclass (scripts/src_model.py) carries no version field, so there is no schema slot to name a version range on an enhances: relationship today, and nothing in crickets calls the matcher. The enforcement policy is settled (at-load resolution ยท out-of-range = not-present for that edge โ see Risks); only the schema/call-site wiring is parked, until an edge needs a version pin.
The same requires: / enhances: mechanism reaches up to agentm's opinions. A capability โ or a single primitive โ can depend on an opinion (its gate needs what "done" looks like to run at all) or be enhanced by one (it produces better output when what "good" looks like is available, and still runs without it). When the opinion is present it shapes the work; when absent, the capability degrades gracefully.
The opinion surfaces (done / good / efficient / how-we-engineer) and the request-by-name path a tool would query live in the agentm Opinions design โ the resolver itself is built (opinion_resolver.py + the nine opinions/*.md stubs, AG Wave B). As of PLAN-wave-d-opinion-wiring (2026-07-06) only 2 of the 9 originally-scoped consumer bindings across the crickets portfolio were wired; as of PLAN-wave-d-personas (2026-07-07, below) every markdown-prose binding the grammar governs has now moved through it โ either interpolated, declared self-provider, or honestly re-grounded as having no real site:
-
Wired: diagnostics's
writer.pyrequestshow-we-engineerand folds the resolved body into every written incident. development-lifecycle's routed-dispatch layer discoverstokens/scriptsviaopinion_resolve('efficient')['implements']instead of a hardcoded path (the concrete tier/model/effort data still comes fromtoken-audit's own routing table โ the opinion'simplements:artifact, not a duplicate). -
Interpolated (markdown-prose consumer grammar, cross-plugin case):
design's two bindings โsrc/design/commands/design.mddeclaresopinions: [good, how-we-engineer].good's marker sits at Step 6 (Review pass, PLAN-opinion-consumer-grammar task 2, 2026-07-07);how-we-engineer's marker sits at the "Rungs" table's sizing call (PLAN-wave-d-personas task 2, 2026-07-07). Both splice their committed snapshot (scripts/opinion-snapshots/{good,how-we-engineer}.md) into an<!-- opinion:name --> โฆ <!-- /opinion:name -->marker atgenerate.pybuild time, baked into bothdist/claude-code/anddist/antigravity/โ see the build-system design's Amendment log for the mechanism. -
Declared self-provider, staying hardwired by design (no splice, drift-check only):
code-review'sgoodbinding (adversarial-reviewer.md, PLAN-opinion-consumer-grammar task 3, 2026-07-07) and development-lifecycle's own two direct bindings โwork.mddeclaresopinions: [done],bugfix.mddeclaresopinions: [how-we-engineer](PLAN-wave-d-personas task 3, 2026-07-07;bugfix.md, notplan.md/work.md, ishow-we-engineer's canonical site โ confirmed by grep, not the first guess). In all three cases the caller file itself IS the opinion'simplements:artifact, so the grammar calls for a drift check only (scripts/check-opinion-self-provider-drift.py'sSELF_PROVIDER_BINDINGSregistry, flagging agentm'sopinions/<name>.mdstub if it drifts from the caller's own prose, checking only in that direction). "Hardwired" is the correct terminal state here, not a waypoint to interpolation. -
Not grounded โ no prose site exists to wire:
maintenance(done),wiki(good) (both PLAN-opinion-consumer-grammar task 4 grounding pass, 2026-07-07), andresearch(how-we-engineer, PLAN-wave-d-personas task 1, 2026-07-07). None of the three capabilities' shippedsrc/files state the claimed standard anywhere.maintenance's only substantive file,src/maintenance/skills/dependabot-fixer/SKILL.md, has its own local completion criterion (verify.shexit 0) that's philosophically similar todonebut not a citation ofdone's actual prose (which names development-lifecycle'scheck-all.sh/PLAN.md/progress.mdtriad โ a mismatch for a skill that runs standalone, often with noPLAN.mdin scope).wiki's files (documenter.md,diataxis-author/SKILL.md,diataxis-evaluator.md,wiki-author/SKILL.md) state no hostile-read/failing-test/defect/no-issues-found-shaped standard;documenter.md:15explicitly disclaims the closest candidate role ("You are not a style reviewer and not a quality judge").researchcarries exactly two files (scripts/agentm_bridge.py,scripts/idea_search.py) โ zero skill/command markdown, so there is no static-prose site at all. Wiring any of the three would require authoring new standard-prose first, a content decision left to whoever next substantively touches that capability โ not this grammar's job. -
Dropped, not deferred:
privacy'sprivacy-reviewskill (the skill itself is[PENDING-IMPL]โ nothing exists yet to wire; its opinion binding belongs in whichever plan builds it) andtoken-audit(it'sefficient's one-way measurement provider, not a consumer with hardwired guidance text โ the original staging research misread the direction of that arrow).
The follow-up shape, proven then fanned out to completion. Build-time interpolation via generate.py's emit pipeline (scripts/src_model.py's interpolate_opinions() / render_primitive_text()), reading a primitive's opinions: frontmatter key and splicing a committed snapshot's body into an HTML-comment marker pair in the source, resolved at build time โ mirroring how style_resolver.py already composes wiki's voice overlay at author time, just shifted to build-time since these files have no author-time render step. Locked on designโgood (PLAN-opinion-consumer-grammar task 2). The self-provider half of the grammar (declare opinions:, no splice, drift-check only) is separately proven on code-reviewโgood (task 3, same date). PLAN-wave-d-personas (2026-07-07) fanned both shapes out to the three bindings the grammar's own build pass left unswept (designโhow-we-engineer cross-plugin; development-lifecycle's done/how-we-engineer self-provider) and closed out the one remaining ungrounded claim (researchโhow-we-engineer) โ every markdown-prose binding this grammar governs is now either wired, declared, or honestly re-grounded; none is left silently contradicting what its design doc claims about it.
crickets depends on agentm; agentm never depends on crickets. That arrow is the central rule of the whole split. A tool draws on the substrate by asking: the authoritative resolver lives in agentm (capability_resolver.py); crickets reaches it through a thin bridge (agentm_bridge.py's capability verb) that discovers it by path-fallback and skips gracefully when agentm is absent. The graceful skip runs both ways โ remove the tools and agentm still remembers; remove agentm and the tools still run, just without memory-backed continuity. A bare agentm is whole on its own.
Three decisions drew the arrow: the repo split made them siblings sharing only a byte-identical lib/install/; the V5 unbundling deleted the phase loop from agentm and re-homed it in crickets, removing even the hard-require; and the routing-plane de-vaulting kept agentm's substrate speaking in backend-agnostic terms, so a tool can ask without assuming vault paths (V5-6, in the memory-storage-seam living design). (The first two decisions now live in the agentm HLD amendment log. Transitional wrinkle: until the orchestration-split slim lands, agentm still carries baked-in copies of some dev-loop scripts from before the unbundling โ a cleanup-status detail.)
There is no role tier. What used to be called a "role" is a persona (an agentm concept โ see the agentm Personas design) wielding a package of crickets tools. The agent-definitions the phase loop ships today (worker.md, tech-lead.md, โฆ) are transitional: their stance migrates up into agentm personas, and crickets keeps the tools plus the package โ correlated tools named after the persona that wields them. The read-only helpers (explorer, evaluator) stay tools, by the cross-capability-judgment discriminator. This resolves the persona-vs-role question the launched developer-suite design (since subsumed into this design) deferred; Coordinator-Roles.md and the agent-defs reconcile to the persona-wields-tools shape when role-retirement lands.
A v6.0 capability rename โ developer-workflows โ development-lifecycle, github-ci โ maintenance, design-docs โ design, wiki-maintenance โ wiki, token-audit โ tokens, pii โ privacy, plus the testing+releasing โ conventions merge โ does not break the existing requires: / enhances: edges that named the old capability. There is no separate alias map: the renamed (or merged) plugin's group.yaml simply declares both the old and the new capability name in its capabilities: list, and the resolver โ which matches by declared name โ resolves either. The old name is dropped in a later major once no consumer references it (a no-dangling-name check at that point). The seven renames all reference this one mechanism; it is what their Migrations sections mean by "keeps the old names resolving."
This covers capability names only. A design's governs: stamp names a directory path, and there is no both-paths equivalent โ when the plugin directory follows the rename, every governs: stamp pointing into it must be re-pointed by hand in the same change. Nothing catches a missed one: governs_resolver matches globs against the tree, so a stale path simply stops matching, and the file falls through to the HLD's src/** instead of failing loud. agentm's check-governs-index.py gates overlap and area: vocabulary, not path existence, and crickets does not run it. See the Amendment log (2026-08-02).
-
agentm's resolver, via the bridge โ composition's by-name lookups resolve through agentm's
capability_resolver.py, reached by crickets'agentm_bridge.py(capabilityverb; path-fallback + graceful-skip). The one-way arrow: crickets depends on agentm, never the reverse. -
The generator's lints โ
lint_src.pyenforces the four honesty lints over every plugin'srequires:/enhances:/capabilities:; the crickets build-system design owns the generator. -
Version matching โ
capability_version_match.py(agentm) exists, but crickets doesn't yet wire it in.[PENDING-IMPL](wiring only) โ theEnhancedataclass has no version field, so no relationship can name a version range on its target today; the enforcement policy is settled (at-load ยท out-of-range = not-present), the wiring is parked (Risks). -
Sibling designs โ agentm Opinions (the opinion surfaces + the request-by-name path), agentm Personas (the persona tier that wields tool packages), crickets build-system (where the lints +
capabilities:are generated).
-
Version-matching policy โ settled (2026-07-07); wiring parked. The enforcement policy is decided (G12 close-out, operator-ratified): a range resolves at load (with the resolver, where all by-name composition resolves โ not at call), and an out-of-range target is treated as "not present" for that edge โ an
enhances:mismatch degrades to the same quiet absence a missing soft target gives, and arequires:mismatch fails loud at resolution, the same as a missing hard dep; a malformed range degrades to a non-match (alreadycapability_version_match.py's behavior), never a raise. The wiring is parked (backlog):Enhancestill has no version field and nothing calls the matcher, and no crickets edge needs a version pin today, so building the schema slot + call sites + a range-parses lint is deferred until a real edge wants one. The policy is decided so that build, when wanted, is mechanical. - The opinion request-by-name path is built, but only 2 of 9 consumer bindings are wired onto it โ the resolver itself shipped in AG Wave B; the remaining 6 hardwired bindings are blocked on an unlocked markdown-prose consumer grammar (see "Capabilities compose with opinions" above for the full breakdown), not a Phase-3/4 timeline that will resolve itself as other work lands.
-
researchanddiagnosticsare newly designed, not yet built โ their precise depends/enhances are carried from their authored sub-designs; the edges land as they ship. -
Role-retirement is mid-flight โ
Coordinator-Roles.md+ the transitional agent-defs (worker.md,tech-lead.md, โฆ) reconcile to the persona-wields-tools shape when role-retirement lands. - A transitional baked-in-scripts wrinkle โ until the orchestration-split slim lands, agentm still carries copies of some pre-unbundling dev-loop scripts.
-
Re-audit triggers: re-derive the relationship map from
dist/default-set.jsonas the set grows; confirm the three new capabilities' edges when their sub-designs land; reconcileCoordinator-Roles.mdat role-retirement; convert the mermaid map to a vector diagram at the parent's diagram pass; repoint the ADR references as agentm 0006/0011/0016 fold into living designs.
-
Resolver + bridge: agentm
scripts/capability_resolver.py(build_registryยทcapability_availableยทcapability_resolve+ CLI) ยท cricketssrc/development-lifecycle/scripts/agentm_bridge.py(capabilityverb; path-fallback discovery, graceful-skip) -
Version match: agentm
scripts/capability_version_match.py(single-range semver check; graceful-degrade to a non-match on malformed input) -
Lints: the generator's
lint_src.py(target-exists ยท no-self-enhance ยท enhances โฉ requires = โ ยท target is declared) -
Living designs (the ADR model is retired in agentm + crickets): this design is now the single home for the
enhances:soft-composition rationale (it subsumed the earlierdeveloper-plugin-suite.md, incl. the persona-vs-role deferral โ see the Amendment log, where ADRs 0017 + 0027 are preserved) ยท agentmmemory-storage-seam(V5-6 routing-plane de-vaulting). Still-standing decisions โ agentm crickets-split, V5 unbundling, persona tier โ now live in the agentm HLD / Foundations HLD amendment logs. -
Siblings: agentm Opinions ยท agentm Personas ยท crickets build-system ยท
wiki/reference/Coordinator-Roles.md(the transitional role agent-defs)
2026-08-02 โ every in-place plugin rename left its design's governs: stamp stale; three found by sweep, and the rename mechanism is documented as not covering them. A stale governs: [src/github-ci/] on crickets-maintenance prompted a sweep of every governs: path in wiki/designs/ against the tree. Three of the fourteen designs with a non-empty stamp pointed at a directory that no longer exists โ crickets-maintenance (src/github-ci/ โ src/maintenance/), crickets-design (src/design-docs/ โ src/design/), and crickets-wiki (src/wiki-maintenance/ โ src/wiki/) โ one per in-place directory rename that has landed so far, and each design's own body already documented the new path. All three re-pointed. This is the third recurrence of the class (the 2026-07-05 entry below caught a file-scoped stamp at work-time; 2026-07-10 re-pointed the same stamp again), which is why it is recorded here rather than fixed silently: the ยง"Renames keep both old and new names resolving" mechanism gains an explicit paragraph stating that it covers capability names and not governs: paths. The failure is quiet, not loud โ a stale glob stops matching and the file falls through to the HLD's src/**, so /plan's Hook 2 grounding and /release's Hook 7 prompt get the arc-level design instead of the child, which reads as a plausible answer rather than an error. crickets-reporting (governs: [], designed-not-built) and crickets-vault-git (no stamp, governs no code yet) are correct as-is. Why not add a path-existence gate now: out of this change's scope, and the right home is arguable โ agentm owns governs_resolver and check-governs-index.py, so the check likely belongs upstream alongside the overlap/area checks rather than as a fourteenth crickets gate. Re-audit trigger: the next in-place plugin rename (token-audit โ tokens and pii โ privacy have landed; the remaining v6.0 renames have not) โ re-point its governs: stamp in the same change, or land the path-existence gate and stop relying on the discipline.
2026-07-10 โ governs: path re-pointed again: find_capability.py -> agentm_bridge.py (Consolidation arc, CONS-2 task 2). development-lifecycle's four independent find_*.py-style bridge scripts (find_capability.py, find_governing_design.py, find_process_seam.py, resolve_workflow_persona.py) โ each re-implementing the same env-var/co-located/conventional-clone path-fallback cascade and subprocess-proxy contract under its own filename โ merged into one agentm_bridge.py with a four-verb dispatcher (capability / governing-design / process-seam / workflow-persona); every command-file call site and this design's own bridge references updated to match. No behavior change to any verb's discovery order, exit codes, or graceful-skip contract โ only the file (and the CLI shape that selects which verb) changed. Why not keep the four files separate: they were near-identical copy-paste of the same cascade with no behavior divergence to justify four files; a bridge script drift-check (a separate follow-up task) is far cheaper to write and maintain against one file than four. Re-audit trigger: if a fifth agentm-facing lookup is added to development-lifecycle, extend this same dispatcher rather than starting a new standalone bridge file.
2026-07-07 โ version-matching policy settled; wiring parked (G12 AG close-out, operator-ratified). The design left the version-matching enforcement policy to "the per-capability sub-designs to settle"; the G12 roadmap session settled it, operator-ratified. Policy: a range resolves at load (with the resolver, where all by-name composition resolves โ not at call, which would fragment the model and re-check every invocation); an out-of-range target is treated as "not present" for that edge, reusing the existing presence semantics rather than a new warn/error axis โ an enhances: mismatch degrades to quiet absence (like a missing soft target), a requires: mismatch fails loud at resolution (like a missing hard dep); a malformed range degrades to a non-match (already the matcher's behavior). Wiring parked: the version: field on Enhance + the call sites + a range-parses lint are a backlog item, not built now โ no crickets edge needs a version pin today (zero current demand, mirroring the "park until a consumer exists" call). Updated the Risks bullet from "unsettled" to "settled; wiring parked" and the two body [PENDING-IMPL] notes to name the split (policy settled, wiring only pending). Why not build the wiring now: pure optionality with no consumer โ adding schema + call sites speculatively risks locking a shape no edge has exercised. Re-audit trigger: build the wiring when a real enhances:/requires: edge first needs to pin a target version range; revisit at-load-vs-at-call if a host ever ships live per-invocation capability versions.
2026-07-07 โ the opinion-consumer conformance sweep completes: every markdown-prose binding this grammar governs is now wired, declared, or re-grounded (PLAN-wave-d-personas tasks 1-3). The three bindings the grammar's own build pass left unswept โ researchโhow-we-engineer, designโhow-we-engineer, and development-lifecycle's own direct done/how-we-engineer bindings โ are closed out: research re-grounded as having no real prose site (task 1, same shape as the maintenance/wiki finding below); designโhow-we-engineer interpolated via the now-proven cross-plugin marker+snapshot mechanism (task 2); development-lifecycle's done/how-we-engineer declared self-provider on work.md/bugfix.md respectively (task 3) โ bugfix.md, not plan.md/work.md as this plan's own preamble first guessed, confirmed by grep for the stub's own "Report โ Analyze โ Fix โ Verify" phrase across all six phase-command files rather than assumed from the first hit. Rewrote the "Capabilities compose with opinions" section above: the now-empty "still hardwired and undeclared, ready for mechanical fan-out" bullet is retired; its two entries (designโhow-we-engineer, development-lifecycle's direct bindings) moved to Interpolated/Declared self-provider respectively, and research moved to Not-grounded alongside maintenance/wiki. Re-audit trigger: none โ this closes the fan-out this doc named as the natural follow-up (2026-07-07, task-2 entry below); a genuinely new binding (a new capability, a new opinion) starts its own classification from scratch, not a reopening of this one.
2026-07-07 โ grounding pass finds no real prose site for maintenance/wiki; corrects an overclaim in this doc (PLAN-opinion-consumer-grammar task 4). Task 4 searched src/maintenance/ and src/wiki/ for any real prose stating the done/good standards those two capabilities were listed against. Verdict: neither has one. maintenance's only substantive file (dependabot-fixer/SKILL.md) has its own local, verify.sh-scoped completion criterion โ philosophically similar to done but not a citation of done's actual prose (the check-all.sh/PLAN.md/progress.md triad, a mismatch for a standalone skill). None of wiki's substantive files (documenter.md, diataxis-author/SKILL.md, diataxis-evaluator.md, wiki-author/SKILL.md) states a hostile-read/failing-test/defect/no-issues-found-shaped standard; documenter.md explicitly disclaims the closest candidate role, and diataxis-evaluator.md is a mode-classification judge, not a content-quality judge. This corrects the "Capabilities compose with opinions" section above, which previously lumped maintenance/wiki into the same "still hardwired and undeclared" bullet as research/design's how-we-engineer/development-lifecycle's direct bindings โ implying all five were equally ready for the mechanical fan-out proven in tasks 2/3 (real prose, just needs opinions: frontmatter). That overclaimed readiness for maintenance/wiki specifically: there is no prose to declare. Split the bullet into fan-out-ready (research, design's how-we-engineer, development-lifecycle's direct bindings โ real prose exists) and not grounded (maintenance, wiki โ no prose site exists; wiring either requires authoring the standard's prose first, a content decision out of this plan's scope). Why not author the missing prose here: this plan's scope is the consumer grammar (declaration + splice/drift-check mechanism), not authoring net-new opinion-standard content for capabilities that don't yet state one โ that's a content decision for whoever next substantively touches maintenance or wiki. Re-audit trigger: if a future change adds real done/good-shaped prose to either capability's src/ files, reclassify it into the fan-out-ready row and wire it via the now-proven grammar.
2026-07-07 โ the self-provider half of the grammar is proven on code-reviewโgood (PLAN-opinion-consumer-grammar task 3). adversarial-reviewer.md now declares opinions: [good] frontmatter and is checked by scripts/check-opinion-self-provider-drift.py โ a self-provider binding (code-review IS good's implements: artifact) stays hardwired with no splice, unlike the cross-plugin designโgood case (task 2, below). Split the "Capabilities compose with opinions" hardwired bullet in two: a declared self-provider row for code-review and a still hardwired and undeclared row for the remaining four/five bindings, so a reader doesn't conflate "no opinions: frontmatter at all" with "declared self-provider, correctly staying hardwired." Scope note surfaced mid-task: the plan's initial survey wrongly assumed no src/code-review/ file states the good standard in prose and scoped the drift check's target as wiki/designs/crickets-code-review.md; mid-task it turned out adversarial-reviewer.md does state it (in different words), so the drift check targets that file directly โ crickets-code-review.md's own "Opinions it consumes" section and hardwired-risk bullet were updated to match (see that design's Amendment log, same date). Re-audit trigger: research/maintenance/wiki/development-lifecycle's direct bindings each get classified self-provider vs. cross-plugin and update their own bullet the same way.
2026-07-07 โ the markdown-prose consumer grammar is locked and proven on designโgood (PLAN-opinion-consumer-grammar task 2). The previous entry (2026-07-06, below) narrowed the opinion-wiring status to an honest 2-of-9 and named the markdown-prose consumer grammar as the blocker for the remaining six bindings. That grammar is now built: generate.py's emit pipeline splices a committed opinion snapshot into an <!-- opinion:name --> โฆ <!-- /opinion:name --> marker at build time (scripts/src_model.py's interpolate_opinions()/render_primitive_text()), proven end-to-end on src/design/commands/design.md's good binding โ verified byte-deterministic across both hosts and across repeat builds. Moved design's good binding from "still hardwired" to "interpolated" in the "Capabilities compose with opinions" section above; design's how-we-engineer binding is untouched and stays hardwired. Why not fan the grammar out to the other five deferred bindings in this same plan: the plan's own scope was to prove the mechanism on the smallest real cross-plugin case, not to fan it out mechanically โ that's named as the natural follow-up, not done here. Re-audit trigger: each subsequent binding that moves from hardwired to interpolated should update its own bullet in "Capabilities compose with opinions," same as this one.
2026-07-06 โ the opinion-wiring status is now honestly 2-of-9, not "designed, not built" (PLAN-wave-d-opinion-wiring task 3). A first build attempt against the original 10-binding/9-file plan surfaced that 6 of the remaining 7 targets are static markdown skill/command/agent files with no runtime render step, privacy-review doesn't exist yet, and token-audit was scoped on a backwards premise (a provider, not a consumer). The plan narrowed to the 2 bindings that are real code with a render step (diagnostics, development-lifecycle's routed-dispatch slice) and now ships them; this entry replaces the old undifferentiated "Phase-3/4" framing with the honest done/deferred/dropped breakdown above, so a reader doesn't infer that six more bindings are one build session away. Why not invent the missing markdown-prose consumer grammar now: Wave B's own check-opinion-honesty.py docstring already defers it "until that grammar is locked" โ inventing it inside a narrow wiring plan risks locking the wrong shape under time pressure rather than as deliberate design work. Re-audit trigger: a future design locks the markdown-prose consumer grammar โ flip this entry's "still hardwired" list to as-built as each binding moves.
2026-07-05 โ governs: path re-pointed: src/developer-workflows/scripts/find_capability.py -> src/development-lifecycle/scripts/find_capability.py (PLAN-wave-a-renames-1 task 3, staging-miss caught at work-time). The AG Wave A rename 1 moved the directory this stamp names a file under; staging's "only crickets-development-lifecycle.md claims src/developer-workflows/" check matched the whole-directory bracket form and missed this file-scoped stamp. No content change beyond the path.
2026-07-05 โ doc-truth sweep: corrected a version-matching overclaim (PLAN-r2-ledger-and-dist task 8). The "Version matching" paragraph and its Dependencies echo stated that capability_version_match.py-backed version ranges on enhances: are live and usable today. Confirmed against the code that this overclaims: crickets' Enhance dataclass (scripts/src_model.py) has no version field at all โ no schema slot exists to name a range on an enhances: entry โ and grep -rln "capability_version_match\|version_match\|satisfies(" scripts/*.py src/*/scripts/*.py (excluding tests) returns zero call sites in crickets. The matcher genuinely exists in agentm; crickets has neither the schema field nor a call site. Marked both spots [PENDING-IMPL] and folded the gap into the existing "Version-matching policy is unsettled" Risks bullet rather than replacing it, since the enforcement-policy question and the schema/call-site gap are both real and distinct. Why not the alternative: adding the version field to Enhance now would be new capability-schema work, which belongs to a build or design session, not a doc-truth sweep โ fixing the doc's accuracy is in scope, extending the schema is not. Re-audit trigger: flip [PENDING-IMPL] to built when a version field lands on Enhance and capability_version_match.py/satisfies() gets a real call site in crickets.
2026-06-28 โ lock-down sweep (operator review). Converted the relationship-map mermaid to a house-style hand-SVG (diagrams/crickets-composition.svg); reversed this log to newest-first (the convention); and dropped the two dead ADR-number citations in the dependency-arrow paragraph (the repo split + the V5 unbundling now point to the agentm HLD amendment log, matching the V5-6 treatment beside them). The folded ADR 0017/0027 records stay (this design owns them). No change to the composition contract. Locked as a v5โv8 guidepost.
2026-06-28 โ added the rename mechanism (critique W5 / ruling 11). Added ยง"Renames keep both old and new names resolving": a v6.0 rename or merge keeps existing requires: / enhances: resolving because the plugin's group.yaml declares both the old and the new capability name โ there is no separate alias map, the resolver matches by declared name. Replaced the imprecise "resolver aliasing" wording across the seven rename designs with a pointer here. Re-audit: add the no-dangling-name check when an old name is dropped in a later major.
2026-06-24 โ subsumed the launched developer-plugin-suite.md design (AG Wave 2, move-and-retire). This design is now the single canonical home for crickets composition; the earlier developer-suite design โ which the 2026-06-22 grounding pass had reconciled against โ is deleted (git history + its six part files hold the full text). Its still-live value is folded here; in particular the two C4-folded ADRs it had absorbed (AG Phase-2) are preserved below with decision + why-not + re-audit, since this design now owns governs: scripts/suggest_enhancers.py in addition to the bridge.
-
ADR 0017 โ soft composition (
enhances:), the three-way developer split, capability-keyed resolution (2026-06-04; amended 2026-06-18). A new optionalenhances: [{group, capability?, effect}]group.yamlfield declares "augment X when both are installed," orthogonal to hardrequires:/standalone:, declared on the enhancer (keeps the enhancee's manifest closed to edit);lint_srcvalidates the edge. The monolithicdeveloperseed split three ways โdeveloper-workflows(the phase loop, the base) ยทdeveloper-safety(control hooks + safety conventions) ยทcode-review(adversarial review) โ composing viaenhances:, nonerequires:another. Two enabling modes: emergent (safety hooks fire session-global once installed) + conditional dispatch (a phase command dispatches an enhancer iff present, else graceful-skip). Resolution:find_capability.py(a developer-workflows bridge) discovers agentm'scapability_resolver.pyby path-fallback, exit-1 when agentm absent (DC-2: siblings not layers). Amended 2026-06-18 (ad2c2ed): the interim slug-keyedcapability_probe.pyretired once agentm V5-8 shipped (e7b9139) โ the capability-keyed resolver is the live path. Why not hardrequires:/enhanced_by:on the enhancee / agent-judgment: a hard dep denies standalone use;enhanced_by:re-opens the enhancee to edits; agent-judgment is non-reproducible (composition must be deterministic + testable). Re-audit trigger: a host shipping anenhances-like primitive; Antigravity gaining hook-veto. -
ADR 0027 โ output-style + rule discovery paths within developer-workflows (2026-06-14). The first concrete
output-style(terse) +rule(edit-over-write) instances live asoutput-styles/+rules/subdirs insidesrc/developer-workflows/, not new top-level groups โ dev-loop-specific token-discipline levers with no meaning outside the loop, sharing its version lifecycle; plural-hyphenated subdir names matching thekindenum; single-file primitives (no companion scripts, unlikehooks/<name>/). Why not new top-level groups / arequires:-sibling: neither lever is independently useful โ subdirness is the right container, not an installable pair. Re-audit trigger: a second group adding an output-style/rule, or one needing a runtime script (would need the dir-plus-file pattern).
Why not keep developer-plugin-suite.md as a standalone living design: it was already up-pointered and reconciled by this design + the crickets HLD โ keeping the husk forces a chain-read; the living body here is the single source. Re-audit trigger: a host shipping native soft-composition (drop the tooling-resolved enhances: layer), or a second group needing an output-style/rule.
2026-06-23 โ github-ci โ maintenance reframe (operator). The map's github-ci node is renamed maintenance (deps repair + currency ยท CVE ยท tech-debt), still a hard requires: on the spine; the count stays 13 (a rename, not an add). maintenance composes diagnostics (its dependabot-fixer calls the diagnose engine โ repair here, analysis there) and pairs with privacy (reactive advisory vs proactive static); those soft compose-edges aren't drawn on this requires/enhances spine map but live in the maintenance sub-design. Re-audit trigger: add the maintenance โ diagnostics / maintenance โ privacy compose-edges if the map grows a composition layer beyond the spine.
2026-06-22 โ map updated for the lifecycle merge (operator). The standalone lifecycle capability is folded back into the spine: the map drops the lifecycle node, renames developer-workflows โ development-lifecycle (the spine now owns the feature's whole arc, launch/deprecate/retire included), and the target count moves 14 โ 13. Two new capabilities remain dimmed (research, diagnostics). Why not keep lifecycle separate: /launch is the step right after /release, so splitting adjacent lifecycle steps across two plugins was an artificial seam. Re-audit trigger: when github-ci is reframed as maintenance, update that node too.
2026-06-22 โ grounded against live code, corrected, and conformed to the abbreviated-design template.
Restructured from a topic-outline into the abbreviated template (Objective / Overview / Design / Dependencies / Risks & open questions / References / Amendment log): the framing + the relationship map move to Overview, the four mechanics become Design subsections, and Dependencies + Risks are drawn out of the inline prose. A read-only grounding pass against the live agentm + crickets repos corrected four drifts โ version matching is implemented (capability_version_match.py), not a stub; all thirteen plugins declare capabilities: today (the former "6 of 13" gap is closed), so that claim is dropped; the dead ADR references are repointed at living designs (crickets soft-composition โ the developer-suite design, since subsumed into this design 2026-06-24; agentm routing-plane โ memory-storage-seam; the still-standing 0006/0011/0016 kept with a fold note); and the relationship map is now labeled as the target shape with the three unshipped capabilities visually dimmed, since the body had narrated the v6.0 target (renames, merges, new capabilities) in the present tense.
Verified-correct and unchanged: the requires:/enhances: semantics, the asymmetric/order-free/quiet-absence resolution, the four lint_src.py lints, the one-way arrow (bridge path-fallback + graceful-skip), and the read-only-helper discriminator. Re-audit triggers: re-derive the map from dist/default-set.json as the set grows; confirm the new capabilities' edges when their sub-designs land; convert the map to a vector diagram at the parent's diagram pass; repoint the ADR references as 0006/0011/0016 fold.