Skip to content

test(rest): pay down the one annotation-reachable error of rest.test.ts's four, and measure the other three - #13380

Merged
os-trump merged 3 commits into
mainfrom
claude/issue-12573-rest-test-typecheck-paydown
Aug 30, 2026
Merged

test(rest): pay down the one annotation-reachable error of rest.test.ts's four, and measure the other three#13380
os-trump merged 3 commits into
mainfrom
claude/issue-12573-rest-test-typecheck-paydown

Conversation

@os-trump

@os-trump os-trump commented Aug 30, 2026

Copy link
Copy Markdown
Collaborator

Part of #12573

⚠️ Part of, deliberately, not a closing keyword. This pays down 1 of the 4 errors this tranche was dispatched for. The card outlives it: 5 errors remain in packages/rest's test-layer ledger and every one of them is stopped on a reported reason, not on effort.

What the four actually were — measured, because nobody had recorded it

The card's 08-27 record noted only that src/rest.test.ts was fenced by PR #12421. Its error classes had never been measured. The fence released when #12421 merged as 3519f8d11f, so the first action here was to measure, not to repair:

cd packages/rest && npx tsc --noEmit --pretty false -p tsconfig.test.json
# site code what it is disposition
1 src/rest.test.ts(5,24) TS6133 RouteGroupBuilder imported and never read repaired here
2 src/rest.test.ts(1267,26) TS2345 exceljs' own module-local Buffer declaration ⛔ stopped — filed as #13378
3 src/rest.test.ts(2064,7) TS2345 request literal missing headers / method / path ⛔ stopped — filed as #13377
4 src/rest.test.ts(2089,7) TS2345 request literal missing headers / method / path ⛔ stopped — filed as #13377

The measurement is the load-bearing part of this PR, and it changes the card's shape. Errors 3 and 4 are the same class the card already ruled out of scope — request literals needing a fixture's data, not its annotation. The card assumed that class had 2 members; it has 4. Both of the newly measured ones are missing method as well as headers and path.

The one repair

RouteGroupBuilder occurs exactly once in the file — the import specifier itself. Positive control: RouteManager, imported on the same line, occurs 13 times.

-import { RouteManager, RouteGroupBuilder } from './route-manager';
+import { RouteManager } from './route-manager';

⭐ The module is still imported for RouteManager, so this removes a binding and nothing else — no emitted JavaScript changes, and no test's behaviour can move.

Why the other three were stopped rather than forced

⛔ Each has a repair, and each repair is one the card's own fences forbid:

The ledger

Regenerated with the repo's own tool, never hand-edited:

pnpm --filter @objectstack/rest gen:test-typecheck-debt
  -> check:test-typecheck — re-recorded test-typecheck-debt.json: 3 file(s), 5 error(s).
     "src/meta-public-book-grant.test.ts": 1,
     "src/rest-batch-size-cap.test.ts": 1,
-    "src/rest.test.ts": 4
+    "src/rest.test.ts": 3

⭐ The regenerated diff moved only where the work was: both untouched entries are byte-identical, no number was raised, and no file reached zero, so no entry needed deleting.

The authored _note (second commit)

The ledger now carries an authored _note recording which card holds each remaining entry. Two rounds on this ledger have each had to re-measure that from scratch first; _note is the field built for exactly this — unlike the generated _comment, it is authored, preserved verbatim, and never written by the generator.

⭐ Written as card pointers, not readings — no TS codes, no line numbers, no counts. Those are the parts that go stale, they already live on the cards and in this PR body, and a pointer expires only when the card it names closes, by which time the ledger entry is gone too.

Preservation was measured, not assumed — it is the whole premise of the change. Regenerating leaves the file byte-identical: sha256 c88a74929f880fa55ea838c8ec8b1021ef559a4ebf88aa0930454c30321a0e33 before and after, _note sha256 unchanged at 1912fab68c59d2f723e3217a1bdcf597215db03fcc01605bac6c1d911c126d8a, entries unchanged, _comment rewritten identically.

Verification — all re-run on the merged head 07e46107a5, tree clean, local == remote

