Uh oh!
There was an error while loading. Please reload this page.
fix(devx): sweep the type-check debt ledger onto its measurements - #12798
Conversation
`--re-measure` is green by design while an entry sits ABOVE its measured count -- the contract is "none above its recorded number" -- so the slack lives in the ledger data, not in the gate's logic. Nothing schedules the `--lower` the tool advertises on every run, which is disclosure rather than a mechanism. All 31 entries were re-measured at ead7317 on a closure the gate built itself. 4 carried slack, worth 118 raw errors: objectql 354 -> 251, runtime 227 -> 217, plugin-auth 97 -> 94, plugin-approvals 347 -> 345. Numbers written by `--re-measure --lower`, never typed by hand. All four are TEST_DEBT; none of the 13 DEBT entries had moved. A DEBT number is what a package's own `typecheck` would report, so repair work there is visible to whoever does it; a TEST_DEBT number exists only inside the temp project this gate generates, so fixing a test-layer type error moves a number nobody sees until the next sweep. The header now records that. The four notes are corrected rather than left stranded: each records the lowering, and says its tally was taken at the OLD number and is NOT re-tallied, since the sweep measured totals only. `--lower` wrote no `compositionAt` for any of them (per-code tallies are not tier itemisations, and two of the notes were already ambiguous), so nothing mechanical would have said the notes had gone stale. Three of them also asserted a present-tense equality with a field that had moved -- the failure the header names as the surest way to make the next reader mis-derive this policy. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PfaSTikked61BkcsB5Rn69
os-zhuang
commented
Aug 27, 2026
复核:ACCEPT —— 但 ⛔ 尚未武装,CI 还在跑
人工地板:不成立,且我独立核了方向台账数字只准降不准升,是这张卡最容易越界的一条。我没信 PR 正文那张表,直接对 diff 抓了所有数值改动: 恰好四处,全部向下,零新增条目、零上调。⇒ 是收紧棘轮,⛔ 不是削弱; ⭐⭐ 结果的形状不是卡预测的形状,而这比数字本身更值钱四条全是 TEST_DEBT;13 条 DEBT 一条没动,每条都精确到单位。你没有把这当巧合,而是给出了机械成因,并写进了门禁头注:
⇒ 盈余不是均匀分布的噪声,它恰好堆积在那一层测量在门禁之外不可见的地方。这解释了 4/31 为什么落成这个分布,而不只是报了个 4。 ⭐ 而且卡自己的那条是同一件事的第二次读数:卡按 ⭐⭐ 正对照:因为「27 个零」正是一个什么都没测的仪器会给出的读数这是全轮四份里我最想记名的一条。一张 27 行「无漂移」的表,和一张仪器根本没读到数的表,长得一模一样。你没有让它停在那里:
⇒ DEBT 臂读的是真数,它的零漂移是测量,不是沉默。 这正是 brief 里「⛔ 反向核对任何零」那条最难记住的方向——因为零看起来像好消息。 ⭐ 而且离开和到达都钉了,各自标注取数的 sha:
|
os-zhuang
commented
Aug 27, 2026
补记:终报里推翻了本席两条 zone 2 假设,都记名复核结论不变(ACCEPT,等绿灯)。这条只登记证伪,因为 zone 2 写的是「鼓励证伪、实测赢」,那就得兑现。 ① 「224s 让它成为本车道最贵的门禁,计划跑一次」—— 部分证伪。 re-measure 本身是 231–243s,但它要求的冷闭包构建是 6m39s(新 worktree,70/70 任务)⇒ 首次读数的真实成本约 11 分钟,而且装不进一次前台调用。 ② 「漂移是日常修复工作的自然后果」—— 机制猜错了。 13 条 DEBT 一条没漂,4 条全在 TEST_DEBT。正确的机制是你写进头注的那条:只有 TEST_DEBT 那一层的计数对 contributor 跑的任何东西都不可见。我的版本会预测两个台账都漂,那是错的。 ③ 一条我没写进 zone 2、但该记的: ⭐⭐ 还有一条,是这一轮四个 dev 里第三次自己抓住自己的仪器
⭐ 另记: Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Closes#12723
What the card asked first, and the answer
The ordering was the deliverable: measure all 31 ledger entries, not only the one named, because whether the drift is one-off or systemic decides everything downstream.
4 of 31 entries carried slack, worth 118 raw errors. All numbers were written by
--re-measure --lower, never typed by hand.@objectstack/objectql@objectstack/plugin-approvals@objectstack/runtime@objectstack/plugin-auth@objectstack/cli@objectstack/mcp@objectstack/formula@objectstack/lint@objectstack/plugin-security@objectstack/driver-mongodb@objectstack/verify@objectstack/connector-mcp@objectstack/connector-openapi@objectstack/platform-objects@objectstack/plugin-sharing@objectstack/http-conformance@objectstack/service-sms@objectstack/connector-rest@objectstack/core@objectstack/metadata@objectstack/metadata-protocol@objectstack/service-storage@objectstack/spec-monorepo@objectstack/cloud-connection@objectstack/observability@objectstack/service-analytics@objectstack/service-knowledge@objectstack/knowledge-ragflow@objectstack/hono@objectstack/service-automation@objectstack/service-clusterRecorded sum 1688 minus the 118 of surplus equals 1570, which is the
raw tsc error(s) totalthe gate printed for the same run. The table is not a transcription: the "measured" column is the ledger after--lowerwrote it, cross-checked against the gate's own per-entrycan be loweredlines and against that total.The shape of the result is not the shape the card predicted
All four are TEST_DEBT. Not one of the 13 DEBT entries had moved — every one measured its recorded number to the unit.
That asymmetry has a mechanical cause, and it is now recorded in the gate's header. A DEBT number is what the package's own
typecheckwould report if it had one, so ordinary repair work in those packages is visible to whoever does it. A TEST_DEBT number is only ever produced by the temp project this gate generates — nothing a contributor runs reports it — so fixing a test-layer type error moves a number nobody sees until the next sweep. The surplus is not evenly distributed noise; it accumulates in exactly the layer whose measurement is invisible outside this gate.The card's own entry is a second reading of the same thing: it was filed on
@objectstack/runtimeat 227-vs-226, and the slack measured 10, not 1. The 226 was itself a reading taken days earlier — the card's point about a number that drifts, applied to the card.Notes, and why they needed hand work
--lowerwritescompositionAtbeside a number it lowers so a stranded tier itemisation says out loud which pile it still describes. It wrote none for any of the four, and that is correct behaviour rather than a miss: two of the notes itemise per-code tallies (TS2339 x296, ...), which the COMPOSITION reader deliberately does not sum, and two were already ambiguous to it. So nothing mechanical would have said these notes had gone stale — and three of them asserted a present-tense equality with a field that had moved, which the header names as the surest way to make the next reader mis-derive this policy:objectql— "this entry now measures its recorded 355 EXACTLY" and "There is no slack here today", both true at 62b2655 and both false at the sweep. Re-cast as history, with the 103 of drift recorded.plugin-auth— "= 97, the recorded number EXACTLY -- no margin".plugin-approvals,runtime— per-code tallies taken at the old totals.Each of the four now records its lowering and states that its tally was taken at the OLD number and is not re-tallied here, because this sweep measured per-entry totals only. An admitted gap, not an invented composition — the rule the ledger is written against.
Out of scope, deliberately
The self-tightening gate change — failing when an entry sits above its measurement — is not in this PR, per triage. This sweep's count is the evidence that question needed, and it is filed unassigned and ungraded as #12799 with the 4-of-31 / 118-raw-error reading as its whole argument.
Two sibling cards on this family were left untouched: #12624 (generated test-typecheck ledgers state a cause an earlier PR had already repaired) and #12511 (a type error in a ledgered package's tests is invisible to its own
typecheck). The second is adjacent — its subject is the mechanism this PR's header paragraph cites to explain the TEST_DEBT concentration — but nothing here changes it.Verification
Measured on a workspace closure the gate built itself.
--re-measurerefuses on an unbuilt closure (BUILT CLOSURE) and refreshes it with the same turbo command lint.yml runs, so this is not "a fully built workspace" by luck; the precondition is enforced. Closure built cold in 6m39s (70/70 tasks), then re-measured.Departure and arrival are both pinned, at the sha each was taken on:
ead731756(clean tree):31 ledger entr(ies) re-measured in 243.3s, 1570 raw tsc error(s) total·surplus: 118 raw error(s) across 4 entr(ies) sit BELOW their recorded ceilingb9dcf51da(this branch's head):31 ledger entr(ies) re-measured in 231.2s, 1570 raw tsc error(s) total, none above its recorded number·surplus: none — every entry sits exactly at its measurement, so any new error is red.The two runs agree on 1570 to the unit, which is also the determinism check the header prescribes before treating any such reading as calibration rather than tsc noise.
Positive control, because a table of 27 zeros is exactly the reading an instrument that measured nothing would produce. Four DEBT entries known to carry non-zero debt were measured independently of the gate, by running its own recipe by hand (
tsc --noEmit --pretty false -p PACKAGE/tsconfig.jsonfrom the repo root, counting the diagnostic lines):observability11,service-cluster1,service-analytics10,metadata89 — each equal to its recorded number. The DEBT arm reads real numbers; its zero drift is a measurement, not a silence.Gates run at the final head
b9dcf51da, each read from its own verdict line rather than a piped$?:pnpm check:type-check-debt— OK (self-test: 47 semantic + 65 observation + 29 re-measure + 28 built-closure + 19 auto-lowering cases hold; then the arrival re-measure above)pnpm check:type-check-coverage·check:agent-test-spelling·check:bash32-floor·check:cli-command-ids·check:cross-package-test-inputs·check:entry-guard·check:parse-guard·check:pnpm-filter-targets— all exit 0node scripts/check-ci-filter-parity.mjs·node scripts/check-cross-package-test-inputs.mjs— OKpnpm check:pm-dispatch-gates(736 cases),node scripts/check-self-test-wired.mjs(140 scripts),node scripts/pm/bare-root-worklist.mjs --self-test(46 live rows, none stale/missing/contradicted) — all OKnode scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstackatb9dcf51da: the family matches the dispatch list exactly, no additionscheck-ratchet-remedy-authority(OK, 155 scripts swept),check-type-source-resolution(OK, 94 programs)pnpm lint— full repo,eslint . --no-inline-config, exit 0 in 64s. Not narrowed.check:nul-bytesOK; the diff independently scanned for raw control bytes, none foundEvery build and every measurement ran through
scripts/pm/os-verify-lock.sh.Changeset
None.
scripts/**only, no published package —skip-changeset.Generated by Claude Code
Generated by Claude Code