codex-workflow-v2 2.0.0-alpha.7.2.1 → 2.0.0-beta.10

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.
Files changed (164) hide show
  1. package/README.md +63 -7
  2. package/dist/src/alpha6/adoption.js +13 -3
  3. package/dist/src/alpha6/adoption.js.map +1 -1
  4. package/dist/src/alpha6/handoff.d.ts +23 -0
  5. package/dist/src/alpha6/handoff.js +221 -28
  6. package/dist/src/alpha6/handoff.js.map +1 -1
  7. package/dist/src/alpha6/milestone.d.ts +29 -0
  8. package/dist/src/alpha6/milestone.js +167 -1
  9. package/dist/src/alpha6/milestone.js.map +1 -1
  10. package/dist/src/alpha6/plan-risk.d.ts +1 -0
  11. package/dist/src/alpha6/plan-risk.js +15 -7
  12. package/dist/src/alpha6/plan-risk.js.map +1 -1
  13. package/dist/src/alpha6/remediation.js +18 -6
  14. package/dist/src/alpha6/remediation.js.map +1 -1
  15. package/dist/src/alpha6/review.d.ts +3 -0
  16. package/dist/src/alpha6/review.js +24 -0
  17. package/dist/src/alpha6/review.js.map +1 -1
  18. package/dist/src/beta1/project-transaction.d.ts +52 -0
  19. package/dist/src/beta1/project-transaction.js +297 -0
  20. package/dist/src/beta1/project-transaction.js.map +1 -0
  21. package/dist/src/cli.js +478 -32
  22. package/dist/src/cli.js.map +1 -1
  23. package/dist/src/contracts.d.ts +189 -5
  24. package/dist/src/contracts.js +1 -1
  25. package/dist/src/credential-output.d.ts +10 -0
  26. package/dist/src/credential-output.js +73 -0
  27. package/dist/src/credential-output.js.map +1 -0
  28. package/dist/src/dependency-provenance.d.ts +19 -0
  29. package/dist/src/dependency-provenance.js +185 -0
  30. package/dist/src/dependency-provenance.js.map +1 -0
  31. package/dist/src/diagnostics.d.ts +11 -0
  32. package/dist/src/diagnostics.js +54 -0
  33. package/dist/src/diagnostics.js.map +1 -1
  34. package/dist/src/errors.d.ts +1 -1
  35. package/dist/src/errors.js.map +1 -1
  36. package/dist/src/git.js +7 -9
  37. package/dist/src/git.js.map +1 -1
  38. package/dist/src/index.d.ts +1 -1
  39. package/dist/src/index.js +1 -1
  40. package/dist/src/index.js.map +1 -1
  41. package/dist/src/lifecycle/canonical-hash.d.ts +6 -0
  42. package/dist/src/lifecycle/canonical-hash.js +24 -0
  43. package/dist/src/lifecycle/canonical-hash.js.map +1 -0
  44. package/dist/src/lifecycle/catalog.d.ts +26 -0
  45. package/dist/src/lifecycle/catalog.js +208 -0
  46. package/dist/src/lifecycle/catalog.js.map +1 -0
  47. package/dist/src/lifecycle/compiler-inspection.d.ts +48 -0
  48. package/dist/src/lifecycle/compiler-inspection.js +29 -0
  49. package/dist/src/lifecycle/compiler-inspection.js.map +1 -0
  50. package/dist/src/lifecycle/core-static-readiness.d.ts +6 -0
  51. package/dist/src/lifecycle/core-static-readiness.js +130 -0
  52. package/dist/src/lifecycle/core-static-readiness.js.map +1 -0
  53. package/dist/src/lifecycle/corrective-replan-authority.d.ts +53 -0
  54. package/dist/src/lifecycle/corrective-replan-authority.js +139 -0
  55. package/dist/src/lifecycle/corrective-replan-authority.js.map +1 -0
  56. package/dist/src/lifecycle/corrective-replan-binding-manifest.d.ts +21 -0
  57. package/dist/src/lifecycle/corrective-replan-binding-manifest.js +35 -0
  58. package/dist/src/lifecycle/corrective-replan-binding-manifest.js.map +1 -0
  59. package/dist/src/lifecycle/corrective-replan-credential-core.d.ts +86 -0
  60. package/dist/src/lifecycle/corrective-replan-credential-core.js +563 -0
  61. package/dist/src/lifecycle/corrective-replan-credential-core.js.map +1 -0
  62. package/dist/src/lifecycle/corrective-replan-credential-schema.d.ts +17 -0
  63. package/dist/src/lifecycle/corrective-replan-credential-schema.js +44 -0
  64. package/dist/src/lifecycle/corrective-replan-credential-schema.js.map +1 -0
  65. package/dist/src/lifecycle/corrective-replan-credentials.d.ts +47 -0
  66. package/dist/src/lifecycle/corrective-replan-credentials.js +103 -0
  67. package/dist/src/lifecycle/corrective-replan-credentials.js.map +1 -0
  68. package/dist/src/lifecycle/corrective-replan.d.ts +64 -0
  69. package/dist/src/lifecycle/corrective-replan.js +548 -0
  70. package/dist/src/lifecycle/corrective-replan.js.map +1 -0
  71. package/dist/src/lifecycle/evaluator.d.ts +2 -0
  72. package/dist/src/lifecycle/evaluator.js +35 -0
  73. package/dist/src/lifecycle/evaluator.js.map +1 -0
  74. package/dist/src/lifecycle/fingerprint.d.ts +31 -0
  75. package/dist/src/lifecycle/fingerprint.js +388 -0
  76. package/dist/src/lifecycle/fingerprint.js.map +1 -0
  77. package/dist/src/lifecycle/immutable.d.ts +1 -0
  78. package/dist/src/lifecycle/immutable.js +10 -0
  79. package/dist/src/lifecycle/immutable.js.map +1 -0
  80. package/dist/src/lifecycle/implementation-table.d.ts +29 -0
  81. package/dist/src/lifecycle/implementation-table.js +87 -0
  82. package/dist/src/lifecycle/implementation-table.js.map +1 -0
  83. package/dist/src/lifecycle/index.d.ts +4 -0
  84. package/dist/src/lifecycle/index.js +5 -0
  85. package/dist/src/lifecycle/index.js.map +1 -0
  86. package/dist/src/lifecycle/schema-artifact.d.ts +12 -0
  87. package/dist/src/lifecycle/schema-artifact.js +214 -0
  88. package/dist/src/lifecycle/schema-artifact.js.map +1 -0
  89. package/dist/src/lifecycle/semantic-registry.d.ts +6 -0
  90. package/dist/src/lifecycle/semantic-registry.js +489 -0
  91. package/dist/src/lifecycle/semantic-registry.js.map +1 -0
  92. package/dist/src/lifecycle/types.d.ts +718 -0
  93. package/dist/src/lifecycle/types.js +4 -0
  94. package/dist/src/lifecycle/types.js.map +1 -0
  95. package/dist/src/observation.d.ts +20 -0
  96. package/dist/src/observation.js +171 -0
  97. package/dist/src/observation.js.map +1 -0
  98. package/dist/src/reviewer.d.ts +43 -1
  99. package/dist/src/reviewer.js +203 -50
  100. package/dist/src/reviewer.js.map +1 -1
  101. package/dist/src/state/corrective-replan-executor.d.ts +64 -0
  102. package/dist/src/state/corrective-replan-executor.js +608 -0
  103. package/dist/src/state/corrective-replan-executor.js.map +1 -0
  104. package/dist/src/state/corrective-replan-public-schema.d.ts +3 -0
  105. package/dist/src/state/corrective-replan-public-schema.js +43 -0
  106. package/dist/src/state/corrective-replan-public-schema.js.map +1 -0
  107. package/dist/src/state/corrective-replan-public.d.ts +95 -0
  108. package/dist/src/state/corrective-replan-public.js +665 -0
  109. package/dist/src/state/corrective-replan-public.js.map +1 -0
  110. package/dist/src/state/corrective-replan-transaction.d.ts +160 -0
  111. package/dist/src/state/corrective-replan-transaction.js +730 -0
  112. package/dist/src/state/corrective-replan-transaction.js.map +1 -0
  113. package/dist/src/state/corrective-yield-executor.d.ts +31 -0
  114. package/dist/src/state/corrective-yield-executor.js +236 -0
  115. package/dist/src/state/corrective-yield-executor.js.map +1 -0
  116. package/dist/src/state/corrective-yield-transaction.d.ts +97 -0
  117. package/dist/src/state/corrective-yield-transaction.js +591 -0
  118. package/dist/src/state/corrective-yield-transaction.js.map +1 -0
  119. package/dist/src/state/lock.d.ts +76 -3
  120. package/dist/src/state/lock.js +611 -30
  121. package/dist/src/state/lock.js.map +1 -1
  122. package/dist/src/state/store.d.ts +3 -0
  123. package/dist/src/state/store.js +65 -12
  124. package/dist/src/state/store.js.map +1 -1
  125. package/dist/src/transition-core.d.ts +67 -0
  126. package/dist/src/transition-core.js +318 -0
  127. package/dist/src/transition-core.js.map +1 -0
  128. package/dist/src/version.d.ts +1 -1
  129. package/dist/src/version.js +1 -1
  130. package/dist/src/version.js.map +1 -1
  131. package/dist/src/workflow.d.ts +93 -25
  132. package/dist/src/workflow.js +1712 -218
  133. package/dist/src/workflow.js.map +1 -1
  134. package/docs/autonomy-guardrails.md +43 -3
  135. package/docs/beta1-stabilization-brief.md +165 -0
  136. package/docs/beta2-initial-assembly-navigation-brief.md +616 -0
  137. package/docs/delegated-approval.md +30 -4
  138. package/docs/development-flow.md +38 -6
  139. package/docs/lifecycle/state-machine-stabilization.md +641 -0
  140. package/docs/project-memory.md +7 -5
  141. package/docs/release.md +25 -3
  142. package/docs/split-required-recovery.md +54 -0
  143. package/docs/stable-release-defect-register.md +730 -0
  144. package/docs/updating-existing-project.md +59 -4
  145. package/docs/validation-report.md +85 -56
  146. package/package.json +6 -2
  147. package/plugins/codex-workflow-gateway/.codex-plugin/plugin.json +10 -3
  148. package/plugins/codex-workflow-gateway/references/protocol.md +80 -5
  149. package/plugins/codex-workflow-gateway/scripts/chat-registry.mjs +376 -0
  150. package/plugins/codex-workflow-gateway/skills/codex-workflow-gateway/SKILL.md +255 -3
  151. package/references/state-machine.md +4 -1
  152. package/roles/delivery-coordinator.md +39 -0
  153. package/schemas/adoption-posture-event.schema.json +1 -1
  154. package/schemas/context-envelope.schema.json +1 -1
  155. package/schemas/corrective-replan-credentials.private.schema.json +98 -0
  156. package/schemas/corrective-replan-execution-event.private.schema.json +53 -0
  157. package/schemas/corrective-replan-public.schema.json +142 -0
  158. package/schemas/corrective-replan-task-transaction.private.schema.json +151 -0
  159. package/schemas/corrective-yield-task-transaction.private.schema.json +98 -0
  160. package/schemas/remediation-event.schema.json +11 -1
  161. package/schemas/task-handoff-event.schema.json +1 -1
  162. package/schemas/task.schema.json +25 -0
  163. package/schemas/transition-definition.schema.json +2609 -0
  164. package/schemas/transition-payloads.schema.json +140 -0
