ultracode-for-codex 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,31 +1,58 @@
1
1
  # Ultracode for Codex
2
2
 
3
- Ultracode for Codex ships two Codex skill commands plus a local npm CLI runtime.
4
- `$ultracode-for-codex` is the default high-visibility mode: the Codex main
5
- context plans adaptive phases, spawns focused parallel subagents, synthesizes
6
- their results, and reports progress directly in the chat.
7
- `$ultracode-for-codex-cli` is the explicit runtime path for package validation,
8
- background jobs, attached CLI runs, release checks, and reproducible local
9
- workflow artifacts.
3
+ Dynamic workflows redesigned for Codex, with parallel subagents, visible
4
+ progress, and an optional local CLI runtime.
10
5
 
11
- ## Quick Start
6
+ The default experience is Codex-native: you ask for `$ultracode-for-codex`, and
7
+ the main Codex chat becomes the orchestrator. It plans the next useful phase,
8
+ runs independent subagents in parallel when that helps, summarizes their
9
+ findings, and shows compact progress snapshots directly in the conversation.
12
10
 
13
- Install from npm:
11
+ A local CLI runtime is included for users who want background jobs, reproducible
12
+ workflow runs, package checks, or attached terminal execution.
13
+
14
+ ## Why Use It
15
+
16
+ - Get multi-angle reviews instead of a single linear pass.
17
+ - Run implementation and verification work phase by phase.
18
+ - See what agents are doing, what finished, and what still needs attention.
19
+ - Keep long CLI workflows running in the OS background when desired.
20
+ - Package the same workflow behavior for repeatable local use.
21
+
22
+ ## Install
23
+
24
+ For one project:
14
25
 
15
26
  ```bash
16
27
  npm install --save-dev ultracode-for-codex
17
- npm exec -- ultracode-for-codex --llm-guide
18
28
  ```
19
29
 
20
- Or install the CLI globally:
30
+ For global use:
21
31
 
22
32
  ```bash
23
33
  npm install -g ultracode-for-codex
34
+ ```
35
+
36
+ If you installed it globally, check the CLI directly:
37
+
38
+ ```bash
24
39
  ultracode-for-codex --version
25
40
  ultracode-for-codex --llm-guide
26
41
  ```
27
42
 
28
- Install the Codex skill commands from a project install:
43
+ If you installed it as a project dependency, check it with `npm exec --`:
44
+
45
+ ```bash
46
+ npm exec -- ultracode-for-codex --version
47
+ npm exec -- ultracode-for-codex --llm-guide
48
+ ```
49
+
50
+ ## Install The Codex Skills
51
+
52
+ After installing the npm package, copy the included skill commands into your
53
+ Codex skills folder.
54
+
55
+ From a project install:
29
56
 
30
57
  ```bash
31
58
  mkdir -p "${CODEX_HOME:-$HOME/.codex}/skills"
@@ -35,7 +62,7 @@ cp -R ./node_modules/ultracode-for-codex/skills/ultracode-for-codex-cli \
35
62
  "${CODEX_HOME:-$HOME/.codex}/skills/"
36
63
  ```
37
64
 
38
- Or install the skill commands from a global npm install:
65
+ From a global install:
39
66
 
40
67
  ```bash
41
68
  mkdir -p "${CODEX_HOME:-$HOME/.codex}/skills"
@@ -46,235 +73,160 @@ cp -R "$GLOBAL_NODE_MODULES/ultracode-for-codex/skills/ultracode-for-codex-cli"
46
73
  "${CODEX_HOME:-$HOME/.codex}/skills/"
47
74
  ```
48
75
 
49
- Build and verify a local installable tarball from a source checkout:
76
+ Restart Codex or start a new Codex session if the skills do not appear
77
+ immediately.
50
78
 
51
- ```bash
52
- npm install
53
- npm run pack:ultracode-for-codex
79
+ ## Use In Codex
80
+
81
+ Use the default skill for normal work:
82
+
83
+ ```text
84
+ $ultracode-for-codex Review this change for correctness and security risks.
54
85
  ```
55
86
 
56
- Install the tarball from a target project:
87
+ Good tasks for the default skill:
57
88
 
58
- ```bash
59
- npm install --save-dev /path/to/ultracode-for-codex-<version>.tgz
89
+ - code review;
90
+ - implementation planning;
91
+ - multi-step verification;
92
+ - architecture or design critique;
93
+ - release readiness checks;
94
+ - work that benefits from parallel perspectives.
95
+
96
+ The default skill shows a phase plan before work starts and keeps a cumulative
97
+ progress snapshot as agents finish.
98
+
99
+ Example:
100
+
101
+ ```text
102
+ Phase Review
103
+
104
+ + Runtime correctness done no material issue
105
+ > Security boundary running checking local state handling
106
+ - Package contract queued verify installed files
107
+
108
+ Agents 1 completed | 1 running | 1 queued
109
+ Next: synthesize material findings
60
110
  ```
61
111
 
62
- Run through the CLI runtime when that path is explicitly wanted:
112
+ ## Use The CLI Runtime
113
+
114
+ Use `$ultracode-for-codex-cli` or the `ultracode-for-codex` binary when you
115
+ explicitly want a local command-owned workflow run.
116
+
117
+ Run a built-in task workflow:
63
118
 
64
119
  ```bash
65
120
  npm exec -- ultracode-for-codex run \
66
121
  --accept-llm-guide=v1 \
67
- --cwd /path/to/target-repo \
68
- --script-file .codex/workflows/review.js \
69
- --args '{"prompt":"review the current change"}'
122
+ --cwd /path/to/project \
123
+ --name task \
124
+ --args '{"prompt":"review correctness risks and propose fixes"}'
70
125
  ```
71
126
 
72
- By default this prints a background launch record to stdout. The record contains
73
- `jobId`, `pid`, `resultPath`, `progressPath`, `metadataPath`, and `pidPath`.
74
- Use the job id to inspect or control the background run:
127
+ Run a code review:
75
128
 
76
129
  ```bash
77
- npm exec -- ultracode-for-codex status <jobId> --cwd /path/to/target-repo
78
- npm exec -- ultracode-for-codex wait <jobId> --cwd /path/to/target-repo
79
- npm exec -- ultracode-for-codex logs <jobId> --cwd /path/to/target-repo --tail 40
80
- npm exec -- ultracode-for-codex result <jobId> --cwd /path/to/target-repo
81
- npm exec -- ultracode-for-codex cancel <jobId> --cwd /path/to/target-repo
82
- npm exec -- ultracode-for-codex jobs --cwd /path/to/target-repo
83
- npm exec -- ultracode-for-codex archive <jobId> --cwd /path/to/target-repo
130
+ npm exec -- ultracode-for-codex run \
131
+ --accept-llm-guide=v1 \
132
+ --cwd /path/to/project \
133
+ --name code-review \
134
+ --args '{"prompt":"review the current change"}'
84
135
  ```
85
136
 
86
- Run attached to the current terminal:
137
+ The built-in `code-review` workflow collects bounded repository evidence,
138
+ chooses review lenses, runs finder agents in parallel, verifies each candidate,
139
+ and returns JSON with `findings`, `provenance`, `synthesis`, and `stats`.
140
+ Use `{"level":"high"}` to skip the final sweep, or omit it for the default
141
+ `xhigh` review.
142
+
143
+ CLI runs use OS background execution by default. The command prints a launch
144
+ record with a `jobId`, then you can inspect or control the job:
87
145
 
88
146
  ```bash
89
- npm exec -- ultracode-for-codex run \
90
- --accept-llm-guide=v1 \
91
- --execution attached \
92
- --cwd /path/to/target-repo \
93
- --script-file .codex/workflows/review.js \
94
- --args '{"prompt":"review the current change"}'
147
+ npm exec -- ultracode-for-codex status <jobId> --cwd /path/to/project
148
+ npm exec -- ultracode-for-codex logs <jobId> --cwd /path/to/project --tail 40
149
+ npm exec -- ultracode-for-codex result <jobId> --cwd /path/to/project
150
+ npm exec -- ultracode-for-codex cancel <jobId> --cwd /path/to/project
95
151
  ```
96
152
 
97
- Named workflows are resolved from `.codex/workflows`, user workflow folders,
98
- plugin workflow folders, and built-ins:
153
+ Use attached execution only when the terminal should stay connected until the
154
+ workflow finishes:
99
155
 
100
156
  ```bash
101
157
  npm exec -- ultracode-for-codex run \
102
158
  --accept-llm-guide=v1 \
103
- --cwd /path/to/target-repo \
159
+ --execution attached \
160
+ --cwd /path/to/project \
104
161
  --name task \
105
- --args '{"prompt":"review correctness risks and propose fixes"}'
162
+ --args '{"prompt":"check the release plan"}'
106
163
  ```
107
164
 
108
- The CLI built-in `task` and `code-review` workflows use an LLM planner first,
109
- then run work phase by phase. Within each phase, multiple focused Codex
110
- subagents run in parallel by default, followed by phase and final synthesis. The
111
- planner may choose a single-agent path only when parallel execution would add
112
- risk or waste. Planner guidance includes dynamic workflow patterns such as
113
- classify-and-act, fan-out-and-synthesize, adversarial verification,
114
- generate-and-filter, tournament, and loop-until-done, so different work types
115
- can use different phase shapes.
116
-
117
- ## Settings
118
-
119
- Package defaults live in `settings.json`:
120
-
121
- ```json
122
- {
123
- "workflow": {
124
- "executionMode": "background",
125
- "progress": "jsonl",
126
- "permission": "ask",
127
- "retryLimit": 0,
128
- "timeoutMs": 0,
129
- "background": {
130
- "runDir": ".ultracode-for-codex/background/{jobId}",
131
- "resultFile": "result.json",
132
- "progressFile": "progress.jsonl",
133
- "metadataFile": "metadata.json",
134
- "pidFile": "pid"
135
- }
136
- }
137
- }
138
- ```
165
+ ## What Gets Installed
139
166
 
