codex-workflow-v2 2.0.0-beta.12.8 → 2.0.0-beta.13

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 (124) hide show
  1. package/README.md +60 -16
  2. package/dist/reviewer-runtime-build.json +1092 -0
  3. package/dist/src/alpha6/check-support-anchor.d.ts +24 -0
  4. package/dist/src/alpha6/check-support-anchor.js +102 -0
  5. package/dist/src/alpha6/check-support-anchor.js.map +1 -0
  6. package/dist/src/alpha6/component-owner.d.ts +28 -0
  7. package/dist/src/alpha6/component-owner.js +95 -0
  8. package/dist/src/alpha6/component-owner.js.map +1 -0
  9. package/dist/src/alpha6/downstream-proof.js +4 -2
  10. package/dist/src/alpha6/downstream-proof.js.map +1 -1
  11. package/dist/src/alpha6/mechanical-feasibility.js +42 -12
  12. package/dist/src/alpha6/mechanical-feasibility.js.map +1 -1
  13. package/dist/src/alpha6/milestone.d.ts +6 -2
  14. package/dist/src/alpha6/milestone.js +164 -10
  15. package/dist/src/alpha6/milestone.js.map +1 -1
  16. package/dist/src/alpha6/npm-check-contract.d.ts +11 -0
  17. package/dist/src/alpha6/npm-check-contract.js +36 -0
  18. package/dist/src/alpha6/npm-check-contract.js.map +1 -0
  19. package/dist/src/alpha6/plan-integrity.js +157 -27
  20. package/dist/src/alpha6/plan-integrity.js.map +1 -1
  21. package/dist/src/alpha6/plan-risk.js +3 -1
  22. package/dist/src/alpha6/plan-risk.js.map +1 -1
  23. package/dist/src/alpha6/remediation-cause.d.ts +13 -0
  24. package/dist/src/alpha6/remediation-cause.js +77 -0
  25. package/dist/src/alpha6/remediation-cause.js.map +1 -0
  26. package/dist/src/alpha6/remediation.d.ts +15 -4
  27. package/dist/src/alpha6/remediation.js +430 -67
  28. package/dist/src/alpha6/remediation.js.map +1 -1
  29. package/dist/src/alpha6/review.d.ts +6 -0
  30. package/dist/src/alpha6/review.js +46 -4
  31. package/dist/src/alpha6/review.js.map +1 -1
  32. package/dist/src/artifacts.js +6 -0
  33. package/dist/src/artifacts.js.map +1 -1
  34. package/dist/src/cli-actions.d.ts +25 -0
  35. package/dist/src/cli-actions.js +109 -0
  36. package/dist/src/cli-actions.js.map +1 -0
  37. package/dist/src/cli.js +244 -253
  38. package/dist/src/cli.js.map +1 -1
  39. package/dist/src/contracts.d.ts +202 -5
  40. package/dist/src/credential-transport.d.ts +38 -0
  41. package/dist/src/credential-transport.js +156 -0
  42. package/dist/src/credential-transport.js.map +1 -0
  43. package/dist/src/dependency-provenance.d.ts +23 -2
  44. package/dist/src/dependency-provenance.js +239 -36
  45. package/dist/src/dependency-provenance.js.map +1 -1
  46. package/dist/src/domain/completed-step-carryover.d.ts +13 -0
  47. package/dist/src/domain/completed-step-carryover.js +71 -0
  48. package/dist/src/domain/completed-step-carryover.js.map +1 -0
  49. package/dist/src/domain/validation.d.ts +9 -1
  50. package/dist/src/domain/validation.js +86 -0
  51. package/dist/src/domain/validation.js.map +1 -1
  52. package/dist/src/gateway-handshake.d.ts +11 -0
  53. package/dist/src/gateway-handshake.js +92 -0
  54. package/dist/src/gateway-handshake.js.map +1 -0
  55. package/dist/src/git.js +1 -0
  56. package/dist/src/git.js.map +1 -1
  57. package/dist/src/historical-step-provenance.d.ts +20 -0
  58. package/dist/src/historical-step-provenance.js +111 -0
  59. package/dist/src/historical-step-provenance.js.map +1 -0
  60. package/dist/src/index.d.ts +2 -0
  61. package/dist/src/index.js +2 -0
  62. package/dist/src/index.js.map +1 -1
  63. package/dist/src/lifecycle/corrective-replan-binding-manifest.d.ts +5 -0
  64. package/dist/src/lifecycle/corrective-replan-binding-manifest.js +9 -0
  65. package/dist/src/lifecycle/corrective-replan-binding-manifest.js.map +1 -1
  66. package/dist/src/lifecycle/corrective-replan.js +1 -1
  67. package/dist/src/lifecycle/corrective-replan.js.map +1 -1
  68. package/dist/src/lifecycle/semantic-registry.js +1 -1
  69. package/dist/src/observation.js +1 -2
  70. package/dist/src/observation.js.map +1 -1
  71. package/dist/src/observed-routes.d.ts +114 -0
  72. package/dist/src/observed-routes.js +545 -0
  73. package/dist/src/observed-routes.js.map +1 -0
  74. package/dist/src/operational-contract.d.ts +26 -0
  75. package/dist/src/operational-contract.js +94 -0
  76. package/dist/src/operational-contract.js.map +1 -0
  77. package/dist/src/reviewer.d.ts +218 -8
  78. package/dist/src/reviewer.js +927 -25
  79. package/dist/src/reviewer.js.map +1 -1
  80. package/dist/src/state/corrective-replan-executor.js +23 -15
  81. package/dist/src/state/corrective-replan-executor.js.map +1 -1
  82. package/dist/src/state/corrective-replan-public.js +35 -10
  83. package/dist/src/state/corrective-replan-public.js.map +1 -1
  84. package/dist/src/state/corrective-replan-transaction.js +12 -4
  85. package/dist/src/state/corrective-replan-transaction.js.map +1 -1
  86. package/dist/src/state/corrective-yield-transaction.js +11 -2
  87. package/dist/src/state/corrective-yield-transaction.js.map +1 -1
  88. package/dist/src/state/lock.d.ts +1 -0
  89. package/dist/src/state/lock.js +24 -0
  90. package/dist/src/state/lock.js.map +1 -1
  91. package/dist/src/version.d.ts +1 -1
  92. package/dist/src/version.js +1 -1
  93. package/dist/src/version.js.map +1 -1
  94. package/dist/src/workflow.d.ts +70 -4
  95. package/dist/src/workflow.js +1888 -152
  96. package/dist/src/workflow.js.map +1 -1
  97. package/docs/autonomy-guardrails.md +41 -14
  98. package/docs/delegated-approval.md +6 -1
  99. package/docs/development-flow.md +42 -12
  100. package/docs/pdf/codex-workflow-v2-architecture-ru.pdf +0 -0
  101. package/docs/pdf/codex-workflow-v2-chat-only-guide-ru.pdf +0 -0
  102. package/docs/pdf/codex-workflow-v2-technical-reference-ru.pdf +0 -0
  103. package/docs/pdf/sources/codex-workflow-v2-architecture-ru.md +191 -22
  104. package/docs/pdf/sources/codex-workflow-v2-chat-only-guide-ru.md +163 -45
  105. package/docs/pdf/sources/codex-workflow-v2-technical-reference-ru.md +346 -52
  106. package/docs/problem-briefs/01-pre-implementation-integrity.md +11 -7
  107. package/docs/problem-briefs/04-task-dependency-and-structural-replacement-integrity.md +13 -6
  108. package/docs/problem-briefs/README.md +11 -11
  109. package/docs/release.md +89 -9
  110. package/docs/updating-existing-project.md +235 -0
  111. package/docs/validation-report.md +156 -98
  112. package/package.json +12 -3
  113. package/plugins/codex-workflow-gateway/.codex-plugin/plugin.json +1 -1
  114. package/plugins/codex-workflow-gateway/references/protocol.md +9 -0
  115. package/plugins/codex-workflow-gateway/skills/codex-workflow-gateway/SKILL.md +67 -1
  116. package/schemas/authorization-event.schema.json +10 -3
  117. package/schemas/corrective-decision-event.schema.json +164 -9
  118. package/schemas/corrective-replan-credentials.private.schema.json +4 -2
  119. package/schemas/milestone-scope-change-event.schema.json +25 -1
  120. package/schemas/remediation-event.schema.json +17 -1
  121. package/schemas/review-result.schema.json +1 -0
  122. package/schemas/step-review-event.schema.json +15 -0
  123. package/schemas/task.schema.json +104 -1
  124. package/schemas/transition-definition.schema.json +8 -0
package/dist/src/cli.js CHANGED
@@ -4,106 +4,45 @@ import path from 'node:path';
4
4
  import process from 'node:process';
5
5
  import { defaultTaskWorkerActor } from './alpha6/handoff.js';
6
6
  import { assertCliSuccessCredentialSafety, projectCliErrorMessage, projectCliErrorValue, UnsafeCredentialOutputError, } from './credential-output.js';
7
+ import { assertNoLegacyCredentialArguments, consumeCredentialReference, issueCredentialReference, resolveCredentialReference, } from './credential-transport.js';
7
8
  import { integrationDiagnostics } from './diagnostics.js';
8
9
  import { WorkflowError } from './errors.js';
9
10
  import { prepareGraphView } from './graph.js';
10
11
  import { migrateState } from './migration.js';
11
12
  import { changedFiles, currentBranch, isClean, resolveRepositoryIdentity } from './repository.js';
12
13
  import { launchStrictReviewer } from './reviewer.js';
13
- import { WorkflowService } from './workflow.js';
14
- import { PACKAGE_NAME, PACKAGE_VERSION } from './version.js';
15
- import { PROTOCOL_VERSION, STATE_SCHEMA_VERSION } from './contracts.js';
16
- const CLI_ACTIONS = {
17
- gateway: ['handshake'],
18
- update: [
19
- 'preflight',
20
- 'rescue-preflight',
21
- 'dependency-provenance-preflight',
22
- 'dependency-provenance-recover',
23
- 'downstream-proof-dependency-preflight',
24
- 'downstream-proof-dependency-recover',
25
- 'downstream-proof-replan-update-preflight',
26
- 'downstream-proof-replan-dependency-preflight',
27
- 'downstream-proof-replan-dependency-recover',
28
- ],
29
- delegation: ['prepare', 'grant', 'list', 'show', 'revoke'],
30
- 'project-memory': ['scan', 'show', 'status', 'approve', 'reconcile'],
31
- state: ['migrate', 'adoption-prepare', 'adoption-apply'],
32
- graph: ['prepare', 'status', 'refresh-request', 'bind', 'fallback'],
33
- discovery: ['start', 'update', 'show', 'materialize'],
34
- task: [
35
- 'show',
36
- 'replacement-materialize',
37
- 'plan-set',
38
- 'knowledge-rebind',
39
- 'context-refresh',
40
- 'authorize',
41
- 'plan-risk-audit',
42
- 'start',
43
- 'run',
44
- 'step-complete',
45
- 'submit',
46
- 'review-record',
47
- 'review-launch',
48
- 'review-packet',
49
- 'review-sealed-record',
50
- 'step-review',
51
- 'step-review-packet',
52
- 'step-review-record',
53
- 'corrective-decision-recover',
54
- 'remediation-mode-recover',
55
- 'plan-integrity-recover',
56
- 'downstream-proof-recover',
57
- 'downstream-proof-replan-recover',
58
- 'stop-override-prepare',
59
- 'stop-override-apply',
60
- 'corrective-decision',
61
- 'corrective-yield',
62
- 'corrective-yield-recover',
63
- 'corrective-replan-prepare',
64
- 'corrective-replan-confirm',
65
- 'corrective-replan-execute',
66
- 'corrective-replan-recover',
67
- 'handoff',
68
- 'handoff-prepare',
69
- 'handoff-replace',
70
- 'handoff-show',
71
- 'claim',
72
- 'writer-credential-replace',
73
- 'handback',
74
- 'handback-create',
75
- 'result-set',
76
- 'accept',
77
- 'sync-base',
78
- 'merge',
79
- 'merge-confirm',
80
- ],
81
- milestone: [
82
- 'recover',
83
- 'show',
84
- 'progress',
85
- 'plan-set',
86
- 'scope-change-prepare',
87
- 'scope-change-apply',
88
- 'autonomy-prepare',
89
- 'autonomy-grant',
90
- 'autonomy-evolve',
91
- 'authorize',
92
- 'validate',
93
- 'accept',
94
- 'cancel',
95
- ],
96
- locks: ['inspect', 'repair'],
97
- };
14
+ import { WorkflowService, } from './workflow.js';
15
+ import { gatewayHandshake } from './gateway-handshake.js';
16
+ import { CLI_ACTIONS } from './cli-actions.js';
98
17
  const CLI_HELP_SPECS = {
18
+ 'milestone remediation-materialize': {
19
+ requiredOptions: ['--id', '--expected-revision', '--task', '--expected-task-revision', '--file'],
20
+ optionalOptions: ['--repo', '--json'],
21
+ },
99
22
  'update dependency-provenance-preflight': {
100
23
  requiredOptions: ['--id'],
101
24
  optionalOptions: ['--repo', '--json'],
102
25
  },
26
+ 'task historical-step-provenance-preflight': {
27
+ requiredOptions: ['--id'],
28
+ optionalOptions: ['--repo', '--json'],
29
+ },
30
+ 'task historical-step-provenance-recover': {
31
+ requiredOptions: ['--id', '--expected-revision', '--commit', '--actor', '--reason'],
32
+ optionalOptions: ['--repo', '--json'],
33
+ },
103
34
  'update dependency-provenance-recover': {
104
35
  requiredOptions: ['--id', '--expected-revision', '--actor', '--reason'],
105
36
  optionalOptions: ['--repo', '--json'],
106
37
  },
38
+ 'update historical-step-dependency-preflight': {
39
+ requiredOptions: ['--id'],
40
+ optionalOptions: ['--repo', '--json'],
41
+ },
42
+ 'update historical-step-dependency-recover': {
43
+ requiredOptions: ['--id', '--expected-revision', '--actor', '--reason'],
44
+ optionalOptions: ['--repo', '--json'],
45
+ },
107
46
  'update downstream-proof-dependency-preflight': {
108
47
  requiredOptions: ['--id'],
109
48
  optionalOptions: ['--repo', '--json'],
@@ -124,6 +63,18 @@ const CLI_HELP_SPECS = {
124
63
  requiredOptions: ['--id', '--expected-revision', '--actor', '--reason'],
125
64
  optionalOptions: ['--repo', '--json'],
126
65
  },
66
+ 'update plan-integrity-update-preflight': {
67
+ requiredOptions: ['--id'],
68
+ optionalOptions: ['--repo', '--json'],
69
+ },
70
+ 'update plan-integrity-dependency-preflight': {
71
+ requiredOptions: ['--id'],
72
+ optionalOptions: ['--repo', '--json'],
73
+ },
74
+ 'update plan-integrity-dependency-recover': {
75
+ requiredOptions: ['--id', '--expected-revision', '--actor', '--reason'],
76
+ optionalOptions: ['--repo', '--json'],
77
+ },
127
78
  'milestone progress': {
128
79
  requiredOptions: ['--id'],
129
80
  optionalOptions: ['--repo', '--json'],
@@ -146,22 +97,34 @@ const CLI_HELP_SPECS = {
146
97
  },
147
98
  'task handoff-replace': {
148
99
  requiredOptions: ['--id', '--expected-revision', '--actor', '--target-actor', '--reason'],
149
- optionalOptions: ['--delegation-grant', '--expires-at', '--repo', '--json'],
100
+ optionalOptions: ['--writer-credential-ref', '--delegation-grant', '--expires-at', '--repo', '--json'],
101
+ },
102
+ 'task handoff': {
103
+ requiredOptions: ['--id', '--expected-revision', '--actor', '--reason'],
104
+ optionalOptions: ['--target-actor', '--writer-credential-ref', '--delegation-grant', '--expires-at', '--repo', '--json'],
105
+ },
106
+ 'task handoff-prepare': {
107
+ requiredOptions: ['--id', '--expected-revision', '--actor', '--reason'],
108
+ optionalOptions: ['--target-actor', '--writer-credential-ref', '--delegation-grant', '--expires-at', '--repo', '--json'],
109
+ },
110
+ 'task claim': {
111
+ requiredOptions: ['--id', '--expected-revision', '--actor', '--claim-credential-ref'],
112
+ optionalOptions: ['--writer-credential-ref', '--repo', '--json'],
150
113
  },
151
114
  'task writer-credential-replace': {
152
115
  requiredOptions: ['--id', '--expected-revision', '--actor'],
153
116
  optionalOptions: ['--repo', '--json'],
154
117
  },
155
118
  'task corrective-yield': {
156
- requiredOptions: ['--id', '--expected-revision', '--actor', '--writer-token', '--reason'],
119
+ requiredOptions: ['--id', '--expected-revision', '--actor', '--writer-credential-ref', '--reason'],
157
120
  optionalOptions: ['--repo', '--json'],
158
121
  },
159
122
  'task plan-integrity-recover': {
160
123
  requiredOptions: ['--id', '--step', '--expected-revision', '--actor'],
161
- optionalOptions: ['--writer-token', '--repo', '--json'],
124
+ optionalOptions: ['--writer-credential-ref', '--repo', '--json'],
162
125
  },
163
126
  'task downstream-proof-recover': {
164
- requiredOptions: ['--id', '--expected-revision', '--actor', '--writer-token', '--reason'],
127
+ requiredOptions: ['--id', '--expected-revision', '--actor', '--writer-credential-ref', '--reason'],
165
128
  optionalOptions: ['--repo', '--json'],
166
129
  },
167
130
  'task downstream-proof-replan-recover': {
@@ -206,38 +169,38 @@ const CLI_HELP_SPECS = {
206
169
  },
207
170
  'task run': {
208
171
  requiredOptions: ['--id', '--step', '--expected-revision'],
209
- optionalOptions: ['--owner', '--writer-token', '--repo', '--json'],
172
+ optionalOptions: ['--owner', '--writer-credential-ref', '--repo', '--json'],
210
173
  },
211
174
  'task step-complete': {
212
- requiredOptions: ['--id', '--step', '--expected-revision', '--writer-token'],
175
+ requiredOptions: ['--id', '--step', '--expected-revision', '--writer-credential-ref'],
213
176
  optionalOptions: ['--note', '--actor', '--repo', '--json'],
214
177
  },
215
178
  'task submit': {
216
- requiredOptions: ['--id', '--expected-revision', '--writer-token'],
179
+ requiredOptions: ['--id', '--expected-revision', '--writer-credential-ref'],
217
180
  optionalOptions: ['--actor', '--repo', '--json'],
218
181
  },
219
182
  'task review-launch': {
220
183
  requiredOptions: ['--id', '--expected-revision'],
221
- optionalOptions: ['--actor', '--writer-token', '--repo', '--json'],
184
+ optionalOptions: ['--actor', '--writer-credential-ref', '--repo', '--json'],
222
185
  },
223
186
  'task review-packet': {
224
- requiredOptions: ['--id', '--expected-revision'],
187
+ requiredOptions: ['--id', '--expected-revision', '--review-mode'],
225
188
  optionalOptions: ['--repo', '--json'],
226
189
  },
227
190
  'task review-sealed-record': {
228
191
  requiredOptions: ['--id', '--expected-revision', '--actor', '--file'],
229
- optionalOptions: ['--writer-token', '--repo', '--json'],
192
+ optionalOptions: ['--writer-credential-ref', '--repo', '--json'],
230
193
  },
231
194
  'task step-review-packet': {
232
- requiredOptions: ['--id', '--step', '--expected-revision'],
195
+ requiredOptions: ['--id', '--step', '--expected-revision', '--review-mode'],
233
196
  optionalOptions: ['--repo', '--json'],
234
197
  },
235
198
  'task step-review-record': {
236
199
  requiredOptions: ['--id', '--step', '--expected-revision', '--actor', '--file'],
237
- optionalOptions: ['--writer-token', '--repo', '--json'],
200
+ optionalOptions: ['--writer-credential-ref', '--repo', '--json'],
238
201
  },
239
202
  'task result-set': {
240
- requiredOptions: ['--id', '--expected-revision', '--summary', '--writer-token'],
203
+ requiredOptions: ['--id', '--expected-revision', '--summary', '--writer-credential-ref'],
241
204
  optionalOptions: ['--actor', '--limitation', '--repo', '--json'],
242
205
  },
243
206
  'task accept': {
@@ -245,11 +208,11 @@ const CLI_HELP_SPECS = {
245
208
  optionalOptions: ['--actor', '--delegation-grant', '--repo', '--json'],
246
209
  },
247
210
  'task merge': {
248
- requiredOptions: ['--id', '--expected-revision', '--writer-token'],
211
+ requiredOptions: ['--id', '--expected-revision', '--writer-credential-ref'],
249
212
  optionalOptions: ['--actor', '--repo', '--json'],
250
213
  },
251
214
  'task merge-confirm': {
252
- requiredOptions: ['--id', '--expected-revision', '--writer-token'],
215
+ requiredOptions: ['--id', '--expected-revision', '--writer-credential-ref'],
253
216
  optionalOptions: ['--actor', '--repo', '--json'],
254
217
  },
255
218
  };
@@ -278,6 +241,13 @@ function parseArguments(argv) {
278
241
  function option(args, name) {
279
242
  return args.options.get(name)?.at(-1);
280
243
  }
244
+ function reviewMode(args) {
245
+ const value = required(args, 'review-mode');
246
+ if (value !== 'ordinary' && value !== 'security') {
247
+ throw new WorkflowError('INVALID_ARGUMENT', '--review-mode must be ordinary or security.');
248
+ }
249
+ return value;
250
+ }
281
251
  function cliHelp(args) {
282
252
  const [noun, action] = args.positionals;
283
253
  if (!noun) {
@@ -299,9 +269,11 @@ function cliHelp(args) {
299
269
  command: noun,
300
270
  usage: noun === 'next'
301
271
  ? 'codex-workflow next [--task <task-id>] [--repo <path>] [--json]'
302
- : `codex-workflow ${noun} [--repo <path>] [--json]`,
272
+ : noun === 'status'
273
+ ? 'codex-workflow status [--full] [--repo <path>] [--json]'
274
+ : `codex-workflow ${noun} [--repo <path>] [--json]`,
303
275
  requiredOptions: [],
304
- optionalOptions: [...taskSelector, '--repo', '--json'],
276
+ optionalOptions: [...taskSelector, ...(noun === 'status' ? ['--full'] : []), '--repo', '--json'],
305
277
  exactOptionContractAvailable: true,
306
278
  };
307
279
  }
@@ -401,66 +373,70 @@ function stdinJson() {
401
373
  function repository(args) {
402
374
  return path.resolve(option(args, 'repo') ?? '.');
403
375
  }
404
- function workflowCapabilities() {
405
- return [
406
- 'project-memory-v1',
407
- 'graph-binding-v1',
408
- 'local-state-v1',
409
- 'milestone-lifecycle-v1',
410
- 'milestone-human-final-gate-v1',
411
- 'delegated-approval-v1',
412
- 'task-knowledge-rebind-v1',
413
- 'task-context-refresh-v1',
414
- 'corrective-plan-audit-v1',
415
- 'safe-update-preflight-v1',
416
- 'bounded-dependency-provenance-recovery-v1',
417
- 'task-local-dependency-provenance-recovery-v1',
418
- 'legacy-stop-escalate-override-v1',
419
- 'stop-override-context-rebind-v1',
420
- 'stop-override-context-rebind-chain-v1',
421
- 'stop-override-post-audit-dependency-revision-v1',
422
- 'retained-reviewed-history-recovery-v1',
423
- 'milestone-progress-projection-v1',
424
- 'bounded-plan-integrity-recovery-v1',
425
- 'downstream-proof-predecessor-recovery-v1',
426
- 'downstream-proof-replan-recovery-v1',
427
- 'active-downstream-proof-dependency-recovery-v1',
428
- 'downstream-proof-replan-update-recovery-v1',
429
- 'task-mechanical-feasibility-v1',
430
- 'task-human-gate-lease-release-v1',
431
- 'strict-reviewer-v1',
432
- 'legacy-snapshot-v1',
433
- 'plan-risk-audit-sidecar-v1',
434
- 'step-strict-review-sidecar-v1',
435
- 'step-remediation-circuit-breaker-sidecar-v1',
436
- 'milestone-scope-change-sidecar-v1',
437
- 'milestone-membership-integrity-v1',
438
- 'milestone-task-dependency-dag-v1',
439
- 'milestone-initial-plan-transaction-v1',
440
- 'task-c1-handoff-sidecar-v1',
441
- 'semantic-plan-risk-audit-v2',
442
- 'guarded-remediation-continuation-v1',
443
- 'milestone-reverse-membership-integrity-v1',
444
- 'task-c1-handoff-bundle-v2',
445
- 'alpha6-adoption-posture-v1',
446
- 'alpha6-strict-review-rescue-v1',
447
- 'milestone-initial-assembly-v1',
448
- 'milestone-initial-assembly-navigation-v2',
449
- 'milestone-autonomy-contract-v1',
450
- 'milestone-autonomy-content-refresh-v1',
451
- 'milestone-autonomous-membership-evolution-v1',
452
- 'task-c1-derived-worker-actor-v1',
453
- 'guarded-corrective-auditor-routing-v1',
454
- 'corrective-decision-context-recovery-v1',
455
- 'remediation-mode-recovery-v1',
456
- 'plan-proof-obligations-v1',
457
- 'structural-task-replacement-disabled-v1',
458
- 'project-composite-transaction-journal-v1',
459
- 'corrective-yield-journal-v1',
460
- 'corrective-replan-journal-v1',
461
- 'corrective-replan-human-gate-v1',
462
- 'corrective-replan-protocol-v2',
463
- ];
376
+ const WRITER_CREDENTIAL_ACTIONS = [
377
+ 'task run',
378
+ 'task step-complete',
379
+ 'task submit',
380
+ 'task review-record',
381
+ 'task review-launch',
382
+ 'task review-sealed-record',
383
+ 'task step-review',
384
+ 'task step-review-record',
385
+ 'task corrective-decision-recover',
386
+ 'task remediation-mode-recover',
387
+ 'task plan-integrity-recover',
388
+ 'task downstream-proof-recover',
389
+ 'task corrective-decision',
390
+ 'task corrective-yield',
391
+ 'task handoff',
392
+ 'task handoff-prepare',
393
+ 'task handoff-replace',
394
+ 'task claim',
395
+ 'task handback',
396
+ 'task handback-create',
397
+ 'task result-set',
398
+ 'task merge',
399
+ 'task merge-confirm',
400
+ ];
401
+ function credentialToken(workflow, repo, args, kind, action, entityId, actor, requiredReference) {
402
+ const optionName = kind === 'writer-lease' ? 'writer-credential-ref' : 'claim-credential-ref';
403
+ const reference = option(args, optionName);
404
+ if (!reference) {
405
+ if (requiredReference) {
406
+ throw new WorkflowError('INVALID_ARGUMENT', `Missing required option --${optionName}.`);
407
+ }
408
+ return null;
409
+ }
410
+ const identity = resolveRepositoryIdentity(repo);
411
+ return resolveCredentialReference({
412
+ stateRoot: workflow.store.root,
413
+ projectId: identity.projectId,
414
+ reference,
415
+ kind,
416
+ entityId,
417
+ actor,
418
+ action,
419
+ }).token;
420
+ }
421
+ function writerCredentialReceipt(workflow, repo, taskId, actor, token, expiresAt) {
422
+ const identity = resolveRepositoryIdentity(repo);
423
+ return issueCredentialReference({
424
+ stateRoot: workflow.store.root,
425
+ projectId: identity.projectId,
426
+ entityId: taskId,
427
+ actor,
428
+ kind: 'writer-lease',
429
+ token,
430
+ allowedActions: WRITER_CREDENTIAL_ACTIONS,
431
+ expiresAt,
432
+ oneTime: false,
433
+ });
434
+ }
435
+ function consumeCredentialOption(workflow, repo, args, optionName) {
436
+ const reference = option(args, optionName);
437
+ if (!reference)
438
+ return;
439
+ consumeCredentialReference(workflow.store.root, resolveRepositoryIdentity(repo).projectId, reference);
464
440
  }
465
441
  async function dispatch(args) {
466
442
  const [noun, action] = args.positionals;
@@ -468,13 +444,7 @@ async function dispatch(args) {
468
444
  return cliHelp(args);
469
445
  const repo = repository(args);
470
446
  if (noun === 'gateway' && action === 'handshake') {
471
- return {
472
- packageName: PACKAGE_NAME,
473
- packageVersion: PACKAGE_VERSION,
474
- protocolVersion: PROTOCOL_VERSION,
475
- stateSchemaVersion: STATE_SCHEMA_VERSION,
476
- capabilities: workflowCapabilities(),
477
- };
447
+ return gatewayHandshake();
478
448
  }
479
449
  const workflow = new WorkflowService();
480
450
  if (noun === 'doctor') {
@@ -499,7 +469,7 @@ async function dispatch(args) {
499
469
  };
500
470
  }
501
471
  if (noun === 'status')
502
- return workflow.status(repo);
472
+ return args.options.has('full') ? workflow.status(repo) : workflow.compactStatus(repo);
503
473
  if (noun === 'next')
504
474
  return workflow.next(repo, option(args, 'task') ?? null);
505
475
  if (noun === 'update' && action === 'preflight')
@@ -510,9 +480,21 @@ async function dispatch(args) {
510
480
  if (noun === 'update' && action === 'dependency-provenance-preflight') {
511
481
  return workflow.dependencyProvenanceRecoveryPreflight(repo, required(args, 'id'));
512
482
  }
483
+ if (noun === 'task' && action === 'historical-step-provenance-preflight') {
484
+ return workflow.historicalStepProvenanceRecoveryPreflight(repo, required(args, 'id'));
485
+ }
486
+ if (noun === 'task' && action === 'historical-step-provenance-recover') {
487
+ return workflow.recoverHistoricalStepProvenance(repo, required(args, 'id'), revision(args), required(args, 'commit'), required(args, 'actor'), required(args, 'reason'));
488
+ }
513
489
  if (noun === 'update' && action === 'dependency-provenance-recover') {
514
490
  return workflow.recoverDependencyProvenance(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'reason'));
515
491
  }
492
+ if (noun === 'update' && action === 'historical-step-dependency-preflight') {
493
+ return workflow.historicalStepDependencyRecoveryPreflight(repo, required(args, 'id'));
494
+ }
495
+ if (noun === 'update' && action === 'historical-step-dependency-recover') {
496
+ return workflow.recoverHistoricalStepDependencyProvenance(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'reason'));
497
+ }
516
498
  if (noun === 'update' && action === 'downstream-proof-dependency-preflight') {
517
499
  return workflow.activeDownstreamProofDependencyRecoveryPreflight(repo, required(args, 'id'));
518
500
  }
@@ -528,6 +510,15 @@ async function dispatch(args) {
528
510
  if (noun === 'update' && action === 'downstream-proof-replan-dependency-recover') {
529
511
  return workflow.recoverDownstreamProofReplanDependencyProvenance(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'reason'));
530
512
  }
513
+ if (noun === 'update' && action === 'plan-integrity-update-preflight') {
514
+ return workflow.planIntegrityUpdatePreflight(repo, required(args, 'id'));
515
+ }
516
+ if (noun === 'update' && action === 'plan-integrity-dependency-preflight') {
517
+ return workflow.planIntegrityDependencyRecoveryPreflight(repo, required(args, 'id'));
518
+ }
519
+ if (noun === 'update' && action === 'plan-integrity-dependency-recover') {
520
+ return workflow.recoverPlanIntegrityDependencyProvenance(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'reason'));
521
+ }
531
522
  if (noun === 'delegation' && action === 'prepare') {
532
523
  return workflow.prepareDelegation(repo, jsonFile(args));
533
524
  }
@@ -688,7 +679,9 @@ async function dispatch(args) {
688
679
  return workflow.startTask(repo, required(args, 'id'), revision(args), owner);
689
680
  }
690
681
  if (noun === 'task' && action === 'run') {
691
- const outcome = workflow.runStep(repo, required(args, 'id'), required(args, 'step'), revision(args), option(args, 'owner') ?? 'worker', option(args, 'writer-token') ?? null);
682
+ const taskId = required(args, 'id');
683
+ const owner = option(args, 'owner') ?? 'worker';
684
+ const outcome = workflow.runStep(repo, taskId, required(args, 'step'), revision(args), owner, credentialToken(workflow, repo, args, 'writer-lease', 'task run', taskId, owner, false));
692
685
  const { writerToken, ...envelope } = outcome.envelope;
693
686
  if (outcome.writerCredential.disposition === 'issued' && !writerToken) {
694
687
  throw new WorkflowError('STATE_CORRUPT', 'Fresh task run credential issuance did not return its protocol-v1 writer token.');
@@ -699,16 +692,7 @@ async function dispatch(args) {
699
692
  return {
700
693
  writerCredential: { disposition: outcome.writerCredential.disposition },
701
694
  ...(writerToken ? {
702
- writerLeaseReceipt: {
703
- token: writerToken,
704
- kind: 'writer-lease',
705
- owner: outcome.lease.owner,
706
- action: 'task step-complete',
707
- option: '--writer-token',
708
- source: 'task run',
709
- sensitive: true,
710
- oneTime: false,
711
- },
695
+ writerCredentialReference: writerCredentialReceipt(workflow, repo, taskId, outcome.lease.owner, writerToken, outcome.lease.expiresAt),
712
696
  } : {}),
713
697
  task: outcome.task,
714
698
  lease: outcome.lease,
@@ -716,14 +700,16 @@ async function dispatch(args) {
716
700
  };
717
701
  }
718
702
  if (noun === 'task' && action === 'step-complete') {
719
- return workflow.completeStep(repo, required(args, 'id'), required(args, 'step'), revision(args), required(args, 'writer-token'), repeated(args, 'note'), option(args, 'actor'));
703
+ const taskId = required(args, 'id');
704
+ return workflow.completeStep(repo, taskId, required(args, 'step'), revision(args), credentialToken(workflow, repo, args, 'writer-lease', 'task step-complete', taskId, option(args, 'actor') ?? null, true), repeated(args, 'note'), option(args, 'actor'));
720
705
  }
721
706
  if (noun === 'task' && action === 'submit') {
722
- return workflow.submitTask(repo, required(args, 'id'), revision(args), required(args, 'writer-token'), option(args, 'actor'));
707
+ const taskId = required(args, 'id');
708
+ return workflow.submitTask(repo, taskId, revision(args), credentialToken(workflow, repo, args, 'writer-lease', 'task submit', taskId, option(args, 'actor') ?? null, true), option(args, 'actor'));
723
709
  }
724
710
  if (noun === 'task' && action === 'review-record') {
725
711
  const review = jsonFile(args);
726
- return workflow.recordReview(repo, required(args, 'id'), revision(args), review, option(args, 'actor'), option(args, 'writer-token') ?? null);
712
+ return workflow.recordReview(repo, required(args, 'id'), revision(args), review, option(args, 'actor'), credentialToken(workflow, repo, args, 'writer-lease', 'task review-record', required(args, 'id'), option(args, 'actor') ?? null, false));
727
713
  }
728
714
  if (noun === 'task' && action === 'review-launch') {
729
715
  const identity = resolveRepositoryIdentity(repo);
@@ -740,37 +726,45 @@ async function dispatch(args) {
740
726
  const launch = launchStrictReviewer(identity.repositoryRoot, task, workflow.store.taskRoot(task.projectId, task.id), envelope);
741
727
  // The independent reviewer identity belongs to the strict reviewer payload. CLI --actor
742
728
  // remains the lifecycle mutation actor, such as the current C1 claimant.
743
- const saved = workflow.recordReview(repo, id, expectedRevision, launch.review, option(args, 'actor'), option(args, 'writer-token') ?? null);
729
+ const saved = workflow.recordReview(repo, id, expectedRevision, launch.review, option(args, 'actor'), credentialToken(workflow, repo, args, 'writer-lease', 'task review-launch', id, option(args, 'actor') ?? null, false));
744
730
  return { launch, task: saved };
745
731
  }
746
732
  if (noun === 'task' && action === 'review-packet') {
747
- return workflow.prepareExternalTaskReview(repo, required(args, 'id'), revision(args));
733
+ return workflow.prepareExternalTaskReview(repo, required(args, 'id'), revision(args), reviewMode(args));
748
734
  }
749
735
  if (noun === 'task' && action === 'review-sealed-record') {
750
- return workflow.recordExternalTaskReview(repo, required(args, 'id'), revision(args), jsonFile(args), required(args, 'actor'), option(args, 'writer-token') ?? null);
736
+ return workflow.recordExternalTaskReview(repo, required(args, 'id'), revision(args), jsonFile(args), required(args, 'actor'), credentialToken(workflow, repo, args, 'writer-lease', 'task review-sealed-record', required(args, 'id'), required(args, 'actor'), false));
751
737
  }
752
738
  if (noun === 'task' && action === 'step-review') {
753
739
  // Strict Step Review launches and records the isolated reviewer inside Core. CLI --actor
754
740
  // remains the lifecycle actor from next, typically the active C1 claimant.
755
- return workflow.reviewStep(repo, required(args, 'id'), required(args, 'step'), revision(args), undefined, option(args, 'actor'), option(args, 'writer-token') ?? null);
741
+ return workflow.reviewStep(repo, required(args, 'id'), required(args, 'step'), revision(args), undefined, option(args, 'actor'), credentialToken(workflow, repo, args, 'writer-lease', 'task step-review', required(args, 'id'), option(args, 'actor') ?? null, false));
756
742
  }
757
743
  if (noun === 'task' && action === 'step-review-packet') {
758
- return workflow.prepareExternalStepReview(repo, required(args, 'id'), required(args, 'step'), revision(args));
744
+ return workflow.prepareExternalStepReview(repo, required(args, 'id'), required(args, 'step'), revision(args), reviewMode(args));
759
745
  }
760
746
  if (noun === 'task' && action === 'step-review-record') {
761
- return workflow.recordExternalStepReview(repo, required(args, 'id'), required(args, 'step'), revision(args), jsonFile(args), required(args, 'actor'), option(args, 'writer-token') ?? null);
747
+ return workflow.recordExternalStepReview(repo, required(args, 'id'), required(args, 'step'), revision(args), jsonFile(args), required(args, 'actor'), credentialToken(workflow, repo, args, 'writer-lease', 'task step-review-record', required(args, 'id'), required(args, 'actor'), false));
762
748
  }
763
749
  if (noun === 'task' && action === 'corrective-decision-recover') {
764
- return workflow.recoverStepCorrectiveDecision(repo, required(args, 'id'), required(args, 'step'), revision(args), required(args, 'actor'), option(args, 'writer-token') ?? null);
750
+ const taskId = required(args, 'id');
751
+ const actor = required(args, 'actor');
752
+ return workflow.recoverStepCorrectiveDecision(repo, taskId, required(args, 'step'), revision(args), actor, credentialToken(workflow, repo, args, 'writer-lease', 'task corrective-decision-recover', taskId, actor, false));
765
753
  }
766
754
  if (noun === 'task' && action === 'remediation-mode-recover') {
767
- return workflow.recoverRemediationMode(repo, required(args, 'id'), required(args, 'step'), revision(args), required(args, 'actor'), option(args, 'writer-token') ?? null);
755
+ const taskId = required(args, 'id');
756
+ const actor = required(args, 'actor');
757
+ return workflow.recoverRemediationMode(repo, taskId, required(args, 'step'), revision(args), actor, credentialToken(workflow, repo, args, 'writer-lease', 'task remediation-mode-recover', taskId, actor, false));
768
758
  }
769
759
  if (noun === 'task' && action === 'plan-integrity-recover') {
770
- return workflow.recoverPlanIntegrity(repo, required(args, 'id'), required(args, 'step'), revision(args), required(args, 'actor'), option(args, 'writer-token') ?? null);
760
+ const taskId = required(args, 'id');
761
+ const actor = required(args, 'actor');
762
+ return workflow.recoverPlanIntegrity(repo, taskId, required(args, 'step'), revision(args), actor, credentialToken(workflow, repo, args, 'writer-lease', 'task plan-integrity-recover', taskId, actor, false));
771
763
  }
772
764
  if (noun === 'task' && action === 'downstream-proof-recover') {
773
- return workflow.recoverDownstreamProof(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'writer-token'), required(args, 'reason'));
765
+ const taskId = required(args, 'id');
766
+ const actor = required(args, 'actor');
767
+ return workflow.recoverDownstreamProof(repo, taskId, revision(args), actor, credentialToken(workflow, repo, args, 'writer-lease', 'task downstream-proof-recover', taskId, actor, true), required(args, 'reason'));
774
768
  }
775
769
  if (noun === 'task' && action === 'downstream-proof-replan-recover') {
776
770
  return workflow.recoverDownstreamProofReplan(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'reason'));
@@ -782,10 +776,15 @@ async function dispatch(args) {
782
776
  return workflow.applyTaskStopOverride(repo, required(args, 'id'), required(args, 'step'), revision(args), required(args, 'actor'), required(args, 'reason'), required(args, 'confirmation-code'));
783
777
  }
784
778
  if (noun === 'task' && action === 'corrective-decision') {
785
- return workflow.recordStepCorrectiveDecision(repo, required(args, 'id'), required(args, 'step'), revision(args), jsonFile(args), option(args, 'actor'), option(args, 'writer-token') ?? null);
779
+ const taskId = required(args, 'id');
780
+ return workflow.recordStepCorrectiveDecision(repo, taskId, required(args, 'step'), revision(args), jsonFile(args), option(args, 'actor'), credentialToken(workflow, repo, args, 'writer-lease', 'task corrective-decision', taskId, option(args, 'actor') ?? null, false));
786
781
  }
787
782
  if (noun === 'task' && action === 'corrective-yield') {
788
- return workflow.executeCorrectiveYield(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'writer-token'), required(args, 'reason'));
783
+ const taskId = required(args, 'id');
784
+ const actor = required(args, 'actor');
785
+ const outcome = workflow.executeCorrectiveYield(repo, taskId, revision(args), actor, credentialToken(workflow, repo, args, 'writer-lease', 'task corrective-yield', taskId, actor, true), required(args, 'reason'));
786
+ consumeCredentialOption(workflow, repo, args, 'writer-credential-ref');
787
+ return outcome;
789
788
  }
790
789
  if (noun === 'task' && action === 'corrective-yield-recover') {
791
790
  return workflow.recoverCorrectiveYield(repo, required(args, 'id'), required(args, 'transaction-id'));
@@ -804,21 +803,27 @@ async function dispatch(args) {
804
803
  }
805
804
  if (noun === 'task' && (action === 'handoff' || action === 'handoff-prepare' || action === 'handoff-replace')) {
806
805
  const replacePending = action === 'handoff-replace';
807
- const outcome = workflow.handoffTask(repo, required(args, 'id'), revision(args), required(args, 'actor'), replacePending
806
+ const taskId = required(args, 'id');
807
+ const actor = required(args, 'actor');
808
+ const targetActor = replacePending
808
809
  ? required(args, 'target-actor')
809
- : 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);
810
+ : option(args, 'target-actor') ?? defaultTaskWorkerActor(taskId);
811
+ const outcome = workflow.handoffTask(repo, taskId, revision(args), actor, targetActor, required(args, 'reason'), credentialToken(workflow, repo, args, 'writer-lease', `task ${action}`, taskId, actor, false), option(args, 'delegation-grant') ?? null, option(args, 'expires-at') ?? null, replacePending);
812
+ consumeCredentialOption(workflow, repo, args, 'writer-credential-ref');
810
813
  const { claimToken, ...bundle } = outcome.bundle;
814
+ const identity = resolveRepositoryIdentity(repo);
811
815
  return {
812
- credentialHandoff: {
813
- token: claimToken,
816
+ claimCredentialReference: issueCredentialReference({
817
+ stateRoot: workflow.store.root,
818
+ projectId: identity.projectId,
819
+ entityId: taskId,
820
+ actor: outcome.bundle.delegate,
814
821
  kind: 'claim-token',
815
- targetActor: outcome.bundle.delegate,
816
- action: 'task claim',
817
- option: '--claim-token',
818
- source: replacePending ? 'task handoff-replace' : 'task handoff-prepare',
819
- sensitive: true,
822
+ token: claimToken,
823
+ allowedActions: ['task claim'],
824
+ expiresAt: outcome.bundle.expiresAt,
820
825
  oneTime: true,
821
- },
826
+ }),
822
827
  task: outcome.task,
823
828
  event: outcome.event,
824
829
  bundle,
@@ -828,20 +833,15 @@ async function dispatch(args) {
828
833
  return workflow.showTaskHandoff(repo, required(args, 'id'));
829
834
  }
830
835
  if (noun === 'task' && action === 'claim') {
831
- const outcome = workflow.claimTask(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'claim-token'), option(args, 'writer-token') ?? null);
836
+ const taskId = required(args, 'id');
837
+ const actor = required(args, 'actor');
838
+ const claimToken = credentialToken(workflow, repo, args, 'claim-token', 'task claim', taskId, actor, true);
839
+ const outcome = workflow.claimTask(repo, taskId, revision(args), actor, claimToken, credentialToken(workflow, repo, args, 'writer-lease', 'task claim', taskId, actor, false));
840
+ consumeCredentialOption(workflow, repo, args, 'claim-credential-ref');
832
841
  return {
833
842
  writerCredential: { disposition: outcome.writerCredential.disposition },
834
843
  ...(outcome.writerCredential.disposition === 'issued' ? {
835
- writerLeaseReceipt: {
836
- token: outcome.writerCredential.token,
837
- kind: 'writer-lease',
838
- owner: outcome.lease.owner,
839
- action: 'task run',
840
- option: '--writer-token',
841
- source: 'task claim',
842
- sensitive: true,
843
- oneTime: false,
844
- },
844
+ writerCredentialReference: writerCredentialReceipt(workflow, repo, taskId, outcome.lease.owner, outcome.writerCredential.token, outcome.lease.expiresAt),
845
845
  } : {}),
846
846
  task: outcome.task,
847
847
  event: outcome.event,
@@ -849,27 +849,30 @@ async function dispatch(args) {
849
849
  };
850
850
  }
851
851
  if (noun === 'task' && action === 'writer-credential-replace') {
852
- const outcome = workflow.replaceClaimedWriterCredential(repo, required(args, 'id'), revision(args), required(args, 'actor'));
852
+ const taskId = required(args, 'id');
853
+ const actor = required(args, 'actor');
854
+ const outcome = workflow.replaceClaimedWriterCredential(repo, taskId, revision(args), actor);
853
855
  return {
854
856
  writerCredential: { disposition: outcome.writerCredential.disposition },
855
- writerLeaseReceipt: {
856
- token: outcome.writerCredential.token,
857
- kind: 'writer-lease',
858
- source: 'task writer-credential-replace',
859
- sensitive: true,
860
- oneTime: false,
861
- },
857
+ writerCredentialReference: writerCredentialReceipt(workflow, repo, taskId, outcome.lease.owner, outcome.writerCredential.token, outcome.lease.expiresAt),
862
858
  task: outcome.task,
863
859
  lease: outcome.lease,
864
860
  };
865
861
  }
866
862
  if (noun === 'task' && (action === 'handback' || action === 'handback-create')) {
867
- 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'
863
+ const taskId = required(args, 'id');
864
+ const actor = required(args, 'actor');
865
+ const outcome = workflow.handbackTask(repo, taskId, revision(args), actor, required(args, 'reason'), credentialToken(workflow, repo, args, 'writer-lease', `task ${action}`, taskId, actor, false), repeated(args, 'limitation'), action === 'handback-create'
868
866
  ? required(args, 'recommended-next')
869
867
  : option(args, 'recommended-next') ?? 'Coordinator reviews the terminal Task result and recorded evidence.');
868
+ consumeCredentialOption(workflow, repo, args, 'writer-credential-ref');
869
+ return outcome;
870
870
  }
871
871
  if (noun === 'task' && action === 'result-set') {
872
- return workflow.setTaskResult(repo, required(args, 'id'), revision(args), required(args, 'summary'), repeated(args, 'limitation'), required(args, 'writer-token'), option(args, 'actor'));
872
+ const taskId = required(args, 'id');
873
+ const outcome = workflow.setTaskResult(repo, taskId, revision(args), required(args, 'summary'), repeated(args, 'limitation'), credentialToken(workflow, repo, args, 'writer-lease', 'task result-set', taskId, option(args, 'actor') ?? null, true), option(args, 'actor'));
874
+ consumeCredentialOption(workflow, repo, args, 'writer-credential-ref');
875
+ return outcome;
873
876
  }
874
877
  if (noun === 'task' && action === 'accept') {
875
878
  return workflow.acceptTask(repo, required(args, 'id'), revision(args), option(args, 'actor') ?? 'user', option(args, 'delegation-grant') ?? null);
@@ -878,10 +881,16 @@ async function dispatch(args) {
878
881
  return workflow.syncTaskBase(repo, required(args, 'id'), revision(args));
879
882
  }
880
883
  if (noun === 'task' && action === 'merge') {
881
- return workflow.mergeTask(repo, required(args, 'id'), revision(args), required(args, 'writer-token'), option(args, 'actor'));
884
+ const taskId = required(args, 'id');
885
+ const outcome = workflow.mergeTask(repo, taskId, revision(args), credentialToken(workflow, repo, args, 'writer-lease', 'task merge', taskId, option(args, 'actor') ?? null, true), option(args, 'actor'));
886
+ consumeCredentialOption(workflow, repo, args, 'writer-credential-ref');
887
+ return outcome;
882
888
  }
883
889
  if (noun === 'task' && action === 'merge-confirm') {
884
- return workflow.confirmExternalMerge(repo, required(args, 'id'), revision(args), required(args, 'writer-token'), option(args, 'actor'));
890
+ const taskId = required(args, 'id');
891
+ const outcome = workflow.confirmExternalMerge(repo, taskId, revision(args), credentialToken(workflow, repo, args, 'writer-lease', 'task merge-confirm', taskId, option(args, 'actor') ?? null, true), option(args, 'actor'));
892
+ consumeCredentialOption(workflow, repo, args, 'writer-credential-ref');
893
+ return outcome;
885
894
  }
886
895
  if (noun === 'milestone' && action === 'show') {
887
896
  const identity = resolveRepositoryIdentity(repo);
@@ -893,6 +902,9 @@ async function dispatch(args) {
893
902
  if (noun === 'milestone' && action === 'plan-set') {
894
903
  return workflow.setMilestonePlan(repo, required(args, 'id'), revision(args), jsonFile(args));
895
904
  }
905
+ if (noun === 'milestone' && action === 'remediation-materialize') {
906
+ return workflow.materializeAuditedRemediationTask(repo, required(args, 'id'), revision(args), required(args, 'task'), positiveIntegerOption(args, 'expected-task-revision'), jsonFile(args));
907
+ }
896
908
  if (noun === 'milestone' && action === 'scope-change-prepare') {
897
909
  return workflow.prepareMilestoneScopeChange(repo, required(args, 'id'), revision(args), jsonFile(args), required(args, 'actor'));
898
910
  }
@@ -932,30 +944,8 @@ async function dispatch(args) {
932
944
  hint: 'Use doctor, status, next, update preflight, state <action>, delegation <action>, project-memory <action>, discovery <action>, task <action>, milestone <action>, or locks <action>.',
933
945
  });
934
946
  }
935
- function credentialAllowancesForResult(args, value) {
936
- const [noun, action] = args.positionals;
937
- if (!isRecord(value))
938
- return [];
939
- if (noun === 'task' && (action === 'run' || action === 'claim' || action === 'writer-credential-replace')) {
940
- const disposition = isRecord(value.writerCredential) ? value.writerCredential.disposition : null;
941
- const receipt = isRecord(value.writerLeaseReceipt) ? value.writerLeaseReceipt : null;
942
- if (disposition === 'issued'
943
- && receipt?.kind === 'writer-lease'
944
- && receipt.source === `task ${action}`
945
- && receipt.sensitive === true) {
946
- return [{ path: '$.writerLeaseReceipt.token' }];
947
- }
948
- return [];
949
- }
950
- if (noun === 'task' && (action === 'handoff' || action === 'handoff-prepare' || action === 'handoff-replace')) {
951
- const receipt = isRecord(value.credentialHandoff) ? value.credentialHandoff : null;
952
- if (receipt?.kind === 'claim-token'
953
- && receipt.source === (action === 'handoff-replace' ? 'task handoff-replace' : 'task handoff-prepare')
954
- && receipt.sensitive === true
955
- && receipt.oneTime === true) {
956
- return [{ path: '$.credentialHandoff.token' }];
957
- }
958
- }
947
+ function credentialAllowancesForResult(_args, _value) {
948
+ // Beta 13 has no CLI issuance allowance: the host receives reference metadata only.
959
949
  return [];
960
950
  }
961
951
  function rawCredentialInputs(argv) {
@@ -979,6 +969,7 @@ async function main() {
979
969
  const sensitiveInputs = rawCredentialInputs(argv);
980
970
  try {
981
971
  const args = parseArguments(argv);
972
+ assertNoLegacyCredentialArguments(new Set(args.options.keys()));
982
973
  const value = await dispatch(args);
983
974
  assertCliSuccessCredentialSafety(value, credentialAllowancesForResult(args, value), sensitiveInputs);
984
975
  process.stdout.write(`${JSON.stringify({ ok: true, value }, null, 2)}\n`);