Skip to content

test(spec): put the pin file's two prose counts under the counting assertion (#6605) - #6689

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-6605-iso-alias-count-comment
Aug 8, 2026
Merged

test(spec): put the pin file's two prose counts under the counting assertion (#6605)#6689
os-project-manager merged 1 commit into
mainfrom
claude/issue-6605-iso-alias-count-comment

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes #6605

What drifted

packages/spec/src/type-alias-convention.pin.test.ts states its pin count in three
places. One is asserted; two were not, and both had drifted:

site said actual
section header above the pin list (:267) 717 823
the counting case's own title (:1620) 755 823
expect(pins).toHaveLength(...) 823 823

The assertion matches /^export type Iso\d+ = Assert over the file's own source, so it
reads the declarations and never the prose sitting beside them — which is exactly
why the other two could rot unwatched.

Re-counted on origin/main @ b127c8b22 rather than taken from the card:
grep -c '^export type Iso' = 823, and pnpm check:spec-parsed-alias independently
reports 1517 bare z.input aliases, 823 pinned isomorphic, 694 paired with an XParsed.
The card's 822 was correct when filed and went stale the same day — #6596 landed
GetMetaItemLayeredResponseSchema on top of #4593's backfill.

One correction to the issue's premise

The issue title calls the header "the only number not covered by a counting assertion".
It is not the only one — the counting case's own title is a second, and it had
drifted 68 behind. The substantive premise holds in full (the header stated 717, the
truth is 823, nothing asserted it); only the word "only" does not.

That second site also settles the design question, because it is a repeat offender:
the receipt above it records that the title was already hand-corrected once, from 751 to
754 (#6037) — and it drifted again anyway. Hand-maintenance has been tried here and
measured to fail.

The fix: extend the counting machinery, not the literals

Level 2 of the ruling, enforcement variant. The case already reads its own source to
count declarations; it now recomputes the prose against that same operand:

const stated = [...self.matchAll(/(\d+) isomorphic \w+/g)].map((m) => m[0]);
expect(stated.length, phrasingMoved).toBeGreaterThanOrEqual(2);
const wrong = stated.filter((s) => !s.startsWith(`${pins.length} `));
expect(wrong, `prose disagreeing with the ${pins.length} pins counted above`).toEqual([]);

Three deliberate properties:

  • Matched by phrase, not at two fixed line numbers. A sentence a later author writes
    is covered the moment it is written. This is the property the alternative — deleting
    the numbers and pointing at the assertion instead — does not have: removal resets the
    drift but does nothing about re-introduction, and "N isomorphic aliases" is a very
    natural thing for the next author (or agent) to write into a section header. Keeping
    the number and making it unfalsifiable is the same bargain the pins themselves are
    built on, in this file's own words at the top: "An exemption nobody can state falsely
    is the only kind worth having."
  • The receipts are deliberately NOT matched. The block above the assertion is dense
    with historical arithmetic — 749 -> 822, -7, 136 - 17 - 40 - 5 - 1. Those are
    true about past states of the file and rewriting them to today's count would destroy
    the receipts. The matched phrase is the narrow one that can only ever mean "how many
    pins are in this file right now"; verified to match those two sites and nothing else.
  • A guard on the guard. If a reword leaves no sentence matching, the filter would
    pass over an empty list and the check would silently stop existing — the phantom-check
    shape this repo keeps paying for. toBeGreaterThanOrEqual(2) refuses that.

Scope note: docs/adr/0122-...md also carries pin counts (final: 1470 / 754 / 716),
left untouched on purpose — that is the phase-2 flip's own dated outcome table, history
in the same sense as the receipts, not drift.

Reverse verification

Direction predicted before running, and both came out as predicted — plain red, no
inversion:

  1. Restore the stale 717 in the header → the new assertion goes red naming the
    sentence, while toHaveLength(823) above it still passes. This is the issue's
    mechanism, reproduced: the old machinery cannot see this defect.
    AssertionError: prose disagreeing with the 823 pins counted above:
      expected [ '717 isomorphic aliases' ] to deeply equal []
    ❯ src/type-alias-convention.pin.test.ts:1788
    
  2. Reword both sites so the phrase disappears → the guard-the-guard goes red, so the
    check cannot pass vacuously.
    AssertionError: no prose states the pin count any more — has the phrasing moved?:
      expected 0 to be greater than or equal to 2
    ❯ src/type-alias-convention.pin.test.ts:1786
    

Verification

  • pnpm --filter @objectstack/spec exec vitest run345 files / 8844 tests passed
  • pnpm --filter @objectstack/spec typecheck — exit 0 (tsc --noEmit,
    check:scripts-typecheck, check:test-typecheck; the last is where these pins'
    compile-time proof actually lands, per [finding] ADR-0122 D6 措辞精度:同构 pin 的编译期证明实际落在 check:test-typecheck 一步,不在裸 tsc #6183)
  • pnpm check:spec-parsed-alias — OK; self-test 18 assertions. This gate reads this file
    as its exemption registry, so it is the one that would notice a mangled pin line; the
    diff touches only comments, a title string and the case body.
  • pnpm check:nul-bytes — OK (6237 files); plus a targeted control-byte self-scan of the
    edited file, clean.
  • pnpm exec eslint packages/spec/src/type-alias-convention.pin.test.ts — exit 0

Changeset

None: the diff is a single *.test.ts file, so nothing user-visible is published.
skip-changeset is the intended route — flagged here for the PM to apply at acceptance
rather than self-applied. Precedent for test-only diffs carrying that label: #6607, #6658,
#6582.


Generated by Claude Code

ADR-0122 pin 文件里的计数被一条计数断言盯着,但那条断言读的是
`export type Iso...` 声明,读不到旁边散文里写的同一个数字。于是文件里
两处散文各自漂了:分节注释停在 717、用例标题停在 755,而实测 pin 数
是 823。标题此前已被手工纠正过一次(751 -> 754,#6037),之后又漂了
第二次 —— 说明手工维护不是解法。

改为把散文纳入同一条计数机制:按短语匹配,而不是按固定行号,这样以后
新写的句子在写下的那一刻就已被覆盖。收据块里的历史数字(749 -> 822、
-7、136 - 17 - 40 - 5 - 1)刻意不匹配 —— 它们描述的是文件的过去状态。
另加一条"守卫的守卫":短语一个都匹配不到时直接判红,避免改写措辞后
这条检查静默失效。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018ffcE95NaMJcL9XJ9VDYgk
@vercel

vercel Bot commented Aug 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 8, 2026 12:51pm

Request Review

@github-actions github-actions Bot added the size/s label Aug 8, 2026
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

No hand-written docs reference the 0 changed package(s). ✅

Copy link
Copy Markdown
Collaborator Author

skip-changeset applied (PM action at acceptance, per the route this PR's body proposed with its three precedents — #6607 / #6658 / #6582). Existing labels read first and merged, so Auto Label's size/s / tests survived the write; read back after: size/s, tests, skip-changeset.

Check Changeset was red for exactly the predicted reason (test-only diff, no changeset, label not yet applied) — failed jobs re-queued now that the label is in place. Per #5625 that gate reads the PR's live labels rather than the triggering event payload, so the re-run should settle it without a no-op push; if it comes back red on the same signature, that is a new problem and gets diagnosed rather than re-run again.

Review verdict is already recorded on #6605 (ACCEPT). Ready-flip and auto-merge wait for the dev's final report per this seat's flip precondition.


Generated by Claude Code

@os-project-manager
os-project-manager marked this pull request as ready for review August 8, 2026 13:10
@os-project-manager
os-project-manager added this pull request to the merge queue Aug 8, 2026

Copy link
Copy Markdown
Collaborator Author

Correction, on the record — skip-changeset is NOT applied automatically in this repo. The dev's closing report carried an operational note claiming Auto Label applied it within 30 s of PR creation. That is a misreading of a later label read, and left uncorrected it would teach the next PM to leave test-only PRs sitting red.

The check-run timestamps settle it:

when what
12:51:07Z PR created
12:51:31→38Z Auto Label ran — applied size/s and tests only
12:51:36Z PM label read: ["size/s","tests"]no skip-changeset
Check Changeset first run: failure (run 31258185809, job 93104738659)
12:53:56Z PM applied skip-changeset by hand (existing labels read first and merged, then read back)
12:54:29→34Z Check Changeset re-run: success

So the sequence the PR body predicted is exactly what happened, and the PM action it asked for was required. What the note got right is the part that matters for re-runs: the gate reads the PR's live labels rather than the triggering event payload (#5625), so a plain rerun_failed_jobs sufficed — no no-op push, no remove-and-re-add dance.

Flipped ready and auto-merge armed: dev report landed and reconciled with the ACCEPT on #6605, head unchanged at e7d5124, all 28 check runs success/skipped, both gate jobs green (ESLint 12:53:52Z, TypeScript Type Check 13:06:53Z).


Generated by Claude Code

Merged via the queue into main with commit c6b05c7 Aug 8, 2026
31 of 32 checks passed
@os-project-manager
os-project-manager deleted the claude/issue-6605-iso-alias-count-comment branch August 8, 2026 13:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

type-alias-convention.pin.test.ts 的分节注释写着 "717 isomorphic aliases",实际 822 —— 唯一没被计数断言盖住的数字

2 participants