codex-workflow-v2 2.0.0-beta.1 → 2.0.0-beta.11
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 +94 -12
- package/dist/src/alpha6/adoption.js +13 -3
- package/dist/src/alpha6/adoption.js.map +1 -1
- package/dist/src/alpha6/handoff.d.ts +26 -2
- package/dist/src/alpha6/handoff.js +277 -29
- package/dist/src/alpha6/handoff.js.map +1 -1
- package/dist/src/alpha6/mechanical-feasibility.d.ts +7 -0
- package/dist/src/alpha6/mechanical-feasibility.js +303 -0
- package/dist/src/alpha6/mechanical-feasibility.js.map +1 -0
- package/dist/src/alpha6/milestone.d.ts +37 -2
- package/dist/src/alpha6/milestone.js +472 -33
- package/dist/src/alpha6/milestone.js.map +1 -1
- package/dist/src/alpha6/plan-integrity.d.ts +14 -0
- package/dist/src/alpha6/plan-integrity.js +127 -0
- package/dist/src/alpha6/plan-integrity.js.map +1 -0
- package/dist/src/alpha6/plan-risk.d.ts +1 -0
- package/dist/src/alpha6/plan-risk.js +15 -7
- package/dist/src/alpha6/plan-risk.js.map +1 -1
- package/dist/src/alpha6/remediation.d.ts +2 -1
- package/dist/src/alpha6/remediation.js +186 -9
- package/dist/src/alpha6/remediation.js.map +1 -1
- package/dist/src/alpha6/review.d.ts +3 -0
- package/dist/src/alpha6/review.js +24 -0
- package/dist/src/alpha6/review.js.map +1 -1
- package/dist/src/cli.js +486 -46
- package/dist/src/cli.js.map +1 -1
- package/dist/src/contracts.d.ts +238 -6
- 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/dependency-provenance.d.ts +19 -0
- package/dist/src/dependency-provenance.js +185 -0
- package/dist/src/dependency-provenance.js.map +1 -0
- package/dist/src/errors.d.ts +1 -1
- package/dist/src/errors.js.map +1 -1
- package/dist/src/git.d.ts +1 -1
- package/dist/src/git.js +13 -5
- package/dist/src/git.js.map +1 -1
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.js +2 -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 +563 -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 +553 -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 +43 -1
- package/dist/src/reviewer.js +203 -50
- 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 +608 -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 +665 -0
- package/dist/src/state/corrective-replan-public.js.map +1 -0
- package/dist/src/state/corrective-replan-transaction.d.ts +160 -0
- package/dist/src/state/corrective-replan-transaction.js +730 -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 +76 -3
- package/dist/src/state/lock.js +611 -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/version.js.map +1 -1
- package/dist/src/workflow.d.ts +88 -24
- package/dist/src/workflow.js +1647 -270
- package/dist/src/workflow.js.map +1 -1
- package/docs/autonomy-guardrails.md +61 -1
- package/docs/beta11-plan-integrity-recovery-brief.md +38 -0
- package/docs/beta2-initial-assembly-navigation-brief.md +616 -0
- package/docs/delegated-approval.md +26 -1
- package/docs/development-flow.md +63 -8
- package/docs/lifecycle/state-machine-stabilization.md +641 -0
- package/docs/pdf/README.md +24 -0
- package/docs/pdf/codex-workflow-v2-architecture-ru.pdf +0 -0
- package/docs/pdf/codex-workflow-v2-chat-only-guide-ru.pdf +0 -0
- package/docs/pdf/codex-workflow-v2-technical-reference-ru.pdf +0 -0
- package/docs/pdf/requirements.txt +1 -0
- package/docs/pdf/sources/codex-workflow-v2-architecture-ru.md +234 -0
- package/docs/pdf/sources/codex-workflow-v2-chat-only-guide-ru.md +334 -0
- package/docs/pdf/sources/codex-workflow-v2-technical-reference-ru.md +413 -0
- package/docs/problem-briefs/01-pre-implementation-integrity.md +478 -0
- package/docs/problem-briefs/02-minimal-step-integrity.md +411 -0
- package/docs/problem-briefs/03-minimal-agent-context-integrity.md +358 -0
- package/docs/problem-briefs/04-task-dependency-and-structural-replacement-integrity.md +566 -0
- package/docs/problem-briefs/BRIEF-TEMPLATE.md +56 -0
- package/docs/problem-briefs/README.md +120 -0
- package/docs/problem-briefs/evidence/p01-mechanical-feasibility-corpus.md +90 -0
- package/docs/problem-briefs/evidence/signal-v4-pre-m3-replay.md +246 -0
- package/docs/release.md +30 -6
- package/docs/split-required-recovery.md +19 -25
- package/docs/stable-release-defect-register.md +465 -3
- package/docs/updating-existing-project.md +59 -4
- package/docs/validation-report.md +124 -56
- package/package.json +9 -1
- package/plugins/codex-workflow-gateway/.codex-plugin/plugin.json +10 -3
- package/plugins/codex-workflow-gateway/references/protocol.md +92 -4
- package/plugins/codex-workflow-gateway/scripts/chat-registry.mjs +376 -0
- package/plugins/codex-workflow-gateway/skills/codex-workflow-gateway/SKILL.md +263 -4
- package/references/state-machine.md +13 -6
- package/roles/delivery-coordinator.md +39 -0
- package/schemas/adoption-posture-event.schema.json +1 -1
- package/schemas/authorization-event.schema.json +64 -1
- package/schemas/context-envelope.schema.json +1 -1
- package/schemas/corrective-decision-event.schema.json +48 -3
- 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/milestone-scope-change-event.schema.json +6 -1
- package/schemas/milestone.schema.json +6 -1
- package/schemas/remediation-event.schema.json +11 -1
- package/schemas/task-handoff-event.schema.json +19 -3
- package/schemas/task.schema.json +24 -1
- package/schemas/transition-definition.schema.json +2609 -0
- package/schemas/transition-payloads.schema.json +140 -0
- package/scripts/generate-pdf-docs.py +512 -0
- package/scripts/run-pdf-docs.mjs +62 -0
package/dist/src/cli.js
CHANGED
|
@@ -1,18 +1,208 @@
|
|
|
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
|
+
'plan-integrity-recover',
|
|
46
|
+
'corrective-decision',
|
|
47
|
+
'corrective-yield',
|
|
48
|
+
'corrective-yield-recover',
|
|
49
|
+
'corrective-replan-prepare',
|
|
50
|
+
'corrective-replan-confirm',
|
|
51
|
+
'corrective-replan-execute',
|
|
52
|
+
'corrective-replan-recover',
|
|
53
|
+
'handoff',
|
|
54
|
+
'handoff-prepare',
|
|
55
|
+
'handoff-replace',
|
|
56
|
+
'handoff-show',
|
|
57
|
+
'claim',
|
|
58
|
+
'writer-credential-replace',
|
|
59
|
+
'handback',
|
|
60
|
+
'handback-create',
|
|
61
|
+
'result-set',
|
|
62
|
+
'accept',
|
|
63
|
+
'sync-base',
|
|
64
|
+
'merge',
|
|
65
|
+
'merge-confirm',
|
|
66
|
+
],
|
|
67
|
+
milestone: [
|
|
68
|
+
'recover',
|
|
69
|
+
'show',
|
|
70
|
+
'progress',
|
|
71
|
+
'plan-set',
|
|
72
|
+
'scope-change-prepare',
|
|
73
|
+
'scope-change-apply',
|
|
74
|
+
'autonomy-prepare',
|
|
75
|
+
'autonomy-grant',
|
|
76
|
+
'autonomy-evolve',
|
|
77
|
+
'authorize',
|
|
78
|
+
'validate',
|
|
79
|
+
'accept',
|
|
80
|
+
'cancel',
|
|
81
|
+
],
|
|
82
|
+
locks: ['inspect', 'repair'],
|
|
83
|
+
};
|
|
84
|
+
const CLI_HELP_SPECS = {
|
|
85
|
+
'update dependency-provenance-preflight': {
|
|
86
|
+
requiredOptions: ['--id'],
|
|
87
|
+
optionalOptions: ['--repo', '--json'],
|
|
88
|
+
},
|
|
89
|
+
'update dependency-provenance-recover': {
|
|
90
|
+
requiredOptions: ['--id', '--expected-revision', '--actor', '--reason'],
|
|
91
|
+
optionalOptions: ['--repo', '--json'],
|
|
92
|
+
},
|
|
93
|
+
'milestone progress': {
|
|
94
|
+
requiredOptions: ['--id'],
|
|
95
|
+
optionalOptions: ['--repo', '--json'],
|
|
96
|
+
},
|
|
97
|
+
'milestone authorize': {
|
|
98
|
+
requiredOptions: ['--id', '--expected-revision'],
|
|
99
|
+
optionalOptions: ['--actor', '--reason', '--delegation-grant', '--repo', '--json'],
|
|
100
|
+
},
|
|
101
|
+
'milestone validate': {
|
|
102
|
+
requiredOptions: ['--id', '--expected-revision'],
|
|
103
|
+
optionalOptions: ['--repo', '--json'],
|
|
104
|
+
},
|
|
105
|
+
'milestone accept': {
|
|
106
|
+
requiredOptions: ['--id', '--expected-revision', '--actor', '--confirmation-code'],
|
|
107
|
+
optionalOptions: ['--delegation-grant', '--repo', '--json'],
|
|
108
|
+
},
|
|
109
|
+
'task plan-set': {
|
|
110
|
+
requiredOptions: ['--id', '--expected-revision', '--file', '--risk-audit-file'],
|
|
111
|
+
optionalOptions: ['--corrective-audit-file', '--repo', '--json'],
|
|
112
|
+
},
|
|
113
|
+
'task handoff-replace': {
|
|
114
|
+
requiredOptions: ['--id', '--expected-revision', '--actor', '--target-actor', '--reason'],
|
|
115
|
+
optionalOptions: ['--delegation-grant', '--expires-at', '--repo', '--json'],
|
|
116
|
+
},
|
|
117
|
+
'task writer-credential-replace': {
|
|
118
|
+
requiredOptions: ['--id', '--expected-revision', '--actor'],
|
|
119
|
+
optionalOptions: ['--repo', '--json'],
|
|
120
|
+
},
|
|
121
|
+
'task corrective-yield': {
|
|
122
|
+
requiredOptions: ['--id', '--expected-revision', '--actor', '--writer-token', '--reason'],
|
|
123
|
+
optionalOptions: ['--repo', '--json'],
|
|
124
|
+
},
|
|
125
|
+
'task plan-integrity-recover': {
|
|
126
|
+
requiredOptions: ['--id', '--step', '--expected-revision', '--actor'],
|
|
127
|
+
optionalOptions: ['--writer-token', '--repo', '--json'],
|
|
128
|
+
},
|
|
129
|
+
'task corrective-yield-recover': {
|
|
130
|
+
requiredOptions: ['--id', '--transaction-id'],
|
|
131
|
+
optionalOptions: ['--repo', '--json'],
|
|
132
|
+
},
|
|
133
|
+
'task corrective-replan-prepare': {
|
|
134
|
+
requiredOptions: ['--id', '--file'],
|
|
135
|
+
optionalOptions: ['--repo', '--json'],
|
|
136
|
+
},
|
|
137
|
+
'task corrective-replan-confirm': {
|
|
138
|
+
requiredOptions: ['--id', '--file', '--gate-file', '--confirmation-code'],
|
|
139
|
+
optionalOptions: ['--repo', '--json'],
|
|
140
|
+
},
|
|
141
|
+
'task corrective-replan-execute': {
|
|
142
|
+
requiredOptions: ['--id', '--file', '--credential-file'],
|
|
143
|
+
optionalOptions: ['--repo', '--json'],
|
|
144
|
+
},
|
|
145
|
+
'task corrective-replan-recover': {
|
|
146
|
+
requiredOptions: ['--id', '--transaction-id'],
|
|
147
|
+
optionalOptions: ['--repo', '--json'],
|
|
148
|
+
},
|
|
149
|
+
'task authorize': {
|
|
150
|
+
requiredOptions: ['--id', '--expected-revision'],
|
|
151
|
+
optionalOptions: ['--actor', '--reason', '--delegation-grant', '--repo', '--json'],
|
|
152
|
+
},
|
|
153
|
+
'task start': {
|
|
154
|
+
requiredOptions: ['--id', '--expected-revision', '--workspace-owner'],
|
|
155
|
+
optionalOptions: ['--repo', '--json'],
|
|
156
|
+
},
|
|
157
|
+
'task run': {
|
|
158
|
+
requiredOptions: ['--id', '--step', '--expected-revision'],
|
|
159
|
+
optionalOptions: ['--owner', '--writer-token', '--repo', '--json'],
|
|
160
|
+
},
|
|
161
|
+
'task step-complete': {
|
|
162
|
+
requiredOptions: ['--id', '--step', '--expected-revision', '--writer-token'],
|
|
163
|
+
optionalOptions: ['--note', '--actor', '--repo', '--json'],
|
|
164
|
+
},
|
|
165
|
+
'task submit': {
|
|
166
|
+
requiredOptions: ['--id', '--expected-revision', '--writer-token'],
|
|
167
|
+
optionalOptions: ['--actor', '--repo', '--json'],
|
|
168
|
+
},
|
|
169
|
+
'task review-launch': {
|
|
170
|
+
requiredOptions: ['--id', '--expected-revision'],
|
|
171
|
+
optionalOptions: ['--actor', '--writer-token', '--repo', '--json'],
|
|
172
|
+
},
|
|
173
|
+
'task review-packet': {
|
|
174
|
+
requiredOptions: ['--id', '--expected-revision'],
|
|
175
|
+
optionalOptions: ['--repo', '--json'],
|
|
176
|
+
},
|
|
177
|
+
'task review-sealed-record': {
|
|
178
|
+
requiredOptions: ['--id', '--expected-revision', '--actor', '--file'],
|
|
179
|
+
optionalOptions: ['--writer-token', '--repo', '--json'],
|
|
180
|
+
},
|
|
181
|
+
'task step-review-packet': {
|
|
182
|
+
requiredOptions: ['--id', '--step', '--expected-revision'],
|
|
183
|
+
optionalOptions: ['--repo', '--json'],
|
|
184
|
+
},
|
|
185
|
+
'task step-review-record': {
|
|
186
|
+
requiredOptions: ['--id', '--step', '--expected-revision', '--actor', '--file'],
|
|
187
|
+
optionalOptions: ['--writer-token', '--repo', '--json'],
|
|
188
|
+
},
|
|
189
|
+
'task result-set': {
|
|
190
|
+
requiredOptions: ['--id', '--expected-revision', '--summary'],
|
|
191
|
+
optionalOptions: ['--limitation', '--repo', '--json'],
|
|
192
|
+
},
|
|
193
|
+
'task accept': {
|
|
194
|
+
requiredOptions: ['--id', '--expected-revision'],
|
|
195
|
+
optionalOptions: ['--actor', '--delegation-grant', '--repo', '--json'],
|
|
196
|
+
},
|
|
197
|
+
'task merge': {
|
|
198
|
+
requiredOptions: ['--id', '--expected-revision', '--writer-token'],
|
|
199
|
+
optionalOptions: ['--actor', '--repo', '--json'],
|
|
200
|
+
},
|
|
201
|
+
'task merge-confirm': {
|
|
202
|
+
requiredOptions: ['--id', '--expected-revision', '--writer-token'],
|
|
203
|
+
optionalOptions: ['--actor', '--repo', '--json'],
|
|
204
|
+
},
|
|
205
|
+
};
|
|
16
206
|
function parseArguments(argv) {
|
|
17
207
|
const positionals = [];
|
|
18
208
|
const options = new Map();
|
|
@@ -38,6 +228,58 @@ function parseArguments(argv) {
|
|
|
38
228
|
function option(args, name) {
|
|
39
229
|
return args.options.get(name)?.at(-1);
|
|
40
230
|
}
|
|
231
|
+
function cliHelp(args) {
|
|
232
|
+
const [noun, action] = args.positionals;
|
|
233
|
+
if (!noun) {
|
|
234
|
+
return {
|
|
235
|
+
kind: 'cli-help',
|
|
236
|
+
readOnly: true,
|
|
237
|
+
scope: 'top-level',
|
|
238
|
+
usage: 'codex-workflow <command> [action] [options]',
|
|
239
|
+
commands: ['doctor', 'status', 'next', ...Object.keys(CLI_ACTIONS)],
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
if (!action) {
|
|
243
|
+
if (['doctor', 'status', 'next'].includes(noun)) {
|
|
244
|
+
const taskSelector = noun === 'next' ? ['--task'] : [];
|
|
245
|
+
return {
|
|
246
|
+
kind: 'cli-help',
|
|
247
|
+
readOnly: true,
|
|
248
|
+
scope: 'command',
|
|
249
|
+
command: noun,
|
|
250
|
+
usage: noun === 'next'
|
|
251
|
+
? 'codex-workflow next [--task <task-id>] [--repo <path>] [--json]'
|
|
252
|
+
: `codex-workflow ${noun} [--repo <path>] [--json]`,
|
|
253
|
+
requiredOptions: [],
|
|
254
|
+
optionalOptions: [...taskSelector, '--repo', '--json'],
|
|
255
|
+
exactOptionContractAvailable: true,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
return {
|
|
259
|
+
kind: 'cli-help',
|
|
260
|
+
readOnly: true,
|
|
261
|
+
scope: 'command',
|
|
262
|
+
command: noun,
|
|
263
|
+
usage: `codex-workflow ${noun} <action> [options]`,
|
|
264
|
+
actions: CLI_ACTIONS[noun] ?? [],
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
const command = `${noun} ${action}`;
|
|
268
|
+
const spec = CLI_HELP_SPECS[command];
|
|
269
|
+
return {
|
|
270
|
+
kind: 'cli-help',
|
|
271
|
+
readOnly: true,
|
|
272
|
+
scope: 'action',
|
|
273
|
+
command,
|
|
274
|
+
usage: spec
|
|
275
|
+
? ['codex-workflow', noun, action, ...spec.requiredOptions.map((name) => `${name} <value>`), '[options]'].join(' ')
|
|
276
|
+
: `codex-workflow ${noun} ${action} [options]`,
|
|
277
|
+
requiredOptions: spec?.requiredOptions ?? null,
|
|
278
|
+
optionalOptions: spec?.optionalOptions ?? null,
|
|
279
|
+
exactOptionContractAvailable: Boolean(spec),
|
|
280
|
+
...(spec ? {} : { note: 'Consult the packaged protocol for this action option contract.' }),
|
|
281
|
+
};
|
|
282
|
+
}
|
|
41
283
|
function required(args, name) {
|
|
42
284
|
const value = option(args, name)?.trim();
|
|
43
285
|
if (!value)
|
|
@@ -121,6 +363,11 @@ function workflowCapabilities() {
|
|
|
121
363
|
'task-context-refresh-v1',
|
|
122
364
|
'corrective-plan-audit-v1',
|
|
123
365
|
'safe-update-preflight-v1',
|
|
366
|
+
'bounded-dependency-provenance-recovery-v1',
|
|
367
|
+
'retained-reviewed-history-recovery-v1',
|
|
368
|
+
'milestone-progress-projection-v1',
|
|
369
|
+
'bounded-plan-integrity-recovery-v1',
|
|
370
|
+
'task-mechanical-feasibility-v1',
|
|
124
371
|
'strict-reviewer-v1',
|
|
125
372
|
'legacy-snapshot-v1',
|
|
126
373
|
'plan-risk-audit-sidecar-v1',
|
|
@@ -128,6 +375,8 @@ function workflowCapabilities() {
|
|
|
128
375
|
'step-remediation-circuit-breaker-sidecar-v1',
|
|
129
376
|
'milestone-scope-change-sidecar-v1',
|
|
130
377
|
'milestone-membership-integrity-v1',
|
|
378
|
+
'milestone-task-dependency-dag-v1',
|
|
379
|
+
'milestone-initial-plan-transaction-v1',
|
|
131
380
|
'task-c1-handoff-sidecar-v1',
|
|
132
381
|
'semantic-plan-risk-audit-v2',
|
|
133
382
|
'guarded-remediation-hard-stop-v1',
|
|
@@ -136,6 +385,7 @@ function workflowCapabilities() {
|
|
|
136
385
|
'alpha6-adoption-posture-v1',
|
|
137
386
|
'alpha6-strict-review-rescue-v1',
|
|
138
387
|
'milestone-initial-assembly-v1',
|
|
388
|
+
'milestone-initial-assembly-navigation-v2',
|
|
139
389
|
'milestone-autonomy-contract-v1',
|
|
140
390
|
'milestone-autonomy-content-refresh-v1',
|
|
141
391
|
'milestone-autonomous-membership-evolution-v1',
|
|
@@ -144,12 +394,18 @@ function workflowCapabilities() {
|
|
|
144
394
|
'corrective-decision-context-recovery-v1',
|
|
145
395
|
'remediation-mode-recovery-v1',
|
|
146
396
|
'plan-proof-obligations-v1',
|
|
147
|
-
'
|
|
397
|
+
'structural-task-replacement-disabled-v1',
|
|
148
398
|
'project-composite-transaction-journal-v1',
|
|
399
|
+
'corrective-yield-journal-v1',
|
|
400
|
+
'corrective-replan-journal-v1',
|
|
401
|
+
'corrective-replan-human-gate-v1',
|
|
402
|
+
'corrective-replan-protocol-v2',
|
|
149
403
|
];
|
|
150
404
|
}
|
|
151
405
|
async function dispatch(args) {
|
|
152
406
|
const [noun, action] = args.positionals;
|
|
407
|
+
if (args.options.has('help'))
|
|
408
|
+
return cliHelp(args);
|
|
153
409
|
const repo = repository(args);
|
|
154
410
|
if (noun === 'gateway' && action === 'handshake') {
|
|
155
411
|
return {
|
|
@@ -162,19 +418,19 @@ async function dispatch(args) {
|
|
|
162
418
|
}
|
|
163
419
|
const workflow = new WorkflowService();
|
|
164
420
|
if (noun === 'doctor') {
|
|
165
|
-
const
|
|
166
|
-
const integration = integrationDiagnostics(
|
|
421
|
+
const identity = resolveRepositoryIdentity(repo);
|
|
422
|
+
const integration = integrationDiagnostics(identity.repositoryRoot);
|
|
167
423
|
const nodeSupported = Number(process.versions.node.split('.')[0]) >= 22;
|
|
168
424
|
return {
|
|
169
425
|
ok: nodeSupported && integration.localDependency.current,
|
|
170
426
|
node: process.versions.node,
|
|
171
427
|
requiredNode: '>=22',
|
|
172
|
-
repositoryRoot:
|
|
173
|
-
projectId:
|
|
174
|
-
stateRoot:
|
|
175
|
-
branch: currentBranch(
|
|
176
|
-
clean: isClean(
|
|
177
|
-
changedFiles: changedFiles(
|
|
428
|
+
repositoryRoot: identity.repositoryRoot,
|
|
429
|
+
projectId: identity.projectId,
|
|
430
|
+
stateRoot: workflow.store.root,
|
|
431
|
+
branch: currentBranch(identity.repositoryRoot),
|
|
432
|
+
clean: isClean(identity.repositoryRoot),
|
|
433
|
+
changedFiles: changedFiles(identity.repositoryRoot),
|
|
178
434
|
integration,
|
|
179
435
|
limitations: [
|
|
180
436
|
'CLI diagnostics cannot prove that Codex enforced a role, model, sandbox, or read-only reviewer.',
|
|
@@ -185,12 +441,18 @@ async function dispatch(args) {
|
|
|
185
441
|
if (noun === 'status')
|
|
186
442
|
return workflow.status(repo);
|
|
187
443
|
if (noun === 'next')
|
|
188
|
-
return workflow.next(repo);
|
|
444
|
+
return workflow.next(repo, option(args, 'task') ?? null);
|
|
189
445
|
if (noun === 'update' && action === 'preflight')
|
|
190
446
|
return workflow.updatePreflight(repo);
|
|
191
447
|
if (noun === 'update' && action === 'rescue-preflight') {
|
|
192
448
|
return workflow.alpha6StrictReviewRescuePreflight(repo);
|
|
193
449
|
}
|
|
450
|
+
if (noun === 'update' && action === 'dependency-provenance-preflight') {
|
|
451
|
+
return workflow.dependencyProvenanceRecoveryPreflight(repo, required(args, 'id'));
|
|
452
|
+
}
|
|
453
|
+
if (noun === 'update' && action === 'dependency-provenance-recover') {
|
|
454
|
+
return workflow.recoverDependencyProvenance(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'reason'));
|
|
455
|
+
}
|
|
194
456
|
if (noun === 'delegation' && action === 'prepare') {
|
|
195
457
|
return workflow.prepareDelegation(repo, jsonFile(args));
|
|
196
458
|
}
|
|
@@ -198,12 +460,12 @@ async function dispatch(args) {
|
|
|
198
460
|
return workflow.grantDelegation(repo, jsonFile(args), required(args, 'confirmation-code'));
|
|
199
461
|
}
|
|
200
462
|
if (noun === 'delegation' && action === 'list') {
|
|
201
|
-
const
|
|
202
|
-
return
|
|
463
|
+
const identity = resolveRepositoryIdentity(repo);
|
|
464
|
+
return workflow.store.listDelegations(identity.projectId);
|
|
203
465
|
}
|
|
204
466
|
if (noun === 'delegation' && action === 'show') {
|
|
205
|
-
const
|
|
206
|
-
return
|
|
467
|
+
const identity = resolveRepositoryIdentity(repo);
|
|
468
|
+
return workflow.store.readDelegation(identity.projectId, required(args, 'id'));
|
|
207
469
|
}
|
|
208
470
|
if (noun === 'delegation' && action === 'revoke') {
|
|
209
471
|
return workflow.revokeDelegation(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'reason'));
|
|
@@ -306,8 +568,8 @@ async function dispatch(args) {
|
|
|
306
568
|
return workflow.updateDiscovery(repo, required(args, 'id'), revision(args), patch);
|
|
307
569
|
}
|
|
308
570
|
if (noun === 'discovery' && action === 'show') {
|
|
309
|
-
const
|
|
310
|
-
return
|
|
571
|
+
const identity = resolveRepositoryIdentity(repo);
|
|
572
|
+
return workflow.store.readDiscovery(identity.projectId, required(args, 'id'));
|
|
311
573
|
}
|
|
312
574
|
if (noun === 'discovery' && action === 'materialize') {
|
|
313
575
|
const kind = option(args, 'kind') ?? 'task';
|
|
@@ -320,8 +582,8 @@ async function dispatch(args) {
|
|
|
320
582
|
throw new WorkflowError('INVALID_ARGUMENT', '--kind must be task or milestone.');
|
|
321
583
|
}
|
|
322
584
|
if (noun === 'task' && action === 'show') {
|
|
323
|
-
const
|
|
324
|
-
return
|
|
585
|
+
const identity = resolveRepositoryIdentity(repo);
|
|
586
|
+
return workflow.store.readTask(identity.projectId, required(args, 'id'));
|
|
325
587
|
}
|
|
326
588
|
if (noun === 'task' && action === 'replacement-materialize') {
|
|
327
589
|
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 +613,32 @@ async function dispatch(args) {
|
|
|
351
613
|
return workflow.startTask(repo, required(args, 'id'), revision(args), owner);
|
|
352
614
|
}
|
|
353
615
|
if (noun === 'task' && action === 'run') {
|
|
354
|
-
|
|
616
|
+
const outcome = workflow.runStep(repo, required(args, 'id'), required(args, 'step'), revision(args), option(args, 'owner') ?? 'worker', option(args, 'writer-token') ?? null);
|
|
617
|
+
const { writerToken, ...envelope } = outcome.envelope;
|
|
618
|
+
if (outcome.writerCredential.disposition === 'issued' && !writerToken) {
|
|
619
|
+
throw new WorkflowError('STATE_CORRUPT', 'Fresh task run credential issuance did not return its protocol-v1 writer token.');
|
|
620
|
+
}
|
|
621
|
+
if (outcome.writerCredential.disposition === 'renewed' && writerToken !== null) {
|
|
622
|
+
throw new WorkflowError('STATE_CORRUPT', 'Renewed task run credential unexpectedly returned a writer token.');
|
|
623
|
+
}
|
|
624
|
+
return {
|
|
625
|
+
writerCredential: { disposition: outcome.writerCredential.disposition },
|
|
626
|
+
...(writerToken ? {
|
|
627
|
+
writerLeaseReceipt: {
|
|
628
|
+
token: writerToken,
|
|
629
|
+
kind: 'writer-lease',
|
|
630
|
+
owner: outcome.lease.owner,
|
|
631
|
+
action: 'task step-complete',
|
|
632
|
+
option: '--writer-token',
|
|
633
|
+
source: 'task run',
|
|
634
|
+
sensitive: true,
|
|
635
|
+
oneTime: false,
|
|
636
|
+
},
|
|
637
|
+
} : {}),
|
|
638
|
+
task: outcome.task,
|
|
639
|
+
lease: outcome.lease,
|
|
640
|
+
envelope,
|
|
641
|
+
};
|
|
355
642
|
}
|
|
356
643
|
if (noun === 'task' && action === 'step-complete') {
|
|
357
644
|
return workflow.completeStep(repo, required(args, 'id'), required(args, 'step'), revision(args), required(args, 'writer-token'), repeated(args, 'note'), option(args, 'actor'));
|
|
@@ -364,10 +651,10 @@ async function dispatch(args) {
|
|
|
364
651
|
return workflow.recordReview(repo, required(args, 'id'), revision(args), review, option(args, 'actor'), option(args, 'writer-token') ?? null);
|
|
365
652
|
}
|
|
366
653
|
if (noun === 'task' && action === 'review-launch') {
|
|
367
|
-
const
|
|
654
|
+
const identity = resolveRepositoryIdentity(repo);
|
|
368
655
|
const id = required(args, 'id');
|
|
369
656
|
const expectedRevision = revision(args);
|
|
370
|
-
const task =
|
|
657
|
+
const task = workflow.store.readTask(identity.projectId, id);
|
|
371
658
|
if (task.revision !== expectedRevision) {
|
|
372
659
|
throw new WorkflowError('STATE_CONFLICT', `State revision conflict for ${id}`, {
|
|
373
660
|
expectedRevision,
|
|
@@ -375,30 +662,119 @@ async function dispatch(args) {
|
|
|
375
662
|
});
|
|
376
663
|
}
|
|
377
664
|
const envelope = workflow.taskContext(repo, id, 'independent-reviewer');
|
|
378
|
-
const launch = launchStrictReviewer(
|
|
665
|
+
const launch = launchStrictReviewer(identity.repositoryRoot, task, workflow.store.taskRoot(task.projectId, task.id), envelope);
|
|
666
|
+
// The independent reviewer identity belongs to the strict reviewer payload. CLI --actor
|
|
667
|
+
// remains the lifecycle mutation actor, such as the current C1 claimant.
|
|
379
668
|
const saved = workflow.recordReview(repo, id, expectedRevision, launch.review, option(args, 'actor'), option(args, 'writer-token') ?? null);
|
|
380
669
|
return { launch, task: saved };
|
|
381
670
|
}
|
|
671
|
+
if (noun === 'task' && action === 'review-packet') {
|
|
672
|
+
return workflow.prepareExternalTaskReview(repo, required(args, 'id'), revision(args));
|
|
673
|
+
}
|
|
674
|
+
if (noun === 'task' && action === 'review-sealed-record') {
|
|
675
|
+
return workflow.recordExternalTaskReview(repo, required(args, 'id'), revision(args), jsonFile(args), required(args, 'actor'), option(args, 'writer-token') ?? null);
|
|
676
|
+
}
|
|
382
677
|
if (noun === 'task' && action === 'step-review') {
|
|
678
|
+
// Strict Step Review launches and records the isolated reviewer inside Core. CLI --actor
|
|
679
|
+
// remains the lifecycle actor from next, typically the active C1 claimant.
|
|
383
680
|
return workflow.reviewStep(repo, required(args, 'id'), required(args, 'step'), revision(args), undefined, option(args, 'actor'), option(args, 'writer-token') ?? null);
|
|
384
681
|
}
|
|
682
|
+
if (noun === 'task' && action === 'step-review-packet') {
|
|
683
|
+
return workflow.prepareExternalStepReview(repo, required(args, 'id'), required(args, 'step'), revision(args));
|
|
684
|
+
}
|
|
685
|
+
if (noun === 'task' && action === 'step-review-record') {
|
|
686
|
+
return workflow.recordExternalStepReview(repo, required(args, 'id'), required(args, 'step'), revision(args), jsonFile(args), required(args, 'actor'), option(args, 'writer-token') ?? null);
|
|
687
|
+
}
|
|
385
688
|
if (noun === 'task' && action === 'corrective-decision-recover') {
|
|
386
689
|
return workflow.recoverStepCorrectiveDecision(repo, required(args, 'id'), required(args, 'step'), revision(args), required(args, 'actor'), option(args, 'writer-token') ?? null);
|
|
387
690
|
}
|
|
388
691
|
if (noun === 'task' && action === 'remediation-mode-recover') {
|
|
389
692
|
return workflow.recoverRemediationMode(repo, required(args, 'id'), required(args, 'step'), revision(args), required(args, 'actor'), option(args, 'writer-token') ?? null);
|
|
390
693
|
}
|
|
694
|
+
if (noun === 'task' && action === 'plan-integrity-recover') {
|
|
695
|
+
return workflow.recoverPlanIntegrity(repo, required(args, 'id'), required(args, 'step'), revision(args), required(args, 'actor'), option(args, 'writer-token') ?? null);
|
|
696
|
+
}
|
|
391
697
|
if (noun === 'task' && action === 'corrective-decision') {
|
|
392
698
|
return workflow.recordStepCorrectiveDecision(repo, required(args, 'id'), required(args, 'step'), revision(args), jsonFile(args), option(args, 'actor'), option(args, 'writer-token') ?? null);
|
|
393
699
|
}
|
|
394
|
-
if (noun === 'task' &&
|
|
395
|
-
return workflow.
|
|
700
|
+
if (noun === 'task' && action === 'corrective-yield') {
|
|
701
|
+
return workflow.executeCorrectiveYield(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'writer-token'), required(args, 'reason'));
|
|
702
|
+
}
|
|
703
|
+
if (noun === 'task' && action === 'corrective-yield-recover') {
|
|
704
|
+
return workflow.recoverCorrectiveYield(repo, required(args, 'id'), required(args, 'transaction-id'));
|
|
705
|
+
}
|
|
706
|
+
if (noun === 'task' && action === 'corrective-replan-prepare') {
|
|
707
|
+
return workflow.prepareCorrectiveReplan(repo, required(args, 'id'), jsonFile(args));
|
|
708
|
+
}
|
|
709
|
+
if (noun === 'task' && action === 'corrective-replan-confirm') {
|
|
710
|
+
return workflow.confirmCorrectiveReplan(repo, required(args, 'id'), jsonFile(args), jsonFile(args, 'gate-file'), required(args, 'confirmation-code'));
|
|
711
|
+
}
|
|
712
|
+
if (noun === 'task' && action === 'corrective-replan-execute') {
|
|
713
|
+
return workflow.executeCorrectiveReplan(repo, required(args, 'id'), jsonFile(args), jsonFile(args, 'credential-file'));
|
|
714
|
+
}
|
|
715
|
+
if (noun === 'task' && action === 'corrective-replan-recover') {
|
|
716
|
+
return workflow.recoverCorrectiveReplan(repo, required(args, 'id'), required(args, 'transaction-id'));
|
|
717
|
+
}
|
|
718
|
+
if (noun === 'task' && (action === 'handoff' || action === 'handoff-prepare' || action === 'handoff-replace')) {
|
|
719
|
+
const replacePending = action === 'handoff-replace';
|
|
720
|
+
const outcome = workflow.handoffTask(repo, required(args, 'id'), revision(args), required(args, 'actor'), replacePending
|
|
721
|
+
? required(args, 'target-actor')
|
|
722
|
+
: 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);
|
|
723
|
+
const { claimToken, ...bundle } = outcome.bundle;
|
|
724
|
+
return {
|
|
725
|
+
credentialHandoff: {
|
|
726
|
+
token: claimToken,
|
|
727
|
+
kind: 'claim-token',
|
|
728
|
+
targetActor: outcome.bundle.delegate,
|
|
729
|
+
action: 'task claim',
|
|
730
|
+
option: '--claim-token',
|
|
731
|
+
source: replacePending ? 'task handoff-replace' : 'task handoff-prepare',
|
|
732
|
+
sensitive: true,
|
|
733
|
+
oneTime: true,
|
|
734
|
+
},
|
|
735
|
+
task: outcome.task,
|
|
736
|
+
event: outcome.event,
|
|
737
|
+
bundle,
|
|
738
|
+
};
|
|
396
739
|
}
|
|
397
740
|
if (noun === 'task' && action === 'handoff-show') {
|
|
398
741
|
return workflow.showTaskHandoff(repo, required(args, 'id'));
|
|
399
742
|
}
|
|
400
743
|
if (noun === 'task' && action === 'claim') {
|
|
401
|
-
|
|
744
|
+
const outcome = workflow.claimTask(repo, required(args, 'id'), revision(args), required(args, 'actor'), required(args, 'claim-token'), option(args, 'writer-token') ?? null);
|
|
745
|
+
return {
|
|
746
|
+
writerCredential: { disposition: outcome.writerCredential.disposition },
|
|
747
|
+
...(outcome.writerCredential.disposition === 'issued' ? {
|
|
748
|
+
writerLeaseReceipt: {
|
|
749
|
+
token: outcome.writerCredential.token,
|
|
750
|
+
kind: 'writer-lease',
|
|
751
|
+
owner: outcome.lease.owner,
|
|
752
|
+
action: 'task run',
|
|
753
|
+
option: '--writer-token',
|
|
754
|
+
source: 'task claim',
|
|
755
|
+
sensitive: true,
|
|
756
|
+
oneTime: false,
|
|
757
|
+
},
|
|
758
|
+
} : {}),
|
|
759
|
+
task: outcome.task,
|
|
760
|
+
event: outcome.event,
|
|
761
|
+
lease: outcome.lease,
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
if (noun === 'task' && action === 'writer-credential-replace') {
|
|
765
|
+
const outcome = workflow.replaceClaimedWriterCredential(repo, required(args, 'id'), revision(args), required(args, 'actor'));
|
|
766
|
+
return {
|
|
767
|
+
writerCredential: { disposition: outcome.writerCredential.disposition },
|
|
768
|
+
writerLeaseReceipt: {
|
|
769
|
+
token: outcome.writerCredential.token,
|
|
770
|
+
kind: 'writer-lease',
|
|
771
|
+
source: 'task writer-credential-replace',
|
|
772
|
+
sensitive: true,
|
|
773
|
+
oneTime: false,
|
|
774
|
+
},
|
|
775
|
+
task: outcome.task,
|
|
776
|
+
lease: outcome.lease,
|
|
777
|
+
};
|
|
402
778
|
}
|
|
403
779
|
if (noun === 'task' && (action === 'handback' || action === 'handback-create')) {
|
|
404
780
|
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 +797,11 @@ async function dispatch(args) {
|
|
|
421
797
|
return workflow.confirmExternalMerge(repo, required(args, 'id'), revision(args), required(args, 'writer-token'), option(args, 'actor'));
|
|
422
798
|
}
|
|
423
799
|
if (noun === 'milestone' && action === 'show') {
|
|
424
|
-
const
|
|
425
|
-
return
|
|
800
|
+
const identity = resolveRepositoryIdentity(repo);
|
|
801
|
+
return workflow.store.readMilestone(identity.projectId, required(args, 'id'));
|
|
802
|
+
}
|
|
803
|
+
if (noun === 'milestone' && action === 'progress') {
|
|
804
|
+
return workflow.milestoneProgress(repo, required(args, 'id'));
|
|
426
805
|
}
|
|
427
806
|
if (noun === 'milestone' && action === 'plan-set') {
|
|
428
807
|
return workflow.setMilestonePlan(repo, required(args, 'id'), revision(args), jsonFile(args));
|
|
@@ -455,39 +834,100 @@ async function dispatch(args) {
|
|
|
455
834
|
return workflow.cancelMilestone(repo, required(args, 'id'), revision(args), required(args, 'reason'));
|
|
456
835
|
}
|
|
457
836
|
if (noun === 'locks' && (action === 'inspect' || action === 'repair')) {
|
|
458
|
-
const context = workflow.context(repo);
|
|
459
837
|
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;
|
|
838
|
+
if (action === 'repair')
|
|
839
|
+
return workflow.repairStaleWriterLease(repo, id);
|
|
840
|
+
const inspection = workflow.inspectWriterLease(repo, id);
|
|
841
|
+
return inspection ? { ...inspection, repaired: false } : null;
|
|
473
842
|
}
|
|
474
843
|
throw new WorkflowError('INVALID_ARGUMENT', 'Unknown command.', {
|
|
475
844
|
command: args.positionals.join(' '),
|
|
476
845
|
hint: 'Use doctor, status, next, update preflight, state <action>, delegation <action>, project-memory <action>, discovery <action>, task <action>, milestone <action>, or locks <action>.',
|
|
477
846
|
});
|
|
478
847
|
}
|
|
848
|
+
function credentialAllowancesForResult(args, value) {
|
|
849
|
+
const [noun, action] = args.positionals;
|
|
850
|
+
if (!isRecord(value))
|
|
851
|
+
return [];
|
|
852
|
+
if (noun === 'task' && (action === 'run' || action === 'claim' || action === 'writer-credential-replace')) {
|
|
853
|
+
const disposition = isRecord(value.writerCredential) ? value.writerCredential.disposition : null;
|
|
854
|
+
const receipt = isRecord(value.writerLeaseReceipt) ? value.writerLeaseReceipt : null;
|
|
855
|
+
if (disposition === 'issued'
|
|
856
|
+
&& receipt?.kind === 'writer-lease'
|
|
857
|
+
&& receipt.source === `task ${action}`
|
|
858
|
+
&& receipt.sensitive === true) {
|
|
859
|
+
return [{ path: '$.writerLeaseReceipt.token' }];
|
|
860
|
+
}
|
|
861
|
+
return [];
|
|
862
|
+
}
|
|
863
|
+
if (noun === 'task' && (action === 'handoff' || action === 'handoff-prepare' || action === 'handoff-replace')) {
|
|
864
|
+
const receipt = isRecord(value.credentialHandoff) ? value.credentialHandoff : null;
|
|
865
|
+
if (receipt?.kind === 'claim-token'
|
|
866
|
+
&& receipt.source === (action === 'handoff-replace' ? 'task handoff-replace' : 'task handoff-prepare')
|
|
867
|
+
&& receipt.sensitive === true
|
|
868
|
+
&& receipt.oneTime === true) {
|
|
869
|
+
return [{ path: '$.credentialHandoff.token' }];
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
return [];
|
|
873
|
+
}
|
|
874
|
+
function rawCredentialInputs(argv) {
|
|
875
|
+
const values = [];
|
|
876
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
877
|
+
const argument = argv[index];
|
|
878
|
+
for (const optionName of ['--writer-token', '--claim-token', '--confirmation-code']) {
|
|
879
|
+
if (argument === optionName && argv[index + 1])
|
|
880
|
+
values.push(argv[index + 1]);
|
|
881
|
+
if (argument.startsWith(`${optionName}=`))
|
|
882
|
+
values.push(argument.slice(optionName.length + 1));
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
return [...new Set(values.filter(Boolean))];
|
|
886
|
+
}
|
|
887
|
+
function isRecord(value) {
|
|
888
|
+
return typeof value === 'object' && value !== null;
|
|
889
|
+
}
|
|
479
890
|
async function main() {
|
|
891
|
+
const argv = process.argv.slice(2);
|
|
892
|
+
const sensitiveInputs = rawCredentialInputs(argv);
|
|
480
893
|
try {
|
|
481
|
-
const
|
|
894
|
+
const args = parseArguments(argv);
|
|
895
|
+
const value = await dispatch(args);
|
|
896
|
+
assertCliSuccessCredentialSafety(value, credentialAllowancesForResult(args, value), sensitiveInputs);
|
|
482
897
|
process.stdout.write(`${JSON.stringify({ ok: true, value }, null, 2)}\n`);
|
|
483
898
|
}
|
|
484
899
|
catch (error) {
|
|
900
|
+
if (error instanceof UnsafeCredentialOutputError) {
|
|
901
|
+
process.stderr.write(`${JSON.stringify({
|
|
902
|
+
ok: false,
|
|
903
|
+
error: {
|
|
904
|
+
code: 'STATE_CORRUPT',
|
|
905
|
+
message: error.message,
|
|
906
|
+
details: { credentialPaths: error.paths },
|
|
907
|
+
},
|
|
908
|
+
}, null, 2)}\n`);
|
|
909
|
+
process.exitCode = 2;
|
|
910
|
+
return;
|
|
911
|
+
}
|
|
485
912
|
if (error instanceof WorkflowError) {
|
|
486
|
-
process.stderr.write(`${JSON.stringify({
|
|
913
|
+
process.stderr.write(`${JSON.stringify({
|
|
914
|
+
ok: false,
|
|
915
|
+
error: {
|
|
916
|
+
code: error.code,
|
|
917
|
+
message: projectCliErrorMessage(error.message, sensitiveInputs),
|
|
918
|
+
details: projectCliErrorValue(error.details, sensitiveInputs),
|
|
919
|
+
},
|
|
920
|
+
}, null, 2)}\n`);
|
|
487
921
|
process.exitCode = 2;
|
|
488
922
|
return;
|
|
489
923
|
}
|
|
490
|
-
process.stderr.write(`${JSON.stringify({
|
|
924
|
+
process.stderr.write(`${JSON.stringify({
|
|
925
|
+
ok: false,
|
|
926
|
+
error: {
|
|
927
|
+
code: 'UNEXPECTED',
|
|
928
|
+
message: projectCliErrorMessage(error instanceof Error ? error.message : String(error), sensitiveInputs),
|
|
929
|
+
},
|
|
930
|
+
}, null, 2)}\n`);
|
|
491
931
|
process.exitCode = 1;
|
|
492
932
|
}
|
|
493
933
|
}
|