140
- Use `--execution attached`, `--progress`, `--permission`, `--retry-limit`, and
141
- `--timeout-ms` to override settings for one run.
142
- The package default workflow timeout is `0`, meaning the workflow waits until it
143
- completes, is cancelled, or the Codex app-server exits. Set `--timeout-ms` to a
144
- positive value to opt into a deadline for one run.
145
- Use the default background execution for long Codex-launched work so Codex can
146
- continue other tasks and inspect the job later with `status`, `logs`, or
147
- `result`. Use
148
- `--execution attached` only when the caller must block until the final result.
149
-
150
- ## CLI Controls
151
-
152
- - Use `--version` or `-v` to print the installed package version.
153
- - Use `status`, `wait`, `logs`, `result`, and `cancel` with a background
154
- `jobId` or `metadata.json` path to inspect, wait for, read, or cancel OS
155
- background runs.
156
- - Use `jobs` or `list` to enumerate local background runs.
157
- - Use `archive` or `export` to write a sensitive local JSON bundle for one run
158
- without deleting runtime state.
159
- - Use `wait --result`, `cancel --wait`, `logs --event <event>`, and `--plain`
160
- for shorter foreground checks.
161
- - Progress is printed to stderr as JSONL by default.
162
- - The final workflow result is printed as JSON to stdout.
163
- - JSONL records include `kind`, `version`, `event`, `status`, and `summary`;
164
- agent records also include stable agent identity and label fields.
165
- - Built-in `task` and `code-review` emit `workflow.plan.ready` as a planning
166
- snapshot, not a promise that every later phase is already known.
167
- - `workflow.phase.planned` is emitted immediately before each phase starts and
168
- carries that phase's current planned agent role labels. Each
169
- `workflow.phase.started` record repeats the same role labels when the phase
170
- begins.
171
- - Each `workflow.agent.completed` record includes phase progress, total known
172
- agent progress, and elapsed time.
173
- - After a completed run, `workflow.summary.ready` reports each phase with its
174
- planned agent count and angle/focus list, then `workflow.review.recommended`
175
- asks the current session LLM to critically re-check the final result before
176
- acting on it.
177
- - Press `Ctrl-C` once to cancel the active workflow.
178
- - Use `--retry-limit <n>` to retry failed workflows inside the same process.
179
- - `--timeout-ms 0` waits for completion, cancellation, or app-server exit.
180
- Positive values opt into a workflow deadline and per-agent silence budget;
181
- that budget is not divided by the retry budget.
182
- - Use `--permission ask|allow|deny` for project/user/plugin/scriptPath workflow
183
- permission reviews.
184
- - Use `--progress plain` for human-readable log lines.
185
- - Use `--execution background` for OS background runs and `--execution attached`
186
- only when the caller should stay connected until completion.
187
-
188
- ## Codex Skill Commands
189
-
190
- The npm package includes two Codex skill command folders:
191
-
192
- - `skills/ultracode-for-codex`: default Codex-native orchestration. The main
193
- context plans adaptive phases, spawns parallel subagents, synthesizes each
194
- phase, reports completion progress, and recommends a final critical re-check.
195
- Live progress uses test-runner-style visual snapshots; completion reporting
196
- uses a diffstat-style impact summary plus a plan-style result summary.
197
- - `skills/ultracode-for-codex-cli`: explicit CLI runtime operations, including
198
- background jobs, attached runs, packaging, release checks, runtime-boundary
199
- validation, and installed E2E tests.
200
-
201
- ## Runtime Boundaries
202
-
203
- - The only production backend is Codex app-server over stdio.
204
- - Direct provider credentials are stripped from the Codex child process
205
- environment.
206
- - Codex subagents run against the requested workflow cwd and receive bounded
207
- read-only workspace tools for text file reads and directory listings.
208
- - CLI built-in `task` and `code-review` inject deterministic workspace context into
209
- planner-selected phase-wise parallel subagents, then synthesize each phase and
210
- the final result.
211
- - Workflow execution is local and command-owned; settings default to OS
212
- background execution so long runs can keep waiting while Codex does other
213
- work.
214
- - `.ultracode-for-codex` workflow state is sensitive local data.
215
- - `journalPath`, `journal.jsonl`, and journal contents stay out of CLI output.
216
- Local runtime state may still contain runtime-owned
217
- `transcriptDir`, `scriptPath`, and result files.
218
- - `resumeFromRunId` remains runtime-internal and same-session; users retry the
219
- active run or rerun the workflow command.
220
- - `agent(..., { isolation: "worktree" })` runs the agent in a detached git
221
- worktree and preserves the worktree for review, including clean worktrees.
222
-
223
- ## Development
167
+ The package includes:
224
168
 
225
- ```bash
226
- npm install
227
- npm test
228
- npm run pack:ultracode-for-codex
229
- npm run test:e2e:ultracode-for-codex
230
- npm run test:all
231
- ```
169
+ - `ultracode-for-codex`: the local CLI binary;
170
+ - `skills/ultracode-for-codex`: the recommended Codex-native skill;
171
+ - `skills/ultracode-for-codex-cli`: the explicit CLI/runtime skill;
172
+ - `settings.json`: default CLI runtime settings;
173
+ - `ULTRACODE_INSTALL.md`: detailed install and operating guide for agents.
174
+
175
+ ## Local State
176
+
177
+ CLI background runs write local workflow state under `.ultracode-for-codex/` in
178
+ the target project. Treat that folder as local runtime data. It may contain
179
+ progress, metadata, transcripts, and results for the run.
232
180
 
