Skip to content

test(cli): orphans.driver-contract.test.ts's production-posture boot depends on a sibling e2e spawn minting the dev crypto key — deterministic red once the e2e tier leaves the queue #16491

Closed

Description

@claude

Found while landing #16455 (the e2e / live filename tiers move to a nightly run on main; PR #16481). Filed unassigned for triage; not fixed there because that card's ruling forbids editing any test file.

What

packages/cli/src/commands/secret/orphans.driver-contract.test.ts sets process.env.NODE_ENV = 'production' in its beforeAll and boots a real kernel through bootSchemaStack with SettingsServicePlugin. LocalCryptoProvider derives its posture from NODE_ENV alone and, in production, requires OS_SECRET_KEY, OS_DEV_CRYPTO_KEY, or a persisted $HOME/.objectstack/dev-crypto-key. The test provides none of them. It is green today only when an earlier dev-mode boot in the same job has persisted that key file on the runner's home directory — and the only boots that still do so are e2e spawns of bin/run-dev.js that pass no key (for example test/start-port-banner-agreement.e2e.test.ts and test/migrate-meta.e2e.test.ts, which spawn os start). packages/cli/test/helpers/serve-process.ts's header already names this class: "a cross-test ordering coupling through the runner's home directory, and under vitest's parallel workers it is nondeterministic", which is why the helper's own spawns pass OS_SECRET_KEY.

Measured

  • Locally (container, no key file, OS_TEST_TIERS=queue, the whole cli package): Test Files 1 failed | 211 passed (212) — the one failure is this test: Error: [LocalCryptoProvider] Refusing to start in production without a stable encryption key.
  • The same file alone with OS_DEV_CRYPTO_KEY=$(openssl rand -hex 32): Test Files 1 passed (1) / Tests 5 passed (5); alone without: 1 failed, 5 skipped.
  • On CI, PR ci(test): e2e and live filename tiers move to a nightly run on main #16481 (770dd18205, Test Core under OS_TEST_TIERS=queue, no e2e files in the job): Test Core (5/6) = cli slice 1/2, Test Files 1 failed | 106 passed (107), the same refusal, completeness guard OK — https://github.com/objectstack-ai/objectstack/actions/runs/34080518324/job/101614831504
  • main's Test Core is green today (run 34079753529), i.e. the coupling currently resolves in the sibling's favour by ordering.

Fix

One line in the test's own beforeAll: set OS_DEV_CRYPTO_KEY (or OS_SECRET_KEY) for the boot it performs, and restore it in afterAll beside NODE_ENV — the same "nothing written, nothing depended on" rule serve-process.ts applies to its children. A CI-wide key in ci.yml would hide this class for every future production-posture test instead of declaring it, and is not the fix.

Refs #16455, PR #16481.

Generated by Claude Code


Generated by Claude Code

Activity

  1. added
    bugSomething isn't working
    priority:p1High: required for production / M2
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    domain:devxDomain lane — seat card indexed by label:pm:seat
    on Sep 7, 2026
  2. claude commented on Sep 7, 2026

    @claude
    ContributorAuthor

    Claim: PM loop round 9 — rider on flight X (#16455, PR #16481), ruled by the seat at X's delivery 04:3xZ: the card's ⛔ no-test-edit clause is lifted for exactly this one file. packages/cli/src/commands/secret/orphans.driver-contract.test.ts sets the key its own production-posture boot needs in beforeAll (the variable LocalCryptoProvider reads; OS_DEV_CRYPTO_KEY or OS_SECRET_KEY, whichever serve-process.ts already applies to its spawns) and restores it in afterAll beside NODE_ENV; nothing written to the runner's home, nothing depended on from a sibling. No other test file is touched. Reasoning as this issue's own ## Fix states: the dependency is declared in the file that has it; a CI-wide key in ci.yml would hide the class instead of declaring it.
    Session: session_019RfFHiRCSs3JXLK4cwcfox
    Branch: claude/issue-16455-nightly-e2e-live-tiers (rides X's branch)
    Worktree: objectstack-issue-16455
    Domain: domain:devx (dispatched by the skills seat on the maintainer's direction)
    File surface: the one test file named above, plus X's PR body (deviation recorded under its own heading, quoting this ruling).
    Container & model: X's container, mode:subagent, fable (X's tier).
    Clause-②: no (the rider narrows nothing at merge time; X's own Clause-② yes stands on #16455).
    Closing: X's PR carries Fixes #16491 beneath Fixes #16455 if scripts/check-partof-closing-keyword.mjs accepts two closing lines on one PR; otherwise Refs #16491 and the seat closes this issue at X's landing with the merged commit named.


    Generated by Claude Code

  3. removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    on Sep 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdomain:devxDomain lane — seat card indexed by label:pm:seatpriority:p1High: required for production / M2

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions