Skip to content

test(cli): load the os doctor suites' oclif Config without the command scan (#23181 slice 8) - #25633

Merged
objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-23181-slice-8
Oct 24, 2026
Merged

objectstack-fleet[bot] merged 3 commits into
mainfrom
claude/issue-23181-slice-8

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #23181 (slice 8). The card is a series and stays open.

Clause-②: no
Metadata-protocol: none

Rows this PR addresses

Eight @objectstack/cli unit-tier rows from the card's table, the os doctor in-process suites. They share one cause, which this PR removes:

file (unit tier) card CI reading local before (3 runs) local after (3 runs) after / before (medians) CI reading × ratio status
src/commands/doctor-ledger-read-failure.test.ts 17.0 s 34.35 / 28.07 / 26.37 16.50 / 13.85 / 13.03 0.49 8.4 s reduced, projected under 10 s, not proven
src/commands/doctor-ledger-posture-independence.test.ts 16.6 s 24.46 / 29.89 / 27.00 17.37 / 15.12 / 14.69 0.56 9.3 s reduced, projected under 10 s, not proven
src/commands/doctor-unexamined-spec-tree.test.ts 14.3 s 18.02 / 18.65 / 19.55 10.41 / 11.20 / 11.12 0.60 8.5 s reduced, projected under 10 s, not proven
src/commands/doctor-node-env-default.test.ts 14.0 s 24.42 / 18.29 / 18.08 13.00 / 13.86 / 14.47 0.76 10.6 s reduced, not closed
src/commands/doctor-deprecation-hint-commands.test.ts 11.6 s 13.70 / 17.26 / 14.19 7.03 / 6.64 / 6.91 0.49 5.6 s done
src/commands/doctor-config-load-cause.test.ts 11.6 s 13.58 / 12.94 / 14.16 6.41 / 6.50 / 5.77 0.47 5.5 s done
src/commands/doctor-ledger-dir-authority.test.ts 10.3 s 18.78 / 19.57 / 14.62 7.28 / 7.08 / 6.45 0.38 3.9 s done
src/commands/doctor-config-env-overlay.test.ts 10.2 s 12.23 / 11.89 / 12.32 5.37 / 5.01 / 4.71 0.41 4.2 s done

The pin is the card's: the next landed refresh's per-file list no longer names a "done" row. The "projected" rows rest on a ratio applied to the card's old CI reading, so CI decides them, not this table.

The cause and the fix

Each suite drives the real command with Doctor.run(argv, { root: CLI_ROOT }). Given a root, oclif loads a fresh Config. @objectstack/cli ships no oclif.manifest.json, so that load builds the command manifest by importing every compiled command under dist/commands (73 commands). Measured in-process: 6.6 s for that Config.load, paid by each file's first test. doctor.ts never reads this.config, so the command list is pure overhead for these suites.

packages/cli/src/utils/__tests__/doctor-config.ts (new, 36 lines) loads one Config per file from the package's own package.json with only oclif.commands dropped. Hooks still load (the preparse separator strip is present: hooks = ["preparse"]), and the load takes 36 ms. The eight files pass await doctorConfig() instead of { root: CLI_ROOT } (12 call sites) and drop the now-unused CLI_ROOT / HERE / fileURLToPath lines.

  • It lives under src/**/__tests__/, the path tsconfig.build.json already excludes, next to src/utils/__tests__/server-body.ts. It is not under test/helpers/, because tsconfig.json's rootDir: src refuses a src/ test importing from test/ (TS6059, measured). It is not under src/commands/, because environments.test.ts walks every .ts there as a command source and would have modelled a phantom __tests__ doctor-config command id (measured: the unit tier went from 4812 to 4813 tests).
  • No test was deleted, renamed or re-tiered, and no timeout changed. All 139 tests pass in every run, with test full names identical before and after, file by file.

Why these rows (A2: win per changed line)

One 36-line helper plus 12 one-line call-site swaps (+57 / −48) removes 6.6 s from each of eight rows and brings four under the line. Rows looked at and not taken:

  • The @objectstack/cli integration files at 90 to 301 s (data-commands.absent-database, stack-conversion-record-door, package-install-local-*, ...). Each spawns the real CLI per fixture. Their fix is either a per-file restructuring or the test-budget: header method (slice 6), and that method needs a CI reading this container could not obtain (see A1).
  • test/scaffold-emission-typechecks.test.ts (unit, 33.3 s): a type-graph compile, a test-budget class candidate, so the same CI-reading constraint applies.
  • migrate-meta-* and explain-rule-id unit rows (10.2 to 18.1 s): not measured in this slice.
  • The other packages' rows: slices 1 to 5 and 7 took runtime, client, verify, rest and create-objectstack.