233
- ## Publishing
181
+ Add it to `.gitignore` if your project does not already ignore it:
234
182
 
235
- The npm package name is `ultracode-for-codex`. Public publish metadata lives in
236
- `package.json`, and `prepublishOnly` runs the full verification suite before
237
- `npm publish`.
183
+ ```gitignore
184
+ .ultracode-for-codex/
185
+ ```
186
+
187
+ ## Troubleshooting
238
188
 
239
- Check the package before publishing:
189
+ If Codex does not recognize `$ultracode-for-codex`, confirm that the skill
190
+ folder exists:
240
191
 
241
192
  ```bash
242
- npm run publish:dry-run
193
+ ls "${CODEX_HOME:-$HOME/.codex}/skills/ultracode-for-codex"
243
194
  ```
244
195
 
245
- Publish after `npm login`:
196
+ If `npm exec -- ultracode-for-codex` fails, confirm the package is installed:
246
197
 
247
198
  ```bash
248
- npm run publish:npm
199
+ npm ls ultracode-for-codex
249
200
  ```
250
201
 
251
- For supported CI/CD environments, provenance is available as an explicit opt-in:
202
+ If a CLI workflow is still running, list local jobs:
252
203
 
253
204
  ```bash
254
- npm run publish:npm:provenance
205
+ npm exec -- ultracode-for-codex jobs --cwd /path/to/project
255
206
  ```
256
207
 
257
- Optional live smoke against the local Codex CLI:
208
+ ## For Maintainers
209
+
210
+ Common source checkout commands:
258
211
 
259
212
  ```bash
260
- ULTRACODE_LIVE_SMOKE=1 npm run smoke:live
213
+ npm install
214
+ npm test
215
+ npm run test:e2e:ultracode-for-codex
216
+ npm run test:all
217
+ npm run pack:ultracode-for-codex
261
218
  ```
262
219
 
263
- Useful local run:
220
+ Check the publish payload:
264
221
 
265
222
  ```bash
266
- npm run build
267
- node dist/cli.js run --accept-llm-guide=v1 --script-file ./workflow.js
223
+ npm run publish:dry-run
268
224
  ```
269
225
 
