Skip to content

Commit a886fe2

Browse files
os-trumpclaude
andauthored
dispatch-gates: let a wide-population declaration carry exact-file hints (#17048)
check:route-envelope's real population is an AST-content filter over every non-test .ts file under packages/ (does it write a Hono/Express JSON response?), not a filename convention -- no glob spells it short of the whole subtree. bare-root-worklist.mjs's own CENSUS_REFUSE_WIDE ledger had already measured and recorded this verdict (37.4% of tracked packages/ files, REFUSE-WIDE) but the gate's own source never acted on it, so a brand-new response-writing module matched none of its 30 declared MODULES hints and fell into dispatch-gates' Silent bucket -- the weakest verdict, excluded from the runnable union -- instead of the "Declared WIDE population" bucket a reader is explicitly told not to read as clearance. Adding the wide-population marker as-is was refused: widePopulationRefusal treated ANY named hint as a contradiction, but all 10 gates that carry the marker today have zero hints, so deleting check:route-envelope's 30 MODULES keys to fit was the wrong trade -- it would turn a precise MATCHED lead on every already-known route module into an undifferentiated wide-population one. placeFamily's own runtime placement already handles hints coexisting with a wide-population marker correctly (matched stays matched; everything else promotes out of Silent); only the validation-only widePopulationRefusal was stricter than the mechanism it guards. Refined widePopulationRefusal: an exact-file hint (matched only by equality, per hintCovers' own plain branch) never contradicts "no glob places this" -- it is an enumerated member, not a population claim. A hint that reaches beyond itself (a bare directory, or a glob) is compatible only when the marker's own reason text names it, the same "the reason is what a reader trusts" bar wholeTreePopulationRefusal already holds a repo-root walk to. check:route-envelope's one such hint, DISPATCHER_DOMAIN_DIR, is a second, independently audited surface named in the reason for exactly that reason. A glob is never exempt this way, named or not. No change to placeFamily's existing runtime behaviour and no change to check:route-envelope's own audited behaviour -- same files error, same files pass. New self-test coverage for every branch of the refined predicate. Claude-Session: https://claude.ai/code/session_012zTkyNHJ7TkuN2oXtP5x37 Co-authored-by: Claude <noreply@anthropic.com>
1 parent c17b494 commit a886fe2

2 files changed

Lines changed: 137 additions & 13 deletions

File tree

scripts/check-route-envelope.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,8 @@ const UNATTRIBUTED_BATTERY = '(no battery open)';
204204

205205
const ROOT = join(fileURLToPath(new URL('.', import.meta.url)), '..');
206206

207+
// dispatch-gates: wide-population -- discover() and discoverResponseWriters() (the two walks behind MODULES and the Hono/Express surfaces) both root at join(ROOT, 'packages') and admit every non-test .ts file there before an AST pass decides which of them write a response -- a file-KIND filter, not a filename one, so no glob spells the population short of the whole subtree. Measured fresh on this tree: 2403 of 6491 tracked packages/ files are non-test .ts source (37.0%), corroborating the independent fs-trace in scripts/pm/bare-root-worklist.mjs's CENSUS_REFUSE_WIDE ("check:route-envelope packages", 2181/5837 = 37.4% at 2aa8456cf, verdict REFUSE-WIDE) -- the same width trade that table already recorded for this gate, now acted on here (#16828). The MODULES table's own keys stay as exact-file hints below, so a card touching an ALREADY-declared module still MATCHES precisely; this marker only stops a file the walk discovers but MODULES does not yet list -- the #16730 case -- from reading as Silent. packages/runtime/src/domains (DISPATCHER_DOMAIN_DIR) is a second, separately audited surface: discoverDomains() enumerates it exhaustively against DISPATCHER_DOMAINS below, independent of the response-writer population this marker is about.
208+
207209
/**
208210
* Every route module in the repo, with the envelope structure it is DECLARED to
209211
* have. A module the scan finds that is not listed here fails — see the header.

scripts/pm/dispatch-gates.mjs

Lines changed: 135 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2857,6 +2857,47 @@ export function wholeTreePopulationRefusal(entry) {
28572857
return null;
28582858
}
28592859

2860+
/**
2861+
* Whether a hint sitting beside a WIDE-population declaration is compatible
2862+
* with it, rather than a competing claim about the population (#16828, found
2863+
* on `check:route-envelope`).
2864+
*
2865+
* The refusal below used to fire on ANY named hint at all, on the theory that
2866+
* a gate claiming "no subtree glob places me" contradicts itself the moment
2867+
* its own source spells one. That is true of a hint that REACHES beyond the
2868+
* one file it names — a bare directory, or a glob — because such a hint is
2869+
* itself an attempt to spell the population, and two competing spellings of
2870+
* one population is exactly the coin toss this file refuses everywhere else.
2871+
* It is NOT true of a hint that reaches nothing but itself: an exact file path
2872+
* ending in a source/doc extension. `hintCovers`'s own plain branch matches
2873+
* such a hint only by EQUALITY — nothing can start with `<file>.ts/` — so
2874+
* admitting one changes nothing the marker claims about the population's
2875+
* WIDTH; it only records that one member of it happens to already be on
2876+
* record (`check:route-envelope`'s `MODULES` table, keyed by exact path, is
2877+
* the specimen: 30-plus such hints, every one a route module the gate already
2878+
* audits, none of them any narrower a claim than "this one file exists").
2879+
*
2880+
* A hint that DOES reach beyond itself is admitted only when the marker's own
2881+
* REASON TEXT names it — the same bar `wholeTreePopulationRefusal` holds a
2882+
* repo-root walk to (a claim with no reason behind it puts a row out on
2883+
* nothing). `check:route-envelope` carries exactly one such hint,
2884+
* `DISPATCHER_DOMAIN_DIR` (`packages/runtime/src/domains`): a directory whose
2885+
* own membership is exhaustively audited by `discoverDomains()` against the
2886+
* separate `DISPATCHER_DOMAINS` table, so it is a second, independently closed
2887+
* surface rather than a rival spelling of the FIRST one the marker is about.
2888+
* Naming it in the reason is what lets a reader tell the two apart instead of
2889+
* being asked to trust a silent exemption.
2890+
*
2891+
* A glob is never exempt this way, named or not: `judgedAsPattern` reports a
2892+
* hint that is ITSELF a population spelling — reason text that repeats it
2893+
* back is not an account of it, it is the same contradiction typed twice.
2894+
*/
2895+
function widePopulationHintCompatible(hint, reason) {
2896+
if (judgedAsPattern(hint)) return false;
2897+
if (/\.[A-Za-z0-9]{1,6}$/.test(hint)) return true;
2898+
return reason.includes(hint);
2899+
}
2900+
28602901
/**
28612902
* Why this family's WIDE-population declaration must be refused, or null when
28622903
* it stands. Pure, and reading only what the discovery already put on the
@@ -2874,12 +2915,17 @@ export function wholeTreePopulationRefusal(entry) {
28742915
* card — the opposite disposition from this one — so the pair
28752916
* would place the family by whichever branch was read first.
28762917
* NAMES PATHS the declaration says no subtree glob places this gate, and
2877-
* the gate's own source spells one. One of the two is wrong
2878-
* and the derivation cannot tell which: the marker's whole
2879-
* content is the sentence a reader trusts, so a marker sitting
2880-
* above a live population is the rot direction that costs —
2881-
* the reader is told "nothing here can be narrowed" while the
2882-
* matched column narrows it.
2918+
* the gate's own source spells one anyway — a hint
2919+
* `widePopulationHintCompatible` above does not clear. One of
2920+
* the two is wrong and the derivation cannot tell which: the
2921+
* marker's whole content is the sentence a reader trusts, so
2922+
* a marker sitting above an unaccounted-for population is the
2923+
* rot direction that costs — the reader is told "nothing
2924+
* here can be narrowed" while the matched column narrows it.
2925+
* ⚠️ This is deliberately NOT "does the gate name any path at
2926+
* all" (#16828): an enumerated exact-file member, or a
2927+
* subtree the reason itself names, is not that contradiction
2928+
* — see `widePopulationHintCompatible`'s own docblock.
28832929
*/
28842930
export function widePopulationRefusal(entry) {
28852931
const reason = entry?.widePopulationReason ?? null;
@@ -2894,13 +2940,14 @@ export function widePopulationRefusal(entry) {
28942940
+ 'these two carry OPPOSITE dispositions: a whole-tree family is owed by every card and its command is inside every '
28952941
+ "card's runnable total, a wide-population one is owed by CI and is in no card's. Delete the one that is not true.";
28962942
}
2897-
if ((entry?.hints ?? []).length > 0) {
2898-
return 'declares wide-population and its own source NAMES paths: '
2899-
+ `${(entry.hints ?? []).slice(0, 4).join(', ')}${(entry.hints ?? []).length > 4 ? ', …' : ''}. `
2900-
+ 'The declaration says no subtree glob places this gate and the gate spells one, so one of the two is wrong and '
2901-
+ 'nothing here can tell which. If the literals are the real population, delete the marker and let the matched '
2902-
+ 'column do its job; if they are artifacts rather than a population, the marker stands and the literals do not '
2903-
+ 'belong in a scanned position.';
2943+
const uncovered = (entry?.hints ?? []).filter((h) => !widePopulationHintCompatible(h, reason));
2944+
if (uncovered.length > 0) {
2945+
return 'declares wide-population and its own source NAMES paths that reach beyond the single file each one names: '
2946+
+ `${uncovered.slice(0, 4).join(', ')}${uncovered.length > 4 ? ', …' : ''}. `
2947+
+ 'The declaration says no subtree glob places this gate and the gate spells one it does not account for, so one of '
2948+
+ 'the two is wrong and nothing here can tell which. If the literal is the real population, delete the marker and '
2949+
+ 'let the matched column do its job; if it is a second, separately audited surface, name it in the reason text; '
2950+
+ 'if it is an artifact rather than a population, it does not belong in a scanned position.';
29042951
}
29052952
return null;
29062953
}
@@ -18404,6 +18451,81 @@ function selfTest() {
1840418451
return why.includes('NAMES paths') && why.includes('packages/rest/src');
1840518452
})(),
1840618453
);
18454+
// #16828: the line is NOT "does the gate name any path" — an enumerated
18455+
// exact-file member never contradicts a wide declaration, because
18456+
// `hintCovers` can only ever match one by equality. `check:route-envelope`
18457+
// is the specimen: a `MODULES` table keyed by 30-plus exact file paths,
18458+
// none of them a claim about the population's width.
18459+
t(
18460+
'a wide declaration over ONLY exact-file hints stands — an enumerated member is not a competing spelling of the population',
18461+
widePopulationRefusal({
18462+
...wpLive,
18463+
hints: ['packages/rest/src/storage-routes.ts', 'packages/rest/src/error-response.ts'],
18464+
}) === null,
18465+
);
18466+
// A hint that reaches beyond itself (no extension — a bare directory) is
18467+
// still compatible when the marker's own reason text names it: the second,
18468+
// separately audited surface `check:route-envelope`'s DISPATCHER_DOMAIN_DIR
18469+
// is, held to the same "the reason is what a reader trusts" bar
18470+
// `wholeTreePopulationRefusal` holds a repo-root walk to.
18471+
t(
18472+
'a directory hint that reaches beyond itself stands when the reason text names it by name',
18473+
widePopulationRefusal({
18474+
...wpLive,
18475+
widePopulationReason: 'walks packages/ entire; packages/runtime/src/domains is a second, separately audited surface',
18476+
hints: ['packages/runtime/src/domains'],
18477+
}) === null,
18478+
);
18479+
// The SAME directory hint, unnamed in the reason, is still refused — the
18480+
// exemption is not "any directory a real gate happens to carry", it is
18481+
// "an account the reader can check", and a silent one is not that.
18482+
t(
18483+
'the same directory hint is still refused when the reason does not name it — silence is not an account',
18484+
(() => {
18485+
const why = widePopulationRefusal({ ...wpLive, hints: ['packages/runtime/src/domains'] }) ?? '';
18486+
return why.includes('NAMES paths') && why.includes('packages/runtime/src/domains');
18487+
})(),
18488+
);
18489+
// A glob is never exempt this way, even repeated verbatim in the reason:
18490+
// `judgedAsPattern` marks it as ITSELF a population spelling, and a reason
18491+
// that only echoes it back is the same contradiction typed twice, not an
18492+
// account of it. A bare trailing `/**` does NOT qualify — it COLLAPSES to
18493+
// the identical plain directory prefix (`collapseHint`'s own docblock:
18494+
// `packages/**` -> `packages`), so it is judged exactly like the directory
18495+
// case above, on purpose. The species this asserts against is the one
18496+
// `judgedAsPattern` actually flags: a glob in a NON-final segment.
18497+
t(
18498+
'a glob hint is refused even when the reason text repeats it back verbatim',
18499+
(() => {
18500+
const why = widePopulationRefusal({
18501+
...wpLive,
18502+
widePopulationReason: 'walks packages/ entire; packages/*/src is already covered',
18503+
hints: ['packages/*/src'],
18504+
}) ?? '';
18505+
return why.includes('NAMES paths') && why.includes('packages/*/src');
18506+
})(),
18507+
);
18508+
// The bare-trailing-`/**` spelling is the CONTRAST case: it is not a
18509+
// `judgedAsPattern` glob at all (it collapses to a plain prefix), so it is
18510+
// exempt under the SAME "reason names it" rule as any other directory hint.
18511+
t(
18512+
'a bare trailing /** hint is not a glob for this purpose — it stands when the reason names it, same as a plain directory',
18513+
widePopulationRefusal({
18514+
...wpLive,
18515+
widePopulationReason: 'walks packages/ entire; packages/runtime/src/domains/** is a second, separately audited surface',
18516+
hints: ['packages/runtime/src/domains/**'],
18517+
}) === null,
18518+
);
18519+
// A mix of the two compatible shapes together stands — the predicate is
18520+
// per-hint, not "the whole set must be one shape".
18521+
t(
18522+
'a mix of exact-file hints and a reason-named directory hint stands together',
18523+
widePopulationRefusal({
18524+
...wpLive,
18525+
widePopulationReason: 'walks packages/ entire; packages/runtime/src/domains is a second, separately audited surface',
18526+
hints: ['packages/rest/src/storage-routes.ts', 'packages/runtime/src/domains'],
18527+
}) === null,
18528+
);
1840718529

1840818530
// Placement, column by column. The card path is under the very root these
1840918531
// gates walk — the case the ruling is about.

0 commit comments

Comments
 (0)