codex-workflow-v2 2.0.0-beta.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 (156) hide show
  1. package/README.md +52 -4
  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 +12 -0
  8. package/dist/src/alpha6/milestone.js +113 -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/cli.js +473 -45
  19. package/dist/src/cli.js.map +1 -1
  20. package/dist/src/contracts.d.ts +169 -5
  21. package/dist/src/contracts.js +1 -1
  22. package/dist/src/credential-output.d.ts +10 -0
  23. package/dist/src/credential-output.js +73 -0
  24. package/dist/src/credential-output.js.map +1 -0
  25. package/dist/src/dependency-provenance.d.ts +19 -0
  26. package/dist/src/dependency-provenance.js +185 -0
  27. package/dist/src/dependency-provenance.js.map +1 -0
  28. package/dist/src/errors.d.ts +1 -1
  29. package/dist/src/errors.js.map +1 -1
  30. package/dist/src/git.js +5 -4
  31. package/dist/src/git.js.map +1 -1
  32. package/dist/src/index.d.ts +1 -1
  33. package/dist/src/index.js +1 -1
  34. package/dist/src/index.js.map +1 -1
  35. package/dist/src/lifecycle/canonical-hash.d.ts +6 -0
  36. package/dist/src/lifecycle/canonical-hash.js +24 -0
  37. package/dist/src/lifecycle/canonical-hash.js.map +1 -0
  38. package/dist/src/lifecycle/catalog.d.ts +26 -0
  39. package/dist/src/lifecycle/catalog.js +208 -0
  40. package/dist/src/lifecycle/catalog.js.map +1 -0
  41. package/dist/src/lifecycle/compiler-inspection.d.ts +48 -0
  42. package/dist/src/lifecycle/compiler-inspection.js +29 -0
  43. package/dist/src/lifecycle/compiler-inspection.js.map +1 -0
  44. package/dist/src/lifecycle/core-static-readiness.d.ts +6 -0
  45. package/dist/src/lifecycle/core-static-readiness.js +130 -0
  46. package/dist/src/lifecycle/core-static-readiness.js.map +1 -0
  47. package/dist/src/lifecycle/corrective-replan-authority.d.ts +53 -0
  48. package/dist/src/lifecycle/corrective-replan-authority.js +139 -0
  49. package/dist/src/lifecycle/corrective-replan-authority.js.map +1 -0
  50. package/dist/src/lifecycle/corrective-replan-binding-manifest.d.ts +21 -0
  51. package/dist/src/lifecycle/corrective-replan-binding-manifest.js +35 -0
  52. package/dist/src/lifecycle/corrective-replan-binding-manifest.js.map +1 -0
  53. package/dist/src/lifecycle/corrective-replan-credential-core.d.ts +86 -0
  54. package/dist/src/lifecycle/corrective-replan-credential-core.js +563 -0
  55. package/dist/src/lifecycle/corrective-replan-credential-core.js.map +1 -0
  56. package/dist/src/lifecycle/corrective-replan-credential-schema.d.ts +17 -0
  57. package/dist/src/lifecycle/corrective-replan-credential-schema.js +44 -0
  58. package/dist/src/lifecycle/corrective-replan-credential-schema.js.map +1 -0
  59. package/dist/src/lifecycle/corrective-replan-credentials.d.ts +47 -0
  60. package/dist/src/lifecycle/corrective-replan-credentials.js +103 -0
  61. package/dist/src/lifecycle/corrective-replan-credentials.js.map +1 -0
  62. package/dist/src/lifecycle/corrective-replan.d.ts +64 -0
  63. package/dist/src/lifecycle/corrective-replan.js +548 -0
  64. package/dist/src/lifecycle/corrective-replan.js.map +1 -0
  65. package/dist/src/lifecycle/evaluator.d.ts +2 -0
  66. package/dist/src/lifecycle/evaluator.js +35 -0
  67. package/dist/src/lifecycle/evaluator.js.map +1 -0
  68. package/dist/src/lifecycle/fingerprint.d.ts +31 -0
  69. package/dist/src/lifecycle/fingerprint.js +388 -0
  70. package/dist/src/lifecycle/fingerprint.js.map +1 -0
  71. package/dist/src/lifecycle/immutable.d.ts +1 -0
  72. package/dist/src/lifecycle/immutable.js +10 -0
  73. package/dist/src/lifecycle/immutable.js.map +1 -0
  74. package/dist/src/lifecycle/implementation-table.d.ts +29 -0
  75. package/dist/src/lifecycle/implementation-table.js +87 -0
  76. package/dist/src/lifecycle/implementation-table.js.map +1 -0
  77. package/dist/src/lifecycle/index.d.ts +4 -0
  78. package/dist/src/lifecycle/index.js +5 -0
  79. package/dist/src/lifecycle/index.js.map +1 -0
  80. package/dist/src/lifecycle/schema-artifact.d.ts +12 -0
  81. package/dist/src/lifecycle/schema-artifact.js +214 -0
  82. package/dist/src/lifecycle/schema-artifact.js.map +1 -0
  83. package/dist/src/lifecycle/semantic-registry.d.ts +6 -0
  84. package/dist/src/lifecycle/semantic-registry.js +489 -0
  85. package/dist/src/lifecycle/semantic-registry.js.map +1 -0
  86. package/dist/src/lifecycle/types.d.ts +718 -0
  87. package/dist/src/lifecycle/types.js +4 -0
  88. package/dist/src/lifecycle/types.js.map +1 -0
  89. package/dist/src/observation.d.ts +20 -0
  90. package/dist/src/observation.js +171 -0
  91. package/dist/src/observation.js.map +1 -0
  92. package/dist/src/reviewer.d.ts +43 -1
  93. package/dist/src/reviewer.js +203 -50
  94. package/dist/src/reviewer.js.map +1 -1
  95. package/dist/src/state/corrective-replan-executor.d.ts +64 -0
  96. package/dist/src/state/corrective-replan-executor.js +608 -0
  97. package/dist/src/state/corrective-replan-executor.js.map +1 -0
  98. package/dist/src/state/corrective-replan-public-schema.d.ts +3 -0
  99. package/dist/src/state/corrective-replan-public-schema.js +43 -0
  100. package/dist/src/state/corrective-replan-public-schema.js.map +1 -0
  101. package/dist/src/state/corrective-replan-public.d.ts +95 -0
  102. package/dist/src/state/corrective-replan-public.js +665 -0
  103. package/dist/src/state/corrective-replan-public.js.map +1 -0
  104. package/dist/src/state/corrective-replan-transaction.d.ts +160 -0
  105. package/dist/src/state/corrective-replan-transaction.js +730 -0
  106. package/dist/src/state/corrective-replan-transaction.js.map +1 -0
  107. package/dist/src/state/corrective-yield-executor.d.ts +31 -0
  108. package/dist/src/state/corrective-yield-executor.js +236 -0
  109. package/dist/src/state/corrective-yield-executor.js.map +1 -0
  110. package/dist/src/state/corrective-yield-transaction.d.ts +97 -0
  111. package/dist/src/state/corrective-yield-transaction.js +591 -0
  112. package/dist/src/state/corrective-yield-transaction.js.map +1 -0
  113. package/dist/src/state/lock.d.ts +76 -3
  114. package/dist/src/state/lock.js +611 -30
  115. package/dist/src/state/lock.js.map +1 -1
  116. package/dist/src/state/store.d.ts +3 -0
  117. package/dist/src/state/store.js +65 -12
  118. package/dist/src/state/store.js.map +1 -1
  119. package/dist/src/transition-core.d.ts +67 -0
  120. package/dist/src/transition-core.js +318 -0
  121. package/dist/src/transition-core.js.map +1 -0
  122. package/dist/src/version.d.ts +1 -1
  123. package/dist/src/version.js +1 -1
  124. package/dist/src/version.js.map +1 -1
  125. package/dist/src/workflow.d.ts +83 -24
  126. package/dist/src/workflow.js +1255 -187
  127. package/dist/src/workflow.js.map +1 -1
  128. package/docs/autonomy-guardrails.md +40 -1
  129. package/docs/beta2-initial-assembly-navigation-brief.md +616 -0
  130. package/docs/delegated-approval.md +26 -1
  131. package/docs/development-flow.md +32 -2
  132. package/docs/lifecycle/state-machine-stabilization.md +641 -0
  133. package/docs/release.md +17 -2
  134. package/docs/split-required-recovery.md +5 -4
  135. package/docs/stable-release-defect-register.md +465 -3
  136. package/docs/updating-existing-project.md +59 -4
  137. package/docs/validation-report.md +85 -56
  138. package/package.json +5 -1
  139. package/plugins/codex-workflow-gateway/.codex-plugin/plugin.json +10 -3
  140. package/plugins/codex-workflow-gateway/references/protocol.md +74 -3
  141. package/plugins/codex-workflow-gateway/scripts/chat-registry.mjs +376 -0
  142. package/plugins/codex-workflow-gateway/skills/codex-workflow-gateway/SKILL.md +246 -1
  143. package/references/state-machine.md +4 -1
  144. package/roles/delivery-coordinator.md +39 -0
  145. package/schemas/adoption-posture-event.schema.json +1 -1
  146. package/schemas/context-envelope.schema.json +1 -1
  147. package/schemas/corrective-replan-credentials.private.schema.json +98 -0
  148. package/schemas/corrective-replan-execution-event.private.schema.json +53 -0
  149. package/schemas/corrective-replan-public.schema.json +142 -0
  150. package/schemas/corrective-replan-task-transaction.private.schema.json +151 -0
  151. package/schemas/corrective-yield-task-transaction.private.schema.json +98 -0
  152. package/schemas/remediation-event.schema.json +11 -1
  153. package/schemas/task-handoff-event.schema.json +1 -1
  154. package/schemas/task.schema.json +24 -1
  155. package/schemas/transition-definition.schema.json +2609 -0
  156. package/schemas/transition-payloads.schema.json +140 -0
