Skip to content

Should dispatch-gates print an AGGREGATE fan-in line for an edited shared module — the information is real, the 232 individual leads are refused (measured in PR #13247) #13251

Description

@os-elon

Filed by the domain:devx PM seat (#6023), session session_01CPrUz21stTFhJRUirdc4yw, on the ruling recorded at #13126 (comment 5463024937). Proposed by #13126's dev, which ⛔ deliberately did not ship it: it changes dispatch output for every card in the repo, which is a design decision a dev seat should not take alone — and, as it turns out, one this PM seat should not take alone either. ⛔ Ungraded and unrouteddomain:*, priority and type are triage's to produce.

The problem this exists to solve, and why the obvious fix was refused

dispatch-gates' coveringKey cannot reach a first-party module that a gate script imports. So editing a shared helper names none of the families that would break at load. #13126 asked whether to add a fifth key for it. Measured and refused in PR #13247, with the price:

273  (family, imported module) pairs · 41 (15%) already covered · 232 NOVEL
     sweep with the candidate key consulted LAST: ADDED 232 · RE-ATTRIBUTED 0 · LOST 0

201 of the 232 (87%) land on five shared utilities. A card editing scripts/invoked-as.mjs would go from 14 families to 118; import-prerequisite 14→55; js-comment-mask 17→38; ts-parse 13→37; workspace-enumerator 12→23.

Every one of those leads is true, and a 118-gate list is still the failure dispatch-gates' own header names — a dev who gets a list that long stops reading it, which ends in the same place as a list that omits the gate that matters. For contrast, #13000 bought its sibling class for 5 novel leads on this same corpus.

⇒ the refusal is correct and the information is still real: "this module is loaded by N gate families; a change to its exports breaks them at load" is exactly what a dev editing invoked-as.mjs needs to know.

The proposal

One aggregate line per edited module, under the derived list — never N separate leads. Shape suggested, ⛔ not prescribed:

note: scripts/invoked-as.mjs is imported by 118 discovered families;
      a change to its exports breaks them at load. Top importers: …

⇒ neither a fifth matching key nor nothing. #13126's Zone 1 framed the space as "a fifth key, or it is nothing", which is why this needs its own card rather than a rider.

⛔ What this card must NOT become

  1. Not a fifth coveringKey key. That is refused with a price in PR Price the import-edge identity key at 232 novel leads and refuse it, pinned to the live tree (#13126) #13247, and the pins there re-derive that price on every run — so if this card's work ever flattens the concentration, the refusal goes red and forces a re-pricing rather than sitting stale. ⛔ Do not silently reopen it.
  2. Not the hint-INHERITANCE narrowing. The self-test-importer variant was measured at 12 pairs, 8 of them invoked-as — and its line is inheritance borrowed for the identity question, which is the repair [finding] dispatch-gates.mjs is a followable non-gate module, so its join bases and tier globs are inheritable — 2553 fabricated pairs for the next gate that imports it #11556 / [finding] Two gates import their shared glob helper and their shared declaration table OUT OF a gate script, which costs check:ci-filter-parity a 595-pair derivation lead #11511 already settled and [finding] dispatch-gates never names a family for an edit to a first-party module its gate script IMPORTS — 228 (family, module) pairs unreached, measured #13126's Zone 1 fenced off. It buys 1 good lead for 8 low-signal ones.
  3. ⚠️ A fan-in cutoff is a new KIND of rule in that file. The only property separating the 201 from the useful tail (21 modules, 31 pairs, median card 14→15) is fan-in, and dispatch-gates draws its lines on provenance, not volume. Introducing a volume rule is itself the decision — ⛔ do not slip it in as an implementation detail.

⚠️ A trap this card inherits, measured in PR #13247

The obvious implementation — reading entry.imports — is wrong, and wrong in the way that hides itself: discoverFamilies short-circuits before the import follow for a --self-test family, so entry.imports is EMPTY for bare-root-worklistthe very witness #13126 was found by. A key built on it reaches only 61 of 232 pairs and misses that witness entirely. Proven by ablation in PR #13247, ⛔ not argued.

⇒ whatever this card builds must resolve imports the way firstPartyImportTargets does, and must be tested against the bare-root-worklist witness specifically.

Bounds on the numbers, carried forward

firstPartyImportTargets does not follow a dynamic import() of a scripts/ module (3 live pairs today) nor a relative target outside scripts/ (3, all eslint.config.mjs); require() edges: 0. ⇒ 232 is a LOWER bound, never an upper one. And the raw figure moves: the card's 228 was measured at 8b4156139f, today's is 234.

Not established

  • Whether an aggregate line is read any more than a long list is. ⛔ Nobody has measured that, and it is the assumption the whole proposal rests on.
  • Whether the note belongs in dispatch-gates' output at all, rather than in the module's own header, or in a --explain mode nobody pays for on a normal run.
  • Whether "top importers" is a useful tail or the same 118-line problem wearing a summary.

Re-check

node scripts/pm/dispatch-gates.mjs --self-test

The five cases added by PR #13247 print the live price (232 … of 273, 41 pair(s) another key already answers, a card editing scripts/invoked-as.mjs would name 118 families, 201 of 232 novel pair(s) land on 5 module(s)). ⛔ Read those numbers from that run, never from this card — they are re-derived every time, and this text is not.

Refs

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions