Found from the #10648 execution seat (which fixed the identical defect in
scripts/check-doc-authoring.mjs, PR #10662). Out of that card's scope and not
touched there. Seventh instance of the class: #9626 / #9979 / #10114 / #10314 /
#10516 / #10648.
The finding
packages/lint/scripts/check-doc-formula-expressions.mjs:170 declares its
population with the byte-identical line the sixth instance had:
constROOTS=['.claude','docs','skills','content'];
docs, skills and content carry no path separator, so
scripts/pm/dispatch-gates.mjs refuses them as too generic. (.claude is
admitted — it is a top-level dotted directory, which the extractor takes
explicitly. That detail was recorded wrong on #10648 and is corrected in
PR #10662.)
The result has the same inverted shape. Measured on origin/main at
9dd192d48b, the gate's whole extracted hint set is:
@objectstack/formula, .claude, .claude/worktrees, docs/audits,
docs/handoff, docs/plans, content/docs/references, packages/spec/src
Derivation, same tree:
docs/qa/platform-checklist/RUNNER.md not derived
content/docs/deployment/cli.mdx not derived
skills/objectstack-upgrade/SKILL.md not derived
docs/plans/x.md DERIVED <- an exclusion
So the live corpus derives nothing and the exempt subtrees derive the gate —
the inverse error, in a gate that is REQUIRED at .github/workflows/lint.yml:2916
(pnpm --filter @objectstack/lint run check:doc-formula-expressions).
Suggested fix
The pattern is documented and now has two worked instances to copy:
scripts/check-role-word.mjs (ROOT_DIR_WATCH_HINTS) and, closest to this
gate, scripts/check-doc-authoring.mjs after PR #10662 — which also carries the
reasoning for what to do about SKIP_PATHS (the hint language cannot subtract,
so the over-claim is bounded and asserted rather than removed).
⚠️ This gate is package-scoped (@objectstack/lint), so its extractor
resolution goes through that package's manifest rather than the root one. Worth
confirming the declaration is actually picked up after the change rather than
assuming — the whole class is about declarations that read as present and reach
nothing.
Why one at a time, and not the extractor
Asked and answered on #10648 with a measurement worth not repeating: a
class-level guard that flags any gate naming a bare top-level tracked directory
none of its hints reach fires on 40 of 123 families on this tree, and the
majority are correct as they stand (check:error-code-casing really does sweep
all of packages/). The declaration has to be authored because the distinction
between "population root" and "path component" is not in the source text. See
PR #10662's body for the full argument.
Refs: packages/lint/scripts/check-doc-formula-expressions.mjs · .github/workflows/lint.yml:2916 · #10648 · PR #10662
Generated by Claude Code
Generated by Claude Code
Found from the #10648 execution seat (which fixed the identical defect in
scripts/check-doc-authoring.mjs, PR #10662). Out of that card's scope and nottouched there. Seventh instance of the class: #9626 / #9979 / #10114 / #10314 /
#10516 / #10648.
The finding
packages/lint/scripts/check-doc-formula-expressions.mjs:170declares itspopulation with the byte-identical line the sixth instance had:
docs,skillsandcontentcarry no path separator, soscripts/pm/dispatch-gates.mjsrefuses them as too generic. (.claudeisadmitted — it is a top-level dotted directory, which the extractor takes
explicitly. That detail was recorded wrong on #10648 and is corrected in
PR #10662.)
The result has the same inverted shape. Measured on
origin/mainat9dd192d48b, the gate's whole extracted hint set is:Derivation, same tree:
So the live corpus derives nothing and the exempt subtrees derive the gate —
the inverse error, in a gate that is REQUIRED at
.github/workflows/lint.yml:2916(
pnpm --filter @objectstack/lint run check:doc-formula-expressions).Suggested fix
The pattern is documented and now has two worked instances to copy:
scripts/check-role-word.mjs(ROOT_DIR_WATCH_HINTS) and, closest to thisgate,
scripts/check-doc-authoring.mjsafter PR #10662 — which also carries thereasoning for what to do about
SKIP_PATHS(the hint language cannot subtract,so the over-claim is bounded and asserted rather than removed).
@objectstack/lint), so its extractorresolution goes through that package's manifest rather than the root one. Worth
confirming the declaration is actually picked up after the change rather than
assuming — the whole class is about declarations that read as present and reach
nothing.
Why one at a time, and not the extractor
Asked and answered on #10648 with a measurement worth not repeating: a
class-level guard that flags any gate naming a bare top-level tracked directory
none of its hints reach fires on 40 of 123 families on this tree, and the
majority are correct as they stand (
check:error-code-casingreally does sweepall of
packages/). The declaration has to be authored because the distinctionbetween "population root" and "path component" is not in the source text. See
PR #10662's body for the full argument.
Refs:
packages/lint/scripts/check-doc-formula-expressions.mjs·.github/workflows/lint.yml:2916· #10648 · PR #10662Generated by Claude Code
Generated by Claude Code