test: add commander no-daemon smoke contract

This commit is contained in:
Codex
2026-05-21 12:51:53 +00:00
parent 67f6d0e820
commit afe50b9e8f
7 changed files with 367 additions and 6 deletions
+4
View File
@@ -25,6 +25,7 @@ const syntaxFiles = [
"scripts/src/commander.ts",
"scripts/src/remote.ts",
"scripts/host-codex-commander-contract-test.ts",
"scripts/host-codex-commander-no-daemon-smoke-contract-test.ts",
"scripts/host-codex-commander-skeleton-contract-test.ts",
"src/components/frontend/src/index.ts",
"src/components/frontend/src/app.tsx",
@@ -299,6 +300,7 @@ export function runChecks(config: UniDeskConfig, options: CheckOptions = default
fileItem("scripts/code-queue-pr-preflight-contract-test.ts"),
fileItem("scripts/code-queue-submit-routing-contract-test.ts"),
fileItem("scripts/host-codex-commander-skeleton-contract-test.ts"),
fileItem("scripts/host-codex-commander-no-daemon-smoke-contract-test.ts"),
fileItem("scripts/provider-runner-triage-contract-test.ts"),
fileItem("scripts/src/provider-triage.ts"),
fileItem("src/components/microservices/code-queue/src/runner-error-classifier.ts"),
@@ -326,6 +328,7 @@ export function runChecks(config: UniDeskConfig, options: CheckOptions = default
items.push(commandItem("code-queue:pr-preflight-contract", ["bun", "scripts/code-queue-pr-preflight-contract-test.ts"], 30_000));
items.push(commandItem("code-queue:submit-routing-contract", ["bun", "scripts/code-queue-submit-routing-contract-test.ts"], 30_000));
items.push(commandItem("host-codex-commander:skeleton-contract", ["bun", "scripts/host-codex-commander-skeleton-contract-test.ts"], 30_000));
items.push(commandItem("host-codex-commander:no-daemon-smoke-contract", ["bun", "scripts/host-codex-commander-no-daemon-smoke-contract-test.ts"], 30_000));
items.push(commandItem("provider:runner-triage-contract", ["bun", "scripts/provider-runner-triage-contract-test.ts"], 30_000));
items.push(commandItem("deploy:artifact-matrix-contract", ["bun", "scripts/deploy-artifact-matrix-contract-test.ts"], 30_000));
items.push(commandItem("decision-center:desired-state-contract", ["bun", "scripts/decision-center-desired-state-contract-test.ts"], 30_000));
@@ -347,6 +350,7 @@ export function runChecks(config: UniDeskConfig, options: CheckOptions = default
items.push(skippedItem("code-queue:pr-preflight-contract", "Code Queue PR preflight contract is opt-in with script checks", "--scripts-typecheck or --full"));
items.push(skippedItem("code-queue:submit-routing-contract", "Code Queue submit routing contract is opt-in with script checks", "--scripts-typecheck or --full"));
items.push(skippedItem("host-codex-commander:skeleton-contract", "host Codex commander skeleton contract is opt-in with script checks", "--scripts-typecheck or --full"));
items.push(skippedItem("host-codex-commander:no-daemon-smoke-contract", "host Codex commander no-daemon smoke contract is opt-in with script checks", "--scripts-typecheck or --full"));
items.push(skippedItem("provider:runner-triage-contract", "Provider runner triage contract is opt-in with script checks", "--scripts-typecheck or --full"));
items.push(skippedItem("deploy:artifact-matrix-contract", "deploy artifact matrix contract is opt-in with script checks", "--scripts-typecheck or --full"));
items.push(skippedItem("decision-center:desired-state-contract", "Decision Center desired-state drift contract is opt-in with script checks", "--scripts-typecheck or --full"));
+161
View File
@@ -50,6 +50,7 @@ function commanderHelp(): Record<string, unknown> {
usage: [
"bun scripts/cli.ts commander contract",
"bun scripts/cli.ts commander plan --dry-run [--session-id id]",
"bun scripts/cli.ts commander smoke --dry-run [--session-id id]",
"bun scripts/cli.ts commander approval request --action <action> --dry-run [--reason text] [--task-id id]",
],
highRiskActions,
@@ -211,6 +212,165 @@ function commanderPlan(args: string[]): Record<string, unknown> {
};
}
function healthEndpointValidation(): Record<string, unknown> {
return {
surface: "health endpoint",
endpoint: "GET /health",
validationMethod: "invoke createCommanderRequestHandler with a temporary RuntimeConfig inside a short-lived contract test",
expectedEvidence: [
"body.ok=true",
"body.service=host-codex-commander",
"body.stateRoot points at the temp directory",
"body.currentLogFile is reported",
],
noRuntimeSideEffects: [
"do not run Bun.serve",
"do not publish or expose a port",
"do not restart any service",
],
};
}
function stateFileValidation(sessionId: string): Record<string, unknown> {
return {
surface: "state file",
storageRoot: ".state/commander/",
validationMethod: "write and read a session record only under a temporary directory owned by the contract test",
files: [
`sessions/${sessionId}.json`,
`events/${sessionId}.jsonl`,
"approvals/draft.json",
"logs/commander.jsonl",
],
expectedEvidence: [
"session state round-trips through writeCommanderSession/readCommanderSession",
"secret-like notes are redacted before persistence",
"temporary state root is deleted after the smoke contract",
],
noRuntimeSideEffects: [
"do not touch the live .state/commander directory",
"do not patch database state",
"do not discover or signal live host Codex processes",
],
};
}
function traceSummaryValidation(sessionId: string): Record<string, unknown> {
return {
surface: "trace summary dry-run",
validationMethod: "summarize mock JSONL trace input through summarizeCommanderTrace",
inputPolicy: "bounded mock Code Queue trace JSONL only; no live codex task trace fetch",
expectedEvidence: [
"taskId and sessionId are preserved",
"lastSeq is computed from mock seq fields",
"status is derived without returning raw transcript",
"secret-like text is redacted",
],
sampleSessionId: sessionId,
noRuntimeSideEffects: [
"do not call Code Queue manager",
"do not mark tasks read",
"do not interrupt or cancel tasks",
],
};
}
function approvalDraftValidation(): Record<string, unknown> {
return {
surface: "approval draft preview",
validationMethod: "build a draft preview for one high-risk action with --dry-run",
commandShape: "bun scripts/cli.ts commander approval request --action code-queue-task-interrupt --reason <text> --dry-run",
expectedEvidence: [
"requiresExplicitUserApproval=true",
"claudeqq.mutation=false",
"claudeqq.sendImplemented=false",
"reason and messageTemplate are redacted",
],
noRuntimeSideEffects: [
"do not POST to ClaudeQQ",
"do not notify any QQ user or group",
"do not record an approval as consumed",
],
};
}
function sshBridgeBoundaryValidation(): Record<string, unknown> {
return {
surface: "SSH bridge boundary",
validationMethod: "assert contract-only bridge metadata from commander plan --dry-run",
allowedAtThisStage: [
"readonly contract description",
"future reviewed maintenance command shape",
"explicit approval precondition text",
],
noRuntimeSideEffects: [
"do not open provider SSH session",
"do not open PTY bridge",
"do not open stdio bridge",
"do not inject prompt",
"do not restart services",
"do not interrupt or cancel tasks",
],
expectedEvidence: [
"bridge.mutation=false",
"startPlan.enabled=false",
"safetyBoundary.phaseOneMutationAllowed=false",
],
};
}
function commanderSmoke(args: string[]): Record<string, unknown> {
if (!hasFlag(args, "--dry-run")) {
return {
ok: false,
error: "dry-run-required",
message: requiredDryRunMessage,
command: "bun scripts/cli.ts commander smoke --dry-run",
};
}
const sessionId = optionValue(args, "--session-id") ?? "primary";
return {
ok: true,
phase: "source-contract",
mode: "dry-run",
mutation: false,
serviceId: "host-codex-commander",
noDaemonSmokeContract: {
startsDaemon: false,
startsPtyBridge: false,
startsStdioBridge: false,
opensSshBridge: false,
sendsClaudeqq: false,
restartsServices: false,
interruptsTasks: false,
cancelsTasks: false,
deploys: false,
runsFullCheckOrE2e: false,
allowedCommands: [
"bun scripts/cli.ts commander contract",
"bun scripts/cli.ts commander plan --dry-run",
"bun scripts/cli.ts commander smoke --dry-run",
"bun scripts/cli.ts commander approval request --action <action> --dry-run",
"bun scripts/host-codex-commander-no-daemon-smoke-contract-test.ts",
],
},
validationPlan: [
healthEndpointValidation(),
stateFileValidation(sessionId),
traceSummaryValidation(sessionId),
approvalDraftValidation(),
sshBridgeBoundaryValidation(),
],
manualAuthorizationBeforeLiveRuntime: [
"operator explicitly names the exact live action and target session/task/service",
"current source-contract smoke and skeleton contract tests are green",
"risk review confirms no token output, no direct database patch, and no backend restart bypass",
"ClaudeQQ approval draft is reviewed, sent by an authorized future path, and matched to an explicit approval id",
"rollback and observation steps are written before enabling any daemon or bridge",
],
};
}
function commanderApprovalRequest(args: string[]): Record<string, unknown> {
if (!hasFlag(args, "--dry-run")) {
return {
@@ -276,6 +436,7 @@ export function runCommanderCommand(args: string[]): Record<string, unknown> {
if (sub === undefined || isHelpToken(sub)) return commanderHelp();
if (sub === "contract") return commanderContract();
if (sub === "plan") return commanderPlan(args.slice(1));
if (sub === "smoke") return commanderSmoke(args.slice(1));
if (sub === "approval" && second === "request") return commanderApprovalRequest(args.slice(2));
return {
ok: false,
+4 -3
View File
@@ -44,7 +44,7 @@ export function rootHelp(): unknown {
{ command: "dev-env validate|prewarm-images", description: "Validate D601 unidesk-dev guardrails or prewarm dev foundation images into native k3s containerd through a bounded async job." },
{ command: "artifact-registry plan|render|status|health|install|deploy-backend-core|deploy-service", description: "Manage the D601 host-managed CNCF Distribution registry and run pull-only artifact CD for supported services, including D601 direct, k3s-managed, and code-queue dev-only consumers." },
{ command: "gh auth|issue|pr", description: "Run safe GitHub issue and PR CRUD/lifecycle operations through REST with body-file update replace/append, comment delete, token diagnostics, hard delete unsupported, and merge blocked." },
{ command: "commander contract|plan --dry-run|approval request --dry-run", description: "Host Codex commander skeleton contract and dry-run preview; exposes local health, state, trace summary, and approval draft helpers without live bridges or message sends." },
{ command: "commander contract|plan --dry-run|smoke --dry-run|approval request --dry-run", description: "Host Codex commander skeleton contract, no-daemon smoke plan, and dry-run preview; exposes local health, state, trace summary, and approval draft helpers without live bridges or message sends." },
{ command: "code-agent-sandbox", description: "Independent Code Agent Sandbox service skeleton for adapter, mode, and credential-boundary diagnostics." },
{ command: "schedule list|get|runs|run|retry-run|delete", description: "Manage backend-core scheduled tasks and run history; schedule run <id> supports --wait-ms N and retry-run reuses the failed run's schedule." },
{ command: "schedule upsert-pgdata-backup [--time HH:MM] [--remote-base /SERVER_DATA/UNIDESK_PG_DATA]", description: "Create or update the daily PGDATA physical backup task that uploads monthly rotated archives to Baidu Netdisk." },
@@ -188,14 +188,15 @@ function providerHelp(): unknown {
function commanderHelp(): unknown {
return {
command: "commander contract|plan|approval",
command: "commander contract|plan|smoke|approval",
output: "json",
usage: [
"bun scripts/cli.ts commander contract",
"bun scripts/cli.ts commander plan --dry-run [--session-id id]",
"bun scripts/cli.ts commander smoke --dry-run [--session-id id]",
"bun scripts/cli.ts commander approval request --action <action> --dry-run [--reason text] [--task-id id]",
],
description: "Inspect the local host Codex commander skeleton contract, dry-run planner, state helpers, trace summary aggregator, and approval draft preview.",
description: "Inspect the local host Codex commander skeleton contract, dry-run planner, no-daemon smoke validation plan, state helpers, trace summary aggregator, and approval draft preview.",
boundary: [
"the current skeleton is local-only and never attaches to live bridges",
"dry-run commands never open SSH, PTY, or stdio bridges",