test: add commander no-daemon smoke contract
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user