Skip to content

Commit ae46c4a

Browse files
os-elonclaude
andauthored
docs(pm): describe check-dispatch-gates' watch hints by shape, not by count (#13286)
The gate's header said its watch hints were "the one constant below: this gate is matched for a card that edits the tool, and for nothing else". It carries three module-body constants — TOOL, plus SURFACE_MODULE and FRAME_MODULE, declared with their own docblocks — so the sentence was a false negative claim about the derivation, in the file whose subject is derivation correctness. Four sites in this file said it. Two of them are the ones the finding names; the other two are the same claim in different spellings — the backticking measurement ("the same single hint the file ships with") and the TOOL docblock, which said "two watch hints" and had itself gone stale a second time when the third constant landed. All four are now count-free: they name the constants' shape and point at the declarations, where each constant's reason already lives. A re-count would re-rot at the fourth declaration, which is exactly how this survived the second and third. Measured on the parent commit: extractWatchHints over this file returns scripts/pm/dispatch-gates.mjs, scripts/i18n-bundle-surface.mjs and scripts/check-skill-frame-sync.mjs; the gate's step declares no job filter and lint.yml no trigger paths, so hints plus gate-file identity are the whole of what reaches this family. Claude-Session: https://claude.ai/code/session_01CPrUz21stTFhJRUirdc4yw Co-authored-by: Claude <noreply@anthropic.com>
1 parent 54cc155 commit ae46c4a

1 file changed

Lines changed: 30 additions & 10 deletions

File tree

scripts/pm/check-dispatch-gates.mjs

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,20 @@
8383
*
8484
* A separate gate file is also what the other two pm gates look like
8585
* (check-skill-line-ratchet.mjs, check-skill-id-lint.mjs). Its watch hints are
86-
* the one constant below: this gate is matched for a card that edits the tool,
87-
* and for nothing else — which is the blind spot #8162 is about.
86+
* the module-body constants below — the tool it runs, plus every module whose
87+
* edits move this gate's verdict without leaving a hint the extractor can find.
88+
* Two routes reach this gate and there is no third: a card editing any of those
89+
* constants, through the hint; a card editing this file, through identity. The
90+
* step is invoked with no job filter and lint.yml declares no trigger paths, so
91+
* there is no third provenance to inherit — which is the blind spot #8162 is
92+
* about.
93+
*
94+
* ⛔ That sentence names the constants' SHAPE, not their number, for the reason
95+
* the ⛔ note above gives. Written as a count it said "the one constant" across
96+
* two later declarations (#9116) and stayed green the whole time: the self-test
97+
* pins the SET with containment assertions, and nothing counts the prose. Each
98+
* constant carries its own reason at its declaration below, which is where a
99+
* fourth one would be read and where the enumeration therefore lives.
88100
*
89101
* ## Why the paths above are unquoted, and why that is no longer required
90102
*
@@ -99,20 +111,25 @@
99111
*
100112
* The extractor no longer works that way: extractWatchHints opens with
101113
* maskComments, whose own docblock names this file as the specimen it retires.
102-
* Measured on this tree, with every repo path this header names rewritten into
103-
* backticks: 1 hint under today's extractor — scripts/pm/dispatch-gates.mjs,
104-
* the same single hint the file ships with — against 10 under the pre-masking
105-
* one, reaching spec, objectql, plugins, drivers, .claude/agents and .changeset
114+
* Re-measured on 74049254d4, the parent of the commit that rewrote this
115+
* paragraph, with every repo path this header names rewritten into backticks:
116+
* today's extractor returns exactly the hints the file ships with — the
117+
* module-body constants below, and nothing out of the header — against the ten
118+
* the pre-masking extractor returned when this section was first written,
119+
* reaching spec, objectql, plugins, drivers, .claude/agents and .changeset
106120
* exactly as the incident describes. Comment masking alone accounts for the
107121
* difference: masking self-test bodies instead changes nothing here, because
108122
* this file has none.
109123
*
110124
* So the unquoting is no longer load-bearing, and this section is history
111125
* rather than an instruction: quoting a path in a comment here is now free, and
112126
* the paths stay unquoted because rewriting them buys nothing. What is NOT free
113-
* is a path literal in a module body — masking cannot reach one — so the one
114-
* quoted path below is still the one input this gate genuinely has, and that is
115-
* the rule to carry into a new gate's header rather than the unquoting.
127+
* is a path literal in a module body — masking cannot reach one — so the quoted
128+
* paths below are still exactly this gate's watch hints, each one deliberate
129+
* rather than a by-product of how a sentence was typed. Only TOOL is a file this
130+
* gate itself reads; the other two are declared couplings, named because an edit
131+
* to them moves this gate's verdict with no hint to derive it from. That is the
132+
* rule to carry into a new gate's header rather than the unquoting.
116133
*
117134
* Nothing else belongs in this file. Assertions go in the tool's own self-test,
118135
* beside the code they judge; this is the CI invocation and its reason.
@@ -124,7 +141,10 @@ import process from 'node:process';
124141

125142
const ROOT = new URL('../..', import.meta.url).pathname;
126143

127-
/** The tool under test, repo-relative — and one of this gate's two watch hints. */
144+
/**
145+
* The tool under test, repo-relative — the one path declared here that this gate
146+
* actually reads, and one of its watch hints.
147+
*/
128148
const TOOL = 'scripts/pm/dispatch-gates.mjs';
129149

130150
/**

0 commit comments

Comments
 (0)