Repository navigation
test(spec): pin proof 4's message-includes leg with a fifth check-mode box - #19754
Conversation
…e box `delivers()` is a conjunction and check (c) reads a refusal it cannot parse as "no evidence", never as proof. The left half (an `unrecognized_keys` issue exists) is defended by the `ui/ViewItem` fixture; that fixture asserts the probe raises no such issue at all, so `&&` short-circuits in it and the RIGHT half — the refusal carries the declaration's own prescription — was defended by a zero. Adds a fifth sandbox in the shape of the four that already copy `src/`, substitutes `strictObject` in the box's own copy so every closed shape becomes a strict clone built to its declaration WITHOUT the declaration's error map, and pins both directions on one key: LIT map dropped -> `declared-but-silent`, exit 1 DARK map intact -> `prescribed`, the deletion waived, exit 0 A gate that lost the message conjunct turns the LIT case red and leaves the DARK one green. Claude-Session: https://claude.ai/code/session_013RDBh5DqXd2xnLwvHLgLFr Co-authored-by: Claude <noreply@anthropic.com>
📓 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): |
Seat read — and ⛔ NO at-tier subagent is owed here, by the rule's own wordsWritten by the Why there is no isolated review on this PR, ⛔ and why that is not a skipped step
This diff is one file,
⇒ 五面皆不碰 ⇒ CI plus a seat read, and ⛔ not a second agent. Spawning one here would be the seat ignoring a rule to look thorough.
The seat read — structure, ⛔ not a verdict on behaviourRead at head at 2026-09-22T23:03Z:
⛔ This is a reading of the diff's shape. It is ⛔ not a claim that the pin fires — that is what the round's own ablation evidence and CI have to show, and neither is in yet. What is still outstanding on this PR
Generated by Claude Code |
⛔ Correcting this seat's own note
|
|
Served-tier: 117/117 Contract review — PR #19754, head
|
| reading | origin/main c120dbdfb8 |
head cbb3521fe5 |
|---|---|---|
lines (wc -l) |
4531 | 4812 |
it(/test( cases |
85 | 87 |
symlinkSync sites |
6 | 7 |
entry arrays ['src', 'node_modules', 'package.json'] |
1 | 1 |
cpSync(path.join(PKG, 'src') sites |
4 | 5 |
The new block (head :4695–:4699): fs.cpSync(path.join(PKG, 'scripts'), …), fs.cpSync(path.join(PKG, 'src'), …, { recursive: true }), then for (const entry of ['node_modules', 'package.json']) fs.symlinkSync(…) — src absent from the entry array, byte-for-byte the shape of the #4659 / #4725 / #5898 / #17969 boxes (origin/main :3436–3439, :3735–3738, :4101–4104, :4365–4368). The shared createSandbox (origin/main:462–500) is untouched: the diff removes zero lines, and the only change above line 4530 is import { z } from 'zod'; at :51. The 85 pre-existing cases are untouched.
2. Route A is excluded by construction — VERIFIED, with controls
origin/main:packages/spec/package.json files[] carries "src/**/*.zod.ts" (2026-09-22T23:07:28Z), so a synthetic def in the REAL src would ship. The fixture's write target is boxStrictObject = path.join(box, 'src', 'shared', 'strict-object.ts') where box = fixtureTree(…) = fs.mkdtempSync(os.tmpdir()…)/packages/spec and that src is the cpSync copy, not a symlink. The copied scripts/build-schemas.ts reaches schemas only through relative ../src/* imports (origin/main:build-schemas.ts:116–147), never through the symlinked node_modules, so the substitution is read from the copy.
Runtime negative control, my worktree, after the intact run and after every ablation run: git status --porcelain → 0 lines; packages/spec/src/shared/strict-object.ts blob 24c9e672f39d… == HEAD: blob (2026-09-22T23:13:27Z, again 23:15:19Z). Firing control on the same subject: the LIT case exits 1 on the intact tree, which is only possible if the substituted strictObject WAS read by the gate — from the box copy, since the worktree copy is unchanged.
npm pack --dry-run --json --ignore-scripts in the private worktree (no dist/ built here, so the absolute count is 277, not the round's 2031 on a built tree; the discriminating readings do not depend on dist/), 2026-09-22T23:13:16Z: POSITIVE — 204 src/ entries, src/shared/http.zod.ts and src/system/stack-server.zod.ts present (the round's 204 is reproduced exactly). NEGATIVE — 0 entries under scripts/, scripts/build-schemas-check-mode.test.ts absent, src/shared/strict-object.ts (not a .zod.ts) absent. DARK — src/shared/http.zod.tsx absent. With the one changed file put back to base bytes (blob 18100c70f8… proven on disk) the sorted list is byte-identical (diff exit 0), then restored to 326a8c9466…. The round's reading holds.
3. The pin can fail and it discriminates — VERIFIED by my own ablations
delivers() at origin/main:build-schemas.ts:1695–1709: return issue !== undefined && issue.message.includes(prescription); — blob c886e1778316b5ff8c3d1780b599e8bcb50c1970, identical on head and main.
Intact (2026-09-22T23:13:06Z, -t '#18865'): 2 passed | 85 skipped (87), LIT 7.6 s, DARK 9.2 s.
Ablation A (message leg removed → return issue !== undefined;), anchor x1→x0, replacement x0→x1, blob c886e177… → 3cccd072c9cfe48685728086055cefef6cb7b52a (the same mutated blob the round reported), 2026-09-22T23:14:11Z: LIT red, DARK green — × LIT … AssertionError: expected +0 to be 1 at build-schemas-check-mode.test.ts:4751:22, which is expect(status).toBe(1): the gate exited 0 and WAIVED the seeded deletion. That is the card's failure direction, 「reads as compliant」. Restore: blob c886e177… == HEAD, git diff HEAD empty (MATCH).
Ablation B (refuses everything → return false; // ablation-B): anchor x1→x0, replacement x0→x1, blob c886e177… → b67031b7f25fdbcfe3998d36461c2558964e3c9d, 2026-09-22T23:15:59Z: LIT green, DARK red — × DARK … AssertionError: expected '…' to contain 'carry their own proof (#4650)' at :4798, i.e. the tree's own door, which does deliver its prescription, was refused anyway and the gate exited 1. Restore: blob c886e177… == HEAD, git diff HEAD empty (MATCH). (The round did not run this arm; it inferred DARK's role from A. The inference was right, and it is now measured.)
Together: A shows the LIT case is red for exactly the waiver a lost message leg grants (and the DARK case, same box, same key, differing only in whether strictObject hands over its error map, stays green — so the box construction and the seeded key are sound and the red is not a fixture artefact); B shows the DARK case catches a gate that refuses everything. The pair separates 「reads the message」 from 「refuses everything」.
Could LIT go red for another reason? Its assertions after status also exclude the not reachable from the and was LIVE (never tombstoned) verdicts and the prescribed text, all of which exist as the gate's own strings at origin/main:build-schemas.ts:2744–2759 (checked: the DARK string carries the prescription its strictObject declaration owes is on :2745, the LIT string a strictObject declaration NAMES '…', but writing it on :2759). A beforeAll failure would redden both cases; DARK's green under A rules that out.
Full-harness ablation A (the reading the card's acceptance 5737129694 said must be taken before landing, and which the round's 85 skipped did not take): the whole harness, no -t filter, with delivers() at blob 3cccd072… (message leg removed), 2026-09-22T23:16:20Z → 23:28:18Z, 716.94 s on my shared box: Tests 1 failed | 86 passed (87), exit 1 — the single red is the new LIT case at :4751:22 and every one of the 85 pre-existing cases stayed green. Restore proven: blob c886e177… == HEAD, git diff HEAD empty, git status --porcelain 0 lines; final intact re-run (23:14:58Z) 2 passed | 85 skipped, exit 0.
4. The fixture-validity assertions — the argument holds
beforeAll carries, before any box is built: (i) pristineSurface does not contain system/ServerRateLimitConfig:keyBy (re-derived on origin/main: 0 hits in packages/spec/authorable-surface/, firing control: …:enabled, …:maxRequests, …:windowMs present); (ii) the manifest still emits system/ServerRateLimitConfig; (iii) keyBy is not on RateLimitConfigSchema.shape; (iv) the real ServerRateLimitConfigSchema refuses keyBy AND its message carries PRESCRIPTION_BULLET (the DARK leg's tree fact); (v) z.object(RateLimitConfigSchema.shape).strict() refuses keyBy with an unrecognized_keys issue whose message does NOT carry the bullet. Assertion (v) is what makes this a pin on the MESSAGE half: it proves in-process that the probe DOES get an unrecognized_keys issue for the clone, so && does not short-circuit and only issue.message.includes(prescription) can separate LIT from DARK. The existing ui/ViewItem pin (origin/main:1123–1140, :1276–1290) asserts the opposite — not.toContain('unrecognized_keys') — so it defends the left half only. The two pins are disjoint by their own assertions.
The substitution keeps strictObjectError(options, shape) and drops only the map: strictObjectError performs declarationStore().push({ options, shape }) (origin/main:strict-object.ts:346) and strictObject is exactly z.object(shape, { error: strictObjectError(options, shape) }).strict() (:357–359, one 3-line declaration, so STRICT_OBJECT_ANCHOR's lazy [\s\S]*?\n\}\n matches it and nothing else). Proof 4's promisesFor therefore still finds the promise, the door is still closed, and only the refusal text changes — the card's exact shape.
5. Cost — the reasoning is sound and the honest number is the one quoted
Arithmetic re-checked from the round's own figures: 646.38 − 632.50 = 13.88 s = 2.19 % of 632.50; 7.803 + 8.342 = 16.145 s = 2.50 % of 646.38; 625.88 − 623.31 = 2.57 s. The whole-run delta (13.88) is what the direct cost (16.14) minus the unchanged cases' negative drift (−2.57) predicts (13.57; the ~0.3 s remainder is hook time, consistent with the measured 351 ms src copy), so the two numbers agree rather than compete. The seat's argument that a single whole-run pair cannot RESOLVE a ~14 s effect is right on its own evidence (summed per-case absolute drift 31.05 s within the pair; the earlier measurement round saw 59.29 s between two byte-identical runs). The cost this review quotes is the resolvable one: about two gate spawns, 16.1 s, ≈2.5 % of a harness run. My own timings on the same two cases (7.6–10.1 s LIT, 7.1–9.3 s DARK across five runs on a shared box) sit in the same band. No fabricated percentage found; the whole-run delta is not quoted as the cost.
6. Clause-② and the changeset — declared no, and right
The declaration reads no on the card's live claim comment 5784429035 and on the PR body, both by os-support-ai. The path limb (packages/spec/src/** non-test) does not fire: the one path is packages/spec/scripts/build-schemas-check-mode.test.ts. The content limb: the diff adds no key to any published payload, touches no .zod.ts, and the pack list is byte-identical to base (§2). The clause-② value no is correct for this diff.
skip-changeset was applied at 2026-09-22T23:04:33Z by os-support-ai (timeline event; the round's dev report says it applied no label, which is consistent). Route 0 discriminator re-run: git diff --name-status c120dbdfb8 <head> -- '.changeset/*.md' → 0 rows (firing control: the same instrument over c120dbdfb8~30..c120dbdfb8 → 5 A rows; dark control on .changesett/*.md → 0). The gate's own job log (run 35795377021, job 106973341647, 23:03:33Z) prints route 2 as 2. It releases nothing (.github/, .claude/, skills/, docs/, content/, examples/, tests-only, and the like) -> apply the 'skip-changeset' label. <<< PREFERRED and NOT this route if route 0 matched. Route 0 did not match; the diff is tests-only and publishes nothing. The label is the right call. The newer Check Changeset run (106974113468, 23:04:36Z) concluded skipped on the label, as the workflow designs (pr-automation.yml:290, :344–345); the earlier failure (106973341647, 23:03:35Z) is the pre-label first run the workflow itself describes as the common case.
7. Gates — read from this head's check-runs, not re-run
Read from the head's check-runs (GET /commits/cbb3521fe5eb…/check-runs, polled until no run was pending; final read 2026-09-22T23:24:51Z): 39 check-runs, 0 pending. Newest run per check name:
| conclusion | check name (newest run id, completed) |
|---|---|
| success | Build Core (106973409959, 23:10:25Z) · Test Core (106978463090, 23:21:31Z) · Test Core 1/6–6/6 (106973410206 23:19:05Z, 106973410101 23:13:43Z, 106973410102 23:17:36Z, 106973410203 23:15:10Z, 106973410241 23:21:08Z, 106973410197 23:14:38Z) · Lint & Repo Gates (106973341999, 23:24:30Z) · Type Check · source gates / debt ledger / workspace / consumer gates (106973342113 23:04:10Z, 106973342055 23:09:38Z, 106973342048 23:17:34Z, 106973341955 23:12:54Z) · TypeScript Type Check (106977551127, 23:17:39Z) · Temporal Conformance (live PG + MySQL) (106973410014, 23:10:48Z) · Dogfood Regression Gate + 1/3–3/3 · Dogfood Verify CLI · Spec property liveness (106973341781) · Governed Surface Queue Guard · Flag docs affected by code changes · Check Documentation Links · Part-of PR must not also close its card · The card this PR closes must claim this branch · No other open PR may claim the same issue · No other open PR may claim the same single-writer path · filter · Auto Label (first run 106973422242) · Check PR Size (first run 106973341902) |
| skipped | Check Changeset (106974113468, 23:04:36Z — exempt on the skip-changeset label, the workflow's designed exit; its superseded first run 106973341647 concluded failure at 23:03:35Z, before the label) · Build Docs · Console Pin Gate · Packed-tarball smoke (opt-in) · the label-triggered re-runs of Auto Label and Check PR Size |
| failure / cancelled / in_progress | none at the final read |
No run is in_progress or cancelled; no aggregator reports failure. The one failure on the head is the superseded first Check Changeset run, whose own log (§6) prescribes exactly the label that was then applied.
The three families the round declared exit 3 (PREREQUISITE NOT MET, NOT MEASURED locally): check:dual-build-cjs-loads and check:lean-entry-closure are steps of Build Core (ci.yml:2116, :2140); check:type-check-debt is the Type Check · debt ledger job (lint.yml:6059–6060, :6279). Declaring them NOT MEASURED was right — each reads built output of packages this diff does not touch — and none was owed locally for a tests-only diff whose own package typecheck ran green; CI has now measured them: Build Core 106973409959 → success, completed 2026-09-22T23:10:25Z (so check:dual-build-cjs-loads and check:lean-entry-closure ran on a built tree and passed); Type Check · debt ledger 106973342055 → success, completed 2026-09-22T23:09:38Z (check:type-check-debt). Read 2026-09-22T23:17:57Z from this head's check-runs.
Who executes the new pin: packages/spec/vitest.repo-tests.json:2 lists scripts/build-schemas-check-mode.test.ts; packages/spec/package.json:283 "test:repo": "vitest run --project repo"; ci.yml:725 runs pnpm turbo run test test:repo in Test Core. So the harness runs in CI's Test Core shards, and the pin is live there. The shard the run-time planner (scripts/ci/select-shard-packages.sh + partition-test-shards.mjs over turbo ls --affected, ci.yml:551–555) assigned @objectstack/spec to is not readable from here — the job-log download is refused by the egress proxy on the redirect host and the MCP tail of shard 6/6 (12 packages, check-test-completeness: OK (12 of 12 …)) ends in @objectstack/cli:test — so this record names no shard and reads all six Test Core conclusions instead (§7 table). The @objectstack/spec#test:repo turbo input hash includes the changed file ($TURBO_DEFAULT$, turbo.json:532–536), so a main-seeded cache cannot have served it.
The card's distinction, held
The card claims 「no fixture would fire」, not 「it is already broken」. Nothing in this review, in the round, or in the PR measures whether the leg has ever failed silently in the tree; the intact DARK case shows the tree's real door delivers its prescription today. The PR's in-file comment says Measured before this block was written: the leg was defended by a zero — that sentence is now a measured fact rather than a structural reading. The full-harness ablation above is the instrument: with the message leg gone, 85 of 85 pre-existing cases stay green and only the new LIT case fires. So before this PR no fixture would have fired — exactly the card's claim, and nothing more.
② Semver level
None / no release. Tests-only diff under packages/spec/scripts/; no published file changes (pack list byte-identical to base); skip-changeset correctly applied. Were a level ever demanded for this file it would be patch at most, but no changeset is owed.
③ Boundary flags
- No published surface, schema, JSON Schema, prompt or docs artefact moves.
packages/spec/src/**untouched;dist/unaffected. - Route A (a synthetic def in the real
src) excluded by construction: the fixture writes only to the box'scpSynccopy; the realsrcblob is unchanged after every run (§2). - The gate under test,
build-schemas.ts, is byte-identical on head and main (c886e177…); no test-only seam is added to it. - Cross-package inputs: the new block reads only
PKG/**plus the pre-existingREPO_ROOT/scriptssymlink infixtureTree; no new escaping spelling. - Card [finding] proof 4 的
delivers()message-includes 腿今天只由一个零守着 —— 而通往夹具的三条路各被本仓自己写着的一条规矩堵住 #18865 staysdomain:spec; no lane change, no limb hit.
Findings
None that would change whether this PR should land. Observations, none blocking:
- The round reported the ablation with the 85 other cases skipped (
1 failed | 1 passed | 85 skipped); the card's acceptance5737129694had named the full-harness ablation as the reading to take before landing. This review took it (§3):1 failed | 86 passed (87). The round's structural reading was correct; it is now also measured. - The round inferred the DARK case's discriminating role from Ablation A alone; this review ran the 「refuses everything」 arm (Ablation B) and the DARK case caught it at
:4798. The inference was correct; it is now also measured. - The absolute
npm packentry count differs between a built tree (the round's 2031) and this review's unbuilt worktree (277); the discriminating readings — 204src/entries, 0scripts/entries, byte-identical lists before/after — agree exactly and do not depend ondist/. - The one
failurecheck-run on the head (Check Changeset106973341647) is the pre-label first run the workflow itself documents as the common case; its newest run isskippedon the label. Nothing on the head is red at the final read. - The
Served-tiercounts on line 1 are the seat's to fill from the transcript's harnessmodelstamps; this record does not self-report.
Implemented-by: claude/issue-18865-proof4-delivers-fixture
Reviewed-by: session_013RDBh5DqXd2xnLwvHLgLFr
VERDICT: PASS — the pin is measured to fail in both directions for exactly the message leg (LIT red under a lost conjunct, DARK red under a blanket refusal, 85 pre-existing cases untouched either way), the diff publishes nothing and touches no source, and every check on the head is green or designed-skipped.
Tier control — measured by the SEAT from the reviewer's transcript
- 117 assistant requests, 117 stamped
claude-fable-5-1— every per-request"message":{"model":…}. - 260/260 on the superset: 143
"model"plus 117"advisorModel", all the same value. - Dark control: empty.
- Fallback / overload sweep: 21 keyword hits, ⛔ none a notice — tool-schema prose, the dispatch order's own sentence, and the reviewer's own "none received".
CONTRACT_REVIEW_TIERre-read at source:origin/main:scripts/pm/dispatch-gates.mjs—export const CONTRACT_REVIEW_TIER = 'claude-fable-5-1';
⭐ Two things this review did that the round did not, and they are the reason the verdict is worth having
- It ran the ablation the round skipped. The round proved the pin reds when the message conjunct is removed. The reviewer additionally replaced the whole predicate with
return false;— LIT green, DARK red — so the two ablations move the two cases in opposite directions. ⇒ the pair genuinely separates 「reads the refusal text」 from 「refuses everything」, ⛔ it is not two spellings of one assertion. - It ran the FULL 87-case harness under ablation, where the round had only the narrowed run (
85 skipped). Result:1 failed | 86 passed (87)— ⭐ only the new LIT case fires. That is the card's own acceptance condition (「defended by a zero」) turned from a claim into a measurement, and it is what the card said had to exist before landing.
⇒ this seat notes it because the round's evidence was sound but incomplete in exactly the place the card cared about, and the review closed that gap rather than restating it.
Seat's own note on this record's basis
contract-review.md's five-surface test alone. That was wrong and was corrected in 5785745857. This record confirms the correction at source: LANES_OWING_REVIEW = ['domain:spec','domain:skills'] with laneOwesReview reading the card's domain:* labels, and card #18865 carries domain:spec — so the review is owed on every delivered round, surface or no surface.
Generated by Claude Code
Fixes #18865
Clause-②: no
delivers()inpackages/spec/scripts/build-schemas.tsis a conjunction, and proof 4'scheck (c) counts a refusal it cannot read as "no evidence", never as proof:
The left half — "the door refused this write" — is defended by the
ui/ViewItemfixture,which asserts the probe raises no
unrecognized_keysissue at all. So&&short-circuitsin it and the RIGHT half is never evaluated. That half is the only thing that separates a
def parsing through its declaration's own error map from a strict CLONE built to the same
declaration without it. Before this PR it was defended by a zero.
The card asserts "no fixture would fire", not "it is already broken". This PR does not
claim the leg has ever failed silently in the tree, and it measured no such thing.
What lands
One fifth sandbox in this harness, built in the shape of the four that already copy
src/,plus two cases:
strictObjectdeclared-but-silentprescribed, deletion waivedA gate that lost the message conjunct turns the LIT case red and leaves the DARK one green.
⚠️ The failure direction is "reads as compliant" — a defeated leg WAIVES the deletion, it
does not add a "no evidence" row — which is why both directions are pinned, not just one.
Re-derived, not inherited
Read at branch head
cbb3521fe5in this worktree, 2026-09-22T22:07Z. The line numbers thecard and its triage comment cite were taken on 2026-09-18 and have all moved; the sites
below are given by shape and by their reading today.
origin/mainc120dbdfb8cbb3521fe5it(casessymlinkSyncsitessrccreateSandbox,:476)cpSyncofPKG/srcinto a box:3438:3737:4103:4367):4695added)So the shared
createSandboxand the 85 cases that run through it are untouched: the diffis one appended
describeblock and oneimport { z } from 'zod'.The pin can fail — ablation, on disk, both legs proven
node scripts/ablation-replace.mjsin WRAP mode onpackages/spec/scripts/build-schemas.ts,anchor
return issue !== undefined && issue.message.includes(prescription);replaced byreturn issue !== undefined;— the message leg, and nothing else. 2026-09-22T22:10Z.Result, the two cases under
-t '#18865':The LIT case goes red for the ablated reason: with the conjunct gone the gate exits 0 —
it waives the deletion, which is the card's stated failure direction — and the DARK case
stays green, so the pair discriminates "reads the message" from "refuses everything".
Restore, proven on disk rather than by an exit code:
Green again on restore: the full 87-case run below passes both cases with the generator back
at its HEAD bytes.
Route A stays out, measured
@objectstack/spec'sfiles[]carriessrc/**/*.zod.ts, so a synthetic def written intothe real
src/would ship in the tarball. This fixture writes only into the BOX's own copyof
src/, and the repo'ssrc/is never touched.npm pack --dry-run --jsonon a realbuild of
@objectstack/spec(built at 2026-09-22T22:16Z), run on this branch and again withthe one changed file restored to
c120dbdfb8:c120dbdfb8bytes of the one changed file)diffexit 0, 0 linesControls on the after list:
src/shared/http.zod.tspresent,src/system/stack-server.zod.tspresent,204
src/entries in all: the instrument does reach the directory a route-A fixture wouldhave landed in.
scripts/build-schemas-check-mode.test.tsabsent;scripts/contributes 0entries;
src/shared/strict-object.ts(not a.zod.ts) absent.src/shared/http.zod.tsx, a name that does not exist, absent.The file this PR changes is the only file it changes, and it publishes nothing.
The cost this adds, measured here, and what the measurement can and cannot resolve
Both runs:
vitest run --project repo scripts/build-schemas-check-mode.test.ts --reporter=verbose,through the shared heavy-verify lock on one shared 4-core box with sibling agents active —
the before arm queued 123s behind another locked run and the after arm queued 161s, so these are
shared-box seconds, not idle-box figures. The two trees differ in exactly the one file.
Durationc120dbdfb8(blob18100c70f8, 4531 lines)326a8c9466, 4812 lines)Whole-suite delta: +13.88 s (+2.19 %).⚠️ That number is NOT distinguishable from
run-to-run noise, and it is not the cost. The control for it is inside the same pair: the
85 cases that are byte-identical in both arms summed 623.31 s in the after run and
625.88 s in the before run — the unchanged work measured 2.57 s FASTER in the arm that
was supposed to be slower, and its summed per-case absolute drift was 31.05 s (median
290 ms, p90 720 ms, max 1352 ms per case). A 13.88 s whole-run delta sits inside that.
The figure that IS resolvable is the direct one: the two new cases are new work and were timed
individually — 7.803 s + 8.342 s = 16.14 s, 2.50 % of the after run. Both land between
this harness's own p75 (7.405 s) and its max (19.08 s), against a per-case mean of 7.35 s, which
is what two ordinary gate spawns cost here; the one extra
srccopy this box pays is notseparately resolvable at that scale. Sandbox construction is not where this harness spends its
time — 87 gate spawns are.
Plainly: the box costs about two cases' worth, the suite total moved by less than its own
noise, and nothing here supports quoting the whole-run delta as a cost.
Verification
pnpm exec vitest run --project repo scripts/build-schemas-check-mode.test.ts— 87 passed(87), exit 0, 2026-09-22T22:41Z. The
build-schemas-check-modecase count moves 85 to 87.pnpm --filter @objectstack/spec test— thelocalproject, which is where the package'stestscript points; this harness is in therepoproject and is run separately above.515 files passed, 15043 passed | 1 todo (15044), exit 0, 183.81 s, 2026-09-22T22:59Z.
pnpm --filter @objectstack/spec typecheck— exit 0, 50 s, same window.node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands(it reportsthe tree it read:
objectstack-ai/objectstackatcbb3521fe5, 1 changed path, 281 changedlines). 57 commands, each exit code captured before any pipe: 54 exit 0, 3 exit 3.
check:dual-build-cjs-loads,check:lean-entry-closureandcheck:type-check-debteach printPREREQUISITE NOT METandrefuse because this worktree has
dist/for@objectstack/speconly. Each reads BUILT outputof packages this diff does not touch; the reading CI takes on a fully built tree is the one
that counts. Reconciled with
--ran.dispatch-gates.mjsalso names, as outside those 57 and therefore unmeasured here: 58artifact-roster families whose
silentverdict is a fact about a list, 11 wide-populationfamilies, 9 that apply once a changeset exists, 7 that take a value from the workflow, 5
path-scheduled CI jobs and 4 type-check lanes. Its own words: that silence is not a clearance.
Changeset
This diff changes one file,
packages/spec/scripts/build-schemas-check-mode.test.ts, and itpublishes nothing: measured, not argued —
npm pack --dry-runlists 2031 entries and 0 underscripts/, and the list is byte-identical to the one taken with that file restored toc120dbdfb8.The changeset gate's own route 0 discriminator,
git diff --name-status c120dbdfb8...HEAD -- '.changeset/*.md', returns nothing — this PRneither adds nor corrects a changeset — so route 0 does not match and the gate's prescription is
its route 2, quoted from
.github/workflows/pr-automation.yml:(the workflow marks that last line PREFERRED; the marker is dropped from the quote above
only because its arrow characters do not survive a GitHub body intact.)
⛔ This round applies no label. The prescription is reported here for the owning seat to act on.
Acceptance notes
Observations, none of them filed and none of them fixed here — this PR's scope is this card:
lines on
origin/main, not the 4466 the card cites), which is why every site above is givenby shape and re-derived. Nothing in the tree is wrong; a line number is simply not an anchor.
src")is false for four of the five sandboxes, which already copy
src/privately. That is whatmade a fifth box possible without touching
createSandbox.are in the same undefended state, and whether this leg has ever actually failed silently in
the tree. This PR pins one leg and claims nothing about a population.
Generated by Claude Code