You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
⚠️ Definition of Done: this issue must be completed in full, in a single PR. Do not split this
work across multiple PRs, and do not defer any Deliverable below to a follow-up issue. A PR that
satisfies only some of the Deliverables, stubs a required test, or leaves a checkbox
partially-done does NOT resolve this issue and will be closed.
Context
.github/workflows/ci.yml runs each drift check as its own path-gated step — db:migrations:check (line 302), db:schema-drift:check (308), docs:drift-check (357), dead-source-files:check (372), regate-sort-key:check (378), branding-drift:check (410), and so on. Several of those steps carry the same
comment: "Same local-only-until-now gap as the drift checks above: nothing in this workflow previously ran it,
so the two could silently diverge with zero CI signal."
Two checks in package.json's test:ci still have that gap:
coco-dev-versions:check → scripts/check-coco-dev-versions.ts. Its own header states it is "wired
into npm run test:ci so a version bump made in only one of the two files (k8s/coco-dev/versions.json, k8s/coco-dev/kbs/base/kustomization.yaml) fails CI instead of silently shipping a KBS deploy that doesn't
match its own recorded version manifest." No CI job runs it. Its only test, test/unit/check-coco-dev-versions-core.test.ts, exercises the pure core against fabricated inputs and
never reads the two real files. .github/workflows/ contains no reference to k8s at all, so no path
filter would trigger such a job either.
Every other entry in test:ci that has no explicit ci.yml step is covered another way — the contract/parity
suites and validate:mcp run inside the main vitest job, the ui:* and build* scripts run via npx turbo
steps, and coverage-boltons:check / validate:no-hand-written-js are enforced by their real-tree tests
above. These two are the only ones with no enforcement path at all.
Requirements
.github/workflows/ci.yml gains a step that runs npm run coco-dev-versions:check, gated on a new cocoDev path-filter output in the changes job matching k8s/coco-dev/** and scripts/check-coco-dev-versions*.ts, plus the standard github.event_name == 'push' clause every other
drift step uses.
.github/workflows/ci.yml gains a step that runs npm run import-specifiers:check, gated on github.event_name == 'push' || needs.changes.outputs.backend == 'true' || needs.changes.outputs.mcp == 'true' || needs.changes.outputs.engine == 'true' || needs.changes.outputs.miner == 'true' || needs.changes.outputs.discoveryIndex == 'true' — the checker scans src, scripts, test and packages
(BUNDLER_ROOTS/NODENEXT_ROOTS), so every filter covering a packages/* workspace must trigger it.
test/unit/check-import-specifiers-script.test.ts gains a real-tree regression assertion so the guard is also
enforced by the vitest suite, not by the workflow step alone.
Each new step carries a comment naming the gap it closes, in the same style as the surrounding steps.
⚠️ Required pattern: copy the shape of the existing "Dead source-file check" step
(.github/workflows/ci.yml:370-373) for the workflow steps, and test/unit/check-coverage-bolt-on-filenames-script.test.ts:51 for the real-tree assertion. What does NOT
satisfy this issue: adding one of the two checks and not the other; running them unconditionally with no
path gate (every other drift step is gated); folding both into an existing step's run: block instead of
giving each its own named step; or editing anything under k8s/ (out of scope — the check reads those files,
it does not need them changed).
Deliverables
.github/workflows/ci.ymlchanges job declares a cocoDev filter output covering k8s/coco-dev/**
and scripts/check-coco-dev-versions*.ts.
.github/workflows/ci.yml has a named step running npm run coco-dev-versions:check, gated on that
filter plus the push clause.
.github/workflows/ci.yml has a named step running npm run import-specifiers:check, gated as specified
above.
npm run actionlint and npm run lint:composite-actions pass on the edited workflow.
All Deliverables above are required in a single PR. A PR that satisfies only some of them — for example adding
the two workflow steps but skipping the real-tree test in Deliverable 4 — does not resolve this issue.
Test Coverage Requirements
.github/workflows/** and scripts/** are OUTSIDE Codecov's coverage.include (which covers src/**, packages/loopover-engine/src/**, packages/loopover-miner/{lib,bin}/**, packages/discovery-index/src/**, packages/loopover-contract/src/** and packages/loopover-mcp/{lib,bin}/**), so Codecov's patch gate does not
apply to the workflow edit or to scripts/check-import-specifiers.ts. Real tests are still required:
Deliverable 4 is a genuine vitest assertion against the real tree, not a placeholder. Do not add no-op or expect(true) tests to satisfy the checkbox.
Expected Outcome
A PR that bumps k8s/coco-dev/versions.json without k8s/coco-dev/kbs/base/kustomization.yaml (or the
reverse) fails CI, as scripts/check-coco-dev-versions.ts's header already claims it does; and a relative
import that drifts from #9221's per-zone convention fails CI on the PR that introduces it, instead of landing
and needing a follow-up like #9240/#9249.
Links & Resources
package.json → test:ci
.github/workflows/ci.yml (the changes job's filters: block; the drift-check steps at lines 355-432)
Context
.github/workflows/ci.ymlruns each drift check as its own path-gated step —db:migrations:check(line 302),db:schema-drift:check(308),docs:drift-check(357),dead-source-files:check(372),regate-sort-key:check(378),branding-drift:check(410), and so on. Several of those steps carry the samecomment: "Same local-only-until-now gap as the drift checks above: nothing in this workflow previously ran it,
so the two could silently diverge with zero CI signal."
Two checks in
package.json'stest:cistill have that gap:coco-dev-versions:check→scripts/check-coco-dev-versions.ts. Its own header states it is "wiredinto
npm run test:ciso a version bump made in only one of the two files (k8s/coco-dev/versions.json,k8s/coco-dev/kbs/base/kustomization.yaml) fails CI instead of silently shipping a KBS deploy that doesn'tmatch its own recorded version manifest." No CI job runs it. Its only test,
test/unit/check-coco-dev-versions-core.test.ts, exercises the pure core against fabricated inputs andnever reads the two real files.
.github/workflows/contains no reference tok8sat all, so no pathfilter would trigger such a job either.
import-specifiers:check→scripts/check-import-specifiers.ts(scripts: unify relative-import specifiers with src/** (extensionless) and add a drift guard #9221). No CI job runs it, andtest/unit/check-import-specifiers-script.test.tsis entirely injection-based(
listSourceFiles/readFilefakes) with no assertion against the real tree — unlike its siblingtest/unit/check-coverage-bolt-on-filenames-script.test.ts:51("the real repo has zero coverage bolt-onfilenames (regression guard)") and
test/unit/validate-no-hand-written-js.test.ts:80-82("The real gate,run against the real tree"), both of which close the same gap for their own checks. This is not theoretical:
chore(imports): packages/loopover-ui-kit drifted from #9221's extension convention (introduced by #9239) #9240 and chore(imports): test/unit/engine-coverage-script.test.ts drifted from #9221's extension convention (introduced by #9245) #9249 are two separate drifts that landed after scripts: unify relative-import specifiers with src/** (extensionless) and add a drift guard #9221 shipped the guard.
Every other entry in
test:cithat has no explicit ci.yml step is covered another way — the contract/paritysuites and
validate:mcprun inside the main vitest job, theui:*andbuild*scripts run vianpx turbosteps, and
coverage-boltons:check/validate:no-hand-written-jsare enforced by their real-tree testsabove. These two are the only ones with no enforcement path at all.
Requirements
.github/workflows/ci.ymlgains a step that runsnpm run coco-dev-versions:check, gated on a newcocoDevpath-filter output in thechangesjob matchingk8s/coco-dev/**andscripts/check-coco-dev-versions*.ts, plus the standardgithub.event_name == 'push'clause every otherdrift step uses.
.github/workflows/ci.ymlgains a step that runsnpm run import-specifiers:check, gated ongithub.event_name == 'push' || needs.changes.outputs.backend == 'true' || needs.changes.outputs.mcp == 'true' || needs.changes.outputs.engine == 'true' || needs.changes.outputs.miner == 'true' || needs.changes.outputs.discoveryIndex == 'true'— the checker scanssrc,scripts,testandpackages(
BUNDLER_ROOTS/NODENEXT_ROOTS), so every filter covering apackages/*workspace must trigger it.test/unit/check-import-specifiers-script.test.tsgains a real-tree regression assertion so the guard is alsoenforced by the vitest suite, not by the workflow step alone.
Deliverables
.github/workflows/ci.ymlchangesjob declares acocoDevfilter output coveringk8s/coco-dev/**and
scripts/check-coco-dev-versions*.ts..github/workflows/ci.ymlhas a named step runningnpm run coco-dev-versions:check, gated on thatfilter plus the push clause.
.github/workflows/ci.ymlhas a named step runningnpm run import-specifiers:check, gated as specifiedabove.
test/unit/check-import-specifiers-script.test.tscontains a real-tree regression test that callsfindImportSpecifierViolations()with NO injectedlistSourceFiles/readFileand asserts the result is[], with a comment naming chore(imports): packages/loopover-ui-kit drifted from #9221's extension convention (introduced by #9239) #9240/chore(imports): test/unit/engine-coverage-script.test.ts drifted from #9221's extension convention (introduced by #9245) #9249 as the drifts that reached main while the guard was local-only.npm run actionlintandnpm run lint:composite-actionspass on the edited workflow.All Deliverables above are required in a single PR. A PR that satisfies only some of them — for example adding
the two workflow steps but skipping the real-tree test in Deliverable 4 — does not resolve this issue.
Test Coverage Requirements
.github/workflows/**andscripts/**are OUTSIDE Codecov'scoverage.include(which coverssrc/**,packages/loopover-engine/src/**,packages/loopover-miner/{lib,bin}/**,packages/discovery-index/src/**,packages/loopover-contract/src/**andpackages/loopover-mcp/{lib,bin}/**), so Codecov's patch gate does notapply to the workflow edit or to
scripts/check-import-specifiers.ts. Real tests are still required:Deliverable 4 is a genuine vitest assertion against the real tree, not a placeholder. Do not add
no-oporexpect(true)tests to satisfy the checkbox.Expected Outcome
A PR that bumps
k8s/coco-dev/versions.jsonwithoutk8s/coco-dev/kbs/base/kustomization.yaml(or thereverse) fails CI, as
scripts/check-coco-dev-versions.ts's header already claims it does; and a relativeimport that drifts from #9221's per-zone convention fails CI on the PR that introduces it, instead of landing
and needing a follow-up like #9240/#9249.
Links & Resources
package.json→test:ci.github/workflows/ci.yml(thechangesjob'sfilters:block; the drift-check steps at lines 355-432)scripts/check-coco-dev-versions.ts(header, lines 1-5),scripts/check-import-specifiers.tstest/unit/check-coverage-bolt-on-filenames-script.test.ts:51,test/unit/validate-no-hand-written-js.test.ts:80