Skip to content

Commit 844e60b

Browse files
committed
Harden real Codex workflow runs
1 parent 041901b commit 844e60b

23 files changed

Lines changed: 1762 additions & 228 deletions

File tree

‎AGENTS.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ For MCP smoke testing, start the generated server from
5353
Node built-in access.
5454
- Bug-finding workflows should default to read-only workers.
5555
- Model overrides from the caller beat workflow defaults.
56-
- Preserve durable run state under `.codex-workflows/runs/<run-id>/`.
56+
- Default durable run state belongs under Codex home so read-only runs do not
57+
dirty target repos. Project-local `.codex-workflows/runs/<run-id>/` is opt-in
58+
and legacy-readable.
5759

5860
## Writing style
5961

‎CLAUDE.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ For MCP smoke testing, start the generated server from
5353
Node built-in access.
5454
- Bug-finding workflows should default to read-only workers.
5555
- Model overrides from the caller beat workflow defaults.
56-
- Preserve durable run state under `.codex-workflows/runs/<run-id>/`.
56+
- Default durable run state belongs under Codex home so read-only runs do not
57+
dirty target repos. Project-local `.codex-workflows/runs/<run-id>/` is opt-in
58+
and legacy-readable.
5759

5860
## Writing style
5961

‎README.md‎

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ codex plugin add codex-workflows@codex-workflows
2727
Start a new Codex thread after installing. Then ask:
2828

2929
```text
30-
Use codex-workflows to run the bug-sweep workflow with adapter sdk.
30+
Use codex-workflows to run the bug-sweep workflow with adapter auto.
3131
Open the live dashboard automatically and tell me the run id and status.
3232
```
3333

@@ -44,7 +44,10 @@ from Codex or from the CLI.
4444
boundary review.
4545
- Live dashboard with phases, agent rows, token/tool/time metrics, detail view,
4646
pause/resume/stop/restart/save controls, and final report path.
47-
- Durable run state under `.codex-workflows/runs/<run-id>/`.
47+
- Durable run state under `${CODEX_HOME:-~/.codex}/codex-workflows/projects/<project-hash>/runs/<run-id>/`
48+
by default, so read-only bug hunts do not dirty the target repo.
49+
- Project-local storage remains available with `storageScope: "project"` or
50+
`--storage-scope project`.
4851
- Isolated workflow script loading through QuickJS. Workflow scripts define
4952
phases and agent prompts; they do not get direct filesystem, shell, network,
5053
process, or Node built-in access.
@@ -54,7 +57,7 @@ from Codex or from the CLI.
5457
You can route models globally or by phase/agent:
5558

5659
```text
57-
Use codex-workflows to run bug-sweep with adapter sdk,
60+
Use codex-workflows to run bug-sweep with adapter auto,
5861
model gpt-5.5, reasoning xhigh,
5962
and modelMap {"find":"gpt-5.4-mini","synthesize":"gpt-5.5"}.
6063
```
@@ -66,6 +69,10 @@ Caller overrides win over workflow defaults:
6669
- `modelMap`: phase id, agent id, or `phase:agent` overrides.
6770
- `promptSuffix`: extra instruction appended to every worker.
6871

72+
Model names are validated against the local `codex debug models` catalog before
73+
any agents launch. Short names such as `5.4-mini` are rejected with a suggestion
74+
like `gpt-5.4-mini`; they are not silently rewritten.
75+
6976
Bug-finding workflows default to read-only workers unless a workflow explicitly
7077
declares otherwise.
7178

@@ -77,6 +84,7 @@ pnpm validate:plugin
7784
pnpm test
7885
pnpm cwf validate workflows/bug-sweep.workflow.js
7986
pnpm cwf run workflows/bug-sweep.workflow.js --watch --adapter simulate
87+
pnpm cwf run workflows/bug-sweep.workflow.js --watch --adapter auto --model gpt-5.4-mini
8088
```
8189

8290
Useful local commands:

‎docs/architecture.md‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,13 @@ The code is split so those two jobs do not get tangled.
2020

2121
## Run state
2222

23-
Every run writes to `.codex-workflows/runs/<run-id>/`:
23+
By default, read-only workflow runs write under
24+
`${CODEX_HOME:-~/.codex}/codex-workflows/projects/<project-hash>/runs/<run-id>/`
25+
so bug hunts do not dirty the target checkout. Project-local storage is still
26+
available with `storageScope: "project"` or `--storage-scope project`, and
27+
legacy `.codex-workflows/runs/<run-id>/` directories remain readable.
28+
29+
Each run directory contains:
2430

2531
- `manifest.json`: workflow definition, args, and launch options.
2632
- `status.json`: current summary for the TUI and MCP status calls.

‎docs/claude-workflows-parity.md‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,11 +200,13 @@ Use a supervisor process:
200200
4. Require approval for the script hash and capabilities.
201201
5. Execute phases.
202202
6. Spawn workers through Codex SDK/app-server, with `codex exec --json` as fallback.
203-
7. Persist all events to `.codex-workflows/runs/<run-id>/events.jsonl`.
203+
7. Persist all events to the run store, defaulting to
204+
`${CODEX_HOME:-~/.codex}/codex-workflows/projects/<project-hash>/runs/<run-id>/events.jsonl`
205+
so read-only runs do not dirty target repos.
204206
8. Persist checkpoints, agent results, token usage, patches, and final report.
205207
9. Expose status through MCP and the `cwf` CLI.
206208

207-
Suggested run directory:
209+
Suggested project-local run directory when `storageScope: "project"` is used:
208210

209211
```text
210212
.codex-workflows/runs/2026-06-03T20-12-48Z-abc123/

