Skip to content

docs(tests): replace a false typecheck-script premise in four pin headers - #17303

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-16742-pin-placement-header-premise
Sep 10, 2026
Merged

baozhoutao merged 1 commit into
mainfrom
claude/issue-16742-pin-placement-header-premise

Conversation

@claude

@claude claude Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Fixes #16742

Four test files justified a pin's placement (or a typing choice) with the claim that the
package "has no typecheck script (a type-check DEBT ledger entry)". Both halves are false
on this tree. This is comment prose only — every changed line begins with //, proved
mechanically:

git diff -U0 | grep -E '^[+-]' | grep -vE '^(\+\+\+|---)' \
  | grep -vE '^[+-][[:space:]]*//' | grep -vE '^[+-][[:space:]]*$'
  -> no output

The falsification, re-derived rather than transcribed

scripts/check-type-check-coverage.mjs's DEBT object literal (lines 802-830 on this tree)
holds exactly four entries, and they are other packages: @objectstack/cloud-connection,
@objectstack/hono, @objectstack/observability, @objectstack/spec-monorepo. The
DEBT['@objectstack/service-storage'] that appears elsewhere in the same file is past-tense
prose about an entry #15050 deleted, not a fifth entry. TEST_DEBT holds exactly one:
@objectstack/http-conformance. check:type-check-debt printed the same population
independently: "76/80 workspace packages type-checked (plus the root), 4 in the DEBT ledger".

Each named package declares a typecheck script, read out of its own package.json:

@objectstack/core                     tsc --noEmit && tsc --noEmit -p tsconfig.examples.json && pnpm check:test-typecheck
@objectstack/runtime                  tsc --noEmit && pnpm check:test-typecheck
@objectstack/service-automation       tsc --noEmit && pnpm check:test-typecheck

Finding the carriers — a grep cannot, and a count is not a reading

The sentence contains backticks, wraps across lines, and the // prefix lands inside the
wrap. The scan strips comment prefixes, flattens whitespace, drops backticks, then matches the
short fragment has no typecheck script over all 7969 tracked source/doc files. Positive
control DEBT -> 744 hits; nonsense control -> 0.

Seven files carry the fragment, six of them test files, and the count is identical (1) before
and after this change — which is exactly why the count decides nothing. Each was read:

file before in scope
packages/rest/src/plugin-type-closed-set.pin.test.ts quoted and corrected by #16738 no
packages/core/src/plugin-type-closed-set.test.ts quoted and corrected by #16738 no
packages/rest/src/plugin-metadata-retired-fields.pin.test.ts asserted as live justification yes
packages/core/src/plugin-loader.retired-fields.pin.test.ts asserted as live justification yes
packages/runtime/src/sandbox/quickjs-runner.test.ts asserted as live justification yes
packages/services/service-automation/src/flow-trigger-kind-shared-resolver.test.ts asserted as live justification yes
scripts/check-type-check-coverage.mjs a true general statement about DEBT graduates no

All four asserted carriers are now quoted-and-corrected, following the pattern #16738 set:
delete the false premise, promote the surviving true reason, record the correction in place.

The promoted reasons

rest / core retired-fields pair. The compile-time pin lives in rest because only that
program resolves @objectstack/core to the BUILT dist/index.d.ts. Re-proved here with
tsc --noEmit --listFiles on both programs, workspace closure built first, each leg carrying
its own control:

packages/rest/tsconfig.test.json      packages/core/dist/index.d.ts present · 0 files under packages/core/src/
                                      control: 213 of rest's own src files in the program · nonsense path 0
packages/core/tsconfig.test.json      packages/core/src/plugin-loader.ts present · 0 files under packages/core/dist/
                                      control: 120 of core's own src files in the program · nonsense path 0

PluginMetadata is declared at packages/core/src/plugin-loader.ts:41, so a directive in core
would be evaluated — core's typecheck names its own tsconfig.test.json since #14613 — but
against the source declaration, never the emitted surface. That is the durable half; the
script-list half was not.

runtime — the quickjs ctx.crypto pin. Derived from this package's own wiring, not copied.
packages/runtime/tsconfig.json is the BUILD config and excludes **/*.test.ts (measured: 0 of
its test files in that program, 81 non-test src files as the control), which is where the old
sentence came from. But #14504 added tsconfig.test.json, which the typecheck script NAMES
via check:test-typecheck --project, and tsc --listFiles puts
src/sandbox/quickjs-runner.test.ts in it. So a type-level directive there would be live. The
real reason the pin is executable is the defect it pins: ScriptContext.crypto.hash was
DECLARED on the host seam and never installed, so a type-level assertion reads the very artefact
that lied and would have passed green on the broken tree. Only running the sandbox observes what
the VM really got.

service-automation — the FlowTrigger typing note. Derived the same way. That package's
tsconfig.json carries no test exclusion (its include is ["src"]), so the tsc --noEmit
its typecheck script runs already compiles the file, and #15048's tsconfig.test.json
compiles it too (measured: the file is in both programs; 127 own test files in each). There is
no test-typecheck-debt.json beside that config, and the gate confirms the absence is the zero:
"0 file(s) / 0 error(s) / 0 pinned signature(s)". The floor under that file is stricter than the
old sentence claimed, not laxer.

Changeset: skip-changeset, measured

The four files sit under packages/**/src/**, so this was measured rather than assumed. The
criterion is whether anything a package actually ships moves. Each package's files is
["dist","README.md","CHANGELOG.md"]; after a full workspace build, a token unique to each
edited test file was grepped across exactly those shipped paths, with a positive control from
the same package's own source in the same pass:

packages/rest                   'retired-configschema-pin'                    0 files   control 'RestServer'            6
packages/core                   'live-sibling-control'                        0 files   control 'PluginMetadata'        5
packages/runtime                'the VM ctx.crypto exposes exactly randomUUID' 0 files  control 'installCtx'            5
packages/services/service-automation 'flowWith'                               0 files   control 'resolveTriggerBinding' 5

Zero hits with the control hitting means the grep reached the shipped bytes and the comment
prose is not among them — a bundled package emits nothing from src/**/*.test.ts.
check:published-files is green on the same tree. Nothing publishable moves, so this PR
declares no release of its own.

