Skip to content

fix(cli): keep the git-ignored tmp/ out of the vitest tier walk - #26176

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-1nrz43
Oct 26, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-1nrz43

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Leehom · project thread

Fixes #26047

Clause-②: no
Metadata-protocol: none

What was wrong

The merge queue ejected three independent PRs (#25979, #26007, #26026) on the same line: hook-timeout-override-refusal.test.ts › ⭐ CONTROL, AssertionError: expected 1 to be +0. The vitest list child exited 1. Load was not the cause.

packages/cli/vitest.config.ts builds its tier populations at config load through packages/cli/vitest-tiers.ts. testFilesOnDisk walked the whole package, including packages/cli/tmp/, which is git-ignored scratch. Sibling tests in the same slice render whole scaffolds into tmp/ and delete them mid-run (init-template-comments-self-contained, scaffold-manifest-schema). Those scaffolds hold real test files such as package.test.ts and src/index.test.ts. When a delete landed inside the walk, the config load threw ENOENT (scandir or open), so the child exited 1. Two other effects of the same walk: a scaffold's test files joined the unit population while they existed, and the outer vitest run config load could die the same way.

Change

Evidence

All runs on a shared 4-core container, with the @objectstack/cli dependency closure built.

Reading main 0a69482 this PR 358e11b
The control's exact child (vitest list --filesOnly, no override) looped beside the real scaffold-rendering tests 3 of 132 exit 1, each failed to load config … ENOENT … packages/cli/tmp/manifest-init-plugin-…/package.test.ts or …/render-create-plugin-…/src/index.test.ts 0 of 216 (120 + 96)
Test file under synthetic tmp/ churn red on the first run (vitest list exited 1; its output began: failed to load config … ENOENT … scandir …) 0 of 8 red
Test file alone beside 8 busy loops (load, no churn), 5 runs 5 of 5 green; file 27.5–31.3 s, control case 6.7–7.7 s 5 of 5 green; file 27.6–30.9 s, control case 6.4–7.6 s
Population (vitest list --filesOnly) 506 files 506 files
Red-first pin against main's walk × ⭐ CONTROL …: the listing named [unit] tmp/hook-timeout-control-Btvz04/planted.test.ts green

The load-only row rules out the time hypothesis: the control child takes about 7 s against its 27 s budget. A directory watcher across all three CI slices (OS_TEST_SHARD k/3) recorded that the only directories appearing or vanishing in the package tree were under tmp/. The slice holding this test churned 25 of them. CI job logs are not readable from this container, so the queue's own stderr was not seen. The new message makes the next queue red carry it.

Tests and gates (head 358e11b)

  • pnpm --filter @objectstack/cli exec vitest run --project unit: 333 files / 4854 tests passed. The integration tier is left to CI, because this diff touches no spawn entry.
  • pnpm --filter @objectstack/cli run typecheck: exit 0.
  • eslint packages/cli --no-inline-config: exit 0.
  • dispatch-gates --commands: 55 derived, 54 run with exit 0, 1 NOT MEASURED (check:dual-build-cjs-loads, which needs a full build and exited 3). --ran reconciles: 0 unrun. This includes check:tier-file-adoption and check:cross-package-test-inputs, both green, and neither reads the cli SKIP_DIRS. check-plugin-teardown-shape --self-test was rerun green after fetching its positive-control commit. Its first attempt overlapped my synthetic tmp/ churn and refused on an unreadable tmp/ file, which is the same walk class (see Acceptance notes).

Changeset

skip-changeset: @objectstack/cli publishes files: ["dist", "README.md", "CHANGELOG.md"], and neither touched file is in it or built into dist.

Acceptance notes

  • Same walk shape, not changed here, not measured as a failure in CI: packages/qa/vitest-filter-preflight/src/index.ts testFilesUnder (filtered runs only), scripts/nightly-tiers.mjs tierPackages, and check-plugin-teardown-shape all descend into packages/cli/tmp/. A churn in tmp/ during one of them can refuse on a vanished file. Carrier: none.

🤖 Generated with Claude Code

https://claude.ai/code/session_01REwoooZ6nXESkVCEtsbeRC

…pin failures

Every case in hook-timeout-override-refusal.test.ts asserts a child's exit
code, so a dead child read only as `expected 1 to be +0`. Each status
assertion now carries the exit status and the bounded head of the child's
output, where a config-load failure prints its cause.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01REwoooZ6nXESkVCEtsbeRC
…er walk

packages/cli/vitest-tiers.ts walked the whole package at config load,
including tmp/, where sibling tests render scaffolds (test files included)
and delete them mid-run. A delete inside the walk threw ENOENT out of the
config load, so the #18788 pin's no-override vitest list child exited 1 in
the merge queue. tmp/ is now skipped; the control plants a test file there
and asserts the listing does not name it.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01REwoooZ6nXESkVCEtsbeRC
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/cli, touching 2 documentable anchor(s).

5 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/ai/skills-reference.mdx (via node_modules (literal, a string literal in SKIP_DIRS))
  • content/docs/ai/skills.mdx (via node_modules (literal, a string literal in SKIP_DIRS))
  • content/docs/deployment/cli.mdx (via node_modules (literal, a string literal in SKIP_DIRS))
  • content/docs/deployment/self-hosting.mdx (via node_modules (literal, a string literal in SKIP_DIRS))
  • content/docs/upgrading.mdx (via node_modules (literal, a string literal in SKIP_DIRS))

⛔ 1 release-owned page(s) also name something this change touched. These are read-only:

  • content/docs/releases/v18/18-0.mdx (via node_modules (literal, a string literal in SKIP_DIRS))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see

Coarse fallback — 31 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 c7aa9cde24ca7d17563caa4e01037f3ab1b9e990 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 9973670cec23c77457a7e18fb94b4b46098a5008 — the merge of head 358e11b89c06ff37f56d1cff069aa750f198c05e into base c7aa9cde24ca7d17563caa4e01037f3ab1b9e990, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 9973670cec23c77457a7e18fb94b4b46098a5008 && git checkout 9973670cec23c77457a7e18fb94b4b46098a5008
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin c7aa9cde24ca7d17563caa4e01037f3ab1b9e990 358e11b89c06ff37f56d1cff069aa750f198c05e && git checkout -B drift-repro c7aa9cde24ca7d17563caa4e01037f3ab1b9e990 && git merge --no-ff 358e11b89c06ff37f56d1cff069aa750f198c05e

node scripts/docs-audit/affected-docs.mjs --json c7aa9cde24ca7d17563caa4e01037f3ab1b9e990

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs c7aa9cde24ca7d17563caa4e01037f3ab1b9e990 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@github-actions github-actions Bot added the tests label Oct 26, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · ACCEPT · domain:server seat 1 · os-project-manager · session_01R1q2xdtYgU6FKrZ7LgjPCC · 2026-10-26T15:11Z

Head 358e11b89; report 6419032521 (on #26047); claim 6415802873; amendment 6417872008 (seat ruling A). No contract review is owed: there is no packages/spec/** diff and no narrowing.

item reading
Shape draft, base main, Fixes #26047, skip-changeset. vitest-tiers.ts is outside @objectstack/cli files[] (dist, README.md, CHANGELOG.md), as the body states. Mergeable clean.
Files 2 files, +52/−7: packages/cli/vitest-tiers.ts adds tmp to SKIP_DIRS with a comment; packages/cli/test/hook-timeout-override-refusal.test.ts changes the pin.
Root cause Not load: 5/5 green under 8 busy loops. The config-load walk read the git-ignored packages/cli/tmp, where sibling tests render scaffolds (with real *.test.ts files) and delete them. A delete mid-walk threw ENOENT out of the config load, so the ⭐ CONTROL child exited 1. Reproduced on main in 3 of 132 runs with the real neighbours.
Fix Ruling A, one entry in SKIP_DIRS. The pin's status assertions now carry the child's exit and output, so the next red says why. The control plants tmp/.../planted.test.ts and asserts it is not listed (red against main's walk).
Evidence 0 of 216 on the fix (main 3 of 132). Population unchanged at 506; check-tier-file-adoption and the cross-package test-input census green. 36 check runs success and 16 expected skips on this head, 0 failed. Build Core (hosting check:dual-build-cjs-loads, the one gate not measured locally) is green. cli unit tier 333 files / 4,854 tests green.
Landing 「按照 pm-dispatch 规则复核过的都授权」 (Leehom, 2026-10-25T11:35Z): ready and auto-merge through the relay.

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 26, 2026 15:12
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 26, 2026
Merged via the queue into main with commit 6b93552 Oct 26, 2026
53 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-1nrz43 branch October 26, 2026 15:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/s 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.

Queue-flake anchor: test/hook-timeout-override-refusal.test.ts

2 participants