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
finding(pm): dispatch-gates does not derive check:driver-memory-census for a change that trips it — the local family went green and CI found the red #15312
Filed unassigned. Surfaced by the #15232 dev seat, which recorded it in its own report rather than glossing over it — that is the behaviour worth keeping, and this card is the follow-through.
What happened
PR #15282 added packages/plugins/plugin-dev/src/dev-i18n-packages-reader.test.ts, whose line 57 carried vi.mock('@objectstack/driver-memory', …) — copied from that package's sibling harnesses, part of the #3060 "mock every optional package absent" convention.
The seat derived and ran its gate family the way the dispatch contract requires:
53 of 57 exit 0, the other 4 explicitly NOT MEASURED with stated prerequisites. check:driver-memory-census was not among the 57. CI's Lint & Repo Gates then failed on it (job 100960342355):
x LEDGERED: packages/plugins/plugin-dev/src/dev-i18n-packages-reader.test.ts:57 binds
@objectstack/driver-memory (mock) and the ledger does not cover it.
The gate counts vi.mock as a module DECLARATION (its own self-test says so, alongside import / require / dynamic import), and @objectstack/driver-memory's consumer set is locked by maintainer rulings (#5499 froze the driver, #5704 and #6664 ruled the two consumers that stay). A new binding is a red by design.
The defect was real and the seat fixed it correctly — migrated, not ledgered: the mock was redundant, since dev-plugin.ts's one import of that package sits inside if (enabled('driver')) and both boot cases pass services: { driver: false }. Deleting it returned the census to 2 ruled consumers with the ledger file untouched.
Why it is worth a card
The derivation exists so a seat can measure the same things CI will, before pushing. A gate that CI runs and the derivation does not offer inverts that: the local run's green is not evidence, and the seat learns about the failure a cycle later. Same shape as the artifact-roster problem dispatch-gates already reports on itself —
Each declares only tracked FILES — a baseline, an allowlist of the members it already has … no path you pass can move them … ⛔ never read their silence as a clearance.
— except this one does not even appear in the roster block, so there is nothing for a seat to read and decline.
What to look at
Whether check:driver-memory-census declares a scan surface dispatch-gates can match on. Its subject is any module binding anywhere under packages/**, which is a whole-tree predicate — the same class the tool already handles with its "declared WHOLE-TREE and named on every card" bucket (6 families on the finding(agents): a PM-dispatched issue arrives already assigned, and AGENTS.md tells the dev seat that means "taken" #15287 derivation). If it belongs in that bucket, adding it there is the whole fix.
Whether other census/ledger gates in scripts/ have the same shape and are equally invisible. Worth answering by enumeration rather than one at a time: the question is "which gates does CI run that no dispatch-gates derivation can name", and it should be answerable mechanically.
⚠️ Do not fix this by widening what the seat is told to run by hand. The point of the derivation is that the list is computed; a prose instruction to "also remember to run the census gates" reproduces exactly the failure it is meant to remove.
Not to be confused with
This is not the gate misbehaving. check:driver-memory-census did its job — it caught a real new binding on a frozen package, and its message correctly refused the bookkeeping shortcut ("Do NOT add an entry to make this green"). The gap is in what dispatch-gates offers a seat before the push.
Related: #15294 (a rule two contract reviews had to reconstruct because it was never written down) is the same family of problem — something CI or precedent enforces that the tooling does not hand you.
Filed unassigned. Surfaced by the #15232 dev seat, which recorded it in its own report rather than glossing over it — that is the behaviour worth keeping, and this card is the follow-through.
What happened
PR #15282 added
packages/plugins/plugin-dev/src/dev-i18n-packages-reader.test.ts, whose line 57 carriedvi.mock('@objectstack/driver-memory', …)— copied from that package's sibling harnesses, part of the #3060 "mock every optional package absent" convention.The seat derived and ran its gate family the way the dispatch contract requires:
53 of 57 exit 0, the other 4 explicitly NOT MEASURED with stated prerequisites.
check:driver-memory-censuswas not among the 57. CI'sLint & Repo Gatesthen failed on it (job 100960342355):The gate counts
vi.mockas a module DECLARATION (its own self-test says so, alongside import / require / dynamic import), and@objectstack/driver-memory's consumer set is locked by maintainer rulings (#5499 froze the driver, #5704 and #6664 ruled the two consumers that stay). A new binding is a red by design.The defect was real and the seat fixed it correctly — migrated, not ledgered: the mock was redundant, since
dev-plugin.ts's one import of that package sits insideif (enabled('driver'))and both boot cases passservices: { driver: false }. Deleting it returned the census to 2 ruled consumers with the ledger file untouched.Why it is worth a card
The derivation exists so a seat can measure the same things CI will, before pushing. A gate that CI runs and the derivation does not offer inverts that: the local run's green is not evidence, and the seat learns about the failure a cycle later. Same shape as the artifact-roster problem
dispatch-gatesalready reports on itself —— except this one does not even appear in the roster block, so there is nothing for a seat to read and decline.
What to look at
check:driver-memory-censusdeclares a scan surfacedispatch-gatescan match on. Its subject is any module binding anywhere underpackages/**, which is a whole-tree predicate — the same class the tool already handles with its "declared WHOLE-TREE and named on every card" bucket (6 families on the finding(agents): a PM-dispatched issue arrives already assigned, and AGENTS.md tells the dev seat that means "taken" #15287 derivation). If it belongs in that bucket, adding it there is the whole fix.scripts/have the same shape and are equally invisible. Worth answering by enumeration rather than one at a time: the question is "which gates does CI run that nodispatch-gatesderivation can name", and it should be answerable mechanically.Not to be confused with
This is not the gate misbehaving.
check:driver-memory-censusdid its job — it caught a real new binding on a frozen package, and its message correctly refused the bookkeeping shortcut ("Do NOT add an entry to make this green"). The gap is in whatdispatch-gatesoffers a seat before the push.Related: #15294 (a rule two contract reviews had to reconstruct because it was never written down) is the same family of problem — something CI or precedent enforces that the tooling does not hand you.