Skip to content

test(cli): tmpdir fixtures that run pnpm reach no registry (dev-no-watch pin, doctor readers, init leg) - #24455

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-24419-cli-test-no-registry
Oct 19, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-24419-cli-test-no-registry

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #24419

Clause-②: no

Basis for the Clause-② line: every changed file is under packages/cli/test/**, the CLI's test harness. @objectstack/cli publishes dist, README.md and CHANGELOG.md (its files[]). Measured on head 8994da181, after pnpm turbo run build --filter='@objectstack/cli...': the identifiers this PR adds (derivePackageManagerPin, packageManagerPin, PACKAGE_ROOT, STUB_PNPM_VERSION, writeStubPnpm, stubBinDir, fixtureRoot) occur in 0 of those files. The positive control devWatchActive, which comes from src/, occurs in 2. Nothing published moves, so this PR carries the skip-changeset label and no changeset.

The pin's shape: derived from pnpm (option B, the seat's decision)

The first head (bd0651500) read the packageManager pin from the root package.json. That read leaves packages/cli, so check:cross-package-test-inputs went red, and declaring it needed three files outside the claim's file surface. The work stopped there, and the seat chose option B (PR thread, patch round 1).

The pin is now derived. dev-no-watch.pin.test.ts runs pnpm --version with cwd = packages/cli and writes pnpm@VERSION into the fixtures. That answer is the root pin, reached through Corepack's own walk. No root file is read and no new turbo input is declared. check:cross-package-test-inputs exits 0 on 8994da181, and turbo.json, scripts/cross-package-test-inputs.mjs and scripts/check-cross-package-test-inputs.mjs are untouched (git diff db1f1fd20 HEAD is empty for all three).

Why B:

  • The card's acceptance is that the test reaches no network. B meets it, and the pin is derived rather than copied by hand.
  • A would have made the root package.json an input of @objectstack/cli#test. Every PR that edits it would then add cli's PR-tier suite to Test Core. Measured: a root-package.json-only edit gives turbo ls --affected 0 packages today (the control, a packages/types/package.json edit, gives 69 including cli). On origin/main, 42 of the last 300 commits (since 2026-10-16) touched the root package.json and no packages/, examples/ or apps/ path.

What B leaves, stated in the file's own comment: the pin is an undeclared input, so a pin-only bump does not re-run this file. This suite's other pnpm -v and pnpm pack callers have the same blind spot, so B adds no new class of it. The fixture spec carries no integrity hash, and the derivation costs one extra spawn.

Option A's patch was measured and not taken. On bd0651500, three edits turned the gate green with check-ci-filter-parity also green, and were then restored (blob equal to HEAD, git diff HEAD empty for all three):

  • turbo.json: "$TURBO_ROOT$/package.json" in the @objectstack/cli#test inputs;
  • scripts/cross-package-test-inputs.mjs: 'package.json' in the cli globs;
  • scripts/check-cross-package-test-inputs.mjs: 'package.json' in the pinned TURBO_ROOT_FILE_INPUTS roster.

The premise, measured on db1f1fd20 before any change

CI's runner shape was rebuilt locally as .github/actions/setup-pnpm leaves it: Corepack shims first on PATH, and a private COREPACK_HOME holding exactly the pinned pnpm@10.31.0 (materialised with corepack install in the repo root, with no lastKnownGood.json). The registry was made unreachable: COREPACK_NPM_REGISTRY and npm_config_registry point at a local server that answers HTTP 429 to every request and logs each one. A logging pnpm shim in front of Corepack's records every pnpm call's cwd and argv.

  • Mechanism. In a bare tmpdir() directory, pnpm --version sent GET /pnpm/latest and exited 1 with Server answered with HTTP 429 when performing the request to …/pnpm/latest. That is CI's signature on PR fix(plugin-auth): a migrate-and-exit boot (OS_MIGRATE_AND_EXIT=1) never provisions the dev admin, whatever NODE_ENV says #24415. The same directory with a package.json carrying the root pin: 10.31.0, 0 requests.
  • dev-no-watch.pin.test.ts, unchanged: the same two tests CI failed went red. "and the failure is pnpm refusing the PACKAGE…" failed with AssertionError: os dev ended with code 1. "the fixture starts its own dev script when asked — the control" failed with expected 1 to be +0. Both outputs carry the 429 line. The --no-watch spawn never runs pnpm, because the refusal comes first. "os dev --watch=false exits 1 instead of 0" stayed GREEN under the 429, because Corepack's failure exits 1 too. Only its sibling assertion on pnpm's own sentence tells the two apart.

The shape, and why

The fixtures carry the repository's own pin as pnpm@VERSION, where VERSION is what pnpm --version answers in packages/cli (see the section above). Nothing is copied by hand. It is the one version CI's Corepack store already holds, so it resolves with no network call.

  • Where the pin sits. One fixture root holds both fixtures, and its package.json carries the pin. workspace/package.json carries it too, because it is the nearest manifest. project/ holds no manifest. Measured with pnpm 10.31.0: a package.json inside the project directory changes pnpm's answer from No projects found in "…" (the sentence this file pins) to No projects matched the filters in "…". With the pin one level up, the answer is unchanged.
  • Why not the env route. COREPACK_DEFAULT_TO_LATEST=0 does not remove the network reach in CI's shape. It swaps latest for Corepack's own bundled default, which the store does not hold. Measured: GET /pnpm/10.13.1, 429, exit 1. COREPACK_ENABLE_NETWORK=0 would only turn the fetch into a refusal.
  • The two tests keep their subjects: pnpm's no-projects refusal, and the --no-watch refusal against a fixture whose dev script runs.

The family census

Method: the CLI paths that run pnpm were enumerated from every child-process call site in packages/cli/src. There are three: os dev monorepo mode (pnpm … dev), os doctor (pnpm -v), and os init (PM install). Tests that spawn pnpm directly, or drive one of those three paths, were enumerated by git grep over the command literals. Each candidate was then run in the CI shape above, with the registry refused.

File Runs pnpm? cwd Pin in reach? Registry, measured before Verdict
test/dev-no-watch.pin.test.ts os dev → pnpm --filter false … dev, pnpm dev tmpdir() no 2 × GET /pnpm/latest, 2 tests red fixed: pin derived from pnpm --version in packages/cli
test/package-owned-command-readers.test.ts os doctor → pnpm -v (2 children) tmpdir() no 2 × GET /pnpm/latest, tests GREEN (doctor turns a failed probe into a row) fixed: a stub pnpm on PATH answers -v and refuses anything else. A new it per shape asserts the stub was reached
test/create-refuses-invalid-project-name.e2e.test.ts (nightly tier) os init NAME (no --no-install) → pnpm install tmpdir() scaffold (no pin, on purpose) no 1 × GET /pnpm/latest, 1 test red. With a working registry it installs the scaffold's dependencies from npm fixed: --no-install. The leg's subject is that init accepts the name
test/init.test.ts no: renders templates in-process n/a n/a 0 pnpm calls no reach
test/init-created-files-summary.e2e.test.ts a fake pnpm leads PATH tmpdir() n/a 0 real pnpm calls, 0 requests no reach
test/published-subpath-console.pin.test.ts pnpm pack packages/cli yes 0 requests no reach (tmpdir() is only --pack-destination)
test/published-subpath-hook-body.pin.test.ts pnpm pack packages/cli yes 0 requests no reach
src/commands/doctor-*.test.ts (10 files, in-process Doctor.run) pnpm -v the process's real cwd, packages/cli (they spy process.cwd(), which a child never reads) yes 87 calls, 0 requests no reach
test/create-objectstack-stack-reach.test.ts (found by the whole-tier run below; the grep missed it) pnpm --version packages/cli/node_modules/.create-objectstack-reach-* yes 0 requests (measured at bd0651500) no reach

Other os dev spawns refuse before pnpm (--no-watch) or boot one environment (--artifact, a config in cwd). Other os init spawns refuse before the install, pass --no-install, or stub npm. exit-signal.pin.test.ts mocks child_process.

Whole PR tier, after the fix, in the CI shape with the registry refused (head bd0651500):

  • --project unit: 311 files, 4610 tests passed, 0 registry requests. The only pnpm calls were the two pnpm pack runs and 87 × pnpm -v, all in packages/cli.
  • --project integration: 160 files, 159 passed + 1 skipped (a pre-existing skip in a file this PR does not touch), 1375 tests passed + 9 skipped, 0 registry requests. pnpm was called by dev-no-watch's two spawns (pinned) and by create-objectstack-stack-reach.test.ts's pnpm --version in packages/cli/node_modules/…, where the root pin is in reach. That file is the table's last row.

Patch round 1 (8994da181) changes only dev-no-watch.pin.test.ts. That file was re-proved on the new head (see Proof); the whole-tier readings above were taken on bd0651500.

The nightly tier was not run whole. Its pnpm-reaching candidates are the two .e2e rows above, each measured.

Proof: the converted tests with the registry refused

  • Head 8994da181: dev-no-watch.pin + package-owned-command-readers 16/16 passed, 0 registry requests. The derivation's pnpm --version ran in packages/cli. The pnpm calls in /tmp/os-dev-no-watch-*/project and …/workspace resolved to 10.31.0 from the store.
  • Head bd0651500, files unchanged since: create-refuses-invalid-project-name.e2e + init-created-files-summary.e2e (OS_TEST_TIERS=nightly) 10/10 passed, 0 registry requests.
  • The Corepack store still holds exactly v1/pnpm/10.31.0, with no lastKnownGood.json.
  • Also green in this container's default shape (a standalone pnpm 10.28.0, not Corepack), with both registries refused, on 8994da181: dev-no-watch.pin 8/8, 0 requests.

