inherited-population — the declared remedy for a followed module contributing a population its caller never opens — is keyed on the MODULE, while whether the contribution is fabricated is a property of the CALLER. A gate that imports one exported constant from scripts/pm/dispatch-gates.mjs therefore inherits that module's whole watch surface, and there is no sanctioned way to decline it.
Measured, on the live tree
scripts/pm/check-clause2-carriers.mjs gained one line — import { CONTRACT_REVIEW_TIER } from './dispatch-gates.mjs'; — and nothing else that names a path. Ablation, both legs on the committed tree, restoring by blob hash:
base (no import) -> check:pm-clause2-carriers hints: []
head (with import) -> check:pm-clause2-carriers hints: [".github/workflows"]
entry.imports for the family reads ["scripts/pm/dispatch-gates.mjs"], and entry.hintOrigin is {}. The gate never opens .github/workflows; its CI step runs the checker's own --self-test.
Why that is the shape the derivation says it refuses
firstPartyImportTargets' own docblock states the direction, verbatim:
The refusal costs recall in one direction and that is worth naming … and a missing lead costs one card one CI round — the side this file's header errs on everywhere.
and declaredInheritedPopulation's states the harm the marker exists against:
It is wrong for a module whose literals are join bases it builds paths from, or a declaration table it exports for some other purpose: the importer never opens those trees, so every pair they contribute is a fabricated lead in the column a dispatch prompt pastes.
That is exactly this case, and the marker cannot reach it: the same module's globs are a real population for check:pm-widening-tells, which imports SUSPECT_TIER_GLOBS and reads them. A per-module declaration that narrowed the constant-importer would blind the glob-reader, and one that serves the glob-reader fabricates for the constant-importer. ⛔ One declaration cannot be both.
The guard that exists does not fire here, and that is a second reading
discoverFamilies already carries if (entry.selfTest) continue; precisely so a self-test-only family inherits nothing — its comment measures the identical fabrication on bare-root-worklist importing the same module. But entry.selfTest is read off the workflow argv:
selfTest: Boolean(argv) && argv.args.split(/[ \t]+/).includes('--self-test'),
lint.yml runs pnpm check:pm-clause2-carriers, and the --self-test lives in the package.json script body (node scripts/pm/check-clause2-carriers.mjs --self-test). So the flag is invisible to the derivation, entry.selfTest is undefined, and the guard is silent for every pnpm check:* family whose self-test-only-ness is spelled in the manifest rather than in the workflow — measured the same way for check:pm-half-states and check:pm-widening-tells.
Why this is not #11556 again
#11556 (closed) measured the same class from bare-root-worklist and landed inherited-population as the remedy. That remedy is live and correct for what it was built for. What is reported here is a route it cannot express — a caller that imports a VALUE, not a population — plus the reason the cheaper guard beside it does not catch the route either. ⛔ Not a request to revert #11556's follow.
Consequence today
One live fabricated lead, in a column a dispatch prompt pastes: a card touching .github/workflows/** is told to run pnpm check:pm-clause2-carriers. Cheap to run and wrong to believe. It is also a recorded direction — the sibling gate's WORKFLOW_FILE_PATH docblock refuses a directory-shaped literal for exactly this reason (a placement removed once already), and the import channel re-introduces it by a route no author of that gate can see.
Shapes, offered ⛔ not asserted
Three, unmeasured and unranked: make the selfTest reading resolve a pnpm script through package.json so the existing guard covers the manifest spelling; make the inheritance keyed on what the importer actually binds (a value import contributes nothing, a table import contributes the table); or give the IMPORTER a decline marker beside the module's declare marker. ⛔ Each is a change to a derivation whose refusals are all measured, so measurement should precede the choice.
Provenance
Found while landing the served-tier strip gate. The import that exposed it is required: CONTRACT_REVIEW_TIER keeps exactly one value site across scripts/pm/** and .claude/skills/pm-dispatch/**, and restating it in the importing gate is the shape that let the declared tier and the served one drift apart in the first place. That PR retires the importing gate's now-false no-path-population declaration and states the imprecision in place rather than working around it.
⛔ Filed bare and ungraded — no domain:*, no priority:*; both are the triage seat's production.
Generated by Claude Code
inherited-population— the declared remedy for a followed module contributing a population its caller never opens — is keyed on the MODULE, while whether the contribution is fabricated is a property of the CALLER. A gate that imports one exported constant fromscripts/pm/dispatch-gates.mjstherefore inherits that module's whole watch surface, and there is no sanctioned way to decline it.Measured, on the live tree
scripts/pm/check-clause2-carriers.mjsgained one line —import { CONTRACT_REVIEW_TIER } from './dispatch-gates.mjs';— and nothing else that names a path. Ablation, both legs on the committed tree, restoring by blob hash:entry.importsfor the family reads["scripts/pm/dispatch-gates.mjs"], andentry.hintOriginis{}. The gate never opens.github/workflows; its CI step runs the checker's own--self-test.Why that is the shape the derivation says it refuses
firstPartyImportTargets' own docblock states the direction, verbatim:and
declaredInheritedPopulation's states the harm the marker exists against:That is exactly this case, and the marker cannot reach it: the same module's globs are a real population for
check:pm-widening-tells, which importsSUSPECT_TIER_GLOBSand reads them. A per-module declaration that narrowed the constant-importer would blind the glob-reader, and one that serves the glob-reader fabricates for the constant-importer. ⛔ One declaration cannot be both.The guard that exists does not fire here, and that is a second reading
discoverFamiliesalready carriesif (entry.selfTest) continue;precisely so a self-test-only family inherits nothing — its comment measures the identical fabrication onbare-root-worklistimporting the same module. Butentry.selfTestis read off the workflow argv:lint.ymlrunspnpm check:pm-clause2-carriers, and the--self-testlives in thepackage.jsonscript body (node scripts/pm/check-clause2-carriers.mjs --self-test). So the flag is invisible to the derivation,entry.selfTestisundefined, and the guard is silent for everypnpm check:*family whose self-test-only-ness is spelled in the manifest rather than in the workflow — measured the same way forcheck:pm-half-statesandcheck:pm-widening-tells.Why this is not #11556 again
#11556 (closed) measured the same class from
bare-root-worklistand landedinherited-populationas the remedy. That remedy is live and correct for what it was built for. What is reported here is a route it cannot express — a caller that imports a VALUE, not a population — plus the reason the cheaper guard beside it does not catch the route either. ⛔ Not a request to revert #11556's follow.Consequence today
One live fabricated lead, in a column a dispatch prompt pastes: a card touching
.github/workflows/**is told to runpnpm check:pm-clause2-carriers. Cheap to run and wrong to believe. It is also a recorded direction — the sibling gate'sWORKFLOW_FILE_PATHdocblock refuses a directory-shaped literal for exactly this reason (a placement removed once already), and the import channel re-introduces it by a route no author of that gate can see.Shapes, offered ⛔ not asserted
Three, unmeasured and unranked: make the
selfTestreading resolve apnpmscript throughpackage.jsonso the existing guard covers the manifest spelling; make the inheritance keyed on what the importer actually binds (a value import contributes nothing, a table import contributes the table); or give the IMPORTER a decline marker beside the module's declare marker. ⛔ Each is a change to a derivation whose refusals are all measured, so measurement should precede the choice.Provenance
Found while landing the served-tier strip gate. The import that exposed it is required:
CONTRACT_REVIEW_TIERkeeps exactly one value site acrossscripts/pm/**and.claude/skills/pm-dispatch/**, and restating it in the importing gate is the shape that let the declared tier and the served one drift apart in the first place. That PR retires the importing gate's now-falseno-path-populationdeclaration and states the imprecision in place rather than working around it.⛔ Filed bare and ungraded — no
domain:*, nopriority:*; both are the triage seat's production.Generated by Claude Code