package/dist/src/cli.js CHANGED
@@ -3,15 +3,201 @@ import { readFileSync } from 'node:fs';
3
3
  import path from 'node:path';
4
4
  import process from 'node:process';
5
5
  import { defaultTaskWorkerActor } from './alpha6/handoff.js';
6
+ import { assertCliSuccessCredentialSafety, projectCliErrorMessage, projectCliErrorValue, UnsafeCredentialOutputError, } from './credential-output.js';
6
7
  import { integrationDiagnostics } from './diagnostics.js';
7
8
  import { WorkflowError } from './errors.js';
8
9
  import { prepareGraphView } from './graph.js';
9
10
  import { migrateState } from './migration.js';
10
- import { changedFiles, currentBranch, isClean } from './repository.js';
11
+ import { changedFiles, currentBranch, isClean, resolveRepositoryIdentity } from './repository.js';
11
12
  import { launchStrictReviewer } from './reviewer.js';
12
13
  import { WorkflowService } from './workflow.js';
13
14
  import { PACKAGE_NAME, PACKAGE_VERSION } from './version.js';
14
15
  import { PROTOCOL_VERSION, STATE_SCHEMA_VERSION } from './contracts.js';
16
+ const CLI_ACTIONS = {
17
+ gateway: ['handshake'],
18
+ update: ['preflight', 'rescue-preflight', 'dependency-provenance-preflight', 'dependency-provenance-recover'],
19
+ delegation: ['prepare', 'grant', 'list', 'show', 'revoke'],
20
+ 'project-memory': ['scan', 'show', 'status', 'approve', 'reconcile'],
21
+ state: ['migrate', 'adoption-prepare', 'adoption-apply'],
22
+ graph: ['prepare', 'status', 'refresh-request', 'bind', 'fallback'],
23
+ discovery: ['start', 'update', 'show', 'materialize'],
24
+ task: [
25
+ 'show',
26
+ 'replacement-materialize',
27
+ 'plan-set',
28
+ 'knowledge-rebind',
29
+ 'context-refresh',
30
+ 'authorize',
31
+ 'plan-risk-audit',
32
+ 'start',
33
+ 'run',
34
+ 'step-complete',
35
+ 'submit',
36
+ 'review-record',
37
+ 'review-launch',
38
+ 'review-packet',
39
+ 'review-sealed-record',
40
+ 'step-review',
41
+ 'step-review-packet',
42
+ 'step-review-record',
43
+ 'corrective-decision-recover',
44
+ 'remediation-mode-recover',
45
+ 'corrective-decision',
46
+ 'corrective-yield',
47
+ 'corrective-yield-recover',
48
+ 'corrective-replan-prepare',
49
+ 'corrective-replan-confirm',
50
+ 'corrective-replan-execute',
51
+ 'corrective-replan-recover',
52
+ 'handoff',
53
+ 'handoff-prepare',
54
+ 'handoff-replace',
55
+ 'handoff-show',
56
+ 'claim',
57
+ 'writer-credential-replace',
58
+ 'handback',
59
+ 'handback-create',
60
+ 'result-set',
61
+ 'accept',
62
+ 'sync-base',
63
+ 'merge',
64
+ 'merge-confirm',
65
+ ],
66
+ milestone: [
67
+ 'recover',
68
+ 'show',
69
+ 'progress',
70
+ 'plan-set',
71
+ 'scope-change-prepare',
72
+ 'scope-change-apply',
73
+ 'autonomy-prepare',
74
+ 'autonomy-grant',
75
+ 'autonomy-evolve',
76
+ 'authorize',
77
+ 'validate',
78
+ 'accept',
79
+ 'cancel',
80
+ ],
81
+ locks: ['inspect', 'repair'],
82
+ };
83
+ const CLI_HELP_SPECS = {
84
+ 'update dependency-provenance-preflight': {
85
+ requiredOptions: ['--id'],
86
+ optionalOptions: ['--repo', '--json'],
87
+ },
88
+ 'update dependency-provenance-recover': {
89
+ requiredOptions: ['--id', '--expected-revision', '--actor', '--reason'],
90
+ optionalOptions: ['--repo', '--json'],
91
+ },
92
+ 'milestone progress': {
93
+ requiredOptions: ['--id'],
94
+ optionalOptions: ['--repo', '--json'],
95
+ },
96
+ 'milestone authorize': {
97
+ requiredOptions: ['--id', '--expected-revision'],
98
+ optionalOptions: ['--actor', '--reason', '--delegation-grant', '--repo', '--json'],
99
+ },
100
+ 'milestone validate': {
101
+ requiredOptions: ['--id', '--expected-revision'],
102
+ optionalOptions: ['--repo', '--json'],
103
+ },
104
+ 'milestone accept': {
105
+ requiredOptions: ['--id', '--expected-revision', '--actor', '--confirmation-code'],
106
+ optionalOptions: ['--delegation-grant', '--repo', '--json'],
107
+ },
108
+ 'task plan-set': {
109
+ requiredOptions: ['--id', '--expected-revision', '--file', '--risk-audit-file'],
110
+ optionalOptions: ['--corrective-audit-file', '--repo', '--json'],
111
+ },
112
+ 'task handoff-replace': {
113
+ requiredOptions: ['--id', '--expected-revision', '--actor', '--target-actor', '--reason'],
114
+ optionalOptions: ['--delegation-grant', '--expires-at', '--repo', '--json'],
115
+ },
116
+ 'task writer-credential-replace': {
117
+ requiredOptions: ['--id', '--expected-revision', '--actor'],
118
+ optionalOptions: ['--repo', '--json'],
119
+ },
120
+ 'task corrective-yield': {
121
+ requiredOptions: ['--id', '--expected-revision', '--actor', '--writer-token', '--reason'],
122
+ optionalOptions: ['--repo', '--json'],
123
+ },
124
+ 'task corrective-yield-recover': {
125
+ requiredOptions: ['--id', '--transaction-id'],
126
+ optionalOptions: ['--repo', '--json'],
127
+ },
128
+ 'task corrective-replan-prepare': {
129
+ requiredOptions: ['--id', '--file'],
130
+ optionalOptions: ['--repo', '--json'],
131
+ },
132
+ 'task corrective-replan-confirm': {
133
+ requiredOptions: ['--id', '--file', '--gate-file', '--confirmation-code'],
134
+ optionalOptions: ['--repo', '--json'],
135
+ },
136
+ 'task corrective-replan-execute': {
137
+ requiredOptions: ['--id', '--file', '--credential-file'],
138
+ optionalOptions: ['--repo', '--json'],
139
+ },
140
+ 'task corrective-replan-recover': {
141
+ requiredOptions: ['--id', '--transaction-id'],
142
+ optionalOptions: ['--repo', '--json'],
143
+ },
144
+ 'task authorize': {
145
+ requiredOptions: ['--id', '--expected-revision'],
146
+ optionalOptions: ['--actor', '--reason', '--delegation-grant', '--repo', '--json'],
147
+ },
148
+ 'task start': {
149
+ requiredOptions: ['--id', '--expected-revision', '--workspace-owner'],
150
+ optionalOptions: ['--repo', '--json'],
151
+ },
152
+ 'task run': {
153
+ requiredOptions: ['--id', '--step', '--expected-revision'],
154
+ optionalOptions: ['--owner', '--writer-token', '--repo', '--json'],
155
+ },
156
+ 'task step-complete': {
157
+ requiredOptions: ['--id', '--step', '--expected-revision', '--writer-token'],
158
+ optionalOptions: ['--note', '--actor', '--repo', '--json'],
159
+ },
160
+ 'task submit': {
161
+ requiredOptions: ['--id', '--expected-revision', '--writer-token'],
162
+ optionalOptions: ['--actor', '--repo', '--json'],
163
+ },
164
+ 'task review-launch': {
165
+ requiredOptions: ['--id', '--expected-revision'],
166
+ optionalOptions: ['--actor', '--writer-token', '--repo', '--json'],
167
+ },
168
+ 'task review-packet': {
169
+ requiredOptions: ['--id', '--expected-revision'],
170
+ optionalOptions: ['--repo', '--json'],
171
+ },
172
+ 'task review-sealed-record': {
173
+ requiredOptions: ['--id', '--expected-revision', '--actor', '--file'],
174
+ optionalOptions: ['--writer-token', '--repo', '--json'],
175
+ },
176
+ 'task step-review-packet': {
177
+ requiredOptions: ['--id', '--step', '--expected-revision'],
178
+ optionalOptions: ['--repo', '--json'],
179
+ },
180
+ 'task step-review-record': {
181
+ requiredOptions: ['--id', '--step', '--expected-revision', '--actor', '--file'],
182
+ optionalOptions: ['--writer-token', '--repo', '--json'],
183
+ },
184
+ 'task result-set': {
185
+ requiredOptions: ['--id', '--expected-revision', '--summary'],
186
+ optionalOptions: ['--limitation', '--repo', '--json'],
187
+ },
188
+ 'task accept': {
189
+ requiredOptions: ['--id', '--expected-revision'],
190
+ optionalOptions: ['--actor', '--delegation-grant', '--repo', '--json'],
191
+ },
192
+ 'task merge': {
193
+ requiredOptions: ['--id', '--expected-revision', '--writer-token'],
194
+ optionalOptions: ['--actor', '--repo', '--json'],
195
+ },
196
+ 'task merge-confirm': {
197
+ requiredOptions: ['--id', '--expected-revision', '--writer-token'],
198
+ optionalOptions: ['--actor', '--repo', '--json'],
199
+ },
200
+ };
15
201
  function parseArguments(argv) {
16
202
  const positionals = [];
17
203
  const options = new Map();
@@ -37,6 +223,58 @@ function parseArguments(argv) {
37
223
  function option(args, name) {
38
224
  return args.options.get(name)?.at(-1);
39
225
  }
226
+ function cliHelp(args) {
227
+ const [noun, action] = args.positionals;
228
+ if (!noun) {
229
+ return {
230
+ kind: 'cli-help',
231
+ readOnly: true,
232
+ scope: 'top-level',
233
+ usage: 'codex-workflow <command> [action] [options]',
234
+ commands: ['doctor', 'status', 'next', ...Object.keys(CLI_ACTIONS)],
235
+ };
236
+ }
237
+ if (!action) {
238
+ if (['doctor', 'status', 'next'].includes(noun)) {
239
+ const taskSelector = noun === 'next' ? ['--task'] : [];
240
+ return {
241
+ kind: 'cli-help',
242
+ readOnly: true,
243
+ scope: 'command',
244
+ command: noun,
245
+ usage: noun === 'next'
246
+ ? 'codex-workflow next [--task <task-id>] [--repo <path>] [--json]'
247
+ : `codex-workflow ${noun} [--repo <path>] [--json]`,
248
+ requiredOptions: [],
249
+ optionalOptions: [...taskSelector, '--repo', '--json'],
250
+ exactOptionContractAvailable: true,
251
+ };
252
+ }
253
+ return {
254
+ kind: 'cli-help',
255
+ readOnly: true,
256
+ scope: 'command',
257
+ command: noun,
258
+ usage: `codex-workflow ${noun} <action> [options]`,
259
+ actions: CLI_ACTIONS[noun] ?? [],
260
+ };
261
+ }
262
+ const command = `${noun} ${action}`;
263
+ const spec = CLI_HELP_SPECS[command];
264
+ return {
265
+ kind: 'cli-help',
266
+ readOnly: true,
267
+ scope: 'action',
268
+ command,
269
+ usage: spec
270
+ ? ['codex-workflow', noun, action, ...spec.requiredOptions.map((name) => `${name} <value>`), '[options]'].join(' ')
271
+ : `codex-workflow ${noun} ${action} [options]`,
272
+ requiredOptions: spec?.requiredOptions ?? null,
273
+ optionalOptions: spec?.optionalOptions ?? null,
274
+ exactOptionContractAvailable: Boolean(spec),
275
+ ...(spec ? {} : { note: 'Consult the packaged protocol for this action option contract.' }),
276
+ };
277
+ }
40
278
  function required(args, name) {
41
279
  const value = option(args, name)?.trim();
42
280
  if (!value)
@@ -120,6 +358,9 @@ function workflowCapabilities() {
120
358
  'task-context-refresh-v1',
121
359
  'corrective-plan-audit-v1',
122
360
  'safe-update-preflight-v1',
361
+ 'bounded-dependency-provenance-recovery-v1',
362
+ 'retained-reviewed-history-recovery-v1',
363
+ 'milestone-progress-projection-v1',
123
364
  'strict-reviewer-v1',
124
365
  'legacy-snapshot-v1',
125
366
  'plan-risk-audit-sidecar-v1',
@@ -135,6 +376,7 @@ function workflowCapabilities() {
135
376
  'alpha6-adoption-posture-v1',
136
377
  'alpha6-strict-review-rescue-v1',
137
378
  'milestone-initial-assembly-v1',
379
+ 'milestone-initial-assembly-navigation-v2',
138
380
  'milestone-autonomy-contract-v1',
139
381
  'milestone-autonomy-content-refresh-v1',
140
382
  'milestone-autonomous-membership-evolution-v1',
@@ -143,10 +385,18 @@ function workflowCapabilities() {
143
385
  'corrective-decision-context-recovery-v1',
144
386
  'remediation-mode-recovery-v1',
145
387
  'plan-proof-obligations-v1',
388
+ 'terminal-task-replacement-transaction-v1',
389
+ 'project-composite-transaction-journal-v1',
390
+ 'corrective-yield-journal-v1',
391
+ 'corrective-replan-journal-v1',
392
+ 'corrective-replan-human-gate-v1',
393
+ 'corrective-replan-protocol-v2',
146
394
  ];
147
395
  }
148
396
  async function dispatch(args) {
149
397
  const [noun, action] = args.positionals;
398
+ if (args.options.has('help'))
399
+ return cliHelp(args);
150
400
  const repo = repository(args);
151
401
  if (noun === 'gateway' && action === 'handshake') {
152
402
  return {
@@ -159,19 +409,19 @@ async function dispatch(args) {
159
409
  }
160
410
  const workflow = new WorkflowService();
161
411
  if (noun === 'doctor') {
162
- const context = workflow.context(repo);
163
- const integration = integrationDiagnostics(context.identity.repositoryRoot);
412
+ const identity = resolveRepositoryIdentity(repo);
413
+ const integration = integrationDiagnostics(identity.repositoryRoot);
164
414
  const nodeSupported = Number(process.versions.node.split('.')[0]) >= 22;
165
415
  return {
166
416
  ok: nodeSupported && integration.localDependency.current,
167
417
  node: process.versions.node,
168
418
  requiredNode: '>=22',
169
- repositoryRoot: context.identity.repositoryRoot,
170
- projectId: context.identity.projectId,
171
- stateRoot: context.store.root,
172
- branch: currentBranch(context.identity.repositoryRoot),
173
- clean: isClean(context.identity.repositoryRoot),
174
- changedFiles: changedFiles(context.identity.repositoryRoot),
419
+ repositoryRoot: identity.repositoryRoot,
420
+ projectId: identity.projectId,
421
+ stateRoot: workflow.store.root,
422
+ branch: currentBranch(identity.repositoryRoot),
423
+ clean: isClean(identity.repositoryRoot),
424
+ changedFiles: changedFiles(identity.repositoryRoot),
175
425
  integration,
176
426
  limitations: [
177
427
  'CLI diagnostics cannot prove that Codex enforced a role, model, sandbox, or read-only reviewer.',
@@ -182,12 +432,18 @@ async function dispatch(args) {
182
432
  if (noun === 'status')
183
433
  return workflow.status(repo);
184
434
  if (noun === 'next')
185
- return workflow.next(repo);
435
+ return workflow.next(repo, option(args, 'task') ?? null);
186
436
  if (noun === 'update' && action === 'preflight')
187
437
  return workflow.updatePreflight(repo);
188
438
  if (noun === 'update' && action === 'rescue-preflight') {
189
439
  return workflow.alpha6StrictReviewRescuePreflight(repo);
190
440
  }
441
+ if (noun === 'update' && action === 'dependency-provenance-preflight') {
442
+ return workflow.dependencyProvenanceRecoveryPreflight(repo, required(args, 'id'));
443
+ }
444
+ if (noun === 'update' && action === 'dependency-provenance-recover') {
445
+ return workflow.recoverDependencyProvenance(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'reason'));
446
+ }
191
447
  if (noun === 'delegation' && action === 'prepare') {
192
448
  return workflow.prepareDelegation(repo, jsonFile(args));
193
449
  }
@@ -195,12 +451,12 @@ async function dispatch(args) {
195
451
  return workflow.grantDelegation(repo, jsonFile(args), required(args, 'confirmation-code'));
196
452
  }
197
453
  if (noun === 'delegation' && action === 'list') {
198
- const context = workflow.context(repo);
199
- return context.store.listDelegations(context.identity.projectId);
454
+ const identity = resolveRepositoryIdentity(repo);
455
+ return workflow.store.listDelegations(identity.projectId);
200
456
  }
201
457
  if (noun === 'delegation' && action === 'show') {
202
- const context = workflow.context(repo);
203
- return context.store.readDelegation(context.identity.projectId, required(args, 'id'));
458
+ const identity = resolveRepositoryIdentity(repo);
459
+ return workflow.store.readDelegation(identity.projectId, required(args, 'id'));
204
460
  }
205
461
  if (noun === 'delegation' && action === 'revoke') {
206
462
  return workflow.revokeDelegation(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'reason'));
@@ -303,8 +559,8 @@ async function dispatch(args) {
303
559
  return workflow.updateDiscovery(repo, required(args, 'id'), revision(args), patch);
304
560
  }
305
561
  if (noun === 'discovery' && action === 'show') {
306
- const context = workflow.context(repo);
307
- return context.store.readDiscovery(context.identity.projectId, required(args, 'id'));
562
+ const identity = resolveRepositoryIdentity(repo);
563
+ return workflow.store.readDiscovery(identity.projectId, required(args, 'id'));
308
564
  }
309
565
  if (noun === 'discovery' && action === 'materialize') {
310
566
  const kind = option(args, 'kind') ?? 'task';
@@ -317,8 +573,11 @@ async function dispatch(args) {
317
573
  throw new WorkflowError('INVALID_ARGUMENT', '--kind must be task or milestone.');
318
574
  }
319
575
  if (noun === 'task' && action === 'show') {
320
- const context = workflow.context(repo);
321
- return context.store.readTask(context.identity.projectId, required(args, 'id'));
576
+ const identity = resolveRepositoryIdentity(repo);
577
+ return workflow.store.readTask(identity.projectId, required(args, 'id'));
578
+ }
579
+ if (noun === 'task' && action === 'replacement-materialize') {
580
+ return workflow.replaceSplitRequiredTask(repo, required(args, 'id'), revision(args), required(args, 'discovery'), positiveIntegerOption(args, 'expected-discovery-revision'), positiveIntegerOption(args, 'expected-milestone-revision'), required(args, 'title'), option(args, 'actor') ?? 'user');
322
581
  }
323
582
  if (noun === 'task' && action === 'plan-set') {
324
583
  return workflow.setTaskPlan(repo, required(args, 'id'), revision(args), jsonFile(args), option(args, 'corrective-audit-file')
@@ -345,7 +604,32 @@ async function dispatch(args) {
345
604
  return workflow.startTask(repo, required(args, 'id'), revision(args), owner);
346
605
  }
347
606
  if (noun === 'task' && action === 'run') {
348
- return workflow.runStep(repo, required(args, 'id'), required(args, 'step'), revision(args), option(args, 'owner') ?? 'worker', option(args, 'writer-token') ?? null);
607
+ const outcome = workflow.runStep(repo, required(args, 'id'), required(args, 'step'), revision(args), option(args, 'owner') ?? 'worker', option(args, 'writer-token') ?? null);
608
+ const { writerToken, ...envelope } = outcome.envelope;
609
+ if (outcome.writerCredential.disposition === 'issued' && !writerToken) {
610
+ throw new WorkflowError('STATE_CORRUPT', 'Fresh task run credential issuance did not return its protocol-v1 writer token.');
611
+ }
612
+ if (outcome.writerCredential.disposition === 'renewed' && writerToken !== null) {
613
+ throw new WorkflowError('STATE_CORRUPT', 'Renewed task run credential unexpectedly returned a writer token.');
614
+ }
615
+ return {
616
+ writerCredential: { disposition: outcome.writerCredential.disposition },
617
+ ...(writerToken ? {
618
+ writerLeaseReceipt: {
619
+ token: writerToken,
620
+ kind: 'writer-lease',
621
+ owner: outcome.lease.owner,
622
+ action: 'task step-complete',
623
+ option: '--writer-token',
624
+ source: 'task run',
625
+ sensitive: true,
626
+ oneTime: false,
627
+ },
628
+ } : {}),
629
+ task: outcome.task,
630
+ lease: outcome.lease,
631
+ envelope,
632
+ };
349
633
  }
350
634
  if (noun === 'task' && action === 'step-complete') {
351
635
  return workflow.completeStep(repo, required(args, 'id'), required(args, 'step'), revision(args), required(args, 'writer-token'), repeated(args, 'note'), option(args, 'actor'));
@@ -358,10 +642,10 @@ async function dispatch(args) {
358
642
  return workflow.recordReview(repo, required(args, 'id'), revision(args), review, option(args, 'actor'), option(args, 'writer-token') ?? null);
359
643
  }
360
644
  if (noun === 'task' && action === 'review-launch') {
361
- const context = workflow.context(repo);
645
+ const identity = resolveRepositoryIdentity(repo);
362
646
  const id = required(args, 'id');
363
647
  const expectedRevision = revision(args);
364
- const task = context.store.readTask(context.identity.projectId, id);
648
+ const task = workflow.store.readTask(identity.projectId, id);
365
649
  if (task.revision !== expectedRevision) {
366
650
  throw new WorkflowError('STATE_CONFLICT', `State revision conflict for ${id}`, {
367
651
  expectedRevision,
@@ -369,13 +653,29 @@ async function dispatch(args) {
369
653
  });
370
654
  }
371
655
  const envelope = workflow.taskContext(repo, id, 'independent-reviewer');
372
- const launch = launchStrictReviewer(context.identity.repositoryRoot, task, context.store.taskRoot(task.projectId, task.id), envelope);
656
+ const launch = launchStrictReviewer(identity.repositoryRoot, task, workflow.store.taskRoot(task.projectId, task.id), envelope);
657
+ // The independent reviewer identity belongs to the strict reviewer payload. CLI --actor
658
+ // remains the lifecycle mutation actor, such as the current C1 claimant.
373
659
  const saved = workflow.recordReview(repo, id, expectedRevision, launch.review, option(args, 'actor'), option(args, 'writer-token') ?? null);
374
660
  return { launch, task: saved };
375
661
  }
662
+ if (noun === 'task' && action === 'review-packet') {
663
+ return workflow.prepareExternalTaskReview(repo, required(args, 'id'), revision(args));
664
+ }
665
+ if (noun === 'task' && action === 'review-sealed-record') {
666
+ return workflow.recordExternalTaskReview(repo, required(args, 'id'), revision(args), jsonFile(args), required(args, 'actor'), option(args, 'writer-token') ?? null);
667
+ }
376
668
  if (noun === 'task' && action === 'step-review') {
669
+ // Strict Step Review launches and records the isolated reviewer inside Core. CLI --actor
670
+ // remains the lifecycle actor from next, typically the active C1 claimant.
377
671
  return workflow.reviewStep(repo, required(args, 'id'), required(args, 'step'), revision(args), undefined, option(args, 'actor'), option(args, 'writer-token') ?? null);
378
672
  }
673
+ if (noun === 'task' && action === 'step-review-packet') {
674
+ return workflow.prepareExternalStepReview(repo, required(args, 'id'), required(args, 'step'), revision(args));
675
+ }
676
+ if (noun === 'task' && action === 'step-review-record') {
677
+ return workflow.recordExternalStepReview(repo, required(args, 'id'), required(args, 'step'), revision(args), jsonFile(args), required(args, 'actor'), option(args, 'writer-token') ?? null);
678
+ }
379
679
  if (noun === 'task' && action === 'corrective-decision-recover') {
380
680
  return workflow.recoverStepCorrectiveDecision(repo, required(args, 'id'), required(args, 'step'), revision(args), required(args, 'actor'), option(args, 'writer-token') ?? null);
381
681
  }
@@ -385,14 +685,84 @@ async function dispatch(args) {
385
685
  if (noun === 'task' && action === 'corrective-decision') {
386
686
  return workflow.recordStepCorrectiveDecision(repo, required(args, 'id'), required(args, 'step'), revision(args), jsonFile(args), option(args, 'actor'), option(args, 'writer-token') ?? null);
387
687
  }
388
- if (noun === 'task' && (action === 'handoff' || action === 'handoff-prepare')) {
389
- return workflow.handoffTask(repo, required(args, 'id'), revision(args), required(args, 'actor'), option(args, 'target-actor') ?? defaultTaskWorkerActor(required(args, 'id')), required(args, 'reason'), option(args, 'writer-token') ?? null, option(args, 'delegation-grant') ?? null, option(args, 'expires-at') ?? null);
688
+ if (noun === 'task' && action === 'corrective-yield') {
689
+ return workflow.executeCorrectiveYield(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'writer-token'), required(args, 'reason'));
690
+ }
691
+ if (noun === 'task' && action === 'corrective-yield-recover') {
692
+ return workflow.recoverCorrectiveYield(repo, required(args, 'id'), required(args, 'transaction-id'));
693
+ }
694
+ if (noun === 'task' && action === 'corrective-replan-prepare') {
695
+ return workflow.prepareCorrectiveReplan(repo, required(args, 'id'), jsonFile(args));
696
+ }
697
+ if (noun === 'task' && action === 'corrective-replan-confirm') {
698
+ return workflow.confirmCorrectiveReplan(repo, required(args, 'id'), jsonFile(args), jsonFile(args, 'gate-file'), required(args, 'confirmation-code'));
699
+ }
700
+ if (noun === 'task' && action === 'corrective-replan-execute') {
701
+ return workflow.executeCorrectiveReplan(repo, required(args, 'id'), jsonFile(args), jsonFile(args, 'credential-file'));
702
+ }
703
+ if (noun === 'task' && action === 'corrective-replan-recover') {
704
+ return workflow.recoverCorrectiveReplan(repo, required(args, 'id'), required(args, 'transaction-id'));
705
+ }
706
+ if (noun === 'task' && (action === 'handoff' || action === 'handoff-prepare' || action === 'handoff-replace')) {
707
+ const replacePending = action === 'handoff-replace';
708
+ const outcome = workflow.handoffTask(repo, required(args, 'id'), revision(args), required(args, 'actor'), replacePending
709
+ ? required(args, 'target-actor')
710
+ : option(args, 'target-actor') ?? defaultTaskWorkerActor(required(args, 'id')), required(args, 'reason'), option(args, 'writer-token') ?? null, option(args, 'delegation-grant') ?? null, option(args, 'expires-at') ?? null, replacePending);
711
+ const { claimToken, ...bundle } = outcome.bundle;
712
+ return {
713
+ credentialHandoff: {
714
+ token: claimToken,
715
+ kind: 'claim-token',
716
+ targetActor: outcome.bundle.delegate,
717
+ action: 'task claim',
718
+ option: '--claim-token',
719
+ source: replacePending ? 'task handoff-replace' : 'task handoff-prepare',
720
+ sensitive: true,
721
+ oneTime: true,
722
+ },
723
+ task: outcome.task,
724
+ event: outcome.event,
725
+ bundle,
726
+ };
390
727
  }
391
728
  if (noun === 'task' && action === 'handoff-show') {
392
729
  return workflow.showTaskHandoff(repo, required(args, 'id'));
393
730
  }
394
731
  if (noun === 'task' && action === 'claim') {
395
- return workflow.claimTask(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'claim-token'), option(args, 'writer-token') ?? null);
732
+ const outcome = workflow.claimTask(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'claim-token'), option(args, 'writer-token') ?? null);
733
+ return {
734
+ writerCredential: { disposition: outcome.writerCredential.disposition },
735
+ ...(outcome.writerCredential.disposition === 'issued' ? {
736
+ writerLeaseReceipt: {
737
+ token: outcome.writerCredential.token,
738
+ kind: 'writer-lease',
739
+ owner: outcome.lease.owner,
740
+ action: 'task run',
741
+ option: '--writer-token',
742
+ source: 'task claim',
743
+ sensitive: true,
744
+ oneTime: false,
745
+ },
746
+ } : {}),
747
+ task: outcome.task,
748
+ event: outcome.event,
749
+ lease: outcome.lease,
750
+ };
751
+ }
752
+ if (noun === 'task' && action === 'writer-credential-replace') {
753
+ const outcome = workflow.replaceClaimedWriterCredential(repo, required(args, 'id'), revision(args), required(args, 'actor'));
754
+ return {
755
+ writerCredential: { disposition: outcome.writerCredential.disposition },
756
+ writerLeaseReceipt: {
757
+ token: outcome.writerCredential.token,
758
+ kind: 'writer-lease',
759
+ source: 'task writer-credential-replace',
760
+ sensitive: true,
761
+ oneTime: false,
762
+ },
763
+ task: outcome.task,
764
+ lease: outcome.lease,
765
+ };
396
766
  }
397
767
  if (noun === 'task' && (action === 'handback' || action === 'handback-create')) {
398
768
  return workflow.handbackTask(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'reason'), option(args, 'writer-token') ?? null, repeated(args, 'limitation'), action === 'handback-create'
@@ -415,8 +785,11 @@ async function dispatch(args) {
415
785
  return workflow.confirmExternalMerge(repo, required(args, 'id'), revision(args), required(args, 'writer-token'), option(args, 'actor'));
416
786
  }
417
787
  if (noun === 'milestone' && action === 'show') {
418
- const context = workflow.context(repo);
419
- return context.store.readMilestone(context.identity.projectId, required(args, 'id'));
788
+ const identity = resolveRepositoryIdentity(repo);
789
+ return workflow.store.readMilestone(identity.projectId, required(args, 'id'));
790
+ }
791
+ if (noun === 'milestone' && action === 'progress') {
792
+ return workflow.milestoneProgress(repo, required(args, 'id'));
420
793
  }
421
794
  if (noun === 'milestone' && action === 'plan-set') {
422
795
  return workflow.setMilestonePlan(repo, required(args, 'id'), revision(args), jsonFile(args));
@@ -449,27 +822,100 @@ async function dispatch(args) {
449
822
  return workflow.cancelMilestone(repo, required(args, 'id'), revision(args), required(args, 'reason'));
450
823
  }
451
824
  if (noun === 'locks' && (action === 'inspect' || action === 'repair')) {
452
- const context = workflow.context(repo);
453
825
  const id = required(args, 'id');
454
- return action === 'inspect' ? context.locks.inspect(id) : context.locks.repairStale(id);
826
+ if (action === 'repair')
827
+ return workflow.repairStaleWriterLease(repo, id);
828
+ const inspection = workflow.inspectWriterLease(repo, id);
829
+ return inspection ? { ...inspection, repaired: false } : null;
455
830
  }
456
831
  throw new WorkflowError('INVALID_ARGUMENT', 'Unknown command.', {
457
832
  command: args.positionals.join(' '),
458
833
  hint: 'Use doctor, status, next, update preflight, state <action>, delegation <action>, project-memory <action>, discovery <action>, task <action>, milestone <action>, or locks <action>.',
459
834
  });
460
835
  }
836
+ function credentialAllowancesForResult(args, value) {
837
+ const [noun, action] = args.positionals;
838
+ if (!isRecord(value))
839
+ return [];
840
+ if (noun === 'task' && (action === 'run' || action === 'claim' || action === 'writer-credential-replace')) {
841
+ const disposition = isRecord(value.writerCredential) ? value.writerCredential.disposition : null;
842
+ const receipt = isRecord(value.writerLeaseReceipt) ? value.writerLeaseReceipt : null;
843
+ if (disposition === 'issued'
844
+ && receipt?.kind === 'writer-lease'
845
+ && receipt.source === `task ${action}`
846
+ && receipt.sensitive === true) {
847
+ return [{ path: '$.writerLeaseReceipt.token' }];
848
+ }
849
+ return [];
850
+ }
851
+ if (noun === 'task' && (action === 'handoff' || action === 'handoff-prepare' || action === 'handoff-replace')) {
852
+ const receipt = isRecord(value.credentialHandoff) ? value.credentialHandoff : null;
853
+ if (receipt?.kind === 'claim-token'
854
+ && receipt.source === (action === 'handoff-replace' ? 'task handoff-replace' : 'task handoff-prepare')
855
+ && receipt.sensitive === true
856
+ && receipt.oneTime === true) {
857
+ return [{ path: '$.credentialHandoff.token' }];
858
+ }
859
+ }
860
+ return [];
861
+ }
862
+ function rawCredentialInputs(argv) {
863
+ const values = [];
864
+ for (let index = 0; index < argv.length; index += 1) {
865
+ const argument = argv[index];
866
+ for (const optionName of ['--writer-token', '--claim-token', '--confirmation-code']) {
867
+ if (argument === optionName && argv[index + 1])
868
+ values.push(argv[index + 1]);
869
+ if (argument.startsWith(`${optionName}=`))
870
+ values.push(argument.slice(optionName.length + 1));
871
+ }
872
+ }
873
+ return [...new Set(values.filter(Boolean))];
874
+ }
875
+ function isRecord(value) {
876
+ return typeof value === 'object' && value !== null;
877
+ }
461
878
  async function main() {
879
+ const argv = process.argv.slice(2);
880
+ const sensitiveInputs = rawCredentialInputs(argv);
462
881
  try {
463
- const value = await dispatch(parseArguments(process.argv.slice(2)));
882
+ const args = parseArguments(argv);
883
+ const value = await dispatch(args);
884
+ assertCliSuccessCredentialSafety(value, credentialAllowancesForResult(args, value), sensitiveInputs);
464
885
  process.stdout.write(`${JSON.stringify({ ok: true, value }, null, 2)}\n`);
465
886
  }
466
887
  catch (error) {
888
+ if (error instanceof UnsafeCredentialOutputError) {
889
+ process.stderr.write(`${JSON.stringify({
890
+ ok: false,
891
+ error: {
892
+ code: 'STATE_CORRUPT',
893
+ message: error.message,
894
+ details: { credentialPaths: error.paths },
895
+ },
896
+ }, null, 2)}\n`);
897
+ process.exitCode = 2;
898
+ return;
899
+ }
467
900
  if (error instanceof WorkflowError) {
468
- process.stderr.write(`${JSON.stringify({ ok: false, error: { code: error.code, message: error.message, details: error.details } }, null, 2)}\n`);
901
+ process.stderr.write(`${JSON.stringify({
902
+ ok: false,
903
+ error: {
904
+ code: error.code,
905
+ message: projectCliErrorMessage(error.message, sensitiveInputs),
906
+ details: projectCliErrorValue(error.details, sensitiveInputs),
907
+ },
908
+ }, null, 2)}\n`);
469
909
  process.exitCode = 2;
470
910
  return;
471
911
  }
472
- process.stderr.write(`${JSON.stringify({ ok: false, error: { code: 'UNEXPECTED', message: error instanceof Error ? error.message : String(error) } }, null, 2)}\n`);
912
+ process.stderr.write(`${JSON.stringify({
913
+ ok: false,
914
+ error: {
915
+ code: 'UNEXPECTED',
916
+ message: projectCliErrorMessage(error instanceof Error ? error.message : String(error), sensitiveInputs),
917
+ },
918
+ }, null, 2)}\n`);
473
919
  process.exitCode = 1;
474
920
  }
475
921
  }