package/dist/src/cli.js CHANGED
@@ -1,18 +1,203 @@
1
1
  #!/usr/bin/env node
2
- import { createHash } from 'node:crypto';
3
2
  import { readFileSync } from 'node:fs';
4
3
  import path from 'node:path';
5
4
  import process from 'node:process';
6
5
  import { defaultTaskWorkerActor } from './alpha6/handoff.js';
6
+ import { assertCliSuccessCredentialSafety, projectCliErrorMessage, projectCliErrorValue, UnsafeCredentialOutputError, } from './credential-output.js';
7
7
  import { integrationDiagnostics } from './diagnostics.js';
8
8
  import { WorkflowError } from './errors.js';
9
9
  import { prepareGraphView } from './graph.js';
10
10
  import { migrateState } from './migration.js';
11
- import { changedFiles, currentBranch, isClean } from './repository.js';
11
+ import { changedFiles, currentBranch, isClean, resolveRepositoryIdentity } from './repository.js';
12
12
  import { launchStrictReviewer } from './reviewer.js';
13
13
  import { WorkflowService } from './workflow.js';
14
14
  import { PACKAGE_NAME, PACKAGE_VERSION } from './version.js';
15
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
+ };
16
201
  function parseArguments(argv) {
17
202
  const positionals = [];
18
203
  const options = new Map();
@@ -38,6 +223,58 @@ function parseArguments(argv) {
38
223
  function option(args, name) {
39
224
  return args.options.get(name)?.at(-1);
40
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
+ }
41
278
  function required(args, name) {
42
279
  const value = option(args, name)?.trim();
43
280
  if (!value)
@@ -121,6 +358,9 @@ function workflowCapabilities() {
121
358
  'task-context-refresh-v1',
122
359
  'corrective-plan-audit-v1',
123
360
  'safe-update-preflight-v1',
361
+ 'bounded-dependency-provenance-recovery-v1',
362
+ 'retained-reviewed-history-recovery-v1',
363
+ 'milestone-progress-projection-v1',
124
364
  'strict-reviewer-v1',
125
365
  'legacy-snapshot-v1',
126
366
  'plan-risk-audit-sidecar-v1',
@@ -136,6 +376,7 @@ function workflowCapabilities() {
136
376
  'alpha6-adoption-posture-v1',
137
377
  'alpha6-strict-review-rescue-v1',
138
378
  'milestone-initial-assembly-v1',
379
+ 'milestone-initial-assembly-navigation-v2',
139
380
  'milestone-autonomy-contract-v1',
140
381
  'milestone-autonomy-content-refresh-v1',
141
382
  'milestone-autonomous-membership-evolution-v1',
@@ -146,10 +387,16 @@ function workflowCapabilities() {
146
387
  'plan-proof-obligations-v1',
147
388
  'terminal-task-replacement-transaction-v1',
148
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',
149
394
  ];
150
395
  }
151
396
  async function dispatch(args) {
152
397
  const [noun, action] = args.positionals;
398
+ if (args.options.has('help'))
399
+ return cliHelp(args);
153
400
  const repo = repository(args);
154
401
  if (noun === 'gateway' && action === 'handshake') {
155
402
  return {
@@ -162,19 +409,19 @@ async function dispatch(args) {
162
409
  }
163
410
  const workflow = new WorkflowService();
164
411
  if (noun === 'doctor') {
165
- const context = workflow.context(repo);
166
- const integration = integrationDiagnostics(context.identity.repositoryRoot);
412
+ const identity = resolveRepositoryIdentity(repo);
413
+ const integration = integrationDiagnostics(identity.repositoryRoot);
167
414
  const nodeSupported = Number(process.versions.node.split('.')[0]) >= 22;
168
415
  return {
169
416
  ok: nodeSupported && integration.localDependency.current,
170
417
  node: process.versions.node,
171
418
  requiredNode: '>=22',
172
- repositoryRoot: context.identity.repositoryRoot,
173
- projectId: context.identity.projectId,
174
- stateRoot: context.store.root,
175
- branch: currentBranch(context.identity.repositoryRoot),
176
- clean: isClean(context.identity.repositoryRoot),
177
- 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),
178
425
  integration,
179
426
  limitations: [
180
427
  'CLI diagnostics cannot prove that Codex enforced a role, model, sandbox, or read-only reviewer.',
@@ -185,12 +432,18 @@ async function dispatch(args) {
185
432
  if (noun === 'status')
186
433
  return workflow.status(repo);
187
434
  if (noun === 'next')
188
- return workflow.next(repo);
435
+ return workflow.next(repo, option(args, 'task') ?? null);
189
436
  if (noun === 'update' && action === 'preflight')
190
437
  return workflow.updatePreflight(repo);
191
438
  if (noun === 'update' && action === 'rescue-preflight') {
192
439
  return workflow.alpha6StrictReviewRescuePreflight(repo);
193
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
+ }
194
447
  if (noun === 'delegation' && action === 'prepare') {
195
448
  return workflow.prepareDelegation(repo, jsonFile(args));
196
449
  }
@@ -198,12 +451,12 @@ async function dispatch(args) {
198
451
  return workflow.grantDelegation(repo, jsonFile(args), required(args, 'confirmation-code'));
199
452
  }
200
453
  if (noun === 'delegation' && action === 'list') {
201
- const context = workflow.context(repo);
202
- return context.store.listDelegations(context.identity.projectId);
454
+ const identity = resolveRepositoryIdentity(repo);
455
+ return workflow.store.listDelegations(identity.projectId);
203
456
  }
204
457
  if (noun === 'delegation' && action === 'show') {
205
- const context = workflow.context(repo);
206
- 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'));
207
460
  }
208
461
  if (noun === 'delegation' && action === 'revoke') {
209
462
  return workflow.revokeDelegation(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'reason'));
@@ -306,8 +559,8 @@ async function dispatch(args) {
306
559
  return workflow.updateDiscovery(repo, required(args, 'id'), revision(args), patch);
307
560
  }
308
561
  if (noun === 'discovery' && action === 'show') {
309
- const context = workflow.context(repo);
310
- 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'));
311
564
  }
312
565
  if (noun === 'discovery' && action === 'materialize') {
313
566
  const kind = option(args, 'kind') ?? 'task';
@@ -320,8 +573,8 @@ async function dispatch(args) {
320
573
  throw new WorkflowError('INVALID_ARGUMENT', '--kind must be task or milestone.');
321
574
  }
322
575
  if (noun === 'task' && action === 'show') {
323
- const context = workflow.context(repo);
324
- 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'));
325
578
  }
326
579
  if (noun === 'task' && action === 'replacement-materialize') {
327
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');
@@ -351,7 +604,32 @@ async function dispatch(args) {
351
604
  return workflow.startTask(repo, required(args, 'id'), revision(args), owner);
352
605
  }
353
606
  if (noun === 'task' && action === 'run') {
354
- 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
+ };
355
633
  }
356
634
  if (noun === 'task' && action === 'step-complete') {
357
635
  return workflow.completeStep(repo, required(args, 'id'), required(args, 'step'), revision(args), required(args, 'writer-token'), repeated(args, 'note'), option(args, 'actor'));
@@ -364,10 +642,10 @@ async function dispatch(args) {
364
642
  return workflow.recordReview(repo, required(args, 'id'), revision(args), review, option(args, 'actor'), option(args, 'writer-token') ?? null);
365
643
  }
366
644
  if (noun === 'task' && action === 'review-launch') {
367
- const context = workflow.context(repo);
645
+ const identity = resolveRepositoryIdentity(repo);
368
646
  const id = required(args, 'id');
369
647
  const expectedRevision = revision(args);
370
- const task = context.store.readTask(context.identity.projectId, id);
648
+ const task = workflow.store.readTask(identity.projectId, id);
371
649
  if (task.revision !== expectedRevision) {
372
650
  throw new WorkflowError('STATE_CONFLICT', `State revision conflict for ${id}`, {
373
651
  expectedRevision,
@@ -375,13 +653,29 @@ async function dispatch(args) {
375
653
  });
376
654
  }
377
655
  const envelope = workflow.taskContext(repo, id, 'independent-reviewer');
378
- 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.
379
659
  const saved = workflow.recordReview(repo, id, expectedRevision, launch.review, option(args, 'actor'), option(args, 'writer-token') ?? null);
380
660
  return { launch, task: saved };
381
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
+ }
382
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.
383
671
  return workflow.reviewStep(repo, required(args, 'id'), required(args, 'step'), revision(args), undefined, option(args, 'actor'), option(args, 'writer-token') ?? null);
384
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
+ }
385
679
  if (noun === 'task' && action === 'corrective-decision-recover') {
386
680
  return workflow.recoverStepCorrectiveDecision(repo, required(args, 'id'), required(args, 'step'), revision(args), required(args, 'actor'), option(args, 'writer-token') ?? null);
387
681
  }
@@ -391,14 +685,84 @@ async function dispatch(args) {
391
685
  if (noun === 'task' && action === 'corrective-decision') {
392
686
  return workflow.recordStepCorrectiveDecision(repo, required(args, 'id'), required(args, 'step'), revision(args), jsonFile(args), option(args, 'actor'), option(args, 'writer-token') ?? null);
393
687
  }
394
- if (noun === 'task' && (action === 'handoff' || action === 'handoff-prepare')) {
395
- 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
+ };
396
727
  }
397
728
  if (noun === 'task' && action === 'handoff-show') {
398
729
  return workflow.showTaskHandoff(repo, required(args, 'id'));
399
730
  }
400
731
  if (noun === 'task' && action === 'claim') {
401
- 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
+ };
402
766
  }
403
767
  if (noun === 'task' && (action === 'handback' || action === 'handback-create')) {
404
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'
@@ -421,8 +785,11 @@ async function dispatch(args) {
421
785
  return workflow.confirmExternalMerge(repo, required(args, 'id'), revision(args), required(args, 'writer-token'), option(args, 'actor'));
422
786
  }
423
787
  if (noun === 'milestone' && action === 'show') {
424
- const context = workflow.context(repo);
425
- 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'));
426
793
  }
427
794
  if (noun === 'milestone' && action === 'plan-set') {
428
795
  return workflow.setMilestonePlan(repo, required(args, 'id'), revision(args), jsonFile(args));
@@ -455,39 +822,100 @@ async function dispatch(args) {
455
822
  return workflow.cancelMilestone(repo, required(args, 'id'), revision(args), required(args, 'reason'));
456
823
  }
457
824
  if (noun === 'locks' && (action === 'inspect' || action === 'repair')) {
458
- const context = workflow.context(repo);
459
825
  const id = required(args, 'id');
460
- const lease = action === 'inspect' ? context.locks.inspect(id) : context.locks.repairStale(id);
461
- return lease ? {
462
- schemaVersion: lease.schemaVersion,
463
- entityId: lease.entityId,
464
- tokenFingerprint: createHash('sha256').update(lease.token).digest('hex').slice(0, 16),
465
- owner: lease.owner,
466
- pid: lease.pid,
467
- hostname: lease.hostname,
468
- acquiredAt: lease.acquiredAt,
469
- heartbeatAt: lease.heartbeatAt,
470
- expiresAt: lease.expiresAt,
471
- repaired: action === 'repair',
472
- } : null;
826
+ if (action === 'repair')
827
+ return workflow.repairStaleWriterLease(repo, id);
828
+ const inspection = workflow.inspectWriterLease(repo, id);
829
+ return inspection ? { ...inspection, repaired: false } : null;
473
830
  }
474
831
  throw new WorkflowError('INVALID_ARGUMENT', 'Unknown command.', {
475
832
  command: args.positionals.join(' '),
476
833
  hint: 'Use doctor, status, next, update preflight, state <action>, delegation <action>, project-memory <action>, discovery <action>, task <action>, milestone <action>, or locks <action>.',
477
834
  });
478
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
+ }
479
878
  async function main() {
879
+ const argv = process.argv.slice(2);
880
+ const sensitiveInputs = rawCredentialInputs(argv);
480
881
  try {
481
- 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);
482
885
  process.stdout.write(`${JSON.stringify({ ok: true, value }, null, 2)}\n`);
483
886
  }
484
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
+ }
485
900
  if (error instanceof WorkflowError) {
486
- 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`);
487
909
  process.exitCode = 2;
488
910
  return;
489
911
  }
490
- 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`);
491
919
  process.exitCode = 1;
492
920
  }
493
921
  }