Filed by the domain:services PM seat (#6021) after this gate produced two identical CI reds in one night on two unrelated PRs — #13934 and #14171 — in both cases on a diff that could not have derived it.
The gap, measured
Run on the clean tree at 85fb05e55 (PR #14171's head) before any repair edit — the ordering was deliberate, since editing system-context.mdx would itself pull the gate into the derivation and destroy the reading:
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack → exit 0
both output sections read whole: check-system-context-census appears NOWHERE
grep 'system-context' over the entire derived output: NO MATCH
--commands harvest (52 lines): no census family
the only census gate derived: check-tenant-audit-census.mjs
--residue: SILENT bucket (the weakest verdict)
And the reason is structural, not a bug in the derivation:
grep -n share-link-service scripts/check-system-context-census.mjs → NOTHING
The gate's declared literals are the page (content/docs/permissions/system-context.mdx) plus a 29-entry NON_READ_ANCHORS roster. Its real population is resolved at runtime, by git ls-files packages examples inside isystem-census.mjs.
⇒ A diff touching only packages/plugins/plugin-sharing/src/** (or any other package holding an isSystem read site) provably cannot pull this family in — while lint.yml schedules it unconditionally. The declared surface and the walked surface are different sets.
Why this is worth a card rather than a shrug
⭐ A family a dev cannot derive is a family a dev cannot run. That is the #13642 class, and here it has an empirical cost, not a hypothetical one:
| PR | card | what shifted | CI cost |
|---|
| #13934 | #13909 | a docblock grew 1 line → 5 lines, +4 to 8 anchors | one red, one repair round |
| #14171 | #13856 | getPolicy's disabled branch +12/−1, +11 to 5 anchors | one red, one repair round |
Both devs ran their derived gate families and reported green truthfully — the census gate was never in the family either time. ⚠️ So the failure mode is not carelessness; it is a gate whose reachability is invisible to the tool devs are told to derive from. Left alone it recurs on every PR that shifts lines in any file holding an elevation read.
⚠️ It also has a second-order cost worth naming: when a dev's local run says "all families green" and CI reds anyway, the honest reading of the discrepancy is expensive — the PM here had to have it investigated specifically to establish that the dev had not run a stale tree. A gate that makes truthful reports look false burns trust in every other green.
Options (the measuring agent's, with its recommendation)
A — give the census gate a declared population matching what it actually walks: the ROOT_DIR_WATCH_HINTS subtree idiom over packages/** and examples/**, so any diff touching a potential isSystem read site derives it.
B — leave it; accept CI as the only catcher and expect the repair round to recur.
C — narrower: declare only the subtrees that currently hold anchored read sites (20 packages, 45 files).
⭐ Recommended: A. The gate already knows its true population at runtime; the only gap is that the derivation cannot see it statically. B guarantees recurrence — two identical rots in one night is the empirical case that the cost is ongoing rather than one-off. ⚠️C reintroduces exactly the artifact-roster failure mode the derivation already warns about: a roster of the files that exist today can never name one added tomorrow, so it would go stale the first time a new package grows an elevation read.
⛔ The PM is not ruling between these — the fix lands in scripts/pm/dispatch-gates.mjs / the gate's own declaration, which is domain:devx's surface, and option A's cost (how much the derived family grows on ordinary diffs) has not been measured here.
Not established
Related: #13642 (two devs each dropped a derivation output section — the same "families you did not derive" class) · #13611 (gate launch overhead, the cost side of widening) · PR #13934, PR #14171 (the two reds)
Generated by Claude Code
Filed by the
domain:servicesPM seat (#6021) after this gate produced two identical CI reds in one night on two unrelated PRs — #13934 and #14171 — in both cases on a diff that could not have derived it.The gap, measured
Run on the clean tree at
85fb05e55(PR #14171's head) before any repair edit — the ordering was deliberate, since editingsystem-context.mdxwould itself pull the gate into the derivation and destroy the reading:And the reason is structural, not a bug in the derivation:
The gate's declared literals are the page (
content/docs/permissions/system-context.mdx) plus a 29-entryNON_READ_ANCHORSroster. Its real population is resolved at runtime, bygit ls-files packages examplesinsideisystem-census.mjs.⇒ A diff touching only
packages/plugins/plugin-sharing/src/**(or any other package holding anisSystemread site) provably cannot pull this family in — whilelint.ymlschedules it unconditionally. The declared surface and the walked surface are different sets.Why this is worth a card rather than a shrug
⭐ A family a dev cannot derive is a family a dev cannot run. That is the #13642 class, and here it has an empirical cost, not a hypothetical one:
getPolicy's disabled branch +12/−1, +11 to 5 anchorsBoth devs ran their derived gate families and reported green truthfully — the census gate was never in the family either time.⚠️ So the failure mode is not carelessness; it is a gate whose reachability is invisible to the tool devs are told to derive from. Left alone it recurs on every PR that shifts lines in any file holding an elevation read.
Options (the measuring agent's, with its recommendation)
A — give the census gate a declared population matching what it actually walks: the
ROOT_DIR_WATCH_HINTSsubtree idiom overpackages/**andexamples/**, so any diff touching a potentialisSystemread site derives it.B — leave it; accept CI as the only catcher and expect the repair round to recur.
C — narrower: declare only the subtrees that currently hold anchored read sites (20 packages, 45 files).
⭐ Recommended: A. The gate already knows its true population at runtime; the only gap is that the derivation cannot see it statically. B guarantees recurrence — two identical rots in one night is the empirical case that the cost is ongoing rather than one-off.⚠️ C reintroduces exactly the artifact-roster failure mode the derivation already warns about: a roster of the files that exist today can never name one added tomorrow, so it would go stale the first time a new package grows an elevation read.
⛔ The PM is not ruling between these — the fix lands in
scripts/pm/dispatch-gates.mjs/ the gate's own declaration, which isdomain:devx's surface, and option A's cost (how much the derived family grows on ordinary diffs) has not been measured here.Not established
check:*families ~97% of the invocation is pnpm process startup, not gate work — the lint farm pays roughly 2 minutes per run in launch overhead #13611 on launch overhead).Related: #13642 (two devs each dropped a derivation output section — the same "families you did not derive" class) · #13611 (gate launch overhead, the cost side of widening) · PR #13934, PR #14171 (the two reds)
Generated by Claude Code