Repository navigation
test(dogfood): the cold-boot catalog file takes its database roots under tmpdir() and removes them itself - #22416
Merged
objectstack-fleet[bot] merged 1 commit intoOct 9, 2026
Conversation
…der tmpdir() and removes them itself The scratch-directory scan in scripts/pm/dispatch-gates.mjs must be able to read every mkdtempSync base. process.cwd() is not one it reads, so the site came back UNRESOLVED and the pm dispatch-gates self-test failed on main. The base is now join(tmpdir(), 'catalog-cold-boot-'). The per-file cwd sweep no longer covers these directories, so the file records each root it creates and removes them in afterAll, after afterEach has stopped the last kernel. Claude-Session: https://claude.ai/code/session_01WYYhVJ78u7PhwFViWo1EmQ Co-authored-by: Claude <noreply@anthropic.com>
Contributor
📓 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): |
This was referenced Oct 9, 2026
This was referenced Oct 9, 2026
Merged
objectstack-fleet
Bot
deleted the
claude/issue-22400-cold-boot-dogfood-tmpdir
branch
October 9, 2026 05:20
os-tesla
pushed a commit
that referenced
this pull request
Oct 9, 2026
…der tmpdir() and removes them itself (ported from PR #22416) Ported verbatim from PR #22416 (branch claude/issue-22400-cold-boot-dogfood-tmpdir, head d8eee21): its one-file diff against its merge base 83e7ae9, applied with git apply. The resulting blob equals that head's blob byte for byte (ac01935). Main carries the same file blob as that merge base, so the hunks are identical and a later merge of main that brings PR #22416 is a no-op here. It moves the mkdtempSync base from process.cwd() to join(tmpdir(), ...), which the dispatch-gates scratch-directory scan reads, and removes the created roots in an afterAll. Claude-Session: https://claude.ai/code/session_01VZqqwTj2wsihZEbfT6yyYN Co-authored-by: Claude <noreply@anthropic.com>
This was referenced Oct 9, 2026
This was referenced Oct 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #22400
Clause-②: no
What this changes
One test file,
packages/qa/dogfood/test/security-catalog-cold-boot-environment-holder.dogfood.test.ts, in the private@objectstack/dogfoodpackage:databaseFile()takes itsmkdtempSyncbase fromjoin(tmpdir(), 'catalog-cold-boot-'). Before, the base wasjoin(process.cwd(), 'catalog-cold-boot-').databaseFile()creates and removes them in a newafterAll. That hook runs afterafterEachhas stopped the last kernel. A refused boot leaves no kernel to stop, but its directory is still removed. This follows the harness's ownBootOptions.databaseFilecontract: "Callers own the file's lifetime (create it under a temp dir, delete it after)".tmpdir(). The old text ("the files live in this test file's own working directory, which the dogfood run removes at its end") is no longer true.Why:
scripts/pm/dispatch-gates.mjs's scratch-directory scan must be able to read everymkdtempSyncbase.process.cwd()is not a base it reads, so the site came back UNRESOLVED and thepm dispatch-gates self-testcase failed onmain. This uses the same remedy as PR #21935, which fixed the same mechanism onper-file-cwd.setup.ts: the base is made readable at the site. Per triage,dispatch-gates.mjsis not touched (the guard is not loosened, andprocess.cwd()is not taught to the scan), andper-file-cwd.setup.tsis not touched.Evidence
pnpm check:pm-dispatch-gates(run detached, followed withtail --pid)main83e7ae93a(unfixed, in a separate worktree pinned there)✗ dispatch-gates self-test: 1 of 2011 case(s) failed.(the failing case:✗ no mkdtempSync site in this tree takes a base the scan cannot read — UNRESOLVED: packages/qa/dogfood/test/security-catalog-cold-boot-environment-holder.dogfood.test.ts:108 (a base this scan cannot read: process.cwd()))d8eee2191✓ dispatch-gates self-test: 2011 cases pass.On this branch the case itself reads
✓ no mkdtempSync site in this tree takes a base the scan cannot read(log line 1533 in both runs). The wrapper's own battery reads✓ check:pm-dispatch-gates --self-test: the exit contract holds in all three directions.on both trees. The unfixed run endsELIFECYCLE Command failed with exit code 1., and the fixed run prints no such line. Battery time on this shared box: 781.7s before and 774.7s after.The same scan, read directly through
exposedScratchDirs()on both trees:sites=1625 inTree=63 exposed=0, withunresolved(mkdtempSync)going from 1 to 0 andunresolved(all)from 289 to 288. Site and in-tree counts are unchanged, so the one site moved to "outside", not out of the scan.The dogfood file itself (through
scripts/pm/os-verify-lock.sh, ond8eee2191)pnpm --filter @objectstack/dogfood exec vitest run --maxWorkers=2 test/security-catalog-cold-boot-environment-holder.dogfood.test.tsA
catalog-cold-boot-*listing undertmpdir()(/tmphere), taken before and after the run, with a poller sampling/tmpevery 100 ms during it:So the four roots really are created under
tmpdir()and none survives the file. Nothing else removes them: the dogfood globalSetup teardown only sweeps its ownos-dogfood-run-TAG-file-prefix.pnpm --filter @objectstack/dogfood typecheckgivesVERDICT command-exit 0. The package'stsconfig.jsonincludestest/**/*, andtsc --noEmit --listFilesnames this file once.Derived gates
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 53 commands from this diff (1 path vs merge base83e7ae93a). Each was run ond8eee2191with its exit code recorded, then reconciled with--ran:On its first pass,
pnpm check:dual-build-cjs-loadsexited 3 (PREREQUISITE NOT MET): eight packages outside the dogfood closure had nodist/. They were built through the lock (44 of 44 turbo tasks, all cache hits), and the re-run exited 0:✓ check:dual-build-cjs-loads — 107 published require entry point(s) across 66 package(s) load. The record above carries that re-run's code. The other 52 exited 0 on the first pass.ESLint, narrowed to the one changed file:
eslint --no-inline-config --format jsongives 1 file, 0 errors, 0 warnings, and the file is not ignored. The resolved config sets neitherparserOptions.projectnorprojectService, so linting is not type-aware and this diff cannot change the verdict on any file it does not touch. The repo-widepnpm lintis CI's.Acceptance notes
@objectstack/dogfoodisprivate: trueand the diff is one test file.Dogfood Regression Gateruns it. Locally this file ran on its own, as above.check-shard-attestation --emit …,check-test-completeness "$RUNNER_TEMP/…",check-issue-citations --census) take a value that exists only in a CI run. They are CI's.Generated by Claude Code