Skip to content

fix(pm): let a SPELLINGS entry hold a list of segment arrays for multi-hint rows - #14523

Merged
baozhoutao merged 2 commits into
mainfrom
claude/issue-14233-spellings-multi-hint
Sep 2, 2026
Merged

fix(pm): let a SPELLINGS entry hold a list of segment arrays for multi-hint rows#14523
baozhoutao merged 2 commits into
mainfrom
claude/issue-14233-spellings-multi-hint

Conversation

@claude

@claude claude Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Fixes #14233

What

scripts/pm/bare-root-worklist.mjs's SPELLINGS self-test harness held exactly
one hint per entry, so a DECLARED-NARROWER row whose gate declares its
population as more than one glob could not record a spelling at all, and its
declaration went re-measured by nothing in this file. Five rows were in that
state: check:logger-receiver-detach's three SCAN_ROOTS rows (packages,
examples, apps), check:dual-build-cjs-loads SCAN_ROOT packages and
check:ratchet-remedy-authority SCRIPTS_DIR scripts.

This extends SPELLINGS so an entry's segments may hold either one hint (a
flat segment array — unchanged for the nine existing entries, kept readable) or
a LIST of segment arrays — the narrow remedy the card sketched. The pin loop
asks hintCovers and holds of the UNION of an entry's hints. Five multi-hint
(or, for examples, single-hint) entries were added, matching each gate's own
ROOT_DIR_WATCH_HINTS declaration exactly:

entry hints covered / root files
packages TypeScript source packages/**/*.ts, packages/**/*.tsx, packages/**/*.mts 5240 / 5796
examples TypeScript source examples/**/*.ts 206 / 243
apps TypeScript source apps/**/*.ts, apps/**/*.tsx 29 / 41
dual-build manifests and configs packages/**/package.json, packages/**/tsup.config.ts 94 / 5796
scripts top-level script files scripts/*.mjs, scripts/*.mts 183 / 310

Each of the five DECLARED-NARROWER rows now carries spelling: naming its
entry, and each row's why prose is corrected — the check:ratchet-remedy-authority
row previously stated in as many words that "SPELLINGS holds ONE hint per entry
and this population needs one per extension"; that sentence is now false and is
rewritten to describe the new pin instead.

No verdict changes. No gate under scripts/check-*.mjs is edited — their
declarations are read, never written. This is not a new gate: the pin lives
entirely inside bare-root-worklist.mjs --self-test, which already ran on
every PR (lint.yml:766).

Decision recorded, not built

The triage's Zone 3 raised, as an option, a per-member LIVE assertion inside
the pin loop (so a union LIVE cannot let one dead hint hide behind a live
sibling — the exact partial-death shape the parent card described for
check:declared-population-live). Left out: the ruling's own words are "the
remedy is the narrow one the card sketches ... and nothing else," and a
per-member pin is a genuine addition beyond "ask holds of the union," not a
restatement of it. See open_questions in the report comment — every new
entry's hints were individually measured non-empty during this PR's own
verification (see Tests), so the gap is theoretical today, not a live defect.

Tests

  • node scripts/pm/bare-root-worklist.mjs --self-test — green, 78 t()
    assertions execute at runtime (up from 58 on main: +4 per added entry × 5).
  • Five red-proofs, one per added entry: each entry's declaration was
    temporarily edited to break LIVE, PRECISE, NARROWING or COMPLETE in turn,
    the self-test was run and shown to fail on exactly that entry, then reverted
    via git checkout HEAD -- scripts/pm/bare-root-worklist.mjs and reconfirmed
    clean (git diff HEAD empty) before the next mutation. See the report
    comment for each red line quoted.
  • node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands scripts/pm/bare-root-worklist.mjs
    derived 14 commands; all ran green (one, check-test-completeness.mjs, is
    NOT MEASURED locally by design — it grades a saved turbo test log CI
    supplies).
  • pnpm check:ratchet-remedy-authority, pnpm check:declared-population-live,
    node scripts/check-self-test-wired.mjs — all green.
  • node scripts/check-nul-bytes.mjs — clean.
  • Narrow ESLint on the one changed file — 0 errors, 0 warnings.

Full commands, exit codes and quoted verdict lines are in the report comment
on #14233. All gates above were re-run on the merged head (6cc887260,
origin/main merged in — no conflicts, bare-root-worklist.mjs untouched by
upstream).

Changeset

scripts/pm/**-only diff — no user-facing published change. No changeset
added; skip-changeset label applied (confirmed by reading the PR's labels
back after applying).


Draft PR — not marking ready, CI convergence is for the PM to review.

Generated by Claude Code


Generated by Claude Code

…i-hint rows

bare-root-worklist.mjs's SPELLINGS harness held exactly one hint per
entry, so a DECLARED-NARROWER row whose gate declares more than one hint
could not record a spelling at all — five rows were in that state
(check:logger-receiver-detach's three SCAN_ROOTS rows,
check:dual-build-cjs-loads, check:ratchet-remedy-authority). Nothing in
this file re-measured those declarations against hintCovers.

Extend SPELLINGS so an entry's `segments` may hold either one hint (a
flat array, unchanged for the nine existing entries) or a LIST of
segment arrays; the pin loop asks `hintCovers` and `holds` of the
union. Add five multi-hint entries covering the five rows' declared
hints, wire each row's `spelling:`, and correct the `why` prose that
previously stated the harness could not hold this shape.

Fixes #14233
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants