Context
Filed 2026-08-07 from the #16515 census (chapter 3b/4). 2026-08-08 intake correction (same author, next session): the original premise is falsified by the precise instrument — this body is rewritten to the verified state; the original text is preserved in the edit history. The original claims were "7 overlay-import instances exist under test/ at head" and "the class has no mechanical guard (ADR-0019 §7 omits C3)". Both halves were instrument errors:
- The census command was
rg -l "\.\./config\.mjs'|/ai/config\.mjs'" — a STRING grep, listing every file that mentions the pattern. All 7 hits at head ac1c197648 are test-SUBJECT occurrences: fixture strings written into temp roots (initTier1ConfigMigration, initServerConfigs), lint-fixture sources (lintConfigTemplateSsot), bootstrap path-lists (bootstrapWorktree), policy assertions (ContentPolicy asserts /ai/config.mjs is a forbidden asset path), a daemon config-loading assertion (daemon.spec), and one comment (TenantRepoSyncService.spec:4539). Zero are config-source imports.
- A mechanical guard EXISTS and predates this ticket by two months:
ai/scripts/lint/lint-config-template-ssot.mjs (origin #12451, 2026-06-04) scans test/ (TEST_SCAN_ROOT_REL, :62) with AST-resolved import semantics — its "test config-authority" rule is exactly C3, precise against fixtures/comments (its own spec proves commented-out imports and /tmp paths pass while real overlay imports flag). Run receipt at head: [lint-config-template-ssot] OK — … 0 test config-authority violation(s).
The Problem (corrected — two narrow, real gaps)
- The guard cannot fire on the files it guards.
.github/workflows/config-template-ssot-lint.yml path-filters both triggers on ai/**/config.template.mjs · ai/**/configBase.mjs · the parity JSON · the lint itself · the workflow itself — test/** is absent. A PR introducing a real overlay import in a test touches none of the watched paths, so the workflow never runs on it; the violation lands ungated and turns the NEXT unrelated template-touching PR red (late, misattributed enforcement). The workflow's own configBase comment names this exact class: "the guard present, correct, and never run."
- ADR-0019 self-describes its lint coverage and has drifted. §7 scopes the lint to
A1·A4·A5·A6·A7·B1·B3·B4·B5(partial)·C1 — the shipped test config-authority (C3) rule is absent from the record — and §3's C3 row still carries the stale [live: #11976] tag (that ticket closed; the live state is "guarded, 0 at head").
The Fix
- Add
test/** to the workflow's pull_request and push path filters (plus any scanned surface the filter provably misses), so the red fires ON the introducing PR.
- Truth-fold ADR-0019: §7's lint list gains the test config-authority (C3) rule; §3's C3 row tag updated to the guarded/zero state.
- Receipts: lint green at current head recorded; a synthetic reintroduction red-proven locally in the PR.
Acceptance Criteria
Out of Scope
- The sibling path-filtered lint workflows (
mcp-test-location-lint.yml, retry-bound-classification-lint.yml) plausibly share the trigger-gap pattern — separate audit, not this ticket.
- The other census findings (#16515 chapter 4 carries their dispositions; #16515 gets a correction comment for the string-grep instrument error).
Decision Record impact
ADR-0019 §3 (C3 row tag) + §7 (lint-coverage list) truth-fold — recording shipped reality, no decision change.
Related
#16515 (the census — instrument-error correction owed there), #11976 (closed predecessor — reference), #12451 (the lint's origin), ADR-0019.
Origin Session ID: 84d669f4-2271-4d6a-8878-45e8754be6b3 (filing) · e7da18d8-1563-4ab8-9b88-75afc13aa74e (intake correction + drive)
Retrieval Hint: query_raw_memories("C3 overlay import lint workflow path filter test config-authority guard present never run")
Context
Filed 2026-08-07 from the #16515 census (chapter 3b/4). 2026-08-08 intake correction (same author, next session): the original premise is falsified by the precise instrument — this body is rewritten to the verified state; the original text is preserved in the edit history. The original claims were "7 overlay-import instances exist under
test/at head" and "the class has no mechanical guard (ADR-0019 §7 omits C3)". Both halves were instrument errors:rg -l "\.\./config\.mjs'|/ai/config\.mjs'"— a STRING grep, listing every file that mentions the pattern. All 7 hits at headac1c197648are test-SUBJECT occurrences: fixture strings written into temp roots (initTier1ConfigMigration,initServerConfigs), lint-fixture sources (lintConfigTemplateSsot), bootstrap path-lists (bootstrapWorktree), policy assertions (ContentPolicyasserts/ai/config.mjsis a forbidden asset path), a daemon config-loading assertion (daemon.spec), and one comment (TenantRepoSyncService.spec:4539). Zero are config-source imports.ai/scripts/lint/lint-config-template-ssot.mjs(origin #12451, 2026-06-04) scanstest/(TEST_SCAN_ROOT_REL,:62) with AST-resolved import semantics — its "test config-authority" rule is exactly C3, precise against fixtures/comments (its own spec proves commented-out imports and/tmppaths pass while real overlay imports flag). Run receipt at head:[lint-config-template-ssot] OK — … 0 test config-authority violation(s).The Problem (corrected — two narrow, real gaps)
.github/workflows/config-template-ssot-lint.ymlpath-filters both triggers onai/**/config.template.mjs·ai/**/configBase.mjs· the parity JSON · the lint itself · the workflow itself —test/**is absent. A PR introducing a real overlay import in a test touches none of the watched paths, so the workflow never runs on it; the violation lands ungated and turns the NEXT unrelated template-touching PR red (late, misattributed enforcement). The workflow's own configBase comment names this exact class: "the guard present, correct, and never run."A1·A4·A5·A6·A7·B1·B3·B4·B5(partial)·C1— the shipped test config-authority (C3) rule is absent from the record — and §3's C3 row still carries the stale[live: #11976]tag (that ticket closed; the live state is "guarded, 0 at head").The Fix
test/**to the workflow'spull_requestandpushpath filters (plus any scanned surface the filter provably misses), so the red fires ON the introducing PR.Acceptance Criteria
npm run ai:lint-config-template-ssotlocally (red-proven, receipt in the PR body).test/**, so the introducing PR runs the lint.Out of Scope
mcp-test-location-lint.yml,retry-bound-classification-lint.yml) plausibly share the trigger-gap pattern — separate audit, not this ticket.Decision Record impact
ADR-0019 §3 (C3 row tag) + §7 (lint-coverage list) truth-fold — recording shipped reality, no decision change.
Related
#16515 (the census — instrument-error correction owed there), #11976 (closed predecessor — reference), #12451 (the lint's origin), ADR-0019.
Origin Session ID: 84d669f4-2271-4d6a-8878-45e8754be6b3 (filing) · e7da18d8-1563-4ab8-9b88-75afc13aa74e (intake correction + drive)
Retrieval Hint:
query_raw_memories("C3 overlay import lint workflow path filter test config-authority guard present never run")