Summary
Extends the retired-primitive CI guard into a mechanical merge-gate against the "dangerous stale ticket" regression class. The orchestrator daemon is the single source of truth for background memory/KB maintenance; with the Agent OS evolving fast, a backlog ticket older than a week may carry a premise a later migration has obsoleted. A fresh session acting on such a ticket can naively "re-implement the missing config" and resurrect a per-MCP-instance self-trigger — the pattern that caused duplicate background work across harness-spawned instances (Claude Desktop / Codex / Antigravity). A comment can't stop that; a red merge-gate can.
Deltas
ai/scripts/diagnostics/check-retired-primitives.mjs — generalized from one enforcement category to three (declarative tables + category-aware grep matchers; the existing escapeRegex + exit-code handling reused):
- retired-primitive import (existing — ADR 0004 §2.6 Clean-Cut Pattern) — behavior unchanged.
- retired config flag (new) — scans
config.template.mjs for a re-added <flag>: leaf( declaration of any of the 8 boot-time auto-* flags removed in #12139 (autoSummarize, autoStartDatabase, autoStartInference, autoDream, autoGoldenPath, realTimeMemoryParsing, autoIngestFileSystem, autoSync). Line-start-anchored so JSDoc/comment mentions don't false-match.
- retired MCP tool (new) — scans
openapi.yaml for a re-added operationId: of manage_database or summarize_sessions. Line-end-anchored so manage_database_v2-style names don't false-match.
Each category prints a premise-correcting failure message naming the owning subsystem + migration ref (#12139 / #12065), so a developer who trips the guard learns the ticket's premise is obsolete rather than resurrecting the primitive. autoStartInference is the canonical trap — its config was string-matched but the auto-start logic was never implemented; the orchestrator owns inference lifecycle (mlx/lms continuous tasks).
test/playwright/unit/ai/scripts/diagnostics/checkRetiredPrimitives.spec.mjs — extended from 2 to 5 tests via a DRY fixture helper: clean-pass + a fail-fixture for each of the three categories + a JSDoc/comment non-false-match guard (falsifying inputs, not just the happy path). Restored test.describe.serial (the negative cases plant on-disk fixtures under ai/ that would otherwise leak across Playwright's parallel workers).
Test Evidence
Evidence: L2 (executed) — npm run test-unit -- …/checkRetiredPrimitives.spec.mjs exits 0 with 5/5 passing on this branch (rebased onto dev with #12197 merged); CI unit SUCCESS on the head commit.
5/5 spec tests pass: clean tree → exit 0 / PASS; config-flag fixture → exit 1 naming retired config flag + autoStartInference; MCP-tool fixture → exit 1 naming retired MCP tool; import fixture → exit 1 (existing behavior intact); JSDoc-comment fixture → exit 0 (no false-match); all fixtures auto-cleaned. node --check clean on both files; both pre-commit gates (check-whitespace, check-shorthand) pass. The guard is the spec's sole consumer, so the output-format generalization breaks nothing else.
Post-Merge Validation
Pure CI/build-time guard — no runtime behavior. On merge, any future PR re-adding one of these flags/tools becomes unmergeable with a self-explaining message naming the orchestrator owner.
This is the specific mechanical defense; the general stale-Agent-OS-ticket risk is addressed by throughput (shrinking the backlog faster than it decays) + per-ticket premise V-B-A at intake. Follow-up candidate (not in scope): a targeted re-triage sweep of the highest-risk behavior-tickets (e.g. the inference server cluster).
Decision Record impact
aligned-with ADR 0004 §2.6 (Clean-Cut Pattern) + §5.6 — extends the same mechanical-enforcement layer from retired modules to retired config flags + MCP tools.
FAIR-band: n/a — operator-directed lane (#12198).
Resolves #12198.
Authored by Claude Opus 4.8 (Claude Code, 1M context).
Summary
Extends the retired-primitive CI guard into a mechanical merge-gate against the "dangerous stale ticket" regression class. The orchestrator daemon is the single source of truth for background memory/KB maintenance; with the Agent OS evolving fast, a backlog ticket older than a week may carry a premise a later migration has obsoleted. A fresh session acting on such a ticket can naively "re-implement the missing config" and resurrect a per-MCP-instance self-trigger — the pattern that caused duplicate background work across harness-spawned instances (Claude Desktop / Codex / Antigravity). A comment can't stop that; a red merge-gate can.
Deltas
ai/scripts/diagnostics/check-retired-primitives.mjs— generalized from one enforcement category to three (declarative tables + category-aware grep matchers; the existingescapeRegex+ exit-code handling reused):config.template.mjsfor a re-added<flag>: leaf(declaration of any of the 8 boot-time auto-* flags removed in #12139 (autoSummarize,autoStartDatabase,autoStartInference,autoDream,autoGoldenPath,realTimeMemoryParsing,autoIngestFileSystem,autoSync). Line-start-anchored so JSDoc/comment mentions don't false-match.openapi.yamlfor a re-addedoperationId:ofmanage_databaseorsummarize_sessions. Line-end-anchored somanage_database_v2-style names don't false-match.Each category prints a premise-correcting failure message naming the owning subsystem + migration ref (
#12139 / #12065), so a developer who trips the guard learns the ticket's premise is obsolete rather than resurrecting the primitive.autoStartInferenceis the canonical trap — its config was string-matched but the auto-start logic was never implemented; the orchestrator owns inference lifecycle (mlx/lms continuous tasks).test/playwright/unit/ai/scripts/diagnostics/checkRetiredPrimitives.spec.mjs— extended from 2 to 5 tests via a DRY fixture helper: clean-pass + a fail-fixture for each of the three categories + a JSDoc/comment non-false-match guard (falsifying inputs, not just the happy path). Restoredtest.describe.serial(the negative cases plant on-disk fixtures underai/that would otherwise leak across Playwright's parallel workers).Test Evidence
Evidence: L2 (executed) —
npm run test-unit -- …/checkRetiredPrimitives.spec.mjsexits 0 with 5/5 passing on this branch (rebased onto dev with #12197 merged); CIunitSUCCESS on the head commit.5/5 spec tests pass: clean tree → exit 0 / PASS; config-flag fixture → exit 1 naming
retired config flag+autoStartInference; MCP-tool fixture → exit 1 namingretired MCP tool; import fixture → exit 1 (existing behavior intact); JSDoc-comment fixture → exit 0 (no false-match); all fixtures auto-cleaned.node --checkclean on both files; both pre-commit gates (check-whitespace,check-shorthand) pass. The guard is the spec's sole consumer, so the output-format generalization breaks nothing else.Post-Merge Validation
Pure CI/build-time guard — no runtime behavior. On merge, any future PR re-adding one of these flags/tools becomes unmergeable with a self-explaining message naming the orchestrator owner.
This is the specific mechanical defense; the general stale-Agent-OS-ticket risk is addressed by throughput (shrinking the backlog faster than it decays) + per-ticket premise V-B-A at intake. Follow-up candidate (not in scope): a targeted re-triage sweep of the highest-risk behavior-tickets (e.g. the
inference servercluster).Decision Record impact
aligned-with ADR 0004§2.6 (Clean-Cut Pattern) + §5.6 — extends the same mechanical-enforcement layer from retired modules to retired config flags + MCP tools.FAIR-band: n/a — operator-directed lane (#12198).
Resolves #12198.
Authored by Claude Opus 4.8 (Claude Code, 1M context).