Uh oh!
There was an error while loading. Please reload this page.
fix(qa): declare @objectstack/spec in http-conformance, retiring the ledger ceiling it inflated - #12060
Conversation
…ledger ceiling it inflated `packages/qa/http-conformance` imports `@objectstack/spec/contracts` from `src/conformance.integration.test.ts` without declaring `@objectstack/spec`. Under pnpm's strict layout the specifier reached no `@objectstack/spec` anywhere on its resolution walk, so tsc answered TS2307 -- and that diagnostic was one of the 3 recorded in the package's TEST_DEBT entry. The number was therefore a reading of the INSTALL LAYOUT, not of this package's types. Measured on one tree at 3954fb7, same sources, same built closure, only the placement of `@objectstack/spec` differing: as installed (undeclared) 3 `@objectstack/spec` symlinked into the root node_modules, nothing else touched 2 packages/spec/dist moved aside 125 Declaring the dependency makes the program well-defined; the gate's own re-measure then reports `TEST_DEBT records 3, tsc now reports 2 (-1)`, so the ceiling is lowered to 2 and the entry's note re-tallied onto what it now measures. Both surviving diagnostics are in third-party `.d.ts` files (@better-auth/core's `bun:sqlite`, @better-fetch/fetch's `Timer`); no diagnostic is introduced here. devDependencies rather than dependencies: the import is `import type`, in a test file, and every other workspace package this package uses only from its tests already sits there. `workspaceBuildGraph` reads devDependencies too, so the declaration gets the same BUILT CLOSURE protection either way. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019siH5jDmk5hrayvfyojUqR
📓 Docs Drift CheckNothing 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
Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
os-zhuang
commented
Aug 25, 2026
Review — ACCEPTED on substance. ⛔ Not armed: CI has not converged.
The ceiling moved DOWN, and the gate said so before the ledger was touchedThat is the gate's own reading, volunteered before any edit — so the lowering is a measurement the tool made, not a number a dev chose. Every diagnostic is itemised on both sides and the diff is exactly one: ⭐ The card's own wording was corrected twice, and one correction makes the finding sharperThe card said resolution "works when something else happens to have hoisted the package and fails when nothing has" — i.e. intermittent. Measured: in a clean Correcting a card in the direction of "the defect was more definite than filed" is the harder direction to report and the more useful one. The load-bearing claim — that the number was a function of install layout, not of this package's code — survives both corrections intact. The layout dependence was demonstrated, and the legs disagree with each other
E is the load-bearing leg precisely because the manifest never changed — same sources, same built closure, the same generated project through the same ⭐ The honest note is the part I want on the record: "leg B does NOT show what it looks like it shows — diagnostic (c) is present in BOTH A and B, i.e. it was insensitive to whether spec was BUILT; it was sensitive to LAYOUT only, which is exactly what leg E isolates." Leg B is a dramatic number (125) sitting right next to the thesis, and the easy move is to let it read as confirmation. Saying out loud which leg proves the claim — and that the loud one does not — is what separates evidence from decoration. B is still useful, as the positive control proving the instrument produces a positive before its negative is trusted. ⭐ A measurement artifact caught by the authorThe first post-change verification read Two placements argued rather than asserted
Declared, not hiddenThe Also recorded: the shared lock returned ⛔ What gates armingCI has not converged. 32 runs, 10 This card carries no contract-review gate (Clause ② no), so CI convergence is the only remaining condition. Generated by Claude Code |
os-zhuang
commented
Aug 25, 2026
ACCEPT — armed (ready + auto-merge SQUASH)Card #11788. Head CI — 35 check runs, all No contract-review gate (Clause ② no: declaring a dependency the code already imports changes no accept set and no public surface). CI convergence was the only condition. Kept on the record: The ceiling went DOWN, and the gate volunteered it. The card's own wording was corrected in the harder direction — it described the failure as intermittent ("works when something has hoisted it"); measured, nothing hoists it in a clean install, so it failed deterministically. And the entry's recorded note had been stale against its own The loud leg was declared not to be the evidence. Legs A/E/B returned 3 / 2 / 125, and the author wrote down that B does not show what it appears to — the diagnostic it moved was build-sensitive, not layout-sensitive; only leg E, with the manifest byte-identical to base, isolates the claim. A 125 sitting next to a thesis is very easy to let read as confirmation. A stale instrument caught in the act: the first post-change verification reported Both placements argued rather than asserted —
Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#11788
packages/qa/http-conformanceimports@objectstack/spec/contractsfromsrc/conformance.integration.test.ts(line 25,import type { IHttpServer }) withoutdeclaring
@objectstack/spec. This declares it, and lowers the TEST_DEBT ceiling that theundeclared import had inflated — measured, not assumed.
All measurements below are on one tree, at base
3954fb7df, with the closure built exactlyas
lint.ymldoes (turbo run build --filter='./packages/*' --filter='./packages/*/*'—70/70 tasks successful). Final commit:
52a8decfc.The two ledger measurements
Both are
check-type-check-coverage's own--re-measurepath (its generated project, itstsc, its counting rule), scoped to this one entry.
surplus: noneThe gate says it itself, unprompted, before the ledger was touched:
Itemised, every diagnostic in both measurements
Before — 3:
After — 2:
The diff is exactly one line: the
@objectstack/spec/contractsTS2307 is gone and nothingelse moved. Both survivors are third-party
.d.tsdiagnostics that this package cannotfix; no diagnostic in the new measurement was introduced by this PR, and none was
absorbed.
Worth recording for whoever reads the entry next: after this, every file this package checks
in is clean with the test exclusion lifted. The entry cannot graduate (graduation needs 0)
because both remaining diagnostics live in
node_modulesand move with the lockfile.Why moving this ceiling is not a gate weakening
The recorded 3 was not a debt reading. It was a reading of where the package manager
happened to put
@objectstack/spec— demonstrated, not asserted. Three legs, one tree, onecommit, identical sources and identical built closure, running the same generated project
through the same tsc; only the resolution environment differs:
@objectstack/specplacementnode_modules, nothing else touchedpackages/spec/distmoved asideLeg E is the load-bearing one: the manifest is byte-identical to base, and the count still
drops to 2 purely because
@objectstack/specbecame reachable. A number that changes withinstall layout while the source does not is not a measurement of this package's types.
Leg B is the positive control, and it also answers the "both legs failed the same way, so the
diff is empty" trap — the legs are not identical (3 / 2 / 125), so the comparison carries
information. It reproduces exactly the mechanism this gate's own BUILT CLOSURE section
documents: an unresolved workspace import invents TS2307 and then an implicit-any cascade
(
packages/qa/http-conformance/src/*.test.tsalone contributes ~40 fresh TS7006).Note what leg B does not show: the
conformance.integration.test.tsTS2307 is present inboth A and B. That specific diagnostic was insensitive to whether
@objectstack/specwasbuilt, because the specifier never reached
@objectstack/specat all — it was sensitive tolayout only, which is what leg E isolates. After this PR the specifier resolves through the
declared closure, which is the closure
--re-measurerefreshes and refuses on, so the entry'snumber is now governed by the gate instead of by ambient hoisting.
devDependencies, not dependencies
The triage note said "dependencies"; the issue body allowed "or devDependency, matching how
the package consumes it". Measured,
devDependenciesis the match:import type, in a*.test.ts, erased at build time;objectql,driver-sqlite-wasm,plugin-hono-server,runtime) is already a devDependency;@objectstack/coresits independenciesbecausesrc/adapter.tsandsrc/node-plugin.ts— non-test source — import it;
workspaceBuildGraphreadsdependencies,devDependenciesandpeerDependenciesalike, so@objectstack/specis inside the BUILTCLOSURE precondition either way;
private: trueand never published, so no published manifest changes.Clause ②: no — re-affirmed against what was built
Declaring a dependency the code already imported changes no accept set and no public surface.
Re-affirmed rather than recalled: the diff is one manifest line, three lockfile lines, and one
tooling ledger entry; no
packages/specfile is touched (it is read-only for this card); noschema, route, error code or exported type changes;
pnpm --filter @objectstack/http-conformance testis 86/86 green with identical assertions before and after, because the import was type-only and
never existed at runtime.
Changeset:
skip-changeset, arguedNothing publishable moves, so a changeset would describe a release that cannot happen:
@objectstack/http-conformanceis"private": trueand is not one of the 69 publicworkspace packages —
check-changeset-fixedprints✓ .changeset/config.json "fixed" group is in sync with 69 public workspace packages., and thepackage is absent from that group;
scripts/check-type-check-coverage.mjsis repo tooling, never published;pnpm-lock.yamlis not published.check-empty-changesetforbids the empty-changeset alternative, so the honest choice is thelabel rather than a placeholder file.
Checks — each gate's own verdict line, at
52a8decfcGate family re-derived from the real change set with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, and again after thecommit; it did not grow (3 paths, 19 families, both times).
The TEST_DEBT total moves 1463 → 1462, which is exactly this entry's -1 and no other entry.
Also exit 0 at
52a8decfc:check:agent-test-spelling,check:cross-package-test-inputs,check:entry-guard,check:override-consistency,check:parse-guard,check:pnpm-filter-targets,check:published-files,check:slot-lookup,check:test-source-alias,check:type-source-resolution,check-ci-filter-parity.mjs,check-affected-docs.mjs,check-drift-comment.mjs.Declared narrowing
The
--re-measurehalf was run scoped to this one entry, through the gate's own code path(same generated project, same tsc, same counting rule, same BUILT CLOSURE refresh — its
--self-testpasses unmodified). A full-ledger--re-measureis ~2 minutes per entry on thiscontended container across 33 entries, which does not fit a foreground run and would hold the
shared verify lock for an hour. CI runs the full farm regardless; this is the cheap half, not a
substitute for it.
Scope
Only this package's ledger entry is touched — the other four cards in flight were told to leave
the ledger alone, and this diff changes exactly one
errors:field. The entry'snoteisre-tallied onto what it now measures (its old itemisation described a 4-pile that has not been
true for some time), so no
compositionAtdeclaration is needed.Generated by Claude Code