Verification, at b20d479d76

  • dispatch-gates --ran: 55 derived families, 55 run, 0 NOT-MEASURED, 0 UNRUN.
  • Two of the 55 first returned exit 3 — PREREQUISITE NOT MET, which is neither green nor red:
    check:dual-build-cjs-loads and check:type-check-debt both need the whole workspace built.
    The full build was run (turbo run build --filter='./packages/*' --filter='./packages/*/*',
    72/72 tasks) and both were driven to a real verdict: exit 0.
  • pnpm typecheck for the four affected packages: all exit 0. The two test-layer ledgers
    are unmoved — runtime "27 file(s) / 191 error(s) / 69 pinned signature(s)", service-automation
    "0 / 0 / 0". The ledger is keyed by file plus normalised signature, not by line number, so
    inserting comment lines above an existing diagnostic cannot move it.
  • The four edited test files run: rest 2 passed, core 3 passed, runtime 63 passed,
    service-automation 14 passed.
  • pnpm lint (eslint . --no-inline-config) over the whole repo: exit 0. No narrowing, so
    no narrowing claim is being made.
  • Control-byte self-scan over the four files: no hits, with a firing control on the same
    instrument.

Acceptance notes

  • A fifth asserted carrier exists, in a wording the card's fragment does not match, and it is
    deliberately NOT touched here.
    packages/rest/src/rest-api-plugin-slot-lookups.test.ts
    says "packages/rest/tsconfig.json excludes its .test.ts files and the package declares no
    typecheck script (it is a DEBT/TEST_DEBT ledger entry), so NO tsc program compiles this
    file". @objectstack/rest declares tsc --noEmit && pnpm check:test-typecheck, is in neither
    ledger, and its tsconfig.test.json program compiles that file. It was found by widening the
    scan to wording variants (no typecheck script, DEBT ledger entry, DEBT table of,
    type-check DEBT lane) rather than the single fragment. Reported to the dispatching seat
    rather than folded in, per the dispatch's explicit fence.
  • Checked and NOT carriers, so that the next scan does not re-open them:
    plugin-security/src/permission-set-projection.test.ts (already quoted-and-corrected by
    @objectstack/plugin-security excludes **/*.test.ts from its only tsc program — 89 test files unchecked, 11 standing type errors behind a green typecheck #13176), service-datasource/src/__tests__/datasource-driver-handle-contract.test.ts (claims
    absence from the ledger, which is true), verify/src/harness.host-resolution.test.ts (claims
    a TEST_DEBT entry for a different package), and spec/src/contracts/objectql-engine.ts
    (past-tense history of why [P2] framework: 66 个包用 tsup 构建、无人做类型检查 —— 实测 18 个包共 380 处 code-tier 错误(#4118 的 framework 侧对应) #4311 happened, not a live justification).
  • The six-versus-five counting difference the card asked to reconcile: the fragment occurs in
    seven files on this tree, six of them test files. The seventh,
    scripts/check-type-check-coverage.mjs, states it generically about DEBT graduates and is
    true. Two of the six were already fixed, so four were in scope — the arithmetic the card
    states.

Generated by Claude Code

…eaders

Four test files justified a pin's placement (or a typing choice) with the
claim that the package "has no `typecheck` script (a type-check DEBT ledger
entry)". Both halves are false on this tree: `@objectstack/core`,
`@objectstack/runtime` and `@objectstack/service-automation` each declare a
`typecheck` script ending in `check:test-typecheck`, and none of them holds an
entry in `scripts/check-type-check-coverage.mjs`'s `DEBT`.

Following the pattern #16738 set for the two sibling headers: delete the false
premise, promote the surviving true reason, and record the correction in place
so the next reader does not re-derive it.

- rest/core retired-fields pair: the pin lives in `rest` because only that
  program resolves `@objectstack/core` to the BUILT `dist/index.d.ts`.
  Measured with `tsc --listFiles` on both programs: rest's contains
  `packages/core/dist/index.d.ts` and zero files under `packages/core/src/`;
  core's own test program contains `packages/core/src/plugin-loader.ts` and
  zero under `packages/core/dist/`.
- runtime's quickjs `ctx.crypto` pin is executable because the defect was a
  member declared on the host seam and never installed, so a type-level
  assertion reads the artefact that lied. Its file IS in the program
  #14504's `tsconfig.test.json` defines, so a directive there would be live.
- service-automation's `FlowTrigger` typing note: that package's build config
  carries no test exclusion, so its `tsc --noEmit` already compiles the file,
  and no `test-typecheck-debt.json` exists beside its test config, so the
  floor is zero errors rather than a shrink-only lane.

Comment prose only: every changed line begins with `//`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012GKcPZbMoGq7WPzKLfRBTU
@claude claude Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 10, 2026
@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.

What this run could not see
  • 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 — 0 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 439331895b7e38d8065b26a1eb03e911acc0cdb6 → packageMentionDocs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m 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