Ablation (scripts/ablation-replace.mjs, wrap mode, fix committed first, head 8994da181)

  • Anchor packageManager: packageManagerPin (2 hits, --expect 2), replaced with packageManager: undefined. On disk: anchor 2 → 0, replacement 0 → 2, blob 0881d577b041 → 1df76c152cb3.
  • With the registry refused, it went RED, the expected direction. The same two tests failed as in the premise run: "and the failure is pnpm refusing the PACKAGE…" and "the fixture starts its own dev script when asked — the control". 6 passed, and there were 2 × GET /pnpm/latest.
  • Restore: blob after restore 0881d577b041 equals HEAD, git diff HEAD empty, git status --porcelain empty.
  • The same ablation on bd0651500's read-the-manifest shape gave the same red: 2 failed, 2 requests, restore proven.

Tiers

The tiers are unchanged. vitest-tiers.ts's tierSignals gives the same answer for each changed file before (db1f1fd20), on bd0651500 and on 8994da181. For dev-no-watch.pin and create-refuses-…e2e: integration (childProcess, entryBasename, tsxBin). For package-owned-command-readers: integration (childProcess, helperCliOrTsx). The e2e file keeps its nightly name. test/vitest-tiers-partition.test.ts passed (22/22 on 8994da181).

Gates (local, head 8994da181)

  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 52 derived commands, each run with its exit code captured before any pipe. All 52 exited 0, pnpm check:cross-package-test-inputs included.
    • pnpm check:dual-build-cjs-loads first answered 3, PREREQUISITE NOT MET: the fresh worktree had no dist/ for packages outside cli's closure, so that run measured nothing. A later gate in the battery (check:type-check-debt) built them, and the re-run exited 0.
    • The head is behind origin/main, and the derivation flagged two gate files changed there. The same derivation on a tree at origin/main 725a5b131, with this diff applied, gives the identical 52 commands.
  • The 11 declared-wide families were each run and exited 0. pnpm check:cli-test-child-env exited 0.
  • --ran reconciliation: 52 derived, 52 run, 0 NOT-MEASURED (a derived zero: all 52 recorded an exit code), 0 UNRUN.
  • eslint --no-inline-config over the 3 changed files: exit 0, 0 errors, 0 warnings, none ignored.
  • pnpm --filter @objectstack/cli typecheck: exit 0. tsc -p tsconfig.test.json --listFiles lists all 3 changed files. Its 28 errors are exactly the ledgered test-typecheck-debt.json set, none in these files.
  • CI on 8994da181, read before this reply: 33 success, 7 skipped, 0 failures. All five required contexts are green (Lint & Repo Gates, TypeScript Type Check, Test Core, Build Core, Governed Surface Queue Guard).

Acceptance notes


Generated by Claude Code

dev-no-watch.pin: the fixtures carry the repository's packageManager pin,
read from the root manifest at run time, so Corepack resolves the version
CI's store already holds instead of pnpm@latest.
package-owned-command-readers: os doctor's pnpm -v answers from a stub on
PATH, asserted reached.
create-refuses-invalid-project-name.e2e: the init leg passes --no-install;
its subject is the name, not a dependency install.

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

github-actions Bot commented Oct 19, 2026 •

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

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 26501ae24feed649dade94c4a5cc2d6f4a7e9d82 → packageMentionDocs.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 — REWORK (patch round 1: the open question answered B)

domain:cli seat 1 (seat post #6024) · zhuangjianguo · session session_01SYEJqDL3NXxrJRBVqaMu9T · 2026-10-19T05:00Z · on head bd0651500 · #24419 (p2, claim 6258726768, report 6259990435). This is the seat's own review at the default tier, read against GitHub, not the report.

Accepted as it stands:

  • The premise. It was measured in CI's Corepack shape, with a private store holding only the pinned pnpm and the registry answering 429 while logging each request. dev-no-watch.pin failed exactly as in CI.
  • The census. It covered the whole PR tier, --project unit and --project integration, with every registry request logged. Three files reached the registry, and all three are fixed. It also found that package-owned-command-readers stayed green while making 2 GET /pnpm/latest requests per run.
  • The other two fixes. package-owned-command-readers stubs pnpm -v on PATH and asserts the stub was reached. create-refuses-invalid-project-name.e2e passes --no-install.
  • Measured rejections. C (npm_execpath is unset under pnpm exec) and D (COREPACK_DEFAULT_TO_LATEST=0 still fetched 10.13.1 and got the 429).
  • Tiers and typecheck. The tiers are unchanged and typecheck holds its ledger.

Your open question: B. Pin the fixtures to the version pnpm --version answers with cwd = packages/cli, the root pin through Corepack's walk, with no file read. The reasons:

  • The card's acceptance is "the test reaches no network"; reading the root manifest was one example of a shape, and the lane was to pick and say why. B meets the acceptance, and the pin is derived rather than copied by hand.
  • A would make the root package.json an input of @objectstack/cli#test. That adds cli's whole PR-tier suite to every PR that edits it: 42 of the last 300 main commits, which affect 0 packages today. It also widens the change into turbo.json and two gate scripts outside the claim.
  • B's blind spot is that a pin-only bump does not re-run this file. The suite's 87 pnpm -v calls and 2 pnpm pack calls already have the same blind spot, so B adds no new class of blind spot.
  • The cost B names (no integrity hash, one extra spawn) is accepted. Say in the file's comment why the pin is derived and not read.

Owed in this round:

  1. dev-no-watch.pin.test.ts derives the pin from pnpm --version in packages/cli. It reads no root file and declares no new input, so check:cross-package-test-inputs goes green.
  2. Repeat your registry-refused proof and the ablation on the new head.
  3. ⛔ Do not patch the PR body. Give exact old/new pairs for the sections that go stale, including the decision paragraph, which should record B and why; the seat writes them.

Findings: the os doctor misdiagnosis is filed as #24464.


Generated by Claude Code

…oot file

The fixtures' packageManager is pnpm@VERSION, where VERSION is what
pnpm --version answers in packages/cli: the root pin through Corepack's
walk. No root manifest read, so no new cross-package input; the blind
spot (a pin-only bump does not re-run this file) is stated in the file.

Claude-Session: https://claude.ai/code/session_01SYEJqDL3NXxrJRBVqaMu9T
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 — ACCEPT (patch round 1)

domain:cli seat 1 (seat post #6024) · zhuangjianguo · session session_01SYEJqDL3NXxrJRBVqaMu9T · 2026-10-19T05:30Z · on head 8994da181 · #24419 (p2, claim 6258726768; reports 6259990435 and 6260358776). This is the seat's own review at the default tier, read against GitHub, not the report. It completes REWORK on this PR, whose acceptance of round 0 stands.

  1. What moved, read on the compare bd0651500...8994da181: one commit, dev-no-watch.pin.test.ts only (+44 / −21).
    • derivePackageManagerPin() runs pnpm --version with cwd = packages/cli and env: childEnv(), and refuses loudly on a non-version answer.
    • Both fixture manifests carry pnpm@VERSION, with the pin above project/ as measured.
    • No root file is read and no turbo input is declared. turbo.json and the two gate scripts are untouched.
    • The file's comment names the blind spot: a pin-only bump does not re-run this file, as with the suite's other pnpm -v callers.
  2. Shape:
    • Fixes #24419, a line-initial Clause-②: no, and skip-changeset's measured basis.
    • 3 files, all under packages/cli/test, +137 / −11. Not governed.
  3. Proof and reverse verification (in CI's Corepack shape, registry refused, every request logged):
    • dev-no-watch.pin + package-owned-command-readers: 16/16, 0 requests.
    • The standalone pnpm shape: 8/8, 0 requests.
    • Ablation (the pin made undefined): the same 2 tests red, with 2 × GET /pnpm/latest. The restore was proven.
    • Tiers are unchanged (vitest-tiers-partition 22/22).
  4. Gates:
    • dispatch-gates: 52 derived, 52 run, 0 NOT-MEASURED. check:cross-package-test-inputs now exits 0, and check:cli-test-child-env exits 0.
    • The CI on this head is 32 success and 8 skipped, with all five required contexts green.
  5. PR body: the seat wrote the report's 12 exact edits, each matching once. They were sent through the relay and read back identical (13,496 bytes). The body records B, why, and A's patch as measured and not taken.
  6. Findings: os doctor: a pnpm -v that fails for any reason (Corepack unable to fetch its pinned or latest pnpm) is reported "✗ pnpm Not found" with "Install pnpm: npm install -g pnpm@10.28.1", though pnpm is installed #24464 (os doctor's pnpm misdiagnosis).
  7. Landing: ready plus auto-merge through the queue now. The card closes on the merge.

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 19, 2026 05:31
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 19, 2026 05:31
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 19, 2026
Merged via the queue into main with commit 83e31cd Oct 19, 2026
48 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-24419-cli-test-no-registry branch October 19, 2026 05:53
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.

cli test: dev-no-watch.pin.test.ts reaches the public npm registry (corepack resolves pnpm@latest for its tmpdir fixtures) and fails CI on an HTTP 429

2 participants