Skip to content

docs(cli-test): scope the production-default header to the pin it describes - #12569

Merged
os-litant merged 1 commit into
mainfrom
claude/issue-12561-production-default-header-scope
Aug 26, 2026
Merged

docs(cli-test): scope the production-default header to the pin it describes#12569
os-litant merged 1 commit into
mainfrom
claude/issue-12561-production-default-header-scope

Conversation

@os-litant

Copy link
Copy Markdown
Collaborator

Fixes#12561

The header docblock of packages/cli/test/serve-node-env-production-default.e2e.test.ts only. No other file, no test body, no helpers/serve-process.ts, no serve.ts. Net +4 / -2, all inside the /** ... */ block.

The two edits

1. The mechanism is applied to this file's own legs. The header already states it — the card's own correction comment established that, and it holds. The sentence "Measured, deterministic, not load-dependent: unset and production both fail that way, test and development both resolve from src/" now continues:

— which is why the two explicit-NODE_ENVit() blocks below execute src/commands, and only the unset pin measures the built dist/.

⛔ No table, and the mechanism is not restated. The isProd() membership test is already quoted verbatim in this block ("a negated membership test over ['development','test']", in the paragraph beginning "That value is also what makes @oclif/core's tsPath() rewrite the command target"), and a second copy is the rot the sibling rule in packages/cli/vitest.config.ts names ("counts in exactly one place in this file — a second copy is what rotted last time"). What was missing was never the mechanism; it was the consequence for this file's own legs, which neither this header nor any registry entry said out loud.

2. The closing sentence takes a scope word and keeps its force."bin/run.js plus a genuinely built dist/ is the only shape that reaches the gate" now reads "...that reaches the gate for this pin."

⛔ Not weakened and not deleted. It is still the conclusion of the ⛔ "Do NOT 'fix' a command serve not found here by switching the spawn to bin/run-dev.js" warning, and that warning is why the unset-NODE_ENV input stays measurable at all. Three words narrow it from a claim about the file (false — two of three legs contradict it) to a claim about the unset pin (true, and it is the pin the surrounding warning is about).

Premises re-derived — the order was right about the defect, off on some citations

origin/main moved 5fbd58e0ddd4fc6c9d between the card and this branch. The file is nonetheless byte-identical across both and my base: blob 7cdab640b64a6dd92dd4d3ae06a06d164630fde1 at all three, so the card's line numbers are directly checkable. Re-derived on dd4fc6c9d:

premiseorder saysmeasuredverdict
probeOriginCheck definition230230holds
unset leg probeOriginCheck({})405405holds
{ NODE_ENV: 'development' } leg415415holds
{ NODE_ENV: 'test' } leg425425holds
their it( lines403 / 413 / 423402 / 412 / 422off by one
closing sentence152-153152-153exact
"unset and production both fail that way..."143139-141 (143 is "dist/commands read under concurrent spawn load")off by 2-4
isProd() quotation105-107104-106off by one

Still three legs, still {} / development / test — no fork to report. Both mechanism statements the correction comment cites are present, so the card body's "the header nowhere says so" is false and the correction comment is the accurate version, exactly as it says. The citation drift above is itself the correction's own argument for quoting phrases rather than lines, which is why every citation in this PR body is a quoted phrase.

Mechanism verified first-hand, not taken from the card. packages/cli/node_modules/@oclif/core is 4.13.3; lib/util/util.js:65-67 is isProd() returning a negated membership test over ['development','test'] against process.env.NODE_ENV ?? '', and lib/config/ts-path.js:252 is the site that skips the source lookup on it.

⚠️One card premise does not hold, and it is reported rather than reconciled. The card body's section "Why this is not fixed by the registry entry that now covers it" speaks of two DELIBERATE_REROUTE entries as present. PR #12558 is open, not merged (merged: false), and the literal DELIBERATE_REROUTE has zero hits in this tree (reverse-checked: DELIBERATE returns 17 hits in that same file). The DELIBERATE registry that is on main holds two entries for a different rule — helpers/serve-process.ts::childEnv and serve-process-child-env.e2e.test.ts::leakedEnv, both bulk-env-copy declarations, neither a reroute. This changes nothing about the repair: the card's point was that a registry entry in scripts/ cannot repair a sentence in the test file, and that is true whether the entry has landed or not.

The reading owed: is this one cause with #12552, or two unrelated slips?

One cause. PR #12552's edit to this same block and this one are the same operation, on two different axes.

  • test(cli): catch the silent port drift in three serve e2e spawners #12552 corrected "all three leave the variable unset and spawn bin/run.js through plain node — this file's own shape —". False because those three pass --dev on the spawn line and this file does not.
  • This PR corrects "...is the only shape that reaches the gate". False because this file's three legs split two ways on the child's NODE_ENV.

Both sentences say "shape" as though this file has one. It has two axes that vary below file granularity — --dev presence (the axis #12552 got wrong, measured across sibling files) and child NODE_ENV (the axis this card is about, measured across this file's own legs) — and the docblock's habitual unit of description is the file, while the facts it describes are per leg. Two readers a day apart each found the block collapsing a per-leg fact into a file-level one; that they found different axes is why it reads as two slips, and that they found the same collapse is why it is one cause.

What that means for the next person: not a rewrite, a habit. The block is well maintained — both slips were caught within a day and each repaired precisely — and it is the granularity that is wrong, not the prose. So the recommendation is a check, not a restructure: any sentence here that says "this file" or "the only shape" must be held against all three it() blocks before it ships. Evidence that this is the right level of response: both repairs turned out to be the same tiny shape. #12552 added a scope marker and one connecting clause ("⛔ but NOT this file's own shape, and the difference decides how each one FAILS on a taken port"); this PR adds a scope word and one connecting clause. A block needing a structural rewrite would not be repairable twice by the same three-word move. ⛔ A table would make it worse — a fourth copy of a mechanism already stated three times is what rots next.

Verification — all at 96617bbf7, the final commit, clean tree

TREE_AT=96617bbf7 dirty=[]. Exit codes captured before any pipe (redirect-then-capture), and each gate's own verdict line read rather than a bare status.

checkresult
pnpm lint (eslint . --no-inline-config, whole repo, not narrowed)shared verify lock: VERDICT command-exit 0 · held the lock 58s · waited 22s
check:cli-test-child-envexit 0 — "35 spawner source(s) among 97 under packages/cli/test; no new bulk process.env copy reaches a spawned child, and all 41 spawn call(s) declare their child's env"
check:nul-bytesexit 0 — "scanned 6925 text file(s) ... no raw ASCII control bytes"
check:cross-package-test-inputs + check-cross-package-test-inputs.mjsexit 0 — "OK: 20 package(s) read outside themselves, all declared"
check:engine-double-contractexit 0 — "416 pinned, 133 in the DEBT ledger, 2 exempt"
check:where-matcherexit 0 — "303 matcher(s) discovered ... baseline key set verified against dd4fc6c: no files added"
check:query-options-erasureexit 0 — "240 site(s) in 47 file(s) — at the ceiling ... no files added"
check:objectql-double-limit · check:test-source-alias · check:page-declaration-shape · check:published-files · check:slot-lookup · check:type-source-resolution · check:type-check-coverageall exit 0
check-comment-mask-adoption.mjs · check-ci-filter-parity.mjs · check-plugin-teardown-shape.mjsall exit 0

Gate list derived with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack against the real change set (1 path, working tree, three-dot vs merge base dd4fc6c9d) — not from a hand-written list. Its provenance line confirms the answer is about this repo at this commit.

The change is comment-only — proven, not asserted

Transpiling both blobs with removeComments and hashing the emitted program:

before (HEAD blob 7cdab640b) sha256=891582c177224fe3... 5498 bytes
after (this commit) sha256=891582c177224fe3... 5498 bytes
IDENTICAL emitted program

Source grew 158 bytes (21912 to 22070); the executable program did not move a byte. Reverse-verified so the identical hash is informative rather than vacuous: mutating one token in a copy (toBe(403) to toBe(404), injection confirmed on disk by occurrence count before hashing) moves the hash to 1927b609ac2cc031. The harness can say no.

Two narrowings, declared

⛔ Neither is reported as a green.

  1. The file's own three e2e legs were not run. They spawn a real built CLI three times at 180s timeouts each and require packages/cli/dist; the full packages/cli suite does not finish in this container's ~10-minute foreground window (SIGTERM, exit 143 — which is nothing ran, never a pass). The justification is the proof above: the emitted program is byte-identical, so the run would measure the same program it measures on main. CI runs it under @objectstack/cli#test dependsOn build regardless.
  2. pnpm --filter @objectstack/cli typecheck is NOT MEASURED for this edit, not green.packages/cli/tsconfig.json declares include: ["src"], so tsc --listFilesOnly over that program returns 635 files and 0 hits for serve-node-env-production-default.e2e.test.ts (reverse-checked: packages/cli/src/commands/serve.ts returns 1). Any "typecheck passed" line here would be true and empty. The structural half is covered — check:type-check-coverage exits 0 above.

No changeset — skip-changeset

Rule applied: the diff is comment prose inside one packages/cli/test/ file, proven above to leave the emitted program byte-identical. Nothing user-visible changes and this PR publishes nothing, so it takes the skip-changeset label rather than a .changeset/*.md.


Generated by Claude Code

…cribes
`serve-node-env-production-default.e2e.test.ts`'s header states the oclif
reroute mechanism generically and then closes unqualified, while two of the
file's own three legs reach the gate from `src/commands`.
Apply the already-stated mechanism to this file's own legs, and scope the
closing sentence to the unset pin it is the conclusion of. The mechanism
itself is not restated and no table is added — the file already carries both.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UjujZN219uFzBhSYfMykCd
@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
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

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 09b4f4e4ed6019cfd79f89670af9c718ac0ccdf7packageMentionDocs.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/xsskip-changesetPR has no user-facing published change; bypasses the changeset gatetests

Projects

None yet

2 participants

@os-litant@claude