Skip to content

fix(tooling): re-tally @objectstack/rest's TEST_DEBT composition from tsc - #11496

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-10821-plugin-rest-tally-retally
Aug 24, 2026
Merged

fix(tooling): re-tally @objectstack/rest's TEST_DEBT composition from tsc#11496
os-steve merged 1 commit into
mainfrom
claude/issue-10821-plugin-rest-tally-retally

Conversation

@claude

@claude claude Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Fixes #10821

TEST_DEBT['@objectstack/rest'] carried a per-code tally that summed to 147 while
declaring it was counted at 153, with no remainder clause — and the entry's own
errors: field records 155. The tally is now taken from one tsc run against a built
workspace closure
and sums to the recorded number exactly.

⛔ No digit was adjusted to make the old numbers agree. Every number below comes from a
single measurement; the old ones are quoted only as history.

The measurement

Closure built with the same command lint.yml runs before this gate, then the gate's own
re-measure, both under this container's shared heavy-verify lock:

turbo run build --filter=./packages/* --filter=./packages/*/*   → Tasks: 70 successful, 70 total (6m58s)
pnpm check:type-check-debt                                      → 32 ledger entries re-measured in 282.1s,
                                                                  1897 raw tsc errors, none above its recorded number

Per-code histogram for this entry, counted by the gate's own rule
(TSC_ERROR_LINE, TS6059 dropped — 0 dropped here):

code count what it is
TS2835 72 NodeNext extensions
TS7006 49 implicit any
TS2550 16 Array.prototype.at against a lib older than es2022 (all 16 are that one message)
TS2554 14 wrong arity (all 14 are Expected 2-5 arguments, but got 1)
TS2769 2 singleton tail
TS2345 1 singleton tail
TS6133 1 singleton tail

72 + 49 + 16 + 14 + 4 = 155, which is errors: 155 exactly. The remainder is spelled
as the house form the siblings use (plugin-approvals, objectql): "plus 4 singletons
(TS2769 x2, TS2345, TS6133)"
.

Both questions the note raised, answered

(a) the 147-vs-153 gap is retired unattributed, not invented. The per-class breakdown at
e8db1a230 was never retained, so the 6 cannot be recovered — and this ledger's own rule is
that a made-up attribution is worse than an admitted gap. They are retired with the tally
that carried them.

