Skip to content

fix(devx): mark the ledger-expanding remedy maintainer-only in check-test-typecheck (#8538) - #8549

Merged
qq9340100 merged 1 commit into
mainfrom
claude/issue-8538-test-typecheck-authority-marker
Aug 13, 2026
Merged

fix(devx): mark the ledger-expanding remedy maintainer-only in check-test-typecheck (#8538)#8549
qq9340100 merged 1 commit into
mainfrom
claude/issue-8538-test-typecheck-authority-marker

Conversation

@qq9340100

Copy link
Copy Markdown
Collaborator

Fixes#8538

Sixth and final instance of the #8435 ratchet-remedy authority convention — the one the #8519 census could not see, because it swept scripts/*.mjs and this file is one of the two .mts files in that directory.

check-test-typecheck.mts's unledgered-file verdict ended with Only with a reason: add the file to test-typecheck-debt.json. — the ledger-expanding path offered as the plain second of two things to do. The rule that this path is a maintainer's call was written only in the file's own prose (LEDGER_COMMENT's "EXACT ratchet", the GREW verdict's "the ledger only ratchets down"), where a maintainer reading the script sees it and the author who trips the gate never does.

What changed

Only author-facing remedy text and self-test assertions. evaluate()'s detection logic is untouched — same problems, same order, same inputs.

  • the greppable ⛔ MAINTAINER-ONLY token, identical to the five gates already carrying it;
  • a RATCHET_EXPANSION_OFFER detector keyed on the act ("add the file to …"), not on the ledger's name;
  • a pure ratchetRemedyCarriesAuthority() predicate;
  • seven non-overlapping self-test assertions.

The marked message reuses this file's own two statements of the rule rather than inventing a third — one rule stated twice in two voices is two rules by the next reading.

Only the ledger-EXPANDING verdict is marked

The SHRANK ("re-record it"), GRADUATED ("delete its entry") and GREW verdicts are the ratchet tightening — squarely the author's job, and marking them would teach the opposite of the rule. GRADUATED names the ledger file while telling the author to delete an entry, which is exactly why the detector keys on the act and not the name. That is a self-test assertion, not a footnote: mutating the detector to key on test-typecheck-debt.json alone fails with one named failure pointing at GRADUATED.

Verification

RATCHET_AUTHORITY_MARKER is interpolated into exactly one message; the other three are byte-unchanged.

Fail path, planted violation (a deliberate type error in an unledgered packages/client test file, dependency closure built). Old script vs new, same tree:

BEFORE_EXIT=1 AFTER_EXIT=1
BEFORE: 1 problem(s) AFTER: 1 problem(s)
subject both runs: src/realtime-api.test.ts: 1 type error(s)

Identical exit code and flagged-subject set; only the remedy prose differs. Green-path runs of both versions are also identical.

Mutation tests (direction predicted in writing first, each caught by exactly one named assertion):

mutationpredictedobserved
drop the marker from the messageonly "verdict marks the ledger path"as predicted
predicate reduced to return trueonly "REJECTS an offer carrying no marker"as predicted
reword the offeronly "DETECTOR still matches"as predicted
narrow the detector's path gaponly "matches an offer naming the ledger by PATH"as predicted
detector keyed on the ledger NAME aloneonly "does NOT reach the GRADUATED verdict"as predicted

The path-gap control exists because a sibling gate's first-cut regex spelled its gap to exclude the dot, so every offer naming its registry by path silently stopped matching.

Gates:pnpm --filter @objectstack/spec check:test-typecheck and --filter @objectstack/client both green (self-test wired into both, runs ahead of the real check). check:type-check-coverage green — this file contributes 29 of the root entry's 80 errors and that entry is recorded exactly with no margin, so the additions deliberately introduce no new console/process references and the count is still 29. check:nul-bytes green, control-char self-scan clean, eslint clean.

Scope

One file. No gate weakened, no verdict changed, no ledger raised. The five gates covered by PR #8517 / PR #8539 are not touched. The farm-wide detector and the ⛔ SHRINK-ONLY / ⛔ MAINTAINER-ONLY token reconciliation are #8540's and are deliberately left alone here. No changeset: root scripts/ dev tooling releases nothing — skip-changeset applied.


Generated by Claude Code

@vercel

vercelBot commented Aug 13, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectstackIgnoredIgnoredAug 13, 2026 6:55pm

Request Review

@qq9340100qq9340100 added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed size/m labels Aug 13, 2026 — with Claude
@qq9340100
qq9340100 marked this pull request as ready for review August 13, 2026 19:17
@qq9340100
qq9340100 added this pull request to the merge queueAug 13, 2026
Merged via the queue into main with commit c91e19aAug 13, 2026
28 checks passed
@qq9340100
qq9340100 deleted the claude/issue-8538-test-typecheck-authority-marker branch August 13, 2026 19:35
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants

@qq9340100@claude