diff --git a/scripts/pm/check-dispatch-gates.mjs b/scripts/pm/check-dispatch-gates.mjs index b8262098a1..35b41c5b05 100644 --- a/scripts/pm/check-dispatch-gates.mjs +++ b/scripts/pm/check-dispatch-gates.mjs @@ -83,8 +83,20 @@ * * A separate gate file is also what the other two pm gates look like * (check-skill-line-ratchet.mjs, check-skill-id-lint.mjs). Its watch hints are - * the one constant below: this gate is matched for a card that edits the tool, - * and for nothing else — which is the blind spot #8162 is about. + * the module-body constants below — the tool it runs, plus every module whose + * edits move this gate's verdict without leaving a hint the extractor can find. + * Two routes reach this gate and there is no third: a card editing any of those + * constants, through the hint; a card editing this file, through identity. The + * step is invoked with no job filter and lint.yml declares no trigger paths, so + * there is no third provenance to inherit — which is the blind spot #8162 is + * about. + * + * ⛔ That sentence names the constants' SHAPE, not their number, for the reason + * the ⛔ note above gives. Written as a count it said "the one constant" across + * two later declarations (#9116) and stayed green the whole time: the self-test + * pins the SET with containment assertions, and nothing counts the prose. Each + * constant carries its own reason at its declaration below, which is where a + * fourth one would be read and where the enumeration therefore lives. * * ## Why the paths above are unquoted, and why that is no longer required * @@ -99,10 +111,12 @@ * * The extractor no longer works that way: extractWatchHints opens with * maskComments, whose own docblock names this file as the specimen it retires. - * Measured on this tree, with every repo path this header names rewritten into - * backticks: 1 hint under today's extractor — scripts/pm/dispatch-gates.mjs, - * the same single hint the file ships with — against 10 under the pre-masking - * one, reaching spec, objectql, plugins, drivers, .claude/agents and .changeset + * Re-measured on 74049254d4, the parent of the commit that rewrote this + * paragraph, with every repo path this header names rewritten into backticks: + * today's extractor returns exactly the hints the file ships with — the + * module-body constants below, and nothing out of the header — against the ten + * the pre-masking extractor returned when this section was first written, + * reaching spec, objectql, plugins, drivers, .claude/agents and .changeset * exactly as the incident describes. Comment masking alone accounts for the * difference: masking self-test bodies instead changes nothing here, because * this file has none. @@ -110,9 +124,12 @@ * So the unquoting is no longer load-bearing, and this section is history * rather than an instruction: quoting a path in a comment here is now free, and * the paths stay unquoted because rewriting them buys nothing. What is NOT free - * is a path literal in a module body — masking cannot reach one — so the one - * quoted path below is still the one input this gate genuinely has, and that is - * the rule to carry into a new gate's header rather than the unquoting. + * is a path literal in a module body — masking cannot reach one — so the quoted + * paths below are still exactly this gate's watch hints, each one deliberate + * rather than a by-product of how a sentence was typed. Only TOOL is a file this + * gate itself reads; the other two are declared couplings, named because an edit + * to them moves this gate's verdict with no hint to derive it from. That is the + * rule to carry into a new gate's header rather than the unquoting. * * Nothing else belongs in this file. Assertions go in the tool's own self-test, * beside the code they judge; this is the CI invocation and its reason. @@ -124,7 +141,10 @@ import process from 'node:process'; const ROOT = new URL('../..', import.meta.url).pathname; -/** The tool under test, repo-relative — and one of this gate's two watch hints. */ +/** + * The tool under test, repo-relative — the one path declared here that this gate + * actually reads, and one of its watch hints. + */ const TOOL = 'scripts/pm/dispatch-gates.mjs'; /**