(b) 153-vs-155 was never one measurement disagreeing with itself. 153 was measured at
e8db1a230; RECORDED was later lowered onto a different measurement, 155 at 55da611
(#6939); the composition was never re-taken across that move. That is precisely what the
"not re-tallied by class at the 155 below" clause was saying out loud — the note was
honest, not sloppy.

Rescaling the old tally onto 155 would have been wrong in any case, which is why this is
a re-tally and not arithmetic: the shape moved in both directions — TS2835 67 → 72,
TS2550 10 → 16 and TS2554 13 → 14 rose while TS7006 57 → 49 fell — and two classes the
old tally never named (TS2769, TS2345) are in the pile now.

errors: 155 is unchanged

tsc reports exactly 155 for this entry today, so the shrink-only ceiling neither moves nor
needs to. @objectstack/rest does not appear in the run's surplus list; the three entries
that do are named under out-of-scope below. This is a note-only change — no ratchet
number moves in either direction.

Structural facts now in the note, all from the same run: the 72 TS2835 sit on 72 distinct
lines across 64 files but name only 11 distinct import targets, and 49 of the 72 are the
single ./rest-server import; every one of the 22 files carrying a TS7006 also carries a
TS2835, with no exceptions; src/rest.test.ts alone holds 38 of the 155 and no other file
is above x5. That replaces the old "they are one repair, not 124" with a measured
"they are 72 import-line repairs, not 121".

One declared change beyond the entry

The COMPOSITION docblock (#10722) used this entry as its worked example for why per-code
tallies are deliberately not summed:

//     partial by construction: plugin-rest's tally sums to 147 and says so in
//     the same breath ("composition as counted at 153"), so summing them would

Re-tallying the entry makes that sentence false about the tree, in a comment whose job is to
stop someone "fixing" the rule into summing tallies — the docblock's own stated
false-red hazard. The rule is untouched; only its worked example is marked retired, and
the entry is named correctly (@objectstack/rest, not plugin-rest — that mis-naming in
this comment is where the card's own title got the package name from). The gate's self-test
(47 semantic + 59 observation + 29 re-measure + 28 built-closure + 19 auto-lowering cases)
passes, and this entry's note opens with a per-code tally, so COMPOSITION still abstains on
it exactly as before.

Verification — all on 9fef66af

Gate floor derived with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack
(no hand-written path list; 1 path in the change set), all 8 families run plus check:nul-bytes:

gate verdict line
check:type-check-debt --re-measure: OK — 32 ledger entr(ies) re-measured in 282.1s, 1897 raw tsc error(s) total, none above its recorded number.
check:type-check-coverage check-type-check-coverage: OK — 65/78 workspace packages type-checked …
check:cross-package-test-inputs OK: 14 package(s) read outside themselves, all declared …
check:entry-guard ✓ check:entry-guard: 139 scripts/ file(s) — every entry guard goes through invoked-as.mjs …
check:parse-guard ✓ check:parse-guard: 138 scripts/ file(s) — every TypeScript parse goes through ts-parse.mjs.
check:pnpm-filter-targets ✓ check:pnpm-filter-targets: 120/148 --filter occurrence(s) across 25 file(s) resolve …
check-ci-filter-parity.mjs OK: all 89 declared cross-package glob(s) (77 unique) are covered …
check-cross-package-test-inputs.mjs OK: 14 package(s) read outside themselves, all declared …
check:nul-bytes check-nul-bytes: OK (scanned 6448 text file(s) … no raw ASCII control bytes).

Declared narrowing — lint, measured rather than asserted. The repo-wide pnpm lint was
narrowed to the changed file, and the narrowing is a measurement:

  1. Population read from eslint's own resolution, not a guess: the change set is 1 path
    (dispatch-gates, three-dot against the merge base), and eslint returned a result object
    for it rather than an ignore warning.
  2. File count read from --format json: results.length === 1, errorCount 0,
    warningCount 0, suppressedMessages 0, exit 0.
  3. Invariance for untouched files: this repo enables no type-aware linting for any file
    grep -c projectService eslint.config.mjs → 0, no parserOptions carrying project,
    no project: key — so a one-file, comment-only diff cannot move the verdict on any file
    it does not contain. (eslint.config.mjs's own header states the same fact and cites a
    positive control for it.)

CI runs the full farm regardless; this is the cheap half, run early.

Out of scope — recorded only, left untouched

The same re-measure reports three entries sitting below their recorded ceiling. All are
left alone:

The gate prints all three on every run and #6376 is their standing tracking card, so no new
issue was filed for them.

Notes for review

  • The histogram was produced from the gate's own measurement world, not a re-derived one:
    the script was temporarily instrumented to dump raw tsc output, the dump was histogrammed,
    and the script was then restored byte-identically (sha256 5a795e74… before and after,
    git diff --quiet exit 0, zero instrumentation tokens left) before the real edit was
    written. No instrumentation appears in this diff.
  • No changeset: this edits a CI-internal script and releases nothing, which lint.yml's own
    changeset-family block names as the textbook skip-changeset case. The label is applied.

Generated by Claude Code

… tsc

The entry's per-code tally listed TS2835 x67, TS7006 x57, TS2554 x13,
TS2550 x10 -- 147 -- while declaring it was counted at 153, with no
remainder clause, and the entry's own `errors:` field records 155. The
tally is now taken from one tsc run against a built workspace closure
and sums to the recorded 155 exactly:

  TS2835 x72, TS7006 x49, TS2550 x16, TS2554 x14, plus 4 singletons
  (TS2769 x2, TS2345, TS6133)  =  155

No digit was adjusted to make the old numbers agree. The old shape moved
in both directions against the new measurement (TS7006 fell 57 -> 49
while TS2835 rose 67 -> 72), so no rescale of it could have been right.
The 6 unaccounted at 153 are retired unattributed rather than invented --
the per-class breakdown at e8db1a2 was never retained.

`errors: 155` is unchanged: tsc reports exactly 155 today, so the
shrink-only ceiling neither moves nor needs to.

The COMPOSITION docblock used this entry as its worked example for why
per-code tallies are not summed; the rule is untouched, its example is
marked retired so the comment does not assert a tree that no longer
exists.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015ahemw8RcTgqtxrj15PEZx
@claude claude Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 24, 2026
@os-steve
os-steve marked this pull request as ready for review August 24, 2026 01:23
@os-steve
os-steve added this pull request to the merge queue Aug 24, 2026
Merged via the queue into main with commit c2dd951 Aug 24, 2026
32 checks passed
@os-steve
os-steve deleted the claude/issue-10821-plugin-rest-tally-retally branch August 24, 2026 01:33
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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] plugin-rest's TEST_DEBT per-code tally lists 147 while declaring it was counted at 153 — 6 unaccounted, with no remainder clause

2 participants