‎docs/plugin-distribution.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ codex plugin add codex-workflows@codex-workflows
3333
After installing, start a new Codex thread and ask:
3434

3535
```text
36-
Use codex-workflows to run the bug-sweep workflow with adapter sdk.
36+
Use codex-workflows to run the bug-sweep workflow with adapter auto.
3737
Open the live dashboard automatically and tell me the run id.
3838
```
3939

@@ -77,7 +77,8 @@ reload plugin skills and MCP tools.
7777
```
7878

7979
5. Smoke the generated MCP server from `plugins/codex-workflows`.
80-
6. Run at least one real `adapter: sdk` workflow before tagging a release.
80+
6. Run at least one real `adapter: auto` workflow before tagging a release and
81+
confirm the actual adapter is recorded in the run status.
8182
7. Tag and push:
8283

8384
```bash

‎packages/cli/src/dashboard.tsx‎

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import { useEffect, useMemo, useState } from "react";
22
import { spawn } from "node:child_process";
33
import { Box, Text, useInput, useStdout } from "ink";
4-
import type { AgentSummary, RunSummary } from "@codex-workflows/schemas";
5-
import { nowIso, RunStore } from "@codex-workflows/runtime";
4+
import type { AgentSummary, RunSummary, StorageScope } from "@codex-workflows/schemas";
5+
import { defaultStoreRoot, nowIso, RunStore } from "@codex-workflows/runtime";
66
import { formatCount, formatDuration, truncateMiddle } from "./format.js";
77

88
export interface DashboardProps {
99
cwd: string;
1010
runId: string;
11+
storageScope?: StorageScope;
12+
storeRoot?: string;
1113
exitOnComplete?: boolean;
1214
onExit?: () => void;
1315
}
@@ -117,6 +119,18 @@ export function DashboardFrame({
117119
</Text>
118120
</Box>
119121
<Text color="gray">{summary.description}</Text>
122+
<Box justifyContent="space-between">
123+
<Text color={summary.status === "failed" ? "red" : summary.status === "completed" ? "green" : "gray"}>
124+
{summary.status}
125+
{summary.error ? ` · ${truncateMiddle(summary.error, Math.max(20, width - 72))}` : ""}
126+
</Text>
127+
<Text color="gray">
128+
{summary.requestedAdapter ?? "auto"} → {summary.actualAdapter ?? "pending"}
129+
</Text>
130+
</Box>
131+
{summary.finalReportPath ? (
132+
<Text color="gray">Report: {truncateMiddle(summary.finalReportPath, width - 8)}</Text>
133+
) : null}
120134
<Box marginTop={1} borderStyle="single" borderColor="gray">
121135
<Box width={sidebarWidth} flexDirection="column" borderStyle="single" borderTop={false} borderBottom={false} borderLeft={false}>
122136
<Text>Phases</Text>
@@ -198,8 +212,19 @@ export function DashboardFrame({
198212
);
199213
}
200214

201-
export function RunDashboard({ cwd, runId, exitOnComplete = false, onExit }: DashboardProps) {
202-
const store = useMemo(() => new RunStore(cwd), [cwd]);
215+
export function RunDashboard({
216+
cwd,
217+
runId,
218+
storageScope = "codex-home",
219+
storeRoot,
220+
exitOnComplete = false,
221+
onExit
222+
}: DashboardProps) {
223+
const resolvedStoreRoot = storeRoot ?? defaultStoreRoot(cwd, storageScope);
224+
const store = useMemo(
225+
() => new RunStore(cwd, { storageScope, storeRoot: resolvedStoreRoot }),
226+
[cwd, resolvedStoreRoot, storageScope]
227+
);
203228
const [summary, setSummary] = useState<RunSummary | null>(null);
204229
const [selectedPhaseId, setSelectedPhaseId] = useState<string | undefined>();
205230
const [selectedAgentId, setSelectedAgentId] = useState<string | undefined>();
@@ -313,7 +338,18 @@ export function RunDashboard({ cwd, runId, exitOnComplete = false, onExit }: Das
313338
if (input === "r" && selectedAgentId) {
314339
const child = spawn(
315340
process.execPath,
316-
[process.argv[1] ?? "", "restart-agent", runId, selectedAgentId, "--cwd", cwd],
341+
[
342+
process.argv[1] ?? "",
343+
"restart-agent",
344+
runId,
345+
selectedAgentId,
346+
"--cwd",
347+
cwd,
348+
"--storage-scope",
349+
storageScope,
350+
"--store-root",
351+
resolvedStoreRoot
352+
],
317353
{ stdio: "ignore", detached: true }
318354
);
319355
child.unref();

0 commit comments

Comments
 (0)