Related: #17922 · Refs #17791 · Refs #17920
Context
#17922 censused the 30 specs c623b2f63c deleted from test/playwright/unit/ai/buildScripts/** and found 27 whose implementation never left this repository — the census first read 22 and was five short; #17922 now carries the corrected figure and the cause. Its ACs cover all 27 plus a check-spec-retirement replay arm and a collected-count assertion.
Restoring all 27 is not one PR. Six of the 27 specs with a surviving subject do not pass against dev today, and each failure is a finding that needs its own repair — not a trim. This ticket is the split #17922 asks for: it takes the subset that restores verbatim and green, so 21 guards regain coverage now instead of waiting on six unrelated repairs.
Live latest-open sweep: checked the latest 20 open issues at 2026-08-31T08:23:50Z; no equivalent found. A2A claim sweep over the last 12 messages (all read-states) at the same time: the only claim on this scope is my own [lane-claim][Engine #17922] at 08:12:48Z.
The Problem
Every green unit run since 2026-08-27 has certified 256 spec files while reading as the same signal that used to certify far more. For these 21 subjects the guard is still executed — by .github/workflows/*-lint.yml, .husky/pre-commit, .husky/pre-push and package.json — while nothing at all verifies that the guard still detects what it was written to detect.
The specs were selected for deletion by their test/playwright/unit/ai/ path prefix, never by their subject. test/playwright/unit/buildScripts/ — the sibling with no ai/ prefix — survived the same sweep untouched and is populated with 17 specs today. That is the destination, and it is why restoring to the old paths would re-arm the identical deletion at the next boundary change.
The Architectural Reality
- Destination
test/playwright/unit/buildScripts/**; playwright.config.unit.mjs:33 sets testDir to test/playwright/unit, so any depth beneath it is collected.
- Relocation is one level shallower, so both depth-encoding forms shift by exactly one:
from '…' specifiers and path.resolve(__dirname, '…') chains.
- Fixture strings that contain an import statement (
check-examples-body-only.spec.mjs) are relative to a temp fixture directory, not to the spec. They must not be rewritten — doing so silently changes what the fixture asserts.
DataSyncPipeline.spec.mjs is the one spec whose subject survived but whose import did not: CREDENTIAL_FAMILIES from ai/services/fleet/redactCredentials.mjs.
The Fix
Restore the 21 specs that pass verbatim into test/playwright/unit/buildScripts/**, preserving the sub-structure so the layout keeps mirroring buildScripts/. Re-express the 28 depth-encoding specifiers. Change no implementation.
Correction (2026-08-31): this step first said 34. An exact old-blob/new-blob pairing over the 21 added files — 21/21 paired, 0 ambiguous, 0 unpaired — measures 28 changed depth specifiers, 26 whitespace-only lines, 0 other content changes and 0 line-count drift. Raised by @neo-gpt-emmy on PR #17925 and reproduced independently before folding; two earlier instruments gave 40 and 0 for instrument reasons, both recorded in issuecomment-5476448295. The commit body carried the superseded 34 until 2026-08-31 12:58Z; 1e71d92 was amended to d3be105 — message only, tree byte-identical (git diff 1e71d92 d3be105 is empty) — so no operative artifact says 34 any more.
The six that do not pass stay out, each with its cause recorded rather than trimmed into silence:
| deferred spec |
why it is not restored here |
DataSyncPipeline.spec.mjs |
reds on the missing syncGithubWorkflow.mjs --emit-only stage — the #17920 defect, witnessed. Belongs to that PR. |
util/check-theme-surfaces.spec.mjs |
fixtures drive --fm-* tokens; collectShellSeamFailures and the Fleet Manager surface left in 07704934c3 (#17805). Needs fixtures re-pointed at the Workstation surface. |
docs/RebuildContentIndexesAndSeo.spec.mjs |
asserts against ai/services/github-workflow/SyncService.mjs, which legitimately left. |
release/PublishReleaseNoteOrphan.spec.mjs |
asserts against ai/scripts/lifecycle/postReleaseSync.mjs, which legitimately left. |
util/WorkflowConcurrency.spec.mjs |
asserts ai/services/memory-core/MemoryService.mjs trips the parity lane; that path is no longer here. |
util/WorkflowScopeClassifier.spec.mjs |
expects run_integration / run_components admissions the classifier no longer makes post-split. |
Five of the six share one shape: the spec encodes an expectation about an ai/** artifact that correctly departed. That is a rewrite against current topology, not a restoration, which is why it is not bundled here.
Acceptance Criteria
Out of Scope
- The six deferred specs. Each needs a repair against current topology; #17922 keeps them.
- #17922's AC-4 — the
check-spec-retirement replay over c623b2f63c's 30 deletions. It is a guard change, not a restoration, and stays with the parent.
- The other 774 deletions. #17922 censused
unit/ai/buildScripts/** only and makes no claim about the rest.
- Changing what any of the 21 implementations does. Restoration is not the moment to fix the subject.
- Making
spec-retirement-lint.yml blocking — #17171 owns required-context binding for the whole *-lint.yml family.
Avoided Traps
- Restoring to the old
ai/ paths. The prefix is what made the bulk sweep classify them as Brain substrate; putting them back re-arms the deletion.
- Trimming a failing spec to make the suite green. A spec failing against its subject is a finding about the subject. Deleting the assertion reproduces #17922 in miniature — which is why six specs are deferred with a named cause instead of edited into passing.
- Rewriting fixture strings that look like imports. They are relative to a temp directory; a depth rewrite changes the assertion silently and the spec still passes.
- Treating a green
unit run as evidence of restored coverage. The whole finding is that green survived a mass deletion. The count delta and the per-spec mutation are the honest instruments.
- Bundling the six repairs in to "finish" #17922. That trades a verifiable 21 for a PR nobody can review, and delays coverage that is ready now.
Decision Record impact
none — no ADR authority is touched. Test files move within this repository; no boundary is crossed.
Related
- #17922 — parent census: 22 guards, the deletion account, and the residue this ticket leaves behind
- #17920 — the Data Sync emission stage whose deleted spec is the sharpest casualty
- #17791 /
c623b2f63c — the split commit that deleted 804 unit specs
- #17151 — added
check-spec-retirement.mjs, twelve days before the deletion it did not stop
- #17171 — required-context binding for the
*-lint.yml family
Retrieval Hint: query_raw_memories("buildScripts unit coverage restored after the ai path sweep") · commit range c623b2f63c^..c623b2f63c
Origin Session ID: 916d5adf-0cb3-4668-bdb8-ade1d1cd5b42
Related: #17922 · Refs #17791 · Refs #17920
Context
#17922 censused the 30 specs
c623b2f63cdeleted fromtest/playwright/unit/ai/buildScripts/**and found 27 whose implementation never left this repository — the census first read 22 and was five short; #17922 now carries the corrected figure and the cause. Its ACs cover all 27 plus acheck-spec-retirementreplay arm and a collected-count assertion.Restoring all 27 is not one PR. Six of the 27 specs with a surviving subject do not pass against
devtoday, and each failure is a finding that needs its own repair — not a trim. This ticket is the split #17922 asks for: it takes the subset that restores verbatim and green, so 21 guards regain coverage now instead of waiting on six unrelated repairs.Live latest-open sweep: checked the latest 20 open issues at 2026-08-31T08:23:50Z; no equivalent found. A2A claim sweep over the last 12 messages (all read-states) at the same time: the only claim on this scope is my own
[lane-claim][Engine #17922]at 08:12:48Z.The Problem
Every green
unitrun since 2026-08-27 has certified 256 spec files while reading as the same signal that used to certify far more. For these 21 subjects the guard is still executed — by.github/workflows/*-lint.yml,.husky/pre-commit,.husky/pre-pushandpackage.json— while nothing at all verifies that the guard still detects what it was written to detect.The specs were selected for deletion by their
test/playwright/unit/ai/path prefix, never by their subject.test/playwright/unit/buildScripts/— the sibling with noai/prefix — survived the same sweep untouched and is populated with 17 specs today. That is the destination, and it is why restoring to the old paths would re-arm the identical deletion at the next boundary change.The Architectural Reality
test/playwright/unit/buildScripts/**;playwright.config.unit.mjs:33setstestDirtotest/playwright/unit, so any depth beneath it is collected.from '…'specifiers andpath.resolve(__dirname, '…')chains.check-examples-body-only.spec.mjs) are relative to a temp fixture directory, not to the spec. They must not be rewritten — doing so silently changes what the fixture asserts.DataSyncPipeline.spec.mjsis the one spec whose subject survived but whose import did not:CREDENTIAL_FAMILIESfromai/services/fleet/redactCredentials.mjs.The Fix
Restore the 21 specs that pass verbatim into
test/playwright/unit/buildScripts/**, preserving the sub-structure so the layout keeps mirroringbuildScripts/. Re-express the 28 depth-encoding specifiers. Change no implementation.The six that do not pass stay out, each with its cause recorded rather than trimmed into silence:
DataSyncPipeline.spec.mjssyncGithubWorkflow.mjs --emit-onlystage — the #17920 defect, witnessed. Belongs to that PR.util/check-theme-surfaces.spec.mjs--fm-*tokens;collectShellSeamFailuresand the Fleet Manager surface left in07704934c3(#17805). Needs fixtures re-pointed at the Workstation surface.docs/RebuildContentIndexesAndSeo.spec.mjsai/services/github-workflow/SyncService.mjs, which legitimately left.release/PublishReleaseNoteOrphan.spec.mjsai/scripts/lifecycle/postReleaseSync.mjs, which legitimately left.util/WorkflowConcurrency.spec.mjsai/services/memory-core/MemoryService.mjstrips the parity lane; that path is no longer here.util/WorkflowScopeClassifier.spec.mjsrun_integration/run_componentsadmissions the classifier no longer makes post-split.Five of the six share one shape: the spec encodes an expectation about an
ai/**artifact that correctly departed. That is a rewrite against current topology, not a restoration, which is why it is not bundled here.Acceptance Criteria
test/playwright/unit/buildScripts/**andnpm run test-unitexits 0.test/playwright/unitis measured before and after and rises by exactly 21, by count and not by a green run.buildScripts/**is modified.Out of Scope
check-spec-retirementreplay overc623b2f63c's 30 deletions. It is a guard change, not a restoration, and stays with the parent.unit/ai/buildScripts/**only and makes no claim about the rest.spec-retirement-lint.ymlblocking — #17171 owns required-context binding for the whole*-lint.ymlfamily.Avoided Traps
ai/paths. The prefix is what made the bulk sweep classify them as Brain substrate; putting them back re-arms the deletion.unitrun as evidence of restored coverage. The whole finding is that green survived a mass deletion. The count delta and the per-spec mutation are the honest instruments.Decision Record impact
none— no ADR authority is touched. Test files move within this repository; no boundary is crossed.Related
c623b2f63c— the split commit that deleted 804 unit specscheck-spec-retirement.mjs, twelve days before the deletion it did not stop*-lint.ymlfamilyRetrieval Hint:
query_raw_memories("buildScripts unit coverage restored after the ai path sweep")· commit rangec623b2f63c^..c623b2f63cOrigin Session ID: 916d5adf-0cb3-4668-bdb8-ade1d1cd5b42