codex-workflow-v2 2.0.0-beta.1 → 2.0.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -3
- package/dist/src/alpha6/adoption.js +13 -3
- package/dist/src/alpha6/adoption.js.map +1 -1
- package/dist/src/alpha6/handoff.d.ts +21 -0
- package/dist/src/alpha6/handoff.js +100 -19
- package/dist/src/alpha6/handoff.js.map +1 -1
- package/dist/src/alpha6/milestone.d.ts +12 -0
- package/dist/src/alpha6/milestone.js +113 -1
- package/dist/src/alpha6/milestone.js.map +1 -1
- package/dist/src/alpha6/plan-risk.d.ts +1 -0
- package/dist/src/alpha6/plan-risk.js +6 -0
- package/dist/src/alpha6/plan-risk.js.map +1 -1
- package/dist/src/cli.js +383 -43
- package/dist/src/cli.js.map +1 -1
- package/dist/src/contracts.d.ts +111 -5
- package/dist/src/contracts.js +1 -1
- package/dist/src/credential-output.d.ts +10 -0
- package/dist/src/credential-output.js +73 -0
- package/dist/src/credential-output.js.map +1 -0
- package/dist/src/errors.d.ts +1 -1
- package/dist/src/errors.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/lifecycle/canonical-hash.d.ts +6 -0
- package/dist/src/lifecycle/canonical-hash.js +24 -0
- package/dist/src/lifecycle/canonical-hash.js.map +1 -0
- package/dist/src/lifecycle/catalog.d.ts +26 -0
- package/dist/src/lifecycle/catalog.js +208 -0
- package/dist/src/lifecycle/catalog.js.map +1 -0
- package/dist/src/lifecycle/compiler-inspection.d.ts +48 -0
- package/dist/src/lifecycle/compiler-inspection.js +29 -0
- package/dist/src/lifecycle/compiler-inspection.js.map +1 -0
- package/dist/src/lifecycle/core-static-readiness.d.ts +6 -0
- package/dist/src/lifecycle/core-static-readiness.js +130 -0
- package/dist/src/lifecycle/core-static-readiness.js.map +1 -0
- package/dist/src/lifecycle/corrective-replan-authority.d.ts +53 -0
- package/dist/src/lifecycle/corrective-replan-authority.js +139 -0
- package/dist/src/lifecycle/corrective-replan-authority.js.map +1 -0
- package/dist/src/lifecycle/corrective-replan-binding-manifest.d.ts +21 -0
- package/dist/src/lifecycle/corrective-replan-binding-manifest.js +35 -0
- package/dist/src/lifecycle/corrective-replan-binding-manifest.js.map +1 -0
- package/dist/src/lifecycle/corrective-replan-credential-core.d.ts +86 -0
- package/dist/src/lifecycle/corrective-replan-credential-core.js +534 -0
- package/dist/src/lifecycle/corrective-replan-credential-core.js.map +1 -0
- package/dist/src/lifecycle/corrective-replan-credential-schema.d.ts +17 -0
- package/dist/src/lifecycle/corrective-replan-credential-schema.js +44 -0
- package/dist/src/lifecycle/corrective-replan-credential-schema.js.map +1 -0
- package/dist/src/lifecycle/corrective-replan-credentials.d.ts +47 -0
- package/dist/src/lifecycle/corrective-replan-credentials.js +103 -0
- package/dist/src/lifecycle/corrective-replan-credentials.js.map +1 -0
- package/dist/src/lifecycle/corrective-replan.d.ts +64 -0
- package/dist/src/lifecycle/corrective-replan.js +548 -0
- package/dist/src/lifecycle/corrective-replan.js.map +1 -0
- package/dist/src/lifecycle/evaluator.d.ts +2 -0
- package/dist/src/lifecycle/evaluator.js +35 -0
- package/dist/src/lifecycle/evaluator.js.map +1 -0
- package/dist/src/lifecycle/fingerprint.d.ts +31 -0
- package/dist/src/lifecycle/fingerprint.js +388 -0
- package/dist/src/lifecycle/fingerprint.js.map +1 -0
- package/dist/src/lifecycle/immutable.d.ts +1 -0
- package/dist/src/lifecycle/immutable.js +10 -0
- package/dist/src/lifecycle/immutable.js.map +1 -0
- package/dist/src/lifecycle/implementation-table.d.ts +29 -0
- package/dist/src/lifecycle/implementation-table.js +87 -0
- package/dist/src/lifecycle/implementation-table.js.map +1 -0
- package/dist/src/lifecycle/index.d.ts +4 -0
- package/dist/src/lifecycle/index.js +5 -0
- package/dist/src/lifecycle/index.js.map +1 -0
- package/dist/src/lifecycle/schema-artifact.d.ts +12 -0
- package/dist/src/lifecycle/schema-artifact.js +214 -0
- package/dist/src/lifecycle/schema-artifact.js.map +1 -0
- package/dist/src/lifecycle/semantic-registry.d.ts +6 -0
- package/dist/src/lifecycle/semantic-registry.js +489 -0
- package/dist/src/lifecycle/semantic-registry.js.map +1 -0
- package/dist/src/lifecycle/types.d.ts +718 -0
- package/dist/src/lifecycle/types.js +4 -0
- package/dist/src/lifecycle/types.js.map +1 -0
- package/dist/src/observation.d.ts +20 -0
- package/dist/src/observation.js +171 -0
- package/dist/src/observation.js.map +1 -0
- package/dist/src/reviewer.d.ts +4 -0
- package/dist/src/reviewer.js +24 -7
- package/dist/src/reviewer.js.map +1 -1
- package/dist/src/state/corrective-replan-executor.d.ts +64 -0
- package/dist/src/state/corrective-replan-executor.js +598 -0
- package/dist/src/state/corrective-replan-executor.js.map +1 -0
- package/dist/src/state/corrective-replan-public-schema.d.ts +3 -0
- package/dist/src/state/corrective-replan-public-schema.js +43 -0
- package/dist/src/state/corrective-replan-public-schema.js.map +1 -0
- package/dist/src/state/corrective-replan-public.d.ts +95 -0
- package/dist/src/state/corrective-replan-public.js +618 -0
- package/dist/src/state/corrective-replan-public.js.map +1 -0
- package/dist/src/state/corrective-replan-transaction.d.ts +158 -0
- package/dist/src/state/corrective-replan-transaction.js +723 -0
- package/dist/src/state/corrective-replan-transaction.js.map +1 -0
- package/dist/src/state/corrective-yield-executor.d.ts +31 -0
- package/dist/src/state/corrective-yield-executor.js +236 -0
- package/dist/src/state/corrective-yield-executor.js.map +1 -0
- package/dist/src/state/corrective-yield-transaction.d.ts +97 -0
- package/dist/src/state/corrective-yield-transaction.js +591 -0
- package/dist/src/state/corrective-yield-transaction.js.map +1 -0
- package/dist/src/state/lock.d.ts +75 -3
- package/dist/src/state/lock.js +582 -30
- package/dist/src/state/lock.js.map +1 -1
- package/dist/src/state/store.d.ts +3 -0
- package/dist/src/state/store.js +65 -12
- package/dist/src/state/store.js.map +1 -1
- package/dist/src/transition-core.d.ts +67 -0
- package/dist/src/transition-core.js +318 -0
- package/dist/src/transition-core.js.map +1 -0
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/workflow.d.ts +51 -21
- package/dist/src/workflow.js +667 -144
- package/dist/src/workflow.js.map +1 -1
- package/docs/autonomy-guardrails.md +8 -1
- package/docs/beta2-initial-assembly-navigation-brief.md +616 -0
- package/docs/development-flow.md +17 -2
- package/docs/lifecycle/state-machine-stabilization.md +641 -0
- package/docs/release.md +11 -2
- package/docs/split-required-recovery.md +5 -4
- package/docs/stable-release-defect-register.md +330 -1
- package/docs/updating-existing-project.md +11 -0
- package/package.json +4 -1
- package/plugins/codex-workflow-gateway/references/protocol.md +56 -1
- package/plugins/codex-workflow-gateway/skills/codex-workflow-gateway/SKILL.md +44 -0
- package/references/state-machine.md +4 -1
- package/schemas/adoption-posture-event.schema.json +1 -1
- package/schemas/context-envelope.schema.json +1 -1
- package/schemas/corrective-replan-credentials.private.schema.json +98 -0
- package/schemas/corrective-replan-execution-event.private.schema.json +53 -0
- package/schemas/corrective-replan-public.schema.json +142 -0
- package/schemas/corrective-replan-task-transaction.private.schema.json +151 -0
- package/schemas/corrective-yield-task-transaction.private.schema.json +98 -0
- package/schemas/remediation-event.schema.json +11 -1
- package/schemas/task-handoff-event.schema.json +1 -1
- package/schemas/transition-definition.schema.json +2609 -0
- package/schemas/transition-payloads.schema.json +140 -0
package/dist/src/cli.js
CHANGED
|
@@ -1,18 +1,160 @@
|
|
|
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'],
|
|
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
|
+
'step-review',
|
|
39
|
+
'corrective-decision-recover',
|
|
40
|
+
'remediation-mode-recover',
|
|
41
|
+
'corrective-decision',
|
|
42
|
+
'corrective-yield',
|
|
43
|
+
'corrective-yield-recover',
|
|
44
|
+
'corrective-replan-prepare',
|
|
45
|
+
'corrective-replan-confirm',
|
|
46
|
+
'corrective-replan-execute',
|
|
47
|
+
'corrective-replan-recover',
|
|
48
|
+
'handoff',
|
|
49
|
+
'handoff-prepare',
|
|
50
|
+
'handoff-show',
|
|
51
|
+
'claim',
|
|
52
|
+
'handback',
|
|
53
|
+
'handback-create',
|
|
54
|
+
'result-set',
|
|
55
|
+
'accept',
|
|
56
|
+
'sync-base',
|
|
57
|
+
'merge',
|
|
58
|
+
'merge-confirm',
|
|
59
|
+
],
|
|
60
|
+
milestone: [
|
|
61
|
+
'recover',
|
|
62
|
+
'show',
|
|
63
|
+
'plan-set',
|
|
64
|
+
'scope-change-prepare',
|
|
65
|
+
'scope-change-apply',
|
|
66
|
+
'autonomy-prepare',
|
|
67
|
+
'autonomy-grant',
|
|
68
|
+
'autonomy-evolve',
|
|
69
|
+
'authorize',
|
|
70
|
+
'validate',
|
|
71
|
+
'accept',
|
|
72
|
+
'cancel',
|
|
73
|
+
],
|
|
74
|
+
locks: ['inspect', 'repair'],
|
|
75
|
+
};
|
|
76
|
+
const CLI_HELP_SPECS = {
|
|
77
|
+
'milestone authorize': {
|
|
78
|
+
requiredOptions: ['--id', '--expected-revision'],
|
|
79
|
+
optionalOptions: ['--actor', '--reason', '--delegation-grant', '--repo', '--json'],
|
|
80
|
+
},
|
|
81
|
+
'milestone validate': {
|
|
82
|
+
requiredOptions: ['--id', '--expected-revision'],
|
|
83
|
+
optionalOptions: ['--repo', '--json'],
|
|
84
|
+
},
|
|
85
|
+
'milestone accept': {
|
|
86
|
+
requiredOptions: ['--id', '--expected-revision', '--actor', '--confirmation-code'],
|
|
87
|
+
optionalOptions: ['--delegation-grant', '--repo', '--json'],
|
|
88
|
+
},
|
|
89
|
+
'task plan-set': {
|
|
90
|
+
requiredOptions: ['--id', '--expected-revision', '--file', '--risk-audit-file'],
|
|
91
|
+
optionalOptions: ['--corrective-audit-file', '--repo', '--json'],
|
|
92
|
+
},
|
|
93
|
+
'task corrective-yield': {
|
|
94
|
+
requiredOptions: ['--id', '--expected-revision', '--actor', '--writer-token', '--reason'],
|
|
95
|
+
optionalOptions: ['--repo', '--json'],
|
|
96
|
+
},
|
|
97
|
+
'task corrective-yield-recover': {
|
|
98
|
+
requiredOptions: ['--id', '--transaction-id'],
|
|
99
|
+
optionalOptions: ['--repo', '--json'],
|
|
100
|
+
},
|
|
101
|
+
'task corrective-replan-prepare': {
|
|
102
|
+
requiredOptions: ['--id', '--file'],
|
|
103
|
+
optionalOptions: ['--repo', '--json'],
|
|
104
|
+
},
|
|
105
|
+
'task corrective-replan-confirm': {
|
|
106
|
+
requiredOptions: ['--id', '--file', '--gate-file', '--confirmation-code'],
|
|
107
|
+
optionalOptions: ['--repo', '--json'],
|
|
108
|
+
},
|
|
109
|
+
'task corrective-replan-execute': {
|
|
110
|
+
requiredOptions: ['--id', '--file', '--credential-file'],
|
|
111
|
+
optionalOptions: ['--repo', '--json'],
|
|
112
|
+
},
|
|
113
|
+
'task corrective-replan-recover': {
|
|
114
|
+
requiredOptions: ['--id', '--transaction-id'],
|
|
115
|
+
optionalOptions: ['--repo', '--json'],
|
|
116
|
+
},
|
|
117
|
+
'task authorize': {
|
|
118
|
+
requiredOptions: ['--id', '--expected-revision'],
|
|
119
|
+
optionalOptions: ['--actor', '--reason', '--delegation-grant', '--repo', '--json'],
|
|
120
|
+
},
|
|
121
|
+
'task start': {
|
|
122
|
+
requiredOptions: ['--id', '--expected-revision', '--workspace-owner'],
|
|
123
|
+
optionalOptions: ['--repo', '--json'],
|
|
124
|
+
},
|
|
125
|
+
'task run': {
|
|
126
|
+
requiredOptions: ['--id', '--step', '--expected-revision'],
|
|
127
|
+
optionalOptions: ['--owner', '--writer-token', '--repo', '--json'],
|
|
128
|
+
},
|
|
129
|
+
'task step-complete': {
|
|
130
|
+
requiredOptions: ['--id', '--step', '--expected-revision', '--writer-token'],
|
|
131
|
+
optionalOptions: ['--note', '--actor', '--repo', '--json'],
|
|
132
|
+
},
|
|
133
|
+
'task submit': {
|
|
134
|
+
requiredOptions: ['--id', '--expected-revision', '--writer-token'],
|
|
135
|
+
optionalOptions: ['--actor', '--repo', '--json'],
|
|
136
|
+
},
|
|
137
|
+
'task review-launch': {
|
|
138
|
+
requiredOptions: ['--id', '--expected-revision'],
|
|
139
|
+
optionalOptions: ['--actor', '--writer-token', '--repo', '--json'],
|
|
140
|
+
},
|
|
141
|
+
'task result-set': {
|
|
142
|
+
requiredOptions: ['--id', '--expected-revision', '--summary'],
|
|
143
|
+
optionalOptions: ['--limitation', '--repo', '--json'],
|
|
144
|
+
},
|
|
145
|
+
'task accept': {
|
|
146
|
+
requiredOptions: ['--id', '--expected-revision'],
|
|
147
|
+
optionalOptions: ['--actor', '--delegation-grant', '--repo', '--json'],
|
|
148
|
+
},
|
|
149
|
+
'task merge': {
|
|
150
|
+
requiredOptions: ['--id', '--expected-revision', '--writer-token'],
|
|
151
|
+
optionalOptions: ['--actor', '--repo', '--json'],
|
|
152
|
+
},
|
|
153
|
+
'task merge-confirm': {
|
|
154
|
+
requiredOptions: ['--id', '--expected-revision', '--writer-token'],
|
|
155
|
+
optionalOptions: ['--actor', '--repo', '--json'],
|
|
156
|
+
},
|
|
157
|
+
};
|
|
16
158
|
function parseArguments(argv) {
|
|
17
159
|
const positionals = [];
|
|
18
160
|
const options = new Map();
|
|
@@ -38,6 +180,55 @@ function parseArguments(argv) {
|
|
|
38
180
|
function option(args, name) {
|
|
39
181
|
return args.options.get(name)?.at(-1);
|
|
40
182
|
}
|
|
183
|
+
function cliHelp(args) {
|
|
184
|
+
const [noun, action] = args.positionals;
|
|
185
|
+
if (!noun) {
|
|
186
|
+
return {
|
|
187
|
+
kind: 'cli-help',
|
|
188
|
+
readOnly: true,
|
|
189
|
+
scope: 'top-level',
|
|
190
|
+
usage: 'codex-workflow <command> [action] [options]',
|
|
191
|
+
commands: ['doctor', 'status', 'next', ...Object.keys(CLI_ACTIONS)],
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
if (!action) {
|
|
195
|
+
if (['doctor', 'status', 'next'].includes(noun)) {
|
|
196
|
+
return {
|
|
197
|
+
kind: 'cli-help',
|
|
198
|
+
readOnly: true,
|
|
199
|
+
scope: 'command',
|
|
200
|
+
command: noun,
|
|
201
|
+
usage: `codex-workflow ${noun} [--repo <path>] [--json]`,
|
|
202
|
+
requiredOptions: [],
|
|
203
|
+
optionalOptions: ['--repo', '--json'],
|
|
204
|
+
exactOptionContractAvailable: true,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
return {
|
|
208
|
+
kind: 'cli-help',
|
|
209
|
+
readOnly: true,
|
|
210
|
+
scope: 'command',
|
|
211
|
+
command: noun,
|
|
212
|
+
usage: `codex-workflow ${noun} <action> [options]`,
|
|
213
|
+
actions: CLI_ACTIONS[noun] ?? [],
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
const command = `${noun} ${action}`;
|
|
217
|
+
const spec = CLI_HELP_SPECS[command];
|
|
218
|
+
return {
|
|
219
|
+
kind: 'cli-help',
|
|
220
|
+
readOnly: true,
|
|
221
|
+
scope: 'action',
|
|
222
|
+
command,
|
|
223
|
+
usage: spec
|
|
224
|
+
? ['codex-workflow', noun, action, ...spec.requiredOptions.map((name) => `${name} <value>`), '[options]'].join(' ')
|
|
225
|
+
: `codex-workflow ${noun} ${action} [options]`,
|
|
226
|
+
requiredOptions: spec?.requiredOptions ?? null,
|
|
227
|
+
optionalOptions: spec?.optionalOptions ?? null,
|
|
228
|
+
exactOptionContractAvailable: Boolean(spec),
|
|
229
|
+
...(spec ? {} : { note: 'Consult the packaged protocol for this action option contract.' }),
|
|
230
|
+
};
|
|
231
|
+
}
|
|
41
232
|
function required(args, name) {
|
|
42
233
|
const value = option(args, name)?.trim();
|
|
43
234
|
if (!value)
|
|
@@ -136,6 +327,7 @@ function workflowCapabilities() {
|
|
|
136
327
|
'alpha6-adoption-posture-v1',
|
|
137
328
|
'alpha6-strict-review-rescue-v1',
|
|
138
329
|
'milestone-initial-assembly-v1',
|
|
330
|
+
'milestone-initial-assembly-navigation-v2',
|
|
139
331
|
'milestone-autonomy-contract-v1',
|
|
140
332
|
'milestone-autonomy-content-refresh-v1',
|
|
141
333
|
'milestone-autonomous-membership-evolution-v1',
|
|
@@ -146,10 +338,16 @@ function workflowCapabilities() {
|
|
|
146
338
|
'plan-proof-obligations-v1',
|
|
147
339
|
'terminal-task-replacement-transaction-v1',
|
|
148
340
|
'project-composite-transaction-journal-v1',
|
|
341
|
+
'corrective-yield-journal-v1',
|
|
342
|
+
'corrective-replan-journal-v1',
|
|
343
|
+
'corrective-replan-human-gate-v1',
|
|
344
|
+
'corrective-replan-protocol-v2',
|
|
149
345
|
];
|
|
150
346
|
}
|
|
151
347
|
async function dispatch(args) {
|
|
152
348
|
const [noun, action] = args.positionals;
|
|
349
|
+
if (args.options.has('help'))
|
|
350
|
+
return cliHelp(args);
|
|
153
351
|
const repo = repository(args);
|
|
154
352
|
if (noun === 'gateway' && action === 'handshake') {
|
|
155
353
|
return {
|
|
@@ -162,19 +360,19 @@ async function dispatch(args) {
|
|
|
162
360
|
}
|
|
163
361
|
const workflow = new WorkflowService();
|
|
164
362
|
if (noun === 'doctor') {
|
|
165
|
-
const
|
|
166
|
-
const integration = integrationDiagnostics(
|
|
363
|
+
const identity = resolveRepositoryIdentity(repo);
|
|
364
|
+
const integration = integrationDiagnostics(identity.repositoryRoot);
|
|
167
365
|
const nodeSupported = Number(process.versions.node.split('.')[0]) >= 22;
|
|
168
366
|
return {
|
|
169
367
|
ok: nodeSupported && integration.localDependency.current,
|
|
170
368
|
node: process.versions.node,
|
|
171
369
|
requiredNode: '>=22',
|
|
172
|
-
repositoryRoot:
|
|
173
|
-
projectId:
|
|
174
|
-
stateRoot:
|
|
175
|
-
branch: currentBranch(
|
|
176
|
-
clean: isClean(
|
|
177
|
-
changedFiles: changedFiles(
|
|
370
|
+
repositoryRoot: identity.repositoryRoot,
|
|
371
|
+
projectId: identity.projectId,
|
|
372
|
+
stateRoot: workflow.store.root,
|
|
373
|
+
branch: currentBranch(identity.repositoryRoot),
|
|
374
|
+
clean: isClean(identity.repositoryRoot),
|
|
375
|
+
changedFiles: changedFiles(identity.repositoryRoot),
|
|
178
376
|
integration,
|
|
179
377
|
limitations: [
|
|
180
378
|
'CLI diagnostics cannot prove that Codex enforced a role, model, sandbox, or read-only reviewer.',
|
|
@@ -198,12 +396,12 @@ async function dispatch(args) {
|
|
|
198
396
|
return workflow.grantDelegation(repo, jsonFile(args), required(args, 'confirmation-code'));
|
|
199
397
|
}
|
|
200
398
|
if (noun === 'delegation' && action === 'list') {
|
|
201
|
-
const
|
|
202
|
-
return
|
|
399
|
+
const identity = resolveRepositoryIdentity(repo);
|
|
400
|
+
return workflow.store.listDelegations(identity.projectId);
|
|
203
401
|
}
|
|
204
402
|
if (noun === 'delegation' && action === 'show') {
|
|
205
|
-
const
|
|
206
|
-
return
|
|
403
|
+
const identity = resolveRepositoryIdentity(repo);
|
|
404
|
+
return workflow.store.readDelegation(identity.projectId, required(args, 'id'));
|
|
207
405
|
}
|
|
208
406
|
if (noun === 'delegation' && action === 'revoke') {
|
|
209
407
|
return workflow.revokeDelegation(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'reason'));
|
|
@@ -306,8 +504,8 @@ async function dispatch(args) {
|
|
|
306
504
|
return workflow.updateDiscovery(repo, required(args, 'id'), revision(args), patch);
|
|
307
505
|
}
|
|
308
506
|
if (noun === 'discovery' && action === 'show') {
|
|
309
|
-
const
|
|
310
|
-
return
|
|
507
|
+
const identity = resolveRepositoryIdentity(repo);
|
|
508
|
+
return workflow.store.readDiscovery(identity.projectId, required(args, 'id'));
|
|
311
509
|
}
|
|
312
510
|
if (noun === 'discovery' && action === 'materialize') {
|
|
313
511
|
const kind = option(args, 'kind') ?? 'task';
|
|
@@ -320,8 +518,8 @@ async function dispatch(args) {
|
|
|
320
518
|
throw new WorkflowError('INVALID_ARGUMENT', '--kind must be task or milestone.');
|
|
321
519
|
}
|
|
322
520
|
if (noun === 'task' && action === 'show') {
|
|
323
|
-
const
|
|
324
|
-
return
|
|
521
|
+
const identity = resolveRepositoryIdentity(repo);
|
|
522
|
+
return workflow.store.readTask(identity.projectId, required(args, 'id'));
|
|
325
523
|
}
|
|
326
524
|
if (noun === 'task' && action === 'replacement-materialize') {
|
|
327
525
|
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 +549,32 @@ async function dispatch(args) {
|
|
|
351
549
|
return workflow.startTask(repo, required(args, 'id'), revision(args), owner);
|
|
352
550
|
}
|
|
353
551
|
if (noun === 'task' && action === 'run') {
|
|
354
|
-
|
|
552
|
+
const outcome = workflow.runStep(repo, required(args, 'id'), required(args, 'step'), revision(args), option(args, 'owner') ?? 'worker', option(args, 'writer-token') ?? null);
|
|
553
|
+
const { writerToken, ...envelope } = outcome.envelope;
|
|
554
|
+
if (outcome.writerCredential.disposition === 'issued' && !writerToken) {
|
|
555
|
+
throw new WorkflowError('STATE_CORRUPT', 'Fresh task run credential issuance did not return its protocol-v1 writer token.');
|
|
556
|
+
}
|
|
557
|
+
if (outcome.writerCredential.disposition === 'renewed' && writerToken !== null) {
|
|
558
|
+
throw new WorkflowError('STATE_CORRUPT', 'Renewed task run credential unexpectedly returned a writer token.');
|
|
559
|
+
}
|
|
560
|
+
return {
|
|
561
|
+
writerCredential: { disposition: outcome.writerCredential.disposition },
|
|
562
|
+
...(writerToken ? {
|
|
563
|
+
writerLeaseReceipt: {
|
|
564
|
+
token: writerToken,
|
|
565
|
+
kind: 'writer-lease',
|
|
566
|
+
owner: outcome.lease.owner,
|
|
567
|
+
action: 'task step-complete',
|
|
568
|
+
option: '--writer-token',
|
|
569
|
+
source: 'task run',
|
|
570
|
+
sensitive: true,
|
|
571
|
+
oneTime: false,
|
|
572
|
+
},
|
|
573
|
+
} : {}),
|
|
574
|
+
task: outcome.task,
|
|
575
|
+
lease: outcome.lease,
|
|
576
|
+
envelope,
|
|
577
|
+
};
|
|
355
578
|
}
|
|
356
579
|
if (noun === 'task' && action === 'step-complete') {
|
|
357
580
|
return workflow.completeStep(repo, required(args, 'id'), required(args, 'step'), revision(args), required(args, 'writer-token'), repeated(args, 'note'), option(args, 'actor'));
|
|
@@ -364,10 +587,10 @@ async function dispatch(args) {
|
|
|
364
587
|
return workflow.recordReview(repo, required(args, 'id'), revision(args), review, option(args, 'actor'), option(args, 'writer-token') ?? null);
|
|
365
588
|
}
|
|
366
589
|
if (noun === 'task' && action === 'review-launch') {
|
|
367
|
-
const
|
|
590
|
+
const identity = resolveRepositoryIdentity(repo);
|
|
368
591
|
const id = required(args, 'id');
|
|
369
592
|
const expectedRevision = revision(args);
|
|
370
|
-
const task =
|
|
593
|
+
const task = workflow.store.readTask(identity.projectId, id);
|
|
371
594
|
if (task.revision !== expectedRevision) {
|
|
372
595
|
throw new WorkflowError('STATE_CONFLICT', `State revision conflict for ${id}`, {
|
|
373
596
|
expectedRevision,
|
|
@@ -375,11 +598,15 @@ async function dispatch(args) {
|
|
|
375
598
|
});
|
|
376
599
|
}
|
|
377
600
|
const envelope = workflow.taskContext(repo, id, 'independent-reviewer');
|
|
378
|
-
const launch = launchStrictReviewer(
|
|
601
|
+
const launch = launchStrictReviewer(identity.repositoryRoot, task, workflow.store.taskRoot(task.projectId, task.id), envelope);
|
|
602
|
+
// The independent reviewer identity belongs to the strict reviewer payload. CLI --actor
|
|
603
|
+
// remains the lifecycle mutation actor, such as the current C1 claimant.
|
|
379
604
|
const saved = workflow.recordReview(repo, id, expectedRevision, launch.review, option(args, 'actor'), option(args, 'writer-token') ?? null);
|
|
380
605
|
return { launch, task: saved };
|
|
381
606
|
}
|
|
382
607
|
if (noun === 'task' && action === 'step-review') {
|
|
608
|
+
// Strict Step Review launches and records the isolated reviewer inside Core. CLI --actor
|
|
609
|
+
// remains the lifecycle actor from next, typically the active C1 claimant.
|
|
383
610
|
return workflow.reviewStep(repo, required(args, 'id'), required(args, 'step'), revision(args), undefined, option(args, 'actor'), option(args, 'writer-token') ?? null);
|
|
384
611
|
}
|
|
385
612
|
if (noun === 'task' && action === 'corrective-decision-recover') {
|
|
@@ -391,14 +618,66 @@ async function dispatch(args) {
|
|
|
391
618
|
if (noun === 'task' && action === 'corrective-decision') {
|
|
392
619
|
return workflow.recordStepCorrectiveDecision(repo, required(args, 'id'), required(args, 'step'), revision(args), jsonFile(args), option(args, 'actor'), option(args, 'writer-token') ?? null);
|
|
393
620
|
}
|
|
621
|
+
if (noun === 'task' && action === 'corrective-yield') {
|
|
622
|
+
return workflow.executeCorrectiveYield(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'writer-token'), required(args, 'reason'));
|
|
623
|
+
}
|
|
624
|
+
if (noun === 'task' && action === 'corrective-yield-recover') {
|
|
625
|
+
return workflow.recoverCorrectiveYield(repo, required(args, 'id'), required(args, 'transaction-id'));
|
|
626
|
+
}
|
|
627
|
+
if (noun === 'task' && action === 'corrective-replan-prepare') {
|
|
628
|
+
return workflow.prepareCorrectiveReplan(repo, required(args, 'id'), jsonFile(args));
|
|
629
|
+
}
|
|
630
|
+
if (noun === 'task' && action === 'corrective-replan-confirm') {
|
|
631
|
+
return workflow.confirmCorrectiveReplan(repo, required(args, 'id'), jsonFile(args), jsonFile(args, 'gate-file'), required(args, 'confirmation-code'));
|
|
632
|
+
}
|
|
633
|
+
if (noun === 'task' && action === 'corrective-replan-execute') {
|
|
634
|
+
return workflow.executeCorrectiveReplan(repo, required(args, 'id'), jsonFile(args), jsonFile(args, 'credential-file'));
|
|
635
|
+
}
|
|
636
|
+
if (noun === 'task' && action === 'corrective-replan-recover') {
|
|
637
|
+
return workflow.recoverCorrectiveReplan(repo, required(args, 'id'), required(args, 'transaction-id'));
|
|
638
|
+
}
|
|
394
639
|
if (noun === 'task' && (action === 'handoff' || action === 'handoff-prepare')) {
|
|
395
|
-
|
|
640
|
+
const outcome = 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);
|
|
641
|
+
const { claimToken, ...bundle } = outcome.bundle;
|
|
642
|
+
return {
|
|
643
|
+
credentialHandoff: {
|
|
644
|
+
token: claimToken,
|
|
645
|
+
kind: 'claim-token',
|
|
646
|
+
targetActor: outcome.bundle.delegate,
|
|
647
|
+
action: 'task claim',
|
|
648
|
+
option: '--claim-token',
|
|
649
|
+
source: 'task handoff-prepare',
|
|
650
|
+
sensitive: true,
|
|
651
|
+
oneTime: true,
|
|
652
|
+
},
|
|
653
|
+
task: outcome.task,
|
|
654
|
+
event: outcome.event,
|
|
655
|
+
bundle,
|
|
656
|
+
};
|
|
396
657
|
}
|
|
397
658
|
if (noun === 'task' && action === 'handoff-show') {
|
|
398
659
|
return workflow.showTaskHandoff(repo, required(args, 'id'));
|
|
399
660
|
}
|
|
400
661
|
if (noun === 'task' && action === 'claim') {
|
|
401
|
-
|
|
662
|
+
const outcome = workflow.claimTask(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'claim-token'), option(args, 'writer-token') ?? null);
|
|
663
|
+
return {
|
|
664
|
+
writerCredential: { disposition: outcome.writerCredential.disposition },
|
|
665
|
+
...(outcome.writerCredential.disposition === 'issued' ? {
|
|
666
|
+
writerLeaseReceipt: {
|
|
667
|
+
token: outcome.writerCredential.token,
|
|
668
|
+
kind: 'writer-lease',
|
|
669
|
+
owner: outcome.lease.owner,
|
|
670
|
+
action: 'task run',
|
|
671
|
+
option: '--writer-token',
|
|
672
|
+
source: 'task claim',
|
|
673
|
+
sensitive: true,
|
|
674
|
+
oneTime: false,
|
|
675
|
+
},
|
|
676
|
+
} : {}),
|
|
677
|
+
task: outcome.task,
|
|
678
|
+
event: outcome.event,
|
|
679
|
+
lease: outcome.lease,
|
|
680
|
+
};
|
|
402
681
|
}
|
|
403
682
|
if (noun === 'task' && (action === 'handback' || action === 'handback-create')) {
|
|
404
683
|
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 +700,8 @@ async function dispatch(args) {
|
|
|
421
700
|
return workflow.confirmExternalMerge(repo, required(args, 'id'), revision(args), required(args, 'writer-token'), option(args, 'actor'));
|
|
422
701
|
}
|
|
423
702
|
if (noun === 'milestone' && action === 'show') {
|
|
424
|
-
const
|
|
425
|
-
return
|
|
703
|
+
const identity = resolveRepositoryIdentity(repo);
|
|
704
|
+
return workflow.store.readMilestone(identity.projectId, required(args, 'id'));
|
|
426
705
|
}
|
|
427
706
|
if (noun === 'milestone' && action === 'plan-set') {
|
|
428
707
|
return workflow.setMilestonePlan(repo, required(args, 'id'), revision(args), jsonFile(args));
|
|
@@ -455,39 +734,100 @@ async function dispatch(args) {
|
|
|
455
734
|
return workflow.cancelMilestone(repo, required(args, 'id'), revision(args), required(args, 'reason'));
|
|
456
735
|
}
|
|
457
736
|
if (noun === 'locks' && (action === 'inspect' || action === 'repair')) {
|
|
458
|
-
const context = workflow.context(repo);
|
|
459
737
|
const id = required(args, 'id');
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
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;
|
|
738
|
+
if (action === 'repair')
|
|
739
|
+
return workflow.repairStaleWriterLease(repo, id);
|
|
740
|
+
const inspection = workflow.inspectWriterLease(repo, id);
|
|
741
|
+
return inspection ? { ...inspection, repaired: false } : null;
|
|
473
742
|
}
|
|
474
743
|
throw new WorkflowError('INVALID_ARGUMENT', 'Unknown command.', {
|
|
475
744
|
command: args.positionals.join(' '),
|
|
476
745
|
hint: 'Use doctor, status, next, update preflight, state <action>, delegation <action>, project-memory <action>, discovery <action>, task <action>, milestone <action>, or locks <action>.',
|
|
477
746
|
});
|
|
478
747
|
}
|
|
748
|
+
function credentialAllowancesForResult(args, value) {
|
|
749
|
+
const [noun, action] = args.positionals;
|
|
750
|
+
if (!isRecord(value))
|
|
751
|
+
return [];
|
|
752
|
+
if (noun === 'task' && (action === 'run' || action === 'claim')) {
|
|
753
|
+
const disposition = isRecord(value.writerCredential) ? value.writerCredential.disposition : null;
|
|
754
|
+
const receipt = isRecord(value.writerLeaseReceipt) ? value.writerLeaseReceipt : null;
|
|
755
|
+
if (disposition === 'issued'
|
|
756
|
+
&& receipt?.kind === 'writer-lease'
|
|
757
|
+
&& receipt.source === `task ${action}`
|
|
758
|
+
&& receipt.sensitive === true) {
|
|
759
|
+
return [{ path: '$.writerLeaseReceipt.token' }];
|
|
760
|
+
}
|
|
761
|
+
return [];
|
|
762
|
+
}
|
|
763
|
+
if (noun === 'task' && (action === 'handoff' || action === 'handoff-prepare')) {
|
|
764
|
+
const receipt = isRecord(value.credentialHandoff) ? value.credentialHandoff : null;
|
|
765
|
+
if (receipt?.kind === 'claim-token'
|
|
766
|
+
&& receipt.source === 'task handoff-prepare'
|
|
767
|
+
&& receipt.sensitive === true
|
|
768
|
+
&& receipt.oneTime === true) {
|
|
769
|
+
return [{ path: '$.credentialHandoff.token' }];
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
return [];
|
|
773
|
+
}
|
|
774
|
+
function rawCredentialInputs(argv) {
|
|
775
|
+
const values = [];
|
|
776
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
777
|
+
const argument = argv[index];
|
|
778
|
+
for (const optionName of ['--writer-token', '--claim-token', '--confirmation-code']) {
|
|
779
|
+
if (argument === optionName && argv[index + 1])
|
|
780
|
+
values.push(argv[index + 1]);
|
|
781
|
+
if (argument.startsWith(`${optionName}=`))
|
|
782
|
+
values.push(argument.slice(optionName.length + 1));
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
return [...new Set(values.filter(Boolean))];
|
|
786
|
+
}
|
|
787
|
+
function isRecord(value) {
|
|
788
|
+
return typeof value === 'object' && value !== null;
|
|
789
|
+
}
|
|
479
790
|
async function main() {
|
|
791
|
+
const argv = process.argv.slice(2);
|
|
792
|
+
const sensitiveInputs = rawCredentialInputs(argv);
|
|
480
793
|
try {
|
|
481
|
-
const
|
|
794
|
+
const args = parseArguments(argv);
|
|
795
|
+
const value = await dispatch(args);
|
|
796
|
+
assertCliSuccessCredentialSafety(value, credentialAllowancesForResult(args, value), sensitiveInputs);
|
|
482
797
|
process.stdout.write(`${JSON.stringify({ ok: true, value }, null, 2)}\n`);
|
|
483
798
|
}
|
|
484
799
|
catch (error) {
|
|
800
|
+
if (error instanceof UnsafeCredentialOutputError) {
|
|
801
|
+
process.stderr.write(`${JSON.stringify({
|
|
802
|
+
ok: false,
|
|
803
|
+
error: {
|
|
804
|
+
code: 'STATE_CORRUPT',
|
|
805
|
+
message: error.message,
|
|
806
|
+
details: { credentialPaths: error.paths },
|
|
807
|
+
},
|
|
808
|
+
}, null, 2)}\n`);
|
|
809
|
+
process.exitCode = 2;
|
|
810
|
+
return;
|
|
811
|
+
}
|
|
485
812
|
if (error instanceof WorkflowError) {
|
|
486
|
-
process.stderr.write(`${JSON.stringify({
|
|
813
|
+
process.stderr.write(`${JSON.stringify({
|
|
814
|
+
ok: false,
|
|
815
|
+
error: {
|
|
816
|
+
code: error.code,
|
|
817
|
+
message: projectCliErrorMessage(error.message, sensitiveInputs),
|
|
818
|
+
details: projectCliErrorValue(error.details, sensitiveInputs),
|
|
819
|
+
},
|
|
820
|
+
}, null, 2)}\n`);
|
|
487
821
|
process.exitCode = 2;
|
|
488
822
|
return;
|
|
489
823
|
}
|
|
490
|
-
process.stderr.write(`${JSON.stringify({
|
|
824
|
+
process.stderr.write(`${JSON.stringify({
|
|
825
|
+
ok: false,
|
|
826
|
+
error: {
|
|
827
|
+
code: 'UNEXPECTED',
|
|
828
|
+
message: projectCliErrorMessage(error instanceof Error ? error.message : String(error), sensitiveInputs),
|
|
829
|
+
},
|
|
830
|
+
}, null, 2)}\n`);
|
|
491
831
|
process.exitCode = 1;
|
|
492
832
|
}
|
|
493
833
|
}
|