crickets maintenance - alexherrero/crickets GitHub Wiki
Note
LAUNCHED (lifted 2026-06-24, AG Phase 3; originally approved 2026-06-23) Β· locked 2026-06-28 (final AG design sweep). child-design β the maintenance capability (keep an already-shipped codebase healthy: dependency repair + currency, security patching, tech-debt inventory). status: launched (lifted into tracked wiki/designs/ 2026-06-24, AG Phase 3). Points up at the crickets HLD.
maintenance is the capability that keeps an already-shipped codebase healthy β the repair and currency work on a live repo: dependency updates that broke, dependencies that have drifted out of date, security advisories that need patching, and accumulated tech-debt that needs inventorying. It is the executing arm of the Maintainer persona ("keep the house clean β deps, docs, drift"). It diagnoses by composing diagnostics and acts by editing the repo under bounded, never-merge, never-disable-checks guarantees β analysis stays in diagnostics; the act of fixing lives here.
maintenance covers four concerns β all delivered as of Wave C (2026-07-07) β plus the optional scheduled content-refresh (also delivered) and the one still-greenfield primitive, the model-drift-detector:
| Primitive | What it does |
|---|---|
dependabot-fixer (delivered)
|
Repair a broken dependency update β a red Dependabot PR fixed under a bounded loop. |
deps-currency (delivered)
|
Keep dependencies current β surface drifted-but-not-yet-failing deps before CI goes red. |
cve-security-patch (delivered)
|
Patch a vulnerable dependency on a security advisory, before it fails CI. |
tech-debt-inventory (delivered)
|
A standing, recallable, classified debt backlog β not an ad-hoc one-shot pass. |
content-refresh (delivered Β· optional Β· scheduled)
|
Periodically refresh the harness's external-sourced content against a checklist β model pricing (pricing.py), the model+effort routing chart (re-pin on model releases), adapted-skill upstreams, other pinned snapshots. |
model-drift-detector (greenfield)
|
Catch a model release before our pins go stale β a weekly CI job that diffs the live Claude + Gemini model lists against our pinned set and opens an issue to run content-refresh. |
The repair lives here, the analysis in diagnostics (dependabot-fixer calls the diagnose engine); cve-security-patch is privacy's reactive sibling; tech-debt-inventory leans on memory; content-refresh re-pins token-audit's pricing, and the model-drift-detector triggers content-refresh on a model release; one delivered + five greenfield.
-
Entry: a
dependabot/*branch with red CI (or/dependabot-fix [pr]); preconditions:ghauthed, clean tree,verify.shexecutable. - Exit: the PR's CI green or an honest abort β commits pushed to the Dependabot branch, a PR comment with the summary + a residual-risks section; never merged (a human merges).
-
Automated: gather the failing CI + upstream CHANGELOG β call the diagnostics engine to classify the failure + confidence β consult
.harness/known-migrations.mdrecipes first β a bounded loop (β€3 iterations: Edit βverify.shβ re-diagnose) β comment + abort honestly on low confidence. - Composes: diagnostics β the recast: it calls the diagnose engine for the failure category instead of parsing CI logs inline; the repair loop stays here.
-
Artifacts: git commits on the Dependabot branch; a PR comment; an optional
.harness/progress.mdline.
-
Entry: scheduled or on-demand β the before-CI-goes-red gap (drifted-but-not-failing deps), distinct from native Dependabot auto-merge (green PRs) and
dependabot-fixer(red PRs). - Exit: an inventory of installed-vs-latest + a surfacing of what's drifted, as a passive report / recall entry β not a PR (it stays advisory, to avoid competing with native Dependabot and the blast-radius of auto-opened PRs); a PR-emitting mode is a later option.
- Automated: read the repo's manifests, compare installed vs latest, surface the drift; optionally record a depends-on / version-constraint memory entry so currency state is recallable.
- Composes: diagnostics (the currency check is an analysis the engine can host; maintenance owns curating the update) + optionally the agentm memory engine (a depends-on kind).
Delivered (src/maintenance/scripts/deps_currency.py + scripts/test_maintenance_deps_currency.py, PLAN-wave-c-maintenance / PR #157) β the installed-vs-latest inventory + the passive drift report/recall surfacing.
-
Entry: a security advisory handed to it (advisory-as-input) for a dependency not yet failing CI β the gap
dependabot-fixer(CI-red only) andprivacy(static patterns) both miss. -
Exit: the vulnerable dependency patched, under the same repair guarantees as
dependabot-fixer. -
Automated: take the advisory β identify the affected dependency + a safe version β patch β
verify.shβ comment. - Composes: privacy β its reactive sibling: privacy owns proactive static-pattern secret/PII scanning, this acts on advisories. Two halves of supply-chain / secret hygiene, opposite triggers.
Delivered (src/maintenance/scripts/cve_security_patch.py + scripts/test_maintenance_cve_security_patch.py, PR #157) β the advisory-as-input patch workflow. A real GHSA/NVD polling integration remains a later, service-shaped build.
-
Entry: on-demand capture, or fed by a code-review /
/simplifypass that surfaces debt. - Exit: a classified debt entry in memory (taxonomy: refactoring Β· performance Β· security-debt Β· documentation Β· friction-metrics), recallable and prioritizable over time.
-
Automated: capture + classify debt into a
debt/frictionmemory kind; optionally a CI gate enforcing inventory discipline (thecheck-no-piianalogue for debt). -
Composes: the agentm memory engine (a new
debtentry-kind β a convention over the existing append/search/recall, no schema change) + code-review (the episodic/simplify+ adversarial passes populate and draw from the standing inventory).
Delivered (src/maintenance/scripts/tech_debt_inventory.py + scripts/test_maintenance_tech_debt_inventory.py, PR #157) β the classification + surfacing; the debt kind is a memory convention (no schema change), and the taxonomy + the optional CI gate are maintenance's.
-
Entry: an opt-in scheduled task (the agentm runner, fired by the host scheduler), or on-demand. Optional per install β like
wiki-watch, off unless turned on. For the model-release case, themodel-drift-detector(below) is the trigger on CI cron, so that case needs nothing from the agentm runner. - Exit: the harness's pinned external content re-checked against a refresh checklist and surfaced as a report β safe mechanical re-pins applied under the repair guarantees, judgment-bound drift surfaced for operator review.
-
Automated: walk the checklist, and for each source fetch the current upstream, diff against the pinned snapshot, then re-pin or flag. Two classes:
-
mechanical re-pins (a renamed model-version string in
pricing.pyor the model+effort routing chart on a model release) auto-apply under the bounded / never-merge guarantees; -
judgment-bound drift (an adapted skill's upstream changed, or a genuinely new model that needs a tier placement and a price β
adapt-don't-import, tier-assignment, and the price number [from the pricing docs page, which the model-list API doesn't carry] are human calls) surfaces to the watchlist instead of auto-editing.
-
mechanical re-pins (a renamed model-version string in
-
Composes: token-audit (re-pins
pricing.pyβ the standing mitigation for its pricing-drift risk) + the model+effort routing chart (re-pins its model strings on a model release) + the adapt-skills watchlist (re-checks the upstreams behind adapted skills) + themodel-drift-detector(the trigger for the model-release case, on CI cron) + the agentm runner (runs the non-model checklist items on schedule). -
Distinct from
deps-currency: currency tracks package versions drifting in the manifests; content-refresh tracks pinned external-content snapshots (pricing tables, adapted upstream text) going stale. Different sources, same keep-current spirit.
Delivered (src/maintenance/scripts/content_refresh.py + scripts/test_maintenance_content_refresh.py, PR #157) β shipped as a primitive within maintenance, resolving the tentative own-capability-vs-primitive question by building it here (a generic, consumer-agnostic re-pin engine; agentm's own checklist + delegator ride it via scripts/model_effort_routing_refresh.py). The checklist + the mechanical-re-pin/judgment-flag split are as-built.
-
Entry: a weekly GitHub Actions cron (plus
workflow_dispatchfor an on-demand run), in crickets. It runs only on that cron, so a model release never reddens an unrelated contributor's PR. -
Exit: on drift, an opened-or-updated GitHub issue β "run
content-refresh" β naming the per-provider diff, the mechanical-or-judgment class of each item, and the file:line to edit; a clean run is silent. The job exits 0 either way, so the schedule stays green and the drift travels through the issue. -
Automated: query the two providers' read-only model-list endpoints (Anthropic
/v1/models, Geminiβ¦/modelsβ ids only, no generation, no token cost), normalize the ids, and set-diff them per provider against the in-repo known set. A live id we never pinned is a new model; a pinned id the provider has dropped is a removed model; a shifted class default is a changed default. Each item is classified alongcontent-refresh's split β a missingpricing.pyrow or a renamed version string is mechanical (content-refresh can re-pin it), a new model needing a tier or a changed default is judgment-bound (surfaced, never auto-edited). -
Composes: token-audit's
pricing.py(known-set input one β the Claude wire-ids) + the model+effort routing chart (known-set input two β the distinct Gemini model names it pins in prose) +content-refresh(the action it triggers). It reads both pins and writes neither; the re-pin belongs tocontent-refresh.
The known set and the signal β four calls:
-
Source of truth.
pricing.pyis canonical for the Claude axis (it is already machine-readable, the one place a price lives); the chart is canonical for the Gemini side, where the known set is the distinct prose model names it pins (the same name repeats across tier rows). A single wire-id β prose-name map, kept with the detector, is the join key β it collapses the chart's repeated prose names and matches them to the live wire-ids. -
Signals on its own cron. The detector is absent from
check-all.shand from the push path; it exits 0 even on a drift, so the drift travels through the issue. A provider API that is unreachable, rate-limited, or missing its secret logs "could not fetch the live model list β skipping this run" and exits 0, so a transient outage stays distinct from drift. - Emit a deduped issue. Drift opens-or-updates one issue keyed by a stable title/label, so a standing drift reuses its issue across runs; a CI step-summary line is the secondary surface.
-
Home and secrets. The detector, its cron workflow, and the
ANTHROPIC_API_KEY/GEMINI_API_KEYActions secrets live in crickets (withpricing.py,content-refresh, and this design); it reads the agentm chart cross-repo.
Two honest limits. The Models API returns ids and capabilities but no per-MTok prices, so the detector catches model-set drift; a silent price change to an already-pinned model is a separate source (the pricing docs page) and stays out of scope. And a removed model is never auto-deleted from pricing.py β token-audit still needs old prices to cost past transcripts, so a removal is surfaced for review and any deletion goes through the repair guarantees.
[PENDING-IMPL] β build the weekly cron workflow (the first scheduled workflow in either repo) + the detector script (the check-*.py idiom: stdlib, fail-soft, pure-diff-vs-IO split) + the wire-id β prose-name map. It delivers value before content-refresh is built: until then a human acts on the issue.
maintenance is the one side that edits the repo, so every primitive acts under the guarantees dependabot-fixer already enforces: bounded (a capped fix loop) Β· never merge (a human merges) Β· never disable a check or modify a test to pass Β· never pin to an older version Β· residual-risk-honest (never claims "fully verified" β it reports what it tried and what's still risky). Analysis is diagnostics' job; the act of fixing is maintenance's, always gated.
-
vs development-lifecycle (
/ci-cd) β/ci-cdis pipeline authoring (gate ordering, shift-left); it stays in the loop. maintenance acts on an existing repo's deps/debt/advisories. One writes the workflow; the other reacts to it going red or to deps drifting. -
vs diagnostics β diagnostics is the analysis-only diagnose engine; it never edits. maintenance is the only side that applies a fix. The
dependabot-fixerrecast (caller, not re-implementer) is the clearest instance of that split. -
vs privacy β privacy = proactive static-pattern scanning; maintenance's
cve-security-patch= the reactive advisory-driven sibling. Same domain, opposite trigger. -
vs code-review β code-review = ad-hoc
/simplify(episodic, diff-scoped); maintenance = the standing recallable backlog those passes feed and draw from. -
model-drift-detectorvscontent-refreshβ the detector detects and signals;content-refreshrefreshes (it owns every write). Two halves of one detect-then-act pair. -
model-drift-detectorvs token-audit β the detector readspricing.pyas known-set input; token-audit owns it, and the re-pin write iscontent-refresh's. -
model-drift-detectorvs model+effort routing β the detector reads the chart and flags that a model changed; routing owns the tier scale, and a new model's tier placement stays judgment-bound. The detector never assigns a tier.
Rename github-ci β maintenance in place: group.yaml name + capabilities: [maintenance], the directory, the R-dependabot detection rationale in agentm's detect_project.py, and the cross-links β with zero behavior change to dependabot-fixer (pure rename, gates stay green). The three greenfield primitives + the diagnostics recast sequence after, and depend on diagnostics existing as a named capability first.
maintenance's dependabot-fixer applies its own local completion criterion β a repair is not finished until verify.sh passes and the residual risks are stated honestly β philosophically in the spirit of done, and composes good when it leans on code-review / diagnostics. (Not a grounded done binding: a 2026-07-07 grounding pass, PLAN-opinion-consumer-grammar task 4, found no citation of done's actual prose β the check-all.sh/PLAN.md/progress.md triad β anywhere in src/maintenance/; verify.sh-exit-0 is dependabot-fixer's own standalone criterion, not a shared standard. See composition's Amendment log for the full finding. Wiring a real done binding would require the standard's prose to be authored here first β out of scope until a future change does that.)
-
requires
development-lifecycle(hard) β theverify.sh/.harnesscontractdependabot-fixerruns against. -
composes diagnostics (soft) β calls the diagnose engine to classify failures (the
dependabot-fixerrecast;deps-currencytoo); maintenance applies the fix, diagnostics never edits. - pairs with privacy β the reactive (advisory) half of supply-chain / secret hygiene to privacy's proactive (static) half.
-
leans on the agentm memory engine β a
debt/frictionentry-kind (tech-debt inventory) + an optional depends-on/version kind (currency), via the existing append/search/recall. -
feeds + draws from code-review β the standing inventory behind the episodic
/simplifypasses. - the executing arm of the Maintainer persona (agentm Personas).
- Points up at the crickets HLD; the requires/enhances mechanics are in crickets-composition.
The rename is in place: the plugin directory github-ci β maintenance, group.yaml name + capabilities: [ci-repair] β [maintenance] (with dependabot-fixer now a primitive within maintenance rather than its own capability noun), the R-dependabot detection rationale in agentm's detect_project.py, and the wiki cross-links. dependabot-fixer's behavior does not change in the rename. Consumers that named github-ci / ci-repair keep resolving because the merged group declares both the old and new capability names at the v6.0 rename (the composition rename mechanism), so existing requires: resolve.
-
Sequencing β diagnostics before the recast. The
dependabot-fixerrecast (caller, not re-implementer) needsdiagnosticsto exist as a named capability to call; until then it keeps its inline CI-log parsing. Rename first (zero-behavior), recast once diagnostics ships. -
The repair guarantees must hold across every primitive.
deps-currency,cve-security-patch, and any future repairer edit the repo, so they inheritdependabot-fixer's bounded / never-merge / never-disable / never-pin-older / residual-risk-honest contract. A greenfield primitive that edits without them is the risk. -
Advisory by decision β the honest limitation.
deps-currencysurfaces a passive report (not a PR), andcve-security-patchtakes an advisory as input (no polling). So a drifted dep nobody reviews, or a vuln nobody feeds it, isn't acted on. A PR-emitting / polling mode is a deliberate later escalation, not a silent gap. -
The concern is host-neutral; the flagship is github-bound.
dependabot-fixeris github-specific (gh,dependabot/*, GHSA) β a permanent property of that primitive under a host-neutral concern (thegithub-projectsβboard-sync,obsidian-vaultβstorage-backendpattern). Non-github primitives (renovate, plain manifest scanning) are an open door, not planned. The plugin declares the umbrella[maintenance]capability,dependabot-fixera primitive within it (the bare[ci-repair]noun is dropped). -
content-refreshshipped as a primitive within maintenance (Wave C, PR #157). The tentative own-capability-vs-primitive question is resolved: it's a primitive here β an opt-in scheduled task on the agentm runner, with the mechanical-re-pin (auto) / judgment-bound-drift (surfaced, not auto-edited) split as-built. -
Re-audit triggers: recast
dependabot-fixeronto the diagnose engine when diagnostics' engine is called (the rename + all four greenfield primitives +content-refreshhave shipped); flipmodel-drift-detector's[PENDING-IMPL]when its weekly cron + detector script + wire-idβprose-name map land β the one primitive still greenfield.
-
Delivered: crickets
src/maintenance/skills/dependabot-fixer/SKILL.md(the bounded fix loop) Β·src/maintenance/scripts/{deps_currency,cve_security_patch,tech_debt_inventory,content_refresh}.py(the four greenfield primitives, Wave C / PR #157) Β· agentmscripts/detect_project.py(the R-dependabot detection rule) Β·.harness/known-migrations.md(per-project recipes, consulted first) -
Composes: diagnostics (the diagnose engine) Β· privacy (proactive static / this reactive advisory) Β· code-review (the episodic
/simplifypasses) Β· the agentm memory engine (thedebt+ depends-on kinds) Β· token-audit + the adapt-skills watchlist + the agentm scheduler (content-refresh) - Up: crickets HLD Β· composition Β· agentm Personas (Maintainer β the persona this is the executing arm of)
2026-09-13 β debt and content-refresh entries file under memory, not the retired personal (maintenance 0.2.8). agentm_bridge.py's two writers defaulted to group="personal", and agentm files a note under the group it is handed, so every debt and content-refresh-watchlist entry landed in personal/, the memory space's name before stage 2. Both now default to agentm's own default group, memory. Entries already written under personal/ are not moved. The bridge also runs every load of and call into save.py inside _agentm_names, as the research and diagnostics bridges do, because save_entry() imports fingerprint inside the call when no fingerprint is passed and the diagnostics plugin ships a fingerprint.py. Why not omit the group and let agentm choose: the explicit default keeps the destination visible where the entry is written. Re-audit trigger: agentm changing its default group, or retiring memory/ as one.
2026-07-07 β the four greenfield primitives shipped; body flipped designedβas-built (G12 AG close-out sweep). deps-currency, cve-security-patch, tech-debt-inventory, and content-refresh all landed in Wave C (src/maintenance/scripts/{deps_currency,cve_security_patch,tech_debt_inventory,content_refresh}.py + their test_maintenance_* suites, PLAN-wave-c-maintenance / PR #157), but this design's body still marked each [PENDING-IMPL] β the plan's close-out shipped the code without reconciling the design, and the intervening 2026-07-07 opinion-grounding entry below touched only the done-binding wording. Flipped the Overview count line, the primitives table, the four section headers, the four [PENDING-IMPL] body notes, the References "Delivered" list, and the content-refresh-is-tentative Risks bullet to as-built. content-refresh's tentative own-capability-vs-primitive question is resolved by the ship: it's a primitive within maintenance (a generic re-pin engine; agentm's checklist rides it). Still greenfield: model-drift-detector β no cron workflow or detector script exists on disk β so its [PENDING-IMPL] stays. Re-audit trigger: flip model-drift-detector when its weekly cron + detector script + wire-idβprose-name map land.
2026-07-07 β corrected the done binding claim; no real prose site exists (PLAN-opinion-consumer-grammar task 4 grounding pass). A grounding pass across src/maintenance/ for any real prose stating the done standard found none β dependabot-fixer/SKILL.md's verify.sh-exit-0 criterion is philosophically similar but not a citation of done's actual prose (which names development-lifecycle's check-all.sh/PLAN.md/progress.md triad, a mismatch for a skill that runs standalone). Reworded "Opinions it consumes" above from "requests done ... hardwired today" (implying a real, undeclared binding waiting on request-by-name plumbing) to state plainly that no grounded binding exists yet. Why not author the missing prose here: out of this plan's scope (the consumer grammar, not net-new opinion-standard content) β deferred to whoever next substantively touches maintenance. Re-audit trigger: if dependabot-fixer (or a future maintenance primitive) is changed to cite done's actual prose, reclassify this as a grounded binding and wire it via the now-proven markdown-prose consumer grammar (composition).
2026-06-28 β lock-down sweep (operator review). Resized the primitives diagram to the house ~1.3Γ convention (diagrams/crickets-maintenance.svg). Confirmed maintenance keeps a shipped codebase healthy (deps repair + currency Β· CVE patching Β· tech-debt inventory; dependabot-fixer delivered, the rest greenfield) and its composition (calls diagnostics, pairs with privacy, content-refresh re-pins token-audit pricing, model-drift-detector triggers it). No content change. Locked as a v5βv8 guidepost.
2026-06-28 β scheduler β runner rename (Bucket-B / critique W1). Renamed the agentm background-job primitive scheduler β runner in the current-state content-refresh prose (it rides the host scheduler; the agentm Runner design owns it). Also corrected the imprecise "resolver aliasing" rename wording to the merged-group-declares-both-names mechanism (ruling 11). Historical entries keep their original wording. Re-audit: flip the runner's [PENDING-IMPL] to as-built when it ships.
2026-06-26 β added model-drift-detector as the trigger arm of content-refresh (operator, design-critique #5). A weekly CI cron job that queries the live Anthropic + Gemini model-list APIs and set-diffs them per provider against the in-repo known set (pricing.py for Claude ids; the model+effort chart for the Gemini column), opening a deduped "run content-refresh" issue on a new / removed / changed-default model. It gives the P8 principle a real gate and rides CI cron, so it carries no agentm-runner dependency. Calls: known-set source of truth = pricing.py (Claude) + the chart (Gemini) joined by a wire-id β prose-name map; signal-never-block (its own cron, absent from check-all.sh, exits 0 even on drift); deduped issue as the signal; crickets hosts the cron + the ANTHROPIC_API_KEY/GEMINI_API_KEY secrets, reading the agentm chart cross-repo; weekly cadence + workflow_dispatch. Honest limits: it validates model-set drift, not price numbers (the Models API has no prices), and never auto-deletes a removed model's pinned row (token-audit needs it for historical costing β surfaced for review). content-refresh's model-release trigger is reconciled from the agentm scheduler to this detector. [PENDING-IMPL]. Re-audit: build content-refresh as the consumer; revisit the known-set source if the chart's prose table proves brittle to parse; add a price-number re-verification source if the Models API gains prices.
2026-06-23 β added content-refresh as a tentative fifth primitive (operator flag, AG token-audit review). An optional, scheduled (opt-in, agentm-scheduler) primitive that periodically refreshes the harness's external-sourced content against a checklist β model pricing (pricing.py, the standing mitigation for token-audit's pricing-drift risk), the model+effort routing chart (re-pinned on model releases), adapted-skill upstreams, other pinned snapshots β with mechanical re-pins auto-applied under the repair guarantees and judgment-bound drift surfaced to the watchlist (never auto-edited). Distinct from deps-currency (package versions vs pinned content snapshots). [PENDING-IMPL] + tentative: own-capability-vs-primitive is a post-docs-review decision.
2026-06-23 β added the primitives + engine/caller diagram (diagram backfill). Per the every-design-carries-a-diagram rule.
2026-06-23 β added an Opinions-it-consumes clause (portfolio backfill). Made explicit which opinions maintenance leans on (done β the repair guarantees; good via code-review/diagnostics) β a standard Design clause adopted across the capability designs.
2026-06-23 β authored, reviewed, and finalized.
maintenance keeps an already-shipped codebase healthy β the renamed-in-place, broadened github-ci, the executing arm of the Maintainer persona. Four primitives, one delivered (dependabot-fixer) + three greenfield (deps-currency, cve-security-patch, tech-debt-inventory). The key line: the repair lives here, the analysis in diagnostics β dependabot-fixer is recast as a caller of the diagnose engine, and every repairer acts under the named repair guarantees (bounded Β· never-merge Β· never-disable Β· never-pin-older Β· residual-risk-honest). cve-security-patch is privacy's reactive advisory-driven sibling; tech-debt-inventory turns the episodic /simplify pass into a standing memory-backed backlog (a debt memory-kind convention). /ci-cd stays in development-lifecycle (pipeline authoring).
Operator decisions (2026-06-23): rename in place first (zero behavior change, gates green), recast dependabot-fixer after diagnostics ships; deps-currency surfaces a passive report (not a PR); cve-security-patch is advisory-as-input (a skill, no polling); the debt kind is a memory convention (taxonomy + optional CI gate maintenance's); the plugin declares an umbrella [maintenance] capability (drop [ci-repair], dependabot-fixer a primitive within); the github binding is a permanent property of the flagship primitive under a host-neutral concern. Built-vs-designed: dependabot-fixer delivered; the three greenfield primitives + the recast designed. Re-audit triggers: rename first; recast on the diagnose engine when diagnostics ships; flip [PENDING-IMPL] as each primitive lands; reconcile the composition map + HLD + chart at this approval.