A1: the work list

PR #25409 (97be89bb3b), the newest landed refresh, carries no per-file list: its --diff refused (exit 1) on packages/cli/src/commands/migrate/audit-mail-bodies.archive.integration.test.ts:2 (test-budget: 85, off the 10 s grid). origin/main at e649c2d9 already reads 90 there, so the next refresh can list files. Reproducing the diff locally was not possible: the test-core-timings-N-of-6 captures are retained one day, so only 2 of the window's 8 runs still had them, and this container's proxy refuses the artifact blob host (HTTP 403). So the rows above come from the card's table, each re-measured on e649c2d9 (every one still read over 10 s locally before the change).

What the remaining time is (for the next slice)

Measured per warm Doctor.run (about 0.6 to 0.9 s): the three real tool probes pnpm -v (0.4 to 0.9 s under vitest's PATH), tsc -v (0.1 to 0.4 s) and git --version (about 15 ms). On top of that, each file's first run pays the lazy @objectstack/cloud-connection import (4.3 s). The files still near or over the line are the ones with 13 to 18 runs. Stubbing the probes is a separate decision, because the suites then stop seeing the real probe rows. It is not taken here.

Proof

  • Measurement, same way before and after: bash scripts/pm/os-verify-lock.sh -c 'cd packages/cli && pnpm exec vitest run --project unit --maxWorkers=2 --reporter=json --outputFile=FILE' + the 8 files. Per-file = the json reporter's endTime − startTime (the per-file module line CI reports; it sums to vitest's tests total). "Before" restored the 8 files from e649c2d9 (tree only), then restored from HEAD (git diff HEAD empty afterwards). Shared box: absolute seconds are box readings, so ratios are the comparable figure.
  • Shared fixture check: the helper is new and only these eight files import it. doctor.ts and every other Doctor.run suite (doctor-env-provenance, doctor-tenancy-posture-report) are untouched.
  • pnpm --filter @objectstack/cli typecheck (tsc + check:test-typecheck OK): exit 0 at f0e74dd1d. The --noEmit program includes the helper; the build program (tsconfig.build.json --listFilesOnly, 1318 files, doctor.ts among them) includes nothing under __tests__.
  • cli unit tier at f0e74dd1d: 326/327 files, 4811/4812 tests. The one failure is src/utils/boot-preparation-parity.test.ts, a 5 s vitest timeout under load (9.15 s) in a file this diff does not touch. Re-run alone: 37/37, exit 0. The two earlier full runs passed it (327/327). The integration tier is declared to CI: the diff touches no integration file and no spawn entry.
  • node scripts/pm/dispatch-gates.mjs --commands at f0e74dd1d: 58 commands, all exit 0. --ran: "58 derived, 58 run, 0 NOT-MEASURED, 0 UNRUN".
  • eslint --no-inline-config packages/cli: exit 0.
  • pnpm lint (eslint . --no-inline-config, the whole repo): exit 0 at f0e74dd1d.

Changeset

skip-changeset: nothing published changes. Every changed file is a *.test.ts or sits under src/**/__tests__/, which tsconfig.build.json excludes, so no changed file reaches dist/ (files: ["dist", ...]).

Acceptance notes

  • @objectstack/cli ships no oclif.manifest.json, so any Config.load from the package root imports every command. Whether the published os binary pays the same cost per invocation was NOT MEASURED here. This is an observation only.
  • src/utils/boot-preparation-parity.test.ts "every SERVE_ONLY entry is still used by serve.ts" ran 9.15 s against vitest's 5 s default in one contended full-tier run. Observed once.

🤖 Generated with Claude Code

https://claude.ai/code/session_013fXj9gbwakFbBp5U9x4EjF


Generated by Claude Code

Eight in-process `os doctor` suites called `Doctor.run(argv, { root })`,
which makes oclif build the command manifest by importing every compiled
command (no oclif.manifest.json ships): 6.6 s of each file's first test.
Doctor never reads `this.config`, so a shared helper loads the package's
own Config with only `oclif.commands` dropped; hooks still load.