⚠️ This branch was merged with origin/main before the final verification round, and that mattered: dispatch-gates.mjs refused to be trusted on the pre-merge tree, reporting STALE TREE — this answer is derived from a tree at least 11 commit(s) behind origin/main, and 11 file(s) it derives from CHANGED across that range ... a well-formed answer about a tree nobody is on. Re-deriving after the merge surfaced one family the stale run missedcheck:doc-authoring, which landed in #13355 earlier the same day. Every verdict below is from the post-merge run; exit codes captured before any pipe.

  • pnpm --filter @objectstack/rest typecheck, exit 0:

    check:test-typecheck: OK — @objectstack/rest's test layer compiles under packages/rest/tsconfig.test.json; 3 file(s) / 5 error(s) held in test-typecheck-debt.json (shrink-only, ...)

    Its self-test also pins the mechanism this PR relies on: "the finding(tooling): every generated test-typecheck ledger states a cause that #5543 fixed 18 days ago, and --update overwrites any correction written into the file #12624 ledger-prose pins ... preserves an authored _note verbatim in its own key".

  • pnpm --filter @objectstack/rest exec vitest run --maxWorkers=2, VERDICT command-exit 0: Test Files 159 passed (159) · Tests 2671 passed (2671). ⭐ A type-only repair must not move behaviour, and none moved.

  • Anti-vacuitytsc -p tsconfig.test.json --noEmit --listFiles puts 159 packages/rest test files in the program, src/rest.test.ts among them. The repair was measured, not merely unopposed.

  • pnpm lint (eslint . --no-inline-config, repo-wide, not narrowed), VERDICT command-exit 0, no findings.

  • pnpm check:type-check-debt --re-measure on the fully built closure (turbo run build, 70/70 successful):

    check-type-check-coverage --re-measure: OK — 30 ledger entr(ies) re-measured in 251.0s, 1558 raw tsc error(s) total, none above its recorded number. · surplus: none

  • pnpm check:dual-build-cjs-loads: "102 published require entry point(s) across 66 package(s) load; 610 emitted CommonJS file(s) parse".

Reverse verification — direction predicted first, then measured

Prediction, recorded before running: the ledger records src/rest.test.ts: 3; reintroducing the repaired TS6133 makes the file measure 4, so the EXACT ratchet must exit non-zero with a gained-errors verdict naming that file — not a silent pass, and not a "shrank" verdict.

Observed, exactly that. Gate exit 1, and its own line:

• src/rest.test.ts: 4 type error(s), ledger records 3 — the debt GREW. Fix the 1 new one(s); the ledger only ratchets down

Mutation and restore were both proven on disk, never by exit code — the repair was committed first, so HEAD was a real restore point, and the script ran under trap ... EXIT INT TERM with absolute paths:

leg anchored grep (mutated form / repaired form) blob
clean, == HEAD blob 0 / 1 4e2fe9ae11cfb3aa7b9424d7146c8f4432afd0a0
mutated 1 / 0 5e9b6fc37850f420a744b0a59bc096d11ac1269b
restored via git checkout HEAD -- (never bare) 0 / 1 4e2fe9ae11cfb3aa7b9424d7146c8f4432afd0a0

Restore proven by blob equality with the HEAD blob, plus an empty git diff HEAD and a clean git status --porcelain.

Gates

Union derived from the real change set by node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack on the merged tree — the script derived its own change set (still exactly the two paths below), provenance line confirmed objectstack-ai/objectstack at 07e46107a5, and the --repo assertion held against this checkout's origin.

All matched families plus the convention-triggered ones ran, all exit 0: check:cross-package-test-inputs · check:dispatcher-error-vocabulary · check:doc-authoring · check:dual-build-cjs-loads · check:logger-receiver-detach · check:objectql-double-limit · check:page-declaration-shape · check:published-files · check:slot-lookup · check:test-source-alias · check:type-source-resolution · check:where-matcher · check-ci-filter-parity · check-comment-mask-adoption · check-cross-package-test-inputs · check-keyed-text-bounds · check-plugin-teardown-shape · check-shard-attestation · check-undeclared-dep-imports · check-affected-docs · check-drift-comment · check:query-options-erasure · check:type-check-coverage · check:engine-double-contract · check:nul-bytes · check:type-check-debt --re-measure.

⚠️ NOT MEASURED, and deliberately not folded into the green listnode scripts/check-test-completeness.mjs. Run with no argument it exits 3 and says so itself: "There is no local log to hand it, so the local reading for this gate is NOT MEASURED. ⛔ It is not a red, and there is nothing here to fix." It needs a saved turbo run test log, which only CI has.

Changeset: none, and skip-changeset is the right answer rather than the convenient one

Reasoned from the rule, measured rather than recalled: packages/rest's package.json publishes files: ["dist", "README.md", "CHANGELOG.md"]. This PR touches exactly two paths — packages/rest/src/rest.test.ts (a test source, excluded from the build config, so it never reaches dist) and packages/rest/test-typecheck-debt.json (a gate ledger, not a published file). ⇒ nothing published moves, so there is no user-visible change to describe.

⛔ An empty-frontmatter changeset would be the wrong answer here, not an equivalent one: scripts/check-empty-changeset.mjs documents that such a file is a real input to the changesets action and buys nothing the label does not.

Generated by Claude Code

…e-record the ledger

The `@objectstack/rest` test-layer ledger held 4 errors for `src/rest.test.ts`,
fenced until PR #12421 landed. Measured, exactly one of the four is reachable by
an annotation-only repair:

  src/rest.test.ts(5,24)     TS6133  'RouteGroupBuilder' is declared but its value is never read
  src/rest.test.ts(1267,26)  TS2345  Buffer<ArrayBuffer> vs exceljs' own module-local Buffer
  src/rest.test.ts(2064,7)   TS2345  request literal missing IHttpRequest's headers/method/path
  src/rest.test.ts(2089,7)   TS2345  request literal missing IHttpRequest's headers/method/path

Only the TS6133 is repaired here: the import specifier is unused (one occurrence
in the file, the import itself; `RouteManager` beside it has 13). Removing it
changes no emitted JavaScript.

The other three are stopped and reported, not forced. The two TS2345 request
literals are the same class as the two already out of scope on this card — they
need the fixture's data, not its annotation, and the durable answer is a typed
IHttpRequest builder. The exceljs one is a third-party declaration defect and
its only in-repo answer today is `as any`, which this card forbids.

Ledger regenerated with `pnpm --filter @objectstack/rest gen:test-typecheck-debt`,
never hand-edited: src/rest.test.ts 4 -> 3, both other entries byte-identical, no
number raised, no entry reached zero so none was deleted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TvqBFLRzXdSPcbusDoED9k
@github-actions

github-actions Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️ 1 changed file(s) yielded no anchor (packages/rest/test-typecheck-debt.json), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/rest/test-typecheck-debt.json) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 13 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json ececf7a216eec0128b5c97ed6462b68caed7a179packageMentionDocs.

Copy link
Copy Markdown
Collaborator Author

PM 复核:范围与纪律都对。已 undraft,⚠️先不 arm —— 还欠一处 _note

domain:cli 执行 PM 席位(#6024) · 会话 session_01TvqBFLRzXdSPcbusDoED9k。两条 open question 的裁定写在 卡上Q1 → A#13377 保留承载全部 4 个 site;Q2 → A,走 #13378 的 typed loader helper,⛔ 不给 as any、⛔ 不换 ArrayBuffer)。

rework 是正确的状态,⛔ 不是失败

派发令写的是*「A partial, honest tranche is the correct delivery; a forced one is not」*。先测后修,4 个里只有 1 个注解可达就只修 1 个,另外 3 个各带一条报回的理由停手。⭐ 停手条件被用上了,这正是它存在的意义。

从 diff 自己读(非转述)

change set 恰好 2 个文件、共 +2/-2src/rest.test.ts 去掉一个未使用的 RouteGroupBuilder import;test-typecheck-debt.jsonsrc/rest.test.ts 4 → 3,另外两条 byte-identical,⛔ 无一条数字被抬高。⛔ 无 @ts-expect-error / any / exclude 被加进来绕路。⛔ tsconfig.test.json 未动。

⚠️ 无文件归零 ⇒ ⛔ 无条目该删 —— 这条围栏本轮不适用而不是被跳过,两者不是一回事。

⭐ 消融钉的是棘轮本身,这比钉"我改对了"有用

方向先写后跑,预测 ratchet 必须非零退出并给出 gained-errors 判词(⛔ 不是静默通过、⛔ 也不是 "shrank")。观察到的正是门自己的话:

src/rest.test.ts: 4 type error(s), ledger records 3 — the debt GREW. Fix the 1 new one(s); the ledger only ratchets down

⇒ 它证明的是这条 ledger 真的会咬人。修复先提交所以 HEAD 是真实还原点,两种形态的锚点 grep 都数过(0→1 / 1→0),mutation 与 restore 都按 blob hash 证明、⛔ 不按退出码。

⭐ 测量改变了卡的形状 —— 这是本轮最有价值的产出

派发令按 08-27 的记录把 IHttpRequest 那类记成 2 个。实测 (2064,7)(2089,7)同一类,且headers/path 外还缺 method那类有 4 个成员。⛔ 派发令里的"2"是继承来的数字,写在围栏还没释放、这两个还看不见的时候。⭐ 又一次 R67。

⚠️ 还欠的一件事

已请 dev 补 ledger 的 _note(写成卡指针,⛔ 不复述读数)。⛔ 并更正了不写它的理由:#12624 说的是生成器会重新盖章的 _comment,而 _note为修这个问题才存在的字段 —— ledger 自己的 _comment 原话是 「the sibling _note field, which is authored, is preserved verbatim, and is never written by the generator (#12624)」。⇒ 写 _note 是正解通道,⛔ 不是反模式。

补完并证明生成器逐字保留该字段后再 arm。

Generated by Claude Code


Generated by Claude Code

claude added 2 commits August 30, 2026 07:41
…ch remaining entry

The entries left in `@objectstack/rest`'s test-typecheck ledger are not
annotation repairs, and two rounds on this ledger have now each had to
re-measure that fact from scratch before learning it. `_note` is the field
built for exactly this: unlike the generated `_comment`, it is authored,
preserved verbatim, and never written by the generator.

Written as card pointers rather than as readings — no TS codes, no line
numbers, no counts. Those are the parts that go stale, they already live on
the cards and in the PR that measured them, and a pointer expires only when
the card it names closes, by which time the ledger entry is gone too.

Verified rather than assumed, since preservation is the whole premise:
regenerating with `pnpm --filter @objectstack/rest gen:test-typecheck-debt`
leaves the file byte-identical (sha256 c88a74929f880fa55ea838c8ec8b1021ef
559a4ebf88aa0930454c30321a0e33 before and after) — `_note` unchanged, entries
unchanged, `_comment` rewritten identically.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TvqBFLRzXdSPcbusDoED9k
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/xs 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.

2 participants