Skip to content

build(trigger-record-change): graduate the package out of the TEST_DEBT ledger - #11489

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-11204-trigger-record-change-graduation
Aug 24, 2026
Merged

build(trigger-record-change): graduate the package out of the TEST_DEBT ledger#11489
os-steve merged 1 commit into
mainfrom
claude/issue-11204-trigger-record-change-graduation

Conversation

@claude

@claudeclaudeBot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Fixes#11204

check:type-check-debt --re-measure reported @objectstack/trigger-record-change
as a graduation candidate: TEST_DEBT records 9, tsc reports 0.

Premise re-derived on current main

Re-run on origin/main @ 7f30b6be (full closure built first — 70/70 turbo tasks —
then node scripts/check-type-check-coverage.mjs --re-measure, 273.9s):

ℹ @objectstack/trigger-record-change: TEST_DEBT records 9, and tsc now reports 0
-- graduation candidate.
check-type-check-coverage --re-measure: OK — 33 ledger entr(ies) re-measured in
273.9s, 1897 raw tsc error(s) total, none above its recorded number.

Still a graduation, not a ceiling lowering. No other package's entry is touched.

The 0 is a reading, not a zero-hit

A misconfigured invocation reports 0 too, so the measurement was controlled twice.

File census. The generated re-measure project puts 10 files from this package
in the program — 3 src + all 7 tests — out of 467 total (tsc --listFiles).

Planted error. A type error appended to src/formula-context.test.ts (marker
grepped on disk, blob hash compared before/after):

mutated : formula-context.test.ts(115,7): error TS2322 ... COUNTED=1 TSC_EXIT=2
restored : COUNTED=0 TSC_EXIT=0 (hash back to 3672183f, byte-identical)

So the program really reads the test layer, and 0 is its verdict about it.

The gate's two remedies are NOT interchangeable here — measured

The graduation message offers "add a typecheck script"or"drop the test
exclusion"
. Neither description fitted this package.

Remedy 1 was already done. The package has carried "typecheck": "tsc --noEmit"
all along. It was never in DEBT's hole ("src does not check"); it was in TEST_DEBT's
("src checks, tests are hidden" — **/*.test.ts in the build tsconfig's exclude).

Remedy 2 turns main red. Dropping the exclusion is harmless in the two places
one would check, and fails in a third:

readingwith exclusionexclusion dropped
tsc --showConfig resolved files3 (src only)10 (3 src + 7 tests) — the exact set the ledger scored at 0
dist/ after pnpm --filter … build6 files, 0 test artifacts6 files, 0 test artifacts (tsup builds src/index.ts alone)
check:type-source-resolutionexit 0exit 1

The failure:

✗ @objectstack/trigger-record-change: NEW dist-resolved type import(s) since this
entry was measured: @objectstack/driver-sql, @objectstack/formula,
@objectstack/objectql, @objectstack/service-automation.

The 7 re-admitted tests import four workspace packages the build config's program
never contained, and that registry is shrink-only with set equality — its own message
rules that widening the entry is not the remedy. The remedy it does ask for (paths
rules onto those four dependencies' source) is a separate card by that gate's explicit
ruling: "Remediation is per-package and lands as its own card, because the switch is
not free."

What this PR does instead

The sibling-config route the repo already uses for packages/spec, client,
metadata-core and metadata-fs (the #5286 mechanism):

  • newpackages/triggers/trigger-record-change/tsconfig.test.json — extends the
    build config, drops **/*.test.ts from exclude and nothing else, asserts noEmit.
    Module semantics, rootDir and strictness are all left inherited on purpose: the
    ledger's 0 was measured under those settings (and reported TS6059 x0, so there is no
    misconfiguration diagnostic to neutralise). A different module would be a different
    measurement.
  • typecheck becomes tsc --noEmit && tsc --noEmit -p tsconfig.test.json, so the
    sibling is named — a config no script invokes reads as coverage and delivers none.
  • the TEST_DEBT entry is deleted in the same commit, as the gate's structural half
    requires. The prose above TEST_DEBT records why both advertised remedies missed.

tsconfig.json — the only config check:type-source-resolution reads — is untouched,
so that gate's declared population is unchanged.

Resulting program (tsc --showConfig -p tsconfig.test.json): 10 files, module
nodenext, rootDir ./src, strict true — byte-for-byte the file set the 0 was
measured over.

Verification (all at 1a383fa3)

Positive control on the wired script, not just the synthetic project — a planted error
in src/record-change-trigger.test.ts takes pnpm --filter … typecheck from exit 0 to
exit 2 (error TS2322), restored byte-identical:

pnpm --filter @objectstack/trigger-record-change typecheck → exit 0
(echoed: tsc --noEmit && tsc --noEmit -p tsconfig.test.json)
pnpm --filter @objectstack/trigger-record-change test → 7 files, 78 tests passed
pnpm lint (repo-wide, eslint . --no-inline-config) → exit 0, 1m43s

