Skip to content

fix(scripts): optional-error-sink gate header — narrowing count prose - #12323

Merged
yinlianghui merged 1 commit into
mainfrom
claude/issue-12291-narrowing-count-prose
Aug 25, 2026
Merged

fix(scripts): optional-error-sink gate header — narrowing count prose#12323
yinlianghui merged 1 commit into
mainfrom
claude/issue-12291-narrowing-count-prose

Conversation

@yinlianghui

Copy link
Copy Markdown
Collaborator

Fixes#12291

What

Two docblock lines in scripts/check-optional-error-sink-contract.mjs said the gate measures two narrowings; the file documents and pins three (Narrowing 1: as-cast, Narrowing 2: purity, Narrowing 3: unreadable member type — added by #11069), and the runtime string already prints all three narrowings pinned as counts. This repairs the two stale prose lines to match.

- * costs false positives instead, so both narrowings below are measured and- * their cost is printed on every run rather than argued in prose.+ * costs false positives instead, so every narrowing below is measured and+ * its cost is printed on every run rather than argued in prose.
- * Every limb observed FAILING and observed SILENT, plus the two narrowings+ * Every limb observed FAILING and observed SILENT, plus the narrowings
* pinned as positive counts.

Per clause 2c of the dispatch, chose an integer-free spelling ("every narrowing below" / "the narrowings"), matching the repair PR #12290 made for the sibling workflow-comment instance of the same defect — so neither sentence can go stale again when a fourth narrowing arrives. (:60's sentence is a promise that every narrowing's cost is measured and printed; "every narrowing below" states that promise at least as concretely as a number did, without re-encoding a count that has already drifted once.)

:985 is left exactly as written — it is a correct past-tense statement about the state of the world before narrowing 3 existed ("an unsound prefilter survived a self-test that pinned both narrowings as counts (#11069)"), not a present-tense claim. Changing it would make the file lie about its own history.

Sweep (clause 2b)

Swept the whole file for every count-asserting spelling (both, two, pair, either, digit 2) near "narrowing". Found two other clusters that use "two"/"both" near the word "narrowing" and confirmed neither is a third stale site:

No third stale site found. :60 and :789 were the only two instances; :985 the only deliberate non-instance, exactly as the card measured.

No behaviour change

Diff is exactly these two docblock lines — no count, pin, or runtime string touched (git diff --stat: 1 file changed, 3 insertions(+), 3 deletions(-), all inside comments).

Evidence

⚠️ This is a comment-only diff — the gate never reads its own prose, so a green gate run does not verify the fix. The actual evidence of correctness is a read of the three ### Narrowing N sections (:90, :102, :114) against the two repaired sentences: three sections, three pinned expectUnreadable/narrowing cases, and now two sentences that no longer claim two.

The gate/self-test run below only proves no behaviour regressed — it is not evidence the prose is right:

✓ optional-error-sink-contract self-test: 19 case(s), both directions, all three narrowings pinned as counts, prefilter pinned over 9 channel(s) × 4 spellings plus its reject side.
✓ optional-error sink contract: every sink declaring an optional `error` guarantees a `warn` channel (1 baselined, shrink-only).

Both exit 0, unchanged from origin/main.

Gates

node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack at final commit 9097996c94 (no STALE TREE, same file/gate set as the pre-push derivation):

  • pnpm check:agent-test-spelling
  • pnpm check:cli-command-ids
  • pnpm check:cross-package-test-inputs ✓ (OK: 16 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob.)
  • pnpm check:entry-guard
  • pnpm check:optional-error-sink ✓ (verdict lines above)
  • pnpm check:parse-guard
  • pnpm check:pnpm-filter-targets
  • node scripts/check-ci-filter-parity.mjs ✓ (silent/no findings, exit 0 as part of the chained run)

All run through os-verify-lock.sh as one chained command; verdict command-exit 0 · held the lock 30s · waited 0s. Exit codes captured before any pipe/tail.

Changeset

None — scripts/** publishes nothing to any package, so this is a skip-changeset PR (tooling/gate-prose only, no user-visible surface).


Generated by Claude Code

…out its narrowing count
:60 and :789 said "both"/"the two narrowings" while the file documents
and pins three (Narrowing 1: as-cast, Narrowing 2: purity, Narrowing 3:
unreadable member type, added by #11069) and its runtime string already
prints "all three narrowings pinned as counts". Repointed both sentences
to an integer-free spelling ("every narrowing below" / "the narrowings")
so they cannot go stale again when a fourth narrowing arrives, matching
the fix PR #12290 made for the sibling workflow-comment instance.
:985 is left exactly as written — it is a correct past-tense statement
about the state of the world before narrowing 3 existed (#11069's own
history), not a present-tense claim.
No behaviour, count, pin, or runtime string changed.
@yinlianghuiyinlianghui added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 25, 2026 — with Claude
@yinlianghuiClaude

Copy link
Copy Markdown
CollaboratorAuthor

ACCEPT — PM review of #12291.

The two-line edit is not the part worth reviewing. The sweep is, and I re-ran it independently rather than taking your table.

The sweep, re-run here

Every count-word (both / two / pair / either / digit 2) co-occurring with "narrow" in the file, on origin/main:

 60: * costs false positives instead, so both narrowings below are measured and ← stale, repaired
78: * | skipped: shape narrowed by an `as` CAST | 2 | ← a table VALUE
102: * ### Narrowing 2: purity — every member from the log vocabulary ← an ORDINAL
134: * Both were narrowings NOT in the list above — neither argued nor counted, ← the two blind spots
251: * The log-channel vocabulary. Purity is judged against THIS set (narrowing 2), ← ordinal
549: * // Narrowing 2, counted rather than argued … ← ordinal
789: * Every limb observed FAILING and observed SILENT, plus the two narrowings ← stale, repaired
850: * // ⭐ Narrowing 2, same. An options bag is not a sink. ← ordinal
851: * name: 'narrowing 2: an impure shape … is skipped, and COUNTED', ← ordinal
985: // an unsound prefilter survived a self-test that pinned both narrowings as ← past tense, correct

Same answer as yours: two stale sites, one deliberate non-instance, no third.

:134 is the one worth having caught, and I want to record why your call on it is right rather than just agreeing. The sentence reads "Both were narrowings NOT in the list above — neither argued nor counted, which is what made them blind spots rather than trade-offs." It contains the word "narrowings" immediately after the word "Both", which is exactly the surface shape of the defect being repaired — and it is nonetheless correct, because those two were narrowings the file did not list. A sweep that matched on shape and edited on shape would have corrupted a true sentence into a false one. Reading it in context was the difference.

:795's "the two apart" is likewise the FAILING/SILENT observation pair, unrelated to narrowing count. Confirmed by reading the surrounding lines.

On the evidence section

⚠️ This is a comment-only diff — the gate never reads its own prose, so a green gate run does not verify the fix.

That is the correct posture and I am flagging it as such. The failure available here was to run the gate, quote all three narrowings pinned as counts, and let a reader infer the prose had been checked. You stated what the evidence actually is — a read of the three ### Narrowing N sections against the two repaired sentences — and demoted the green run to what it proves, which is that no behaviour regressed.

On the integer-free spelling

Agreed, and your reason is the better one: :60's sentence is a promise that every narrowing's cost is measured, and "every narrowing below" states that promise at least as concretely as a number did, without re-encoding a count that has already drifted once. Same choice PR #12290 made for the sibling workflow-comment instance, which keeps the two halves of this defect repaired the same way.

:985 left alone, as ruled.

Landing conditions

  1. Lint & Repo Gates reports completed + success, read by name — not from an aggregate, not from the check_suite.completed notice, which says in its own text that it does not cover every suite.
  2. Nothing else. mergeable_state currently reads blocked only because the PR is still a draft.

Generated by Claude Code

@yinlianghui
yinlianghui marked this pull request as ready for review August 25, 2026 18:14
@yinlianghui
yinlianghui added this pull request to the merge queueAug 25, 2026
Merged via the queue into main with commit b8419bdAug 25, 2026
34 checks passed
@yinlianghui
yinlianghui deleted the claude/issue-12291-narrowing-count-prose branch August 25, 2026 18:37
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/xsskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] check-optional-error-sink-contract.mjs's own header says "both narrowings" while it documents and pins three

2 participants

@yinlianghui@claude