270
- ## Docs
271
-
272
- - `skills/ultracode-for-codex/SKILL.md`: default Codex-native orchestrator
273
- skill command.
274
- - `skills/ultracode-for-codex/references/progress-visuals.md`: golden visual
275
- progress and completion summary examples for native orchestration.
276
- - `skills/ultracode-for-codex-cli/SKILL.md`: explicit CLI runtime skill command.
277
- - `ULTRACODE_INSTALL.md`: install and operating guide for LLM agents.
278
- - `docs/ultracode-p3a-journal-design.md`: journal contract.
279
- - `docs/ultracode-p3b-resume-cache.md`: runtime-internal resume/cache contract.
280
- - `docs/ultracode-p3c-worktree-isolation.md`: worktree isolation contract.
226
+ ## More Documentation
227
+
228
+ - `ULTRACODE_INSTALL.md`: detailed install and operating guide.
229
+ - `skills/ultracode-for-codex/SKILL.md`: Codex-native orchestration behavior.
230
+ - `skills/ultracode-for-codex/references/progress-visuals.md`: progress display
231
+ examples.
232
+ - `skills/ultracode-for-codex-cli/SKILL.md`: CLI runtime behavior.
@@ -99,13 +99,19 @@ npm exec -- ultracode-for-codex archive <jobId> --cwd /path/to/project
99
99
  ```
100
100
 
101
101
  Use CLI built-in `task` for general work and `code-review` for review-specific
102
- work. Both start with an LLM planner, execute phase by phase, run multiple
103
- focused Codex subagents in parallel within each phase by default, and synthesize
104
- phase and final results. The planner chooses a single-agent path only when
105
- parallel execution would add risk or waste.
106
- Planner guidance includes classify-and-act, fan-out-and-synthesize,
107
- adversarial verification, generate-and-filter, tournament, and loop-until-done
108
- patterns so different work types can use different phase shapes.
102
+ work. `task` starts with an LLM planner, executes phase by phase, runs multiple
103
+ focused Codex subagents in parallel within each phase by default, and chooses a
104
+ single-agent path only when parallel execution would add risk or waste. Planner
105
+ guidance includes classify-and-act, fan-out-and-synthesize, adversarial
106
+ verification, generate-and-filter, tournament, and loop-until-done patterns so
107
+ different work types can use different phase shapes.
108
+
109
+ `code-review` uses a specialized review harness. It collects bounded repository
110
+ evidence, selects active review lenses, runs one finder per lens in parallel,
111
+ verifies every emitted candidate with a candidate-scoped subagent, optionally
112
+ runs an `xhigh` sweep, then synthesizes final findings by verified candidate
113
+ index. The final JSON includes `findings`, `provenance`, `synthesis`, and
114
+ `stats`.
109
115
 
110
116
  Settings defaults:
111
117
 
@@ -145,7 +151,9 @@ Useful controls:
145
151
  - JSONL records include `kind`, `version`, `event`, `status`, and `summary`;
146
152
  agent records also include stable agent identity and label fields.
147
153
  - Built-in `task` and `code-review` emit `workflow.plan.ready` as a planning
148
- snapshot, not a promise that every later phase is already known.
154
+ snapshot, not a promise that every later phase is already known. In
155
+ `code-review`, later verifier agents are discovered after finder agents emit
156
+ candidates.
149
157
  - `workflow.phase.planned` is emitted immediately before each phase starts and
150
158
  carries that phase's current planned agent role labels. Each
151
159
  `workflow.phase.started` record repeats the same role labels when the phase
@@ -180,9 +188,10 @@ Useful controls:
180
188
  - Strip direct provider credentials from child CLI environments.
181
189
  - Run Codex subagents against the requested workflow cwd and provide bounded
182
190
  read-only workspace tools for text file reads and directory listings.
183
- - Built-in `task` and `code-review` add deterministic workspace context to
184
- planner-selected phase-wise parallel subagents, then synthesize each phase and
185
- the final result.
191
+ - Built-in `task` adds deterministic workspace context to planner-selected
192
+ phase-wise parallel subagents. Built-in `code-review` uses deterministic
193
+ review evidence, allowed evidence refs, dynamic lenses, candidate verification,
194
+ and bounded final synthesis.
186
195
  - Install consumers from a packaged artifact.
187
196
  - Keep `journalPath`, `journal.jsonl`, and journal contents out of CLI output.
188
197
  Local runtime state may still contain runtime-owned
package/dist/cli.js CHANGED
@@ -1116,31 +1116,27 @@ function workflowPhaseExecutionSummary(events) {
1116
1116
  for (const event of events) {
1117
1117
  if (event.type !== 'workflow.agent.started' || !event.phase)
1118
1118
  continue;
1119
+ const startedAgent = {
1120
+ title: event.label,
1121
+ label: event.label,
1122
+ angle: event.promptPreview,
1123
+ };
1119
1124
  const existing = phases.get(event.phase);
1120
1125
  if (!existing) {
1121
1126
  phases.set(event.phase, {
1122
1127
  title: event.phase,
1123
1128
  agentCount: 1,
1124
- agents: [{
1125
- title: event.label,
1126
- label: event.label,
1127
- angle: event.promptPreview,
1128
- }],
1129
+ agents: [startedAgent],
1129
1130
  });
1130
1131
  continue;
1131
1132
  }
1132
- if (phaseTitlesWithPlannedAgents.has(event.phase))
1133
+ if (phaseTitlesWithPlannedAgents.has(event.phase)
1134
+ && existing.agents.length > 0
1135
+ && !phaseSummaryAllowsDynamicStartedAgents(existing))
1133
1136
  continue;
1134
1137
  if (existing.agents.some((agent) => agent.label === event.label || agent.title === event.label))
1135
1138
  continue;
1136
- const agents = [
1137
- ...existing.agents,
1138
- {
1139
- title: event.label,
1140
- label: event.label,
1141
- angle: event.promptPreview,
1142
- },
1143
- ];
1139
+ const agents = [...existing.agents, startedAgent];
1144
1140
  phases.set(event.phase, {
1145
1141
  ...existing,
1146
1142
  agentCount: agents.length,
@@ -1149,6 +1145,14 @@ function workflowPhaseExecutionSummary(events) {
1149
1145
  }
1150
1146
  return [...phases.values()];
1151
1147
  }
1148
+ function phaseSummaryAllowsDynamicStartedAgents(phase) {
1149
+ return phase.agents.some((agent) => {
1150
+ const label = agent.label ?? '';
1151
+ const title = agent.title ?? '';
1152
+ const angle = agent.angle ?? '';
1153
+ return /\bdynamic\b/i.test(`${label} ${title} ${angle}`);
1154
+ });
1155
+ }
1152
1156
  function criticalReviewRecommendation() {
1153
1157
  return 'Session LLM should critically re-check the final result before acting: verify whether the conclusion is justified, internally consistent, supported by the observed workflow evidence, and missing material counterarguments.';
1154
1158
  }
@@ -12,6 +12,7 @@ export interface WorkflowAgentSemanticOpts {
12
12
  readonly effort?: string;
13
13
  readonly isolation?: string;
14
14
  readonly agentType?: string;
15
+ readonly logicalKey?: string;
15
16
  }
16
17
  export type WorkflowJournalEntry = WorkflowRunStartedEntry | WorkflowAgentStartedEntry | WorkflowAgentCompletedEntry | WorkflowAgentFailedEntry | WorkflowRunCompletedEntry | WorkflowRunFailedEntry;
17
18
  interface WorkflowJournalEntryEnvelope {
@@ -219,6 +219,9 @@ export function computeWorkflowAgentCallKey(input) {
219
219
  if (!HASH_RE.test(input.previousAgentCallKey)) {
220
220
  throw new WorkflowJournalValidationError('previousAgentCallKey must be a 64-character sha256 hex digest.');
221
221
  }
222
+ if (input.semanticOpts.logicalKey) {
223
+ return sha256(`logical\0${input.semanticOpts.logicalKey}\0${input.prompt}\0${stableJson(input.semanticOpts)}`);
224
+ }
222
225
  return sha256(`${input.previousAgentCallKey}\0${input.prompt}\0${stableJson(input.semanticOpts)}`);
223
226
  }
224
227
  export function workflowJournalHash(entryWithoutEntryHash) {
@@ -473,10 +476,10 @@ function assertWorkflowAgentSemanticOpts(value) {
473
476
  const opts = asRecord(value);
474
477
  if (!opts)
475
478
  throw new WorkflowJournalValidationError('semanticOpts must be an object.');
476
- rejectUnknownKeys(opts, ['schema', 'model', 'effort', 'isolation', 'agentType'], 'semanticOpts');
479
+ rejectUnknownKeys(opts, ['schema', 'model', 'effort', 'isolation', 'agentType', 'logicalKey'], 'semanticOpts');
477
480
  if (typeof opts.model !== 'string' || !opts.model)
478
481
  throw new WorkflowJournalValidationError('semanticOpts.model must be a string.');
479
- for (const key of ['effort', 'isolation', 'agentType']) {
482
+ for (const key of ['effort', 'isolation', 'agentType', 'logicalKey']) {
480
483
  if (opts[key] !== undefined && typeof opts[key] !== 'string') {
481
484
  throw new WorkflowJournalValidationError(`semanticOpts.${key} must be a string.`);
482
485
  }