The 17-family floor from node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack
all exit 0. The two that carry this change:

check-type-check-coverage: OK — 65/78 workspace packages type-checked …
check-type-source-resolution OK — 77 packages with a tsconfig.json scanned;
51 registered as still resolving a workspace dep's types through `dist/`.
check-type-check-coverage --re-measure: OK — 32 ledger entr(ies) re-measured in
291.6s, 1897 raw tsc error(s) total, none above its recorded number.

What moved, origin/main @ 7f30b6be → this branch @ 1a383fa3:

beforeafter
ledger entries re-measured3332
packages hiding their tests2019
hidden test files10481041
frozen raw errors in TEST_DEBT14841475
surplus above measured23 across 414 across 3
total raw tsc errors18971897

The unchanged 1897 is the check that no other ceiling moved: a 0-error entry left the
ledger and nobody else's number did.

Changeset

Labelled skip-changeset. The diff is a build-time typecheck script, a tsconfig the
package does not publish (files is dist / README / CHANGELOG), and a CI-internal
gate script. dist/ was measured byte-identical, so this PR releases nothing.

Filed separately, not addressed here

  • check:type-source-resolution reads each package's tsconfig.json and only that one,
    so a sibling tsconfig.test.json — this repo's own supported repair, now in five
    packages — puts a whole tsc program outside its declared population.
  • The graduation message advertises its two remedies as interchangeable; this card is a
    worked counterexample in both directions.

Generated by Claude Code

…BT ledger
`check:type-check-debt --re-measure` reported TEST_DEBT 9 against a measured 0
for `@objectstack/trigger-record-change`. The 0 re-derived on current main
(7f30b6b) and holds, so this is a graduation rather than a ceiling lowering.
The gate's graduation message offers two remedies as interchangeable. Neither
description fitted this package, and both halves were measured before choosing:
* "add a `typecheck` script" — it already had one (`tsc --noEmit`). The hole
was TESTS_COVERED (src checks, tests hidden by `**/*.test.ts` in the build
tsconfig), not COVERED.
* "drop the test exclusion" — resolves exactly the 10-file program the ledger
scored at 0 (`tsc --showConfig`) and leaves `dist/` byte-identical, but the
7 re-admitted tests import @objectstack/driver-sql, /formula, /objectql and
/service-automation, which the build config's program never held:
`check:type-source-resolution` goes exit 0 -> exit 1 naming all four,
against a shrink-only registry whose own message rules that widening the
entry is not the fix.
So it takes the sibling-config route the repo already uses for `packages/spec`,
`client`, `metadata-core` and `metadata-fs`: a `tsconfig.test.json` named by the
`typecheck` script, putting the same 10 files in front of tsc while the build
config — the only one that gate reads — is untouched. The ledger entry is
deleted in the same commit, as the gate's structural half requires.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ahemw8RcTgqtxrj15PEZx
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

Nothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs.

@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 32673631029 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

失败的 job(日志抽取,best effort):

  • Test Core (6/6) — 失败步骤: Run this shard's tests

    × ABLATION: the fixture still reddens a green run under vitest defaults 10864ms
    FAIL test/vitest-console-teardown-race.test.ts > [#10293] vitest console-forwarding teardown race > ABLATION: the fixture still reddens a green run under vitest defaults
    ↳ 失败原因: AssertionError: the instrument stopped reproducing: 8 attempts under vitest defaults produced no "Closing rpc while "onUserConsoleLog" was pending". Either vitest changed its console forwarding (check
    

↳ 失败原因 是判读的关键:超时Test timed out in … / Hook timed out in …)多半是负载/时序,不是本 PR 的回归;
断言AssertionError: …)才指向真实的行为改变。两者的 FAIL 行长得一模一样,只有这一行能区分。

跨 PR 相同签名(24h,按失败测试文件聚合):

  • test/vitest-console-teardown-race.test.ts — 24h 窗口内只有本 PR 撞到过,暂不汇总(再有一个不同 PR 撞到就会自动开汇总 issue)。
  • ⚠️ 24h 评论账本没读完(超过 5 页仍未读到窗口尽头),所以上面的「不同 PR 数」是下界,不是全量。

历史信号:

  • 本 PR 过去 24h 无队列失败记录(首次)。
  • 过去 24h 队列共有 6 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 看上面的「跨 PR 相同签名」;已有汇总 issue ⇒ flaky/环境问题实锤,去那张 issue 上谈,修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

@os-steve
os-steve added this pull request to the merge queueAug 23, 2026
Merged via the queue into main with commit 951b025Aug 24, 2026
36 checks passed
@os-steve
os-steve deleted the claude/issue-11204-trigger-record-change-graduation branch August 24, 2026 00:03
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependenciesPull requests that update a dependency filesize/sskip-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] @objectstack/trigger-record-change TEST_DEBT records 9 while tsc reports 0 — graduation candidate the ratchet deliberately leaves alone

2 participants

@os-steve@claude