test(cli): kill createProgram-wired flap + stale --actor fixture (base-health, D12) [P11]

Two named base-health causes in the cli suite, characterized hermetically + multi-run at b2435e68
(D12 method; per r1's isolated-flap correction — a single isolated pass is not a flake discriminator).
TEST + vitest.config only; NO src/ change (keep-production-loud).

CAUSE 1 — createProgram-wired FLAP:
  A (kill): the 'wired via createProgram' tests did `await import("../src/index.js")` in the test
    BODY -> an on-demand tsx COMPILE of the whole CLI graph (2-5s, variable) under the 5000ms per-test
    timeout -> flapped. Static top-level import in the 10 mock-free lazy files (add/doctor/env/expand/
    export-import/reconcile-session/status/setup/snapshot-restore/ui) moves the compile to the transform
    phase; wiring tests now ~21ms. Mirrors the shipped norm (queue.test.ts).
  B (quarantine): the 'mounts both commands' tests do createProgram()x2 + parseAsync x2 (~2s inherent,
    Commander consumes parse); cli testTimeout/hookTimeout = 20000 (daemon P6-2 precedent) gives honest
    headroom. Neither masks product latency (tsx dev-compile + tree-build; prod runs bundled dist).

CAUSE 2 — response-integrity STALE --actor FIXTURE (deterministic, failed at BASE — not the flap, not
  a regression): `queue update` requires --actor when OPENRIG_SESSION_NAME is unset (hermetic setup
  scrubs it), so 3 tests short-circuited before the daemon-response-render path they assert. Added
  --actor to the 3 invocations (D12 fix-fixtures); product requirement kept loud.

Full cli suite 2122 pass / 1 skip (147 files), NO createProgram timeouts. Never push.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
v-openrig-buildandClaude Opus 4.8 committed 2026-08-06 14:08:15 +00:00
1 parent b2435e68a6
commit c4d5f4e3e3
12 files changed
+28 -13

No files matched your search

+1 -1
View File
@@ -1,4 +1,5 @@
import { describe, it, expect, vi, beforeAll, beforeEach, afterAll, afterEach } from "vitest";
import { createProgram } from "../src/index.js";
import { Command } from "commander";
import { addMemberCommand } from "../src/commands/add.js";
import { DaemonClient } from "../src/client.js";
@@ -219,7 +220,6 @@ describe("rig add", () => {
});
it("wired via createProgram", async () => {
const { createProgram } = await import("../src/index.js");
const program = createProgram();
const cmd = program.commands.find((c) => c.name() === "add");
expect(cmd).toBeDefined();
+1 -1
View File
@@ -1,4 +1,5 @@
import { describe, it, expect, vi } from "vitest";
import { createProgram } from "../src/index.js";
import { Command } from "commander";
import { doctorCommand, runDoctorChecks, type DoctorDeps } from "../src/commands/doctor.js";
import { resolveCmuxSettingsPath } from "../src/cmux-config.js";
@@ -562,7 +563,6 @@ describe("rig doctor", () => {
});
it("wired via createProgram", async () => {
const { createProgram } = await import("../src/index.js");
const program = createProgram();
const doctorCmd = program.commands.find((c) => c.name() === "doctor");
expect(doctorCmd).toBeDefined();
+1 -1
View File
@@ -1,4 +1,5 @@
import { describe, it, expect, vi, beforeAll, afterAll } from "vitest";
import { createProgram } from "../src/index.js";
import http from "node:http";
import { Command } from "commander";
import { envCommand } from "../src/commands/env.js";
@@ -167,7 +168,6 @@ describe("rig env", () => {
});
it("env is wired via createProgram", async () => {
const { createProgram } = await import("../src/index.js");
const program = createProgram();
const envCmd = program.commands.find((c) => c.name() === "env");
expect(envCmd).toBeDefined();
+1 -1
View File
@@ -1,4 +1,5 @@
import { describe, it, expect, vi, beforeAll, beforeEach, afterAll, afterEach } from "vitest";
import { createProgram } from "../src/index.js";
import { Command } from "commander";
import { expandCommand } from "../src/commands/expand.js";
import { DaemonClient } from "../src/client.js";
@@ -237,7 +238,6 @@ describe("rig expand", () => {
// T5: Wired via createProgram
it("wired via createProgram", async () => {
const { createProgram } = await import("../src/index.js");
const program = createProgram();
const cmd = program.commands.find((c) => c.name() === "expand");
expect(cmd).toBeDefined();
+1 -1
View File
@@ -1,4 +1,5 @@
import { describe, it, expect, vi, beforeAll, afterAll } from "vitest";
import { createProgram } from "../src/index.js";
import http from "node:http";
import { Command } from "commander";
import { exportCommand, type ExportDeps } from "../src/commands/export.js";
@@ -350,7 +351,6 @@ describe("rig export + import", () => {
// Test 11: createProgram: both export AND import mounted
it("createProgram mounts both export and import commands", async () => {
const { createProgram } = await import("../src/index.js");
const stoppedLC = stoppedLifecycleDeps();
const exportD: ExportDeps = { lifecycleDeps: stoppedLC, clientFactory: vi.fn() as never, writeFile: vi.fn() };
+1 -1
View File
@@ -1,5 +1,6 @@
// OPR.0.3.4.3 — rig reconcile-session CLI.
import { describe, it, expect, vi, beforeAll, afterAll } from "vitest";
import { createProgram } from "../src/index.js";
import http from "node:http";
import { Command } from "commander";
import { reconcileSessionCommand } from "../src/commands/reconcile-session.js";
@@ -155,7 +156,6 @@ describe("rig reconcile-session", () => {
});
it("wired via createProgram", async () => {
const { createProgram } = await import("../src/index.js");
const program = createProgram();
expect(program.commands.find((c) => c.name() === "reconcile-session")).toBeDefined();
});
+7 -3
View File
@@ -121,7 +121,11 @@ describe("render response integrity — 3-part error + honest exit, never daemon
it("bad-response renders fact/consequence/action JSON with nonzero exit (json)", async () => {
const err = new DaemonResponseError(502, "<html>502 Bad Gateway</html>");
const { out, exitCode } = await runCli(
["queue", "update", "qitem-x", "--state", "done", "--closure-reason", "denied", "--json"],
// --actor: queue update requires it when OPENRIG_SESSION_NAME is unset (the hermetic setup
// scrubs it); without it the command short-circuits before the daemon-response path under
// test. Product requirement is correct — the fixture was stale (base-health, distinct from
// the P11 createProgram flap).
["queue", "update", "qitem-x", "--actor", "harness@rig", "--state", "done", "--closure-reason", "denied", "--json"],
depsThrowing(err),
);
expect(exitCode).toBe(1);
@@ -137,7 +141,7 @@ describe("render response integrity — 3-part error + honest exit, never daemon
it("bad-response renders 3-part guidance to stderr with nonzero exit, never daemon-down (human)", async () => {
const err = new DaemonResponseError(502, "<html>truncated");
const { err: stderr, exitCode } = await runCli(
["queue", "update", "qitem-x", "--state", "done", "--closure-reason", "denied"],
["queue", "update", "qitem-x", "--actor", "harness@rig", "--state", "done", "--closure-reason", "denied"],
depsThrowing(err),
);
expect(exitCode).toBe(1);
@@ -148,7 +152,7 @@ describe("render response integrity — 3-part error + honest exit, never daemon
it("slow-response (timeout) renders slow guidance, not daemon-down, nonzero exit", async () => {
const err = new DaemonTimeoutError("Request to http://localhost:7433/api/queue/x/update timed out after 5000ms");
const { err: stderr, exitCode } = await runCli(
["queue", "update", "qitem-x", "--state", "done", "--closure-reason", "denied"],
["queue", "update", "qitem-x", "--actor", "harness@rig", "--state", "done", "--closure-reason", "denied"],
depsThrowing(err),
);
expect(exitCode).toBe(1);
+1 -1
View File
@@ -1,4 +1,5 @@
import { describe, it, expect, vi } from "vitest";
import { createProgram } from "../src/index.js";
import { Command } from "commander";
import { parse as parseYaml } from "yaml";
import { setupCommand, runSetup, goldenPathNextSteps, permissionPolicyMenuLines, type SetupDeps, type SetupResult } from "../src/commands/setup.js";
@@ -87,7 +88,6 @@ function expectRuntimeConfigDisclosure(result: SetupResult): void {
describe("rig setup", () => {
it("wired via createProgram", async () => {
const { createProgram } = await import("../src/index.js");
const program = createProgram();
const setupCmd = program.commands.find((c) => c.name() === "setup");
expect(setupCmd).toBeDefined();
+1 -1
View File
@@ -1,4 +1,5 @@
import { describe, it, expect, vi, beforeAll, afterAll } from "vitest";
import { createProgram } from "../src/index.js";
import http from "node:http";
import { Command } from "commander";
import { snapshotCommand } from "../src/commands/snapshot.js";
@@ -443,7 +444,6 @@ describe("rig snapshot + restore", () => {
// Test 11: createProgram: both snapshot AND restore mounted
it("createProgram mounts both snapshot and restore commands", async () => {
const { createProgram } = await import("../src/index.js");
const deps = stoppedDeps();
const program = createProgram({ snapshotDeps: deps, restoreDeps: deps });
+1 -1
View File
@@ -1,4 +1,5 @@
import { describe, it, expect, vi, beforeAll, afterAll } from "vitest";
import { createProgram } from "../src/index.js";
import http from "node:http";
import { Command } from "commander";
import { statusCommand, type StatusDeps } from "../src/commands/status.js";
@@ -371,7 +372,6 @@ describe("rig status", () => {
// Test 8: root-level rig status is mounted (uses real createProgram from index.ts)
it("rig status is wired via createProgram (real index.ts wiring)", async () => {
const { createProgram } = await import("../src/index.js");
const statusDeps: StatusDeps = {
lifecycleDeps: mockLifecycleDeps({
+1 -1
View File
@@ -1,4 +1,5 @@
import { describe, it, expect, vi } from "vitest";
import { createProgram } from "../src/index.js";
import { Command } from "commander";
import {
UI_MAINTENANCE_NOTICE,
@@ -174,7 +175,6 @@ describe("rig ui open", () => {
// Test 5: createProgram: rig ui open mounted
it("rig ui open is wired via createProgram", async () => {
const { createProgram } = await import("../src/index.js");
const execFn = vi.fn(async () => {});
const deps: UiDeps = {
lifecycleDeps: mockLifecycleDeps({
+11
View File
@@ -3,6 +3,17 @@ import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
include: ["test/**/*.test.ts"],
// P11 base-health (createProgram-wired flap): a handful of tests build the FULL CLI
// command tree via createProgram() and drive it through parseAsync — legitimately ~2s
// of work under tsx (the "mounts both commands" wiring tests re-create the program per
// parse because Commander consumes parseAsync). Under whole-suite load that flapped the
// 5000ms default -> non-deterministic timeouts misread as regressions. Match the daemon
// precedent (P6-2, 20000) so real-work tests get honest headroom; the companion fix
// static-imports src/index.js in the wiring files so the on-demand COMPILE no longer
// lands under the per-test timeout. Neither masks a product defect (the cost is tsx
// dev-compile + tree-build, not shipped-CLI latency).
testTimeout: 20000,
hookTimeout: 20000,
// D12 base-health: scrub the seat's live-daemon connection env before every
// test module so the whole-suite fold gate is hermetic (see
// test/hermetic-env.setup.ts); production env behavior is untouched.