Claude-Session: https://claude.ai/code/session_013fXj9gbwakFbBp5U9x4EjF
Co-authored-by: Claude <noreply@anthropic.com>
`tsconfig.json`'s rootDir is `src`, so a `src/` test cannot import from
`test/helpers/`. `src/**/__tests__/**` is the place the build already
excludes (as `src/utils/__tests__/server-body.ts`).

Claude-Session: https://claude.ai/code/session_013fXj9gbwakFbBp5U9x4EjF
Co-authored-by: Claude <noreply@anthropic.com>
`environments.test.ts` walks every `.ts` under `src/commands` as a command
source, so a helper there registered a phantom `__tests__ doctor-config`
id in its model. `src/utils/__tests__/` already holds the package's other
non-test helper and is excluded from the build the same way.

Claude-Session: https://claude.ai/code/session_013fXj9gbwakFbBp5U9x4EjF
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 24, 2026
@github-actions

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 e8de8a7ece08da5875cb50186eed3b6509a367c8 → packageMentionDocs.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对

ACCEPT · domain:server seat 2 · sunhaolin · session_01JVTd3PprStGa26aez5omLB · 2026-10-24T11:53Z · head f0e74dd1dd · claim 6382697995 · report 6383812335

Checklist conclusions (read on GitHub, not from the report):

  • Shape: draft, base main, author objectstack-fleet[bot], assignee sunhaolin. The first line is Part of #23181 (slice 8); no closing keyword. Clause-②: no, Metadata-protocol: none. skip-changeset is right: every changed file is a *.test.ts or sits under src/**/__tests__/, which tsconfig.build.json excludes.
  • Scope: 9 files in packages/cli/src/ (+57/-48): eight doctor-*.test.ts call-site swaps and one new helper, src/utils/__tests__/doctor-config.ts. Not governed. No file that open PRs feat(cli): serve the Console document with a nonce-based content-security-policy #25569, fix(service-analytics)!: an analytics read gate that could not decide answers 503 SERVICE_UNAVAILABLE, not the denial's 403 #25595 or fix(rest)!: apply an inline import mapping entry's transform, defaultValue and required #25540 add is touched.
  • The card's prohibitions, checked: no test deleted, renamed or re-tiered; no timeout raised; no move to a slower or skipped project. The report gives identical test full names per file before and after (139 tests).
  • No vacuous pass, verified by the seat: the helper loads oclif's Config from the package's own package.json with only oclif.commands dropped (hooks still load). packages/cli/src/commands/doctor.ts at head reads no this.config.* member at all, so the command manifest it no longer builds was never an input to what these suites assert. doctor-deprecation-hint-commands.test.ts resolves commands from COMMANDS_DIR on disk, not through Config, so its "no codemod command" pin is unaffected.
  • Rows: four of eight are measured done (5.6 / 5.5 / 3.9 / 4.2 s projected from the card's CI readings), three are projected under 10 s but not proven, and doctor-node-env-default is reduced but not closed. The card's pin decides: the next landed refresh's per-file list. The PR says exactly that.
  • CI on head f0e74dd1dd at this reading: 25 success, 12 skipped, 7 in progress (Test Core 2–6/6, Type Check · workspace / consumer gates), none red. The seat lands only on all green or expected skips.
  • Writes: all through the relay; no GitHub MCP write.

Deviations accepted: as reported. The one local unit failure (boot-preparation-parity.test.ts, a 5 s vitest timeout under load, untouched by this diff, green alone and in two earlier full runs) is noted, not counted; CI decides.

Carried to slice 9: the remaining doctor time is the three real tool probes (pnpm -v, tsc -v, git --version) and the lazy @objectstack/cloud-connection import. Stubbing the probes is a separate call, made only if the next refresh still lists those files. The 90–301 s cli integration rows need a CI reading, which PR #25409's refresh could not give (its --diff refused on an off-grid header that main has since fixed).

Landing: pr_ready + automerge_enable through the relay once every check on this head is green. Then #23181 goes back to pm:queue, and the cloud session session_013fXj9gbwakFbBp5U9x4EjF is archived.


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 24, 2026 12:14
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 24, 2026 12:14
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 24, 2026
Merged via the queue into main with commit 451bf61 Oct 24, 2026
47 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-23181-slice-8 branch October 24, 2026 12:38
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.

2 participants