codex-workflow-v2 2.0.0-beta.14 → 2.0.0-beta.14.1

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 (93) hide show
  1. package/README.md +3 -3
  2. package/dist/reviewer-runtime-build.json +24 -20
  3. package/dist/src/alpha6/adoption.d.ts +1 -1
  4. package/dist/src/alpha6/adoption.js +26 -8
  5. package/dist/src/alpha6/adoption.js.map +1 -1
  6. package/dist/src/alpha6/corrective-decision-boundary.js +9 -3
  7. package/dist/src/alpha6/corrective-decision-boundary.js.map +1 -1
  8. package/dist/src/alpha6/remediation.d.ts +2 -0
  9. package/dist/src/alpha6/remediation.js +68 -2
  10. package/dist/src/alpha6/remediation.js.map +1 -1
  11. package/dist/src/alpha7/autonomy.d.ts +9 -0
  12. package/dist/src/alpha7/autonomy.js +40 -1
  13. package/dist/src/alpha7/autonomy.js.map +1 -1
  14. package/dist/src/beta1/project-transaction.js +14 -4
  15. package/dist/src/beta1/project-transaction.js.map +1 -1
  16. package/dist/src/cli-actions.d.ts +3 -3
  17. package/dist/src/cli-actions.js +5 -0
  18. package/dist/src/cli-actions.js.map +1 -1
  19. package/dist/src/cli.js +31 -1
  20. package/dist/src/cli.js.map +1 -1
  21. package/dist/src/contracts.d.ts +19 -2
  22. package/dist/src/delegation.d.ts +5 -1
  23. package/dist/src/delegation.js +4 -0
  24. package/dist/src/delegation.js.map +1 -1
  25. package/dist/src/failed-checkpoint-update.d.ts +69 -0
  26. package/dist/src/failed-checkpoint-update.js +171 -0
  27. package/dist/src/failed-checkpoint-update.js.map +1 -0
  28. package/dist/src/lifecycle/corrective-replan-credential-core.d.ts +2 -0
  29. package/dist/src/lifecycle/corrective-replan-credential-core.js +45 -9
  30. package/dist/src/lifecycle/corrective-replan-credential-core.js.map +1 -1
  31. package/dist/src/lifecycle/corrective-replan.js +12 -8
  32. package/dist/src/lifecycle/corrective-replan.js.map +1 -1
  33. package/dist/src/lifecycle/semantic-registry.js +4 -2
  34. package/dist/src/lifecycle/semantic-registry.js.map +1 -1
  35. package/dist/src/observed-routes.js +5 -0
  36. package/dist/src/observed-routes.js.map +1 -1
  37. package/dist/src/state/corrective-replan-executor.js +1 -0
  38. package/dist/src/state/corrective-replan-executor.js.map +1 -1
  39. package/dist/src/state/corrective-replan-public.d.ts +9 -1
  40. package/dist/src/state/corrective-replan-public.js +49 -7
  41. package/dist/src/state/corrective-replan-public.js.map +1 -1
  42. package/dist/src/version.d.ts +1 -1
  43. package/dist/src/version.js +1 -1
  44. package/dist/src/version.js.map +1 -1
  45. package/dist/src/workflow-blocker-route.js +1 -1
  46. package/dist/src/workflow-blocker-route.js.map +1 -1
  47. package/dist/src/workflow.d.ts +40 -1
  48. package/dist/src/workflow.js +203 -33
  49. package/dist/src/workflow.js.map +1 -1
  50. package/docs/autonomy-guardrails.md +4 -4
  51. package/docs/development-flow.md +8 -6
  52. package/docs/project-memory.md +2 -2
  53. package/docs/release.md +7 -1
  54. package/docs/updating-existing-project.md +37 -0
  55. package/package.json +1 -1
  56. package/plugins/codex-workflow-gateway/.codex-plugin/plugin.json +1 -1
  57. package/plugins/codex-workflow-gateway/references/chat-dispatch.md +17 -5
  58. package/plugins/codex-workflow-gateway/references/protocol.md +39 -43
  59. package/plugins/codex-workflow-gateway/scripts/chat-dispatch.mjs +13 -3
  60. package/plugins/codex-workflow-gateway/scripts/chat-model-policy.mjs +18 -33
  61. package/plugins/codex-workflow-gateway/skills/codex-workflow-gateway/SKILL.md +15 -10
  62. package/references/state-machine.md +3 -1
  63. package/roles/delivery-coordinator.md +31 -11
  64. package/roles/scope-lead.md +1 -1
  65. package/roles/technical-planner.md +4 -1
  66. package/schemas/adoption-posture-event.schema.json +11 -0
  67. package/schemas/authorization-event.schema.json +1 -1
  68. package/schemas/corrective-decision-event.schema.json +23 -3
  69. package/schemas/corrective-replan-credentials.private.schema.json +8 -5
  70. package/schemas/corrective-replan-execution-event.private.schema.json +9 -0
  71. package/schemas/corrective-replan-public.schema.json +2 -1
  72. package/schemas/delegation-grant.schema.json +1 -1
  73. package/schemas/task.schema.json +18 -0
  74. package/schemas/transition-definition.schema.json +4 -0
  75. package/src/alpha6/adoption.ts +30 -7
  76. package/src/alpha6/corrective-decision-boundary.ts +9 -3
  77. package/src/alpha6/remediation.ts +69 -2
  78. package/src/alpha7/autonomy.ts +39 -1
  79. package/src/beta1/project-transaction.ts +13 -4
  80. package/src/cli-actions.ts +5 -0
  81. package/src/cli.ts +33 -0
  82. package/src/contracts.ts +19 -1
  83. package/src/delegation.ts +5 -1
  84. package/src/failed-checkpoint-update.ts +203 -0
  85. package/src/lifecycle/corrective-replan-credential-core.ts +39 -10
  86. package/src/lifecycle/corrective-replan.ts +12 -8
  87. package/src/lifecycle/semantic-registry.ts +4 -2
  88. package/src/observed-routes.ts +5 -0
  89. package/src/state/corrective-replan-executor.ts +1 -0
  90. package/src/state/corrective-replan-public.ts +50 -6
  91. package/src/version.ts +1 -1
  92. package/src/workflow-blocker-route.ts +1 -1
  93. package/src/workflow.ts +192 -22
@@ -25,6 +25,17 @@
25
25
  "eventHash"
26
26
  ],
27
27
  "properties": {
28
+ "delegatedAuthorization": {
29
+ "type": "object", "additionalProperties": false,
30
+ "required": ["grantId", "policyHash", "principal", "delegate", "transition"],
31
+ "properties": {
32
+ "grantId": { "type": "string", "pattern": "^DGR-[0-9A-HJKMNP-TV-Z]{26}$" },
33
+ "policyHash": { "$ref": "#/$defs/hash64" },
34
+ "principal": { "type": "string", "minLength": 1 },
35
+ "delegate": { "type": "string", "pattern": "^agent:.+" },
36
+ "transition": { "const": "project.adopt" }
37
+ }
38
+ },
28
39
  "eventId": { "type": "string", "minLength": 1 },
29
40
  "projectId": { "type": "string", "pattern": "^[a-f0-9]{24}$" },
30
41
  "eventType": { "enum": ["project-registration", "adoption-apply"] },
@@ -52,7 +52,7 @@
52
52
  "delegate": { "type": "string", "minLength": 1 },
53
53
  "transition": {
54
54
  "enum": [
55
- "project_memory.approve",
55
+ "project.adopt", "project_memory.approve",
56
56
  "task.execution_authorize", "task.final_accept",
57
57
  "milestone.execution_authorize", "milestone.final_accept"
58
58
  ]
@@ -38,8 +38,9 @@
38
38
  "items": { "type": "string", "minLength": 1 }
39
39
  },
40
40
  "planHash": { "$ref": "#/$defs/hash64" },
41
- "recoveryBasis": { "const": "plan-integrity" },
41
+ "recoveryBasis": { "enum": ["plan-integrity", "planning-obstruction"] },
42
42
  "planIntegrityEvidence": { "$ref": "#/$defs/planIntegrityEvidence" },
43
+ "planningObstructionEvidence": { "$ref": "#/$defs/planningObstructionEvidence" },
43
44
  "previousEventHash": { "$ref": "#/$defs/nullableHash64" },
44
45
  "recordedAt": { "type": "string", "format": "date-time" },
45
46
  "eventHash": { "$ref": "#/$defs/hash64" }
@@ -48,17 +49,22 @@
48
49
  {
49
50
  "if": { "properties": { "triggeringAttemptCount": { "const": 2 } }, "required": ["triggeringAttemptCount"] },
50
51
  "then": {
51
- "required": ["recoveryBasis", "planIntegrityEvidence"],
52
+ "required": ["recoveryBasis"],
52
53
  "properties": { "decision": { "enum": ["continue-fix", "replan-required"] } }
53
54
  }
54
55
  },
55
56
  {
56
- "if": { "required": ["recoveryBasis"] },
57
+ "if": { "properties": { "recoveryBasis": { "const": "plan-integrity" } }, "required": ["recoveryBasis"] },
57
58
  "then": {
58
59
  "required": ["planIntegrityEvidence"]
59
60
  },
60
61
  "else": { "not": { "required": ["planIntegrityEvidence"] } }
61
62
  },
63
+ {
64
+ "if": { "properties": { "recoveryBasis": { "const": "planning-obstruction" } }, "required": ["recoveryBasis"] },
65
+ "then": { "required": ["planningObstructionEvidence"], "properties": { "triggeringAttemptCount": { "const": 2 }, "decision": { "const": "replan-required" } } },
66
+ "else": { "not": { "required": ["planningObstructionEvidence"] } }
67
+ },
62
68
  {
63
69
  "if": {
64
70
  "properties": {
@@ -83,6 +89,20 @@
83
89
  }
84
90
  ],
85
91
  "$defs": {
92
+ "planningObstructionEvidence": {
93
+ "type": "object", "additionalProperties": false,
94
+ "required": ["kind", "taskRevision", "sourcePlanHash", "baselinePlanHash", "baselineAuditEventId", "baselineAuditEventHash", "obstructionAuditEventId", "obstructionAuditEventHash", "priorAuthorizationHash", "remediationEventId", "remediationEventHash", "knowledgeRebindCount", "knowledgeRebindHash"],
95
+ "properties": {
96
+ "kind": { "const": "first-failure-rebound-planning-obstruction" },
97
+ "taskRevision": { "type": "integer", "minimum": 1 },
98
+ "sourcePlanHash": { "$ref": "#/$defs/hash64" }, "baselinePlanHash": { "$ref": "#/$defs/hash64" },
99
+ "baselineAuditEventId": { "type": "string", "minLength": 1 }, "baselineAuditEventHash": { "$ref": "#/$defs/hash64" },
100
+ "obstructionAuditEventId": { "type": "string", "minLength": 1 }, "obstructionAuditEventHash": { "$ref": "#/$defs/hash64" },
101
+ "priorAuthorizationHash": { "$ref": "#/$defs/hash64" },
102
+ "remediationEventId": { "type": "string", "minLength": 1 }, "remediationEventHash": { "$ref": "#/$defs/hash64" },
103
+ "knowledgeRebindCount": { "type": "integer", "minimum": 1 }, "knowledgeRebindHash": { "$ref": "#/$defs/hash64" }
104
+ }
105
+ },
86
106
  "taskId": { "type": "string", "pattern": "^TASK-[0-9A-HJKMNP-TV-Z]{26}$" },
87
107
  "stepId": { "type": "string", "pattern": "^STEP-[0-9]{3}(?:-[A-Z0-9-]+)?$" },
88
108
  "hash64": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
@@ -10,6 +10,7 @@
10
10
  "required": ["id", "version"],
11
11
  "properties": { "id": { "$ref": "#/$defs/id" }, "version": { "const": 1 } }
12
12
  },
13
+ "delegatedAuthority": {"type": "object", "additionalProperties": false, "required": ["grantId", "policyHash", "principal", "delegate", "transition", "expiresAt"], "properties": {"grantId": {"$ref": "#/$defs/id"}, "policyHash": {"$ref": "#/$defs/hash"}, "principal": {"$ref": "#/$defs/id"}, "delegate": {"$ref": "#/$defs/id"}, "transition": {"const": "task.execution_authorize"}, "expiresAt": {"type": "string", "format": "date-time"}}},
13
14
  "bindingValues": {
14
15
  "type": "object", "additionalProperties": false,
15
16
  "required": ["transitionId", "runtimeFingerprint", "catalogHash", "lifecycleEpoch", "taskId", "revision", "currentPlanHash", "briefHash", "knowledgeRevision", "knowledgeHash", "targetKnowledgeRevision", "targetKnowledgeHash", "gitHead", "guardedStepId", "correctiveDecisionEventId", "correctiveDecisionHash", "attemptCount", "remediationTailHash", "candidatePlanHash", "candidateStepSetHash", "planAuthorIdentityHash", "planValidationHash", "planValidatorIdentityHash", "riskAuditHash", "riskAuditorIdentityHash", "actorIdentityHash", "actorRole", "humanPrincipalIdentityHash", "capabilityId", "capabilityVersion"],
@@ -23,7 +24,7 @@
23
24
  "targetKnowledgeRevision": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
24
25
  "targetKnowledgeHash": { "$ref": "#/$defs/hash" }, "gitHead": { "type": "string", "pattern": "^(?:[a-f0-9]{40}|[a-f0-9]{64})$" },
25
26
  "guardedStepId": { "$ref": "#/$defs/id" }, "correctiveDecisionEventId": { "$ref": "#/$defs/id" },
26
- "correctiveDecisionHash": { "$ref": "#/$defs/hash" }, "attemptCount": { "type": "integer", "minimum": 2, "maximum": 9007199254740991 },
27
+ "correctiveDecisionHash": { "$ref": "#/$defs/hash" }, "attemptCount": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 },
27
28
  "remediationTailHash": { "$ref": "#/$defs/hash" }, "candidatePlanHash": { "$ref": "#/$defs/hash" },
28
29
  "candidateStepSetHash": { "$ref": "#/$defs/hash" }, "planAuthorIdentityHash": { "$ref": "#/$defs/hash" },
29
30
  "planValidationHash": { "$ref": "#/$defs/hash" }, "planValidatorIdentityHash": { "$ref": "#/$defs/hash" },
@@ -45,10 +46,10 @@
45
46
  "required": ["id", "version", "issuer", "source", "scope", "delegation"],
46
47
  "properties": {
47
48
  "id": { "const": "capability.task.corrective-replan" }, "version": { "const": 1 },
48
- "issuer": { "type": "object", "additionalProperties": false, "required": ["kind", "identityHash"], "properties": { "kind": { "const": "human" }, "identityHash": { "$ref": "#/$defs/hash" } } },
49
- "source": { "const": "human-confirmation" },
49
+ "issuer": { "type": "object", "additionalProperties": false, "required": ["kind", "identityHash"], "properties": { "kind": { "enum": ["human", "delegate"] }, "identityHash": { "$ref": "#/$defs/hash" } } },
50
+ "source": { "enum": ["human-confirmation", "delegation-grant"] },
50
51
  "scope": { "type": "object", "additionalProperties": false, "required": ["transitionId", "taskId", "candidatePlanHash", "manifestSha256"], "properties": { "transitionId": { "const": "task.plan.corrective-replan" }, "taskId": { "$ref": "#/$defs/id" }, "candidatePlanHash": { "$ref": "#/$defs/hash" }, "manifestSha256": { "$ref": "#/$defs/hash" } } },
51
- "delegation": { "const": "forbidden" }
52
+ "delegation": { "oneOf": [{ "const": "forbidden" }, { "$ref": "#/$defs/delegatedAuthority" }] }
52
53
  }
53
54
  },
54
55
  "bindingSha256": { "$ref": "#/$defs/hash" }
@@ -82,10 +83,12 @@
82
83
  "receiptValidation": { "type": "object", "additionalProperties": false, "required": ["attestationId", "attestationHash", "planValidationHash", "snapshotBindingHash", "planAuthorIdentityHash", "planValidatorIdentityHash", "findingsHash", "dispositionsHash", "validatedAtMs", "expiresAtMs"], "properties": { "attestationId": { "$ref": "#/$defs/id" }, "attestationHash": { "$ref": "#/$defs/hash" }, "planValidationHash": { "$ref": "#/$defs/hash" }, "snapshotBindingHash": { "$ref": "#/$defs/hash" }, "planAuthorIdentityHash": { "$ref": "#/$defs/hash" }, "planValidatorIdentityHash": { "$ref": "#/$defs/hash" }, "findingsHash": { "$ref": "#/$defs/hash" }, "dispositionsHash": { "$ref": "#/$defs/hash" }, "validatedAtMs": { "$ref": "#/$defs/time" }, "expiresAtMs": { "$ref": "#/$defs/time" } } },
83
84
  "correctiveReplanReceiptV1": {
84
85
  "type": "object", "additionalProperties": false,
85
- "required": ["schemaVersion", "receiptId", "domain", "binding", "validation", "audit", "human", "supersession", "issuedAtMs", "expiresAtMs", "domainHash", "receiptHash"],
86
+ "oneOf": [{ "required": ["human"], "properties": { "human": {}, "delegated": false } }, { "required": ["delegated"], "properties": { "delegated": {}, "human": false } }],
87
+ "required": ["schemaVersion", "receiptId", "domain", "binding", "validation", "audit", "supersession", "issuedAtMs", "expiresAtMs", "domainHash", "receiptHash"],
86
88
  "properties": {
87
89
  "schemaVersion": { "const": 1 }, "receiptId": { "$ref": "#/$defs/id" }, "domain": { "const": "codex-workflow/corrective-replan-receipt/v1" }, "binding": { "$ref": "#/$defs/correctiveReplanBindingV1" }, "validation": { "$ref": "#/$defs/receiptValidation" },
88
90
  "audit": { "type": "object", "additionalProperties": false, "required": ["riskAuditHash", "riskAuditorIdentityHash"], "properties": { "riskAuditHash": { "$ref": "#/$defs/hash" }, "riskAuditorIdentityHash": { "$ref": "#/$defs/hash" } } },
91
+ "delegated": { "type": "object", "additionalProperties": false, "required": ["authority", "authorizedAtMs"], "properties": { "authority": { "$ref": "#/$defs/delegatedAuthority" }, "authorizedAtMs": { "$ref": "#/$defs/time" } } },
89
92
  "human": { "type": "object", "additionalProperties": false, "required": ["challengeId", "challengeHash", "humanPrincipalIdentityHash", "confirmedAtMs"], "properties": { "challengeId": { "$ref": "#/$defs/id" }, "challengeHash": { "$ref": "#/$defs/hash" }, "humanPrincipalIdentityHash": { "$ref": "#/$defs/hash" }, "confirmedAtMs": { "$ref": "#/$defs/time" } } },
90
93
  "supersession": { "type": "object", "additionalProperties": false, "required": ["priorGrantHash", "disposition"], "properties": { "priorGrantHash": { "$ref": "#/$defs/hash" }, "disposition": { "const": "superseded" } } },
91
94
  "issuedAtMs": { "$ref": "#/$defs/time" }, "expiresAtMs": { "$ref": "#/$defs/time" }, "domainHash": { "$ref": "#/$defs/hash" }, "receiptHash": { "$ref": "#/$defs/hash" }
@@ -42,6 +42,15 @@
42
42
  "planRiskAuditEventHash": { "$ref": "#/$defs/hash" },
43
43
  "actorIdentityHash": { "$ref": "#/$defs/hash" },
44
44
  "humanPrincipalIdentityHash": { "$ref": "#/$defs/hash" },
45
+ "delegatedAuthority": {
46
+ "type": "object", "additionalProperties": false,
47
+ "required": ["grantId", "policyHash", "principal", "delegate", "transition", "expiresAt"],
48
+ "properties": {
49
+ "grantId": { "type": "string", "minLength": 1 }, "policyHash": { "$ref": "#/$defs/hash" },
50
+ "principal": { "type": "string", "minLength": 1 }, "delegate": { "type": "string", "minLength": 1 },
51
+ "transition": { "const": "task.execution_authorize" }, "expiresAt": { "type": "string", "format": "date-time" }
52
+ }
53
+ },
45
54
  "priorGrantHash": { "$ref": "#/$defs/hash" },
46
55
  "taskStateSha256": { "$ref": "#/$defs/hash" },
47
56
  "planBytesSha256": { "$ref": "#/$defs/hash" },
@@ -10,6 +10,7 @@
10
10
  "additionalProperties": false,
11
11
  "required": ["plan", "validation", "riskAudit", "authority"],
12
12
  "properties": {
13
+ "delegation": { "type": "object", "additionalProperties": false, "required": ["grantId", "actor"], "properties": { "grantId": { "$ref": "#/$defs/id" }, "actor": { "$ref": "#/$defs/id" } } },
13
14
  "plan": { "$ref": "https://codex-workflow.local/schemas/transition-payloads.schema.json#/$defs/taskPlanInput" },
14
15
  "validation": {
15
16
  "type": "object",
@@ -69,7 +70,7 @@
69
70
  "additionalProperties": false,
70
71
  "required": ["kind", "version", "taskId", "preparedAtMs", "expiresAtMs", "candidatePlanHash", "bindingSha256", "attestationId", "attestationHash", "challengeId", "runtimeFingerprint", "catalogHash", "lifecycleEpoch", "preparationSha256"],
71
72
  "properties": {
72
- "kind": { "const": "corrective-replan-human-gate" },
73
+ "kind": { "enum": ["corrective-replan-human-gate", "corrective-replan-delegated-binding"] },
73
74
  "version": { "const": 1 },
74
75
  "taskId": { "$ref": "#/$defs/id" },
75
76
  "preparedAtMs": { "$ref": "#/$defs/time" },
@@ -54,7 +54,7 @@
54
54
  "uniqueItems": true,
55
55
  "items": {
56
56
  "enum": [
57
- "project_memory.approve",
57
+ "project.adopt", "project_memory.approve",
58
58
  "task.execution_authorize", "task.final_accept",
59
59
  "milestone.execution_authorize", "milestone.final_accept"
60
60
  ]
@@ -233,6 +233,24 @@
233
233
  },
234
234
  "additionalProperties": false
235
235
  },
236
+ "failedCheckpoint": {
237
+ "type": "object",
238
+ "required": ["protocol", "sourceHead", "sourcePlanHash", "stepId", "sourceDirtyHash", "targetDirtyHash", "dirtyFiles", "remediationEventId", "remediationEventHash", "sourceReceiptHash", "artifactHash"],
239
+ "properties": {
240
+ "protocol": { "const": "failed-checkpoint-update-v1" },
241
+ "sourceHead": { "type": "string", "pattern": "^[a-f0-9]{40}$" },
242
+ "sourcePlanHash": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
243
+ "stepId": { "type": "string", "pattern": "^STEP-[A-Z0-9][A-Z0-9-]{2,63}$" },
244
+ "sourceDirtyHash": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
245
+ "targetDirtyHash": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
246
+ "dirtyFiles": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "type": "string", "minLength": 1 } },
247
+ "remediationEventId": { "type": "string", "pattern": "^RME-[0-9A-HJKMNP-TV-Z]{26}$" },
248
+ "remediationEventHash": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
249
+ "sourceReceiptHash": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
250
+ "artifactHash": { "type": "string", "pattern": "^[a-f0-9]{64}$" }
251
+ },
252
+ "additionalProperties": false
253
+ },
236
254
  "rootCauseReplan": {
237
255
  "type": "object",
238
256
  "required": [
@@ -296,6 +296,7 @@
296
296
  "credential-verifier.corrective-replan.receipt@1"
297
297
  ],
298
298
  "delegationPolicies": [
299
+ "delegation.corrective-execution-exact@1",
299
300
  "delegation.forbidden@1"
300
301
  ],
301
302
  "effectAdapters": [
@@ -360,6 +361,7 @@
360
361
  "ownership.corrective-replan-clear@1"
361
362
  ],
362
363
  "principalBases": [
364
+ "principal-basis.bound-corrective-authority@1",
363
365
  "principal-basis.human-confirmation@1"
364
366
  ],
365
367
  "projections": [
@@ -763,6 +765,7 @@
763
765
  "properties": {
764
766
  "id": {
765
767
  "enum": [
768
+ "principal-basis.bound-corrective-authority",
766
769
  "principal-basis.human-confirmation"
767
770
  ]
768
771
  },
@@ -835,6 +838,7 @@
835
838
  "properties": {
836
839
  "id": {
837
840
  "enum": [
841
+ "delegation.corrective-execution-exact",
838
842
  "delegation.forbidden"
839
843
  ]
840
844
  },
@@ -1,5 +1,6 @@
1
1
  import type {
2
2
  AdoptionPostureEvent,
3
+ DelegatedAuthorizationEvidence,
3
4
  AdoptionRepositoryIdentity,
4
5
  AdoptionTaskBaseline,
5
6
  AdoptionTaskStepSnapshot,
@@ -8,6 +9,7 @@ import type {
8
9
  TaskStatus,
9
10
  } from '../contracts.js';
10
11
  import { PROTOCOL_VERSION, STATE_SCHEMA_VERSION } from '../contracts.js';
12
+ import { assertDelegationCanAuthorize } from '../delegation.js';
11
13
  import { WorkflowError } from '../errors.js';
12
14
  import type { RepositoryIdentity } from '../repository.js';
13
15
  import type { FileStateStore } from '../state/store.js';
@@ -243,8 +245,15 @@ export function applyAdoptionPosture(
243
245
  input: AdoptionPreparationInput,
244
246
  actor: string,
245
247
  confirmationCode: string,
248
+ grantId: string | null = null,
246
249
  ): AdoptionPostureEvent {
247
- const normalizedActor = normalizeHumanActor(actor, 'Adoption apply actor');
250
+ let delegatedAuthorization: DelegatedAuthorizationEvidence | undefined;
251
+ if (grantId) {
252
+ const grant = store.readDelegation(input.projectId, grantId);
253
+ delegatedAuthorization = assertDelegationCanAuthorize(grant, 'project.adopt', actor,
254
+ { kind: 'project', id: input.projectId }, input.now);
255
+ }
256
+ const normalizedActor = delegatedAuthorization ? actor.trim() : normalizeHumanActor(actor, 'Adoption apply actor');
248
257
  const currentPosture = readCurrentAdoptionPosture(store, input.projectId);
249
258
  if (currentPosture) {
250
259
  throw new WorkflowError('TRANSITION_BLOCKED', `Project ${input.projectId} already has an adoption posture.`, {
@@ -279,6 +288,7 @@ export function applyAdoptionPosture(
279
288
  adoptionBoundaryAt: input.now.toISOString(),
280
289
  recordedAt: input.now.toISOString(),
281
290
  actor: normalizedActor,
291
+ ...(delegatedAuthorization ? { delegatedAuthorization } : {}),
282
292
  confirmationCodeBindingHash: prepared.confirmationCodeBindingHash,
283
293
  };
284
294
  event.eventHash = computeSidecarEventHash(event);
@@ -403,6 +413,7 @@ function validateAdoptionPostureEvent(
403
413
  'projectId',
404
414
  'eventType',
405
415
  'actor',
416
+ 'delegatedAuthorization',
406
417
  'packageVersion',
407
418
  'protocolVersion',
408
419
  'stateSchemaVersion',
@@ -504,7 +515,7 @@ function validateAdoptionPostureEvent(
504
515
  validateTerminalTasks(event, file, line);
505
516
  validateActiveTasks(event, file, line);
506
517
  if (event.eventType === 'project-registration') {
507
- if (event.actor !== null || event.confirmationCodeBindingHash !== null) {
518
+ if (event.actor !== null || event.confirmationCodeBindingHash !== null || event.delegatedAuthorization !== undefined) {
508
519
  throw new WorkflowError('STATE_CORRUPT', 'Project registration adoption posture must not record actor or confirmation binding.', {
509
520
  file,
510
521
  line,
@@ -518,11 +529,23 @@ function validateAdoptionPostureEvent(
518
529
  eventId: event.eventId,
519
530
  });
520
531
  } else {
521
- validateStoredHumanActor(event.actor, 'Adoption apply actor', {
522
- file,
523
- line,
524
- eventId: event.eventId,
525
- });
532
+ if (event.delegatedAuthorization !== undefined) {
533
+ const evidence = event.delegatedAuthorization;
534
+ assertPlainObject(evidence, 'Adoption delegated authority', file, line);
535
+ assertExactKeys(evidence as unknown as Record<string, unknown>,
536
+ ['grantId', 'transition', 'principal', 'delegate', 'policyHash'],
537
+ 'Adoption delegated authority contains unexpected fields.', file, line);
538
+ if (['grantId', 'transition', 'principal', 'delegate', 'policyHash'].some((key) =>
539
+ typeof (evidence as unknown as Record<string, unknown>)[key] !== 'string')) {
540
+ throw new WorkflowError('STATE_CORRUPT', 'Adoption delegated authority fields must be strings.', { file, line });
541
+ }
542
+ if (!event.actor.startsWith('agent:') || evidence.delegate !== event.actor
543
+ || evidence.transition !== 'project.adopt' || !/^DGR-[0-9A-HJKMNP-TV-Z]{26}$/.test(evidence.grantId)
544
+ || !/^[a-f0-9]{64}$/.test(evidence.policyHash) || !evidence.principal || evidence.principal.startsWith('agent:'))
545
+ throw new WorkflowError('STATE_CORRUPT', 'Adoption delegated authority is invalid.');
546
+ } else {
547
+ validateStoredHumanActor(event.actor, 'Adoption apply actor', { file, line, eventId: event.eventId });
548
+ }
526
549
  if (event.confirmationCodeBindingHash === null) {
527
550
  throw new WorkflowError('STATE_CORRUPT', 'Adoption apply posture must record confirmationCodeBindingHash.', {
528
551
  file,
@@ -7,6 +7,8 @@ import { changedFiles, currentBranch, headCommit } from '../repository.js';
7
7
  import type { FileStateStore } from '../state/store.js';
8
8
  import { hashDirtyWorktree } from './downstream-proof.js';
9
9
  import { effectiveStepAllowedWrites, readRemediationEvents } from './remediation.js';
10
+ import { readTaskC1Posture } from './handoff.js';
11
+ import { readFailedCheckpointDirtyTransport } from '../failed-checkpoint-update.js';
10
12
 
11
13
  /** Checkout eligibility only: never an audit, writer credential, or permission to widen scope. */
12
14
  export function correctiveDecisionCheckoutEligible(
@@ -18,13 +20,17 @@ export function correctiveDecisionCheckoutEligible(
18
20
  validateTaskHistory(repository, task);
19
21
  const dirty = changedFiles(repository).sort();
20
22
  if (dirty.length === 0) return true;
21
- if (task.workspaceOwner !== 'local' || task.steps.some(step => step.status === 'in_progress')) return false;
23
+ if (!['local', 'external'].includes(task.workspaceOwner ?? '') || task.steps.some(step => step.status === 'in_progress')) return false;
24
+ if (task.workspaceOwner === 'external' && readTaskC1Posture(store, task).state !== 'claimed') return false;
22
25
  const step = task.steps.find(candidate => candidate.id === stepId);
23
26
  const pause = step?.failurePause;
24
27
  if (step?.status !== 'failed' || !pause) return false;
25
28
  const terminal = readRemediationEvents(store, task).filter(event => event.stepId === stepId).at(-1);
29
+ const transport = terminal?.failureEvidence.dirtyWorktreeHash
30
+ ? readFailedCheckpointDirtyTransport(store, repository, task, stepId,
31
+ terminal.failureEvidence.completionCommit, terminal.failureEvidence.dirtyWorktreeHash) : null;
26
32
  if (!terminal || terminal.failureKind !== 'checks-failed'
27
- || terminal.failureEvidence.completionCommit !== headCommit(repository)
33
+ || (transport?.targetHead ?? terminal.failureEvidence.completionCommit) !== headCommit(repository)
28
34
  || terminal.failureEvidence.checksHash !== pause.checksHash
29
35
  || terminal.failureEvidence.dirtyWorktreeHash !== pause.dirtyWorktreeHash
30
36
  || JSON.stringify(dirty) !== JSON.stringify([...pause.dirtyFiles].sort())) return false;
@@ -35,5 +41,5 @@ export function correctiveDecisionCheckoutEligible(
35
41
  try { if (!lstatSync(path.join(repository, file)).isFile()) return false; }
36
42
  catch (error) { if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error; }
37
43
  }
38
- return hashDirtyWorktree(repository, dirty) === pause.dirtyWorktreeHash;
44
+ return hashDirtyWorktree(repository, dirty) === (transport?.targetDirtyHash ?? pause.dirtyWorktreeHash);
39
45
  }
@@ -38,6 +38,7 @@ import {
38
38
  import { correctiveReplanBoundaryMatchesStep, readCompletedCorrectiveReplanHistory } from '../state/corrective-replan-executor.js';
39
39
  import { semanticBoundaryHash, validLiteralTestInvocationEvidence } from './component-owner.js';
40
40
  import { reviewerCauseFingerprint } from './remediation-cause.js';
41
+ import { readFailedStepPlanningRecovery } from './failed-step-planning-recovery.js';
41
42
 
42
43
  export const REMEDIATION_EVENTS_SIDECAR = 'remediation-events.jsonl';
43
44
  export const CORRECTIVE_DECISIONS_SIDECAR = 'corrective-decisions.jsonl';
@@ -419,6 +420,27 @@ function findCorrectiveRecoveryDecisionIdForFailure(
419
420
  return recoveries[0]?.correctiveDecisionEventId ?? null;
420
421
  }
421
422
 
423
+ /** A first failed execution plus immutable rebound obstruction is planning evidence, not permission to retry. */
424
+ export function firstFailurePlanningObstructionEvidence(
425
+ store: FileStateStore,
426
+ task: TaskState,
427
+ stepId: string,
428
+ ): NonNullable<CorrectiveDecisionEvent['planningObstructionEvidence']> | null {
429
+ const failures = readRemediationEvents(store, task).filter(event => event.stepId === stepId);
430
+ if (failures.length !== 1 || task.steps.find(step => step.id === stepId)?.status !== 'failed') return null;
431
+ const recovery = readFailedStepPlanningRecovery(store, task);
432
+ if (!recovery || !recovery.current.reviewRequiredStepIds.includes(stepId)) return null;
433
+ return {
434
+ kind: 'first-failure-rebound-planning-obstruction', taskRevision: task.revision,
435
+ sourcePlanHash: task.planHash!, baselinePlanHash: recovery.baseline.planHash,
436
+ baselineAuditEventId: recovery.baseline.eventId, baselineAuditEventHash: recovery.baseline.eventHash,
437
+ obstructionAuditEventId: recovery.current.audit.eventId, obstructionAuditEventHash: recovery.current.audit.eventHash,
438
+ priorAuthorizationHash: hashCanonical(recovery.priorAuthorization),
439
+ remediationEventId: failures[0]!.eventId, remediationEventHash: failures[0]!.eventHash,
440
+ knowledgeRebindCount: task.knowledgeRebinds.length, knowledgeRebindHash: hashCanonical(task.knowledgeRebinds),
441
+ };
442
+ }
443
+
422
444
  export function appendCorrectiveDecisionEvent(
423
445
  store: FileStateStore,
424
446
  task: TaskState,
@@ -431,7 +453,9 @@ export function appendCorrectiveDecisionEvent(
431
453
  validateCorrectiveDecisionAudit(correctiveAudit);
432
454
  const remediationEvents = readRemediationEvents(store, task).filter((event) => event.stepId === stepId);
433
455
  const triggeringAttemptCount = remediationEvents.length + 1;
434
- if (triggeringAttemptCount < 3) {
456
+ const planningObstructionEvidence = triggeringAttemptCount === 2 && correctiveAudit.decision === 'replan-required'
457
+ ? firstFailurePlanningObstructionEvidence(store, task, stepId) : null;
458
+ if (triggeringAttemptCount < 3 && !planningObstructionEvidence) {
435
459
  throw new WorkflowError(
436
460
  'TRANSITION_BLOCKED',
437
461
  `Corrective decision is not available for ${stepId} before two guarded remediation failures exist.`,
@@ -500,6 +524,7 @@ export function appendCorrectiveDecisionEvent(
500
524
  stepId,
501
525
  triggeringAttemptCount,
502
526
  decision: correctiveAudit.decision,
527
+ ...(planningObstructionEvidence ? { recoveryBasis: 'planning-obstruction' as const, planningObstructionEvidence } : {}),
503
528
  auditor: correctiveAudit.auditor.trim(),
504
529
  coveredFindingIds,
505
530
  coveredEventIds,
@@ -645,6 +670,11 @@ export function readGuardedRemediationPostureForStep(
645
670
  ? findCurrentCorrectiveDecision(task, stepId, 2, history.correctiveDecisions)
646
671
  : null;
647
672
  const currentDecision = findCurrentCorrectiveDecision(task, stepId, history.nextAttemptOrdinal, history.correctiveDecisions);
673
+ if (remediationEvents.length === 1 && currentDecision === null
674
+ && firstFailurePlanningObstructionEvidence(store, task, stepId)) {
675
+ return { stepId, guardedCategory: requireGuardedCategory(planRiskAudit, stepId), attemptCount: 1,
676
+ nextAttemptOrdinal: history.nextAttemptOrdinal, mode: 'corrective', correctiveDecision: null, posture: 'decision-required' };
677
+ }
648
678
  if (remediationEvents.length < 2 && earlyPlanIntegrityDecision?.recoveryBasis !== 'plan-integrity'
649
679
  && currentDecision === null
650
680
  && deriveCurrentCauseDecision(remediationEvents, history.priorRemediationEvents) !== 'root-cause-replan') return null;
@@ -908,6 +938,11 @@ function deriveAttemptGateFromHistory(
908
938
  nextAttemptOrdinal,
909
939
  correctiveDecisions,
910
940
  );
941
+ if (currentCorrectiveDecision?.recoveryBasis === 'planning-obstruction') {
942
+ return { stepId, guardedCategory, attemptCount, nextAttemptOrdinal, mode: 'ordinary',
943
+ correctiveDecision: currentCorrectiveDecision,
944
+ posture: currentCorrectiveDecision.planHash === task.planHash ? 'replan-required' : 'replan-ready' };
945
+ }
911
946
  const planIntegrityDecision = currentCorrectiveDecision;
912
947
  if (planIntegrityDecision?.recoveryBasis === 'plan-integrity'
913
948
  && (planIntegrityDecision.planHash === task.planHash || planIntegrityDecision.decision === 'replan-required'
@@ -1414,7 +1449,19 @@ function validateStoredCorrectiveDecisionEvent(
1414
1449
  normalizeStringList(event.coveredFindingIds, 'Corrective decision coveredFindingIds');
1415
1450
  normalizeStringList(event.coveredEventIds, 'Corrective decision coveredEventIds');
1416
1451
  assertHash64(event.planHash, `Corrective decision planHash at ${file}:${line}`);
1417
- if (event.recoveryBasis === 'plan-integrity' || event.planIntegrityEvidence !== undefined) {
1452
+ if (event.recoveryBasis === 'planning-obstruction' || event.planningObstructionEvidence !== undefined) {
1453
+ const evidence = event.planningObstructionEvidence;
1454
+ if (!evidence || event.recoveryBasis !== 'planning-obstruction' || event.planIntegrityEvidence !== undefined
1455
+ || evidence.kind !== 'first-failure-rebound-planning-obstruction' || event.decision !== 'replan-required'
1456
+ || event.triggeringAttemptCount !== 2 || evidence.sourcePlanHash !== event.planHash
1457
+ || !Number.isSafeInteger(evidence.taskRevision) || evidence.taskRevision < 1
1458
+ || !Number.isSafeInteger(evidence.knowledgeRebindCount) || evidence.knowledgeRebindCount < 1
1459
+ || event.coveredEventIds.length !== 1 || event.coveredEventIds[0] !== evidence.remediationEventId) {
1460
+ throw new WorkflowError('STATE_CORRUPT', 'First-failure planning obstruction requires exact bounded proof.', { file, line, taskId: task.id });
1461
+ }
1462
+ for (const key of ['sourcePlanHash', 'baselinePlanHash', 'baselineAuditEventHash', 'obstructionAuditEventHash',
1463
+ 'priorAuthorizationHash', 'remediationEventHash', 'knowledgeRebindHash'] as const) assertHash64(evidence[key], `Planning obstruction ${key}`);
1464
+ } else if (event.recoveryBasis === 'plan-integrity' || event.planIntegrityEvidence !== undefined) {
1418
1465
  validatePlanIntegrityDecision(event, task, file, line);
1419
1466
  } else if (event.triggeringAttemptCount === 2) {
1420
1467
  throw new WorkflowError('STATE_CORRUPT', 'A second-attempt corrective decision requires bounded Plan-integrity evidence.', {
@@ -2200,6 +2247,26 @@ function validateCorrectiveDecisionCoverage(
2200
2247
  });
2201
2248
  }
2202
2249
  }
2250
+ if (decision.recoveryBasis === 'planning-obstruction') {
2251
+ const proof = decision.planningObstructionEvidence!;
2252
+ const audits = readPlanRiskAuditEvents(store, task);
2253
+ const baseline = audits.find(event => event.eventId === proof.baselineAuditEventId && event.eventHash === proof.baselineAuditEventHash);
2254
+ const obstruction = audits.find(event => event.eventId === proof.obstructionAuditEventId && event.eventHash === proof.obstructionAuditEventHash);
2255
+ const failed = priorEvents[0];
2256
+ if (!baseline || !obstruction || !['approved', 'approved-with-rationale'].includes(baseline.decision)
2257
+ || obstruction.decision !== 'stop-escalate' || audits.indexOf(baseline) >= audits.indexOf(obstruction)
2258
+ || baseline.planHash !== proof.baselinePlanHash || obstruction.planHash !== proof.sourcePlanHash
2259
+ || obstruction.taskRevision !== proof.taskRevision
2260
+ || baseline.briefHash !== obstruction.briefHash || baseline.briefHash !== task.briefHash
2261
+ || !failed || priorEvents.length !== 1 || failed.eventId !== proof.remediationEventId || failed.eventHash !== proof.remediationEventHash
2262
+ || !task.authorizations.some(authorization => authorization.kind === 'execution' && authorization.decision === 'superseded'
2263
+ && authorization.planHash === baseline.planHash && authorization.briefHash === baseline.briefHash
2264
+ && hashCanonical(authorization) === proof.priorAuthorizationHash)
2265
+ || task.knowledgeRebinds.length < proof.knowledgeRebindCount
2266
+ || hashCanonical(task.knowledgeRebinds.slice(0, proof.knowledgeRebindCount)) !== proof.knowledgeRebindHash) {
2267
+ throw new WorkflowError('STATE_CORRUPT', 'Planning-obstruction decision does not match immutable audit, authorization, rebind and failure history.', { taskId: task.id, decisionEventId: decision.eventId });
2268
+ }
2269
+ }
2203
2270
  if (decision.recoveryBasis === 'plan-integrity') {
2204
2271
  const evidence = decision.planIntegrityEvidence;
2205
2272
  const bindings = evidence?.kind === 'missing-npm-script-outside-allowed-writes'
@@ -6,7 +6,7 @@ import type {
6
6
  SidecarEventRecord,
7
7
  } from '../contracts.js';
8
8
  import { STATE_SCHEMA_VERSION } from '../contracts.js';
9
- import { hashDelegationPolicy } from '../delegation.js';
9
+ import { assertDelegationCanAuthorize, hashDelegationPolicy } from '../delegation.js';
10
10
  import { WorkflowError } from '../errors.js';
11
11
  import type { FileStateStore } from '../state/store.js';
12
12
  import { createEntityId, createUlid } from '../ulid.js';
@@ -284,6 +284,44 @@ export function applyMilestoneAutonomyContract(options: {
284
284
  return { contract: event, grant };
285
285
  }
286
286
 
287
+ /** Derive a contract without issuing, extending or reactivating a grant. */
288
+ export function bindMilestoneAutonomyToGrant(options: {
289
+ store: FileStateStore; projectId: string; milestone: MilestoneState;
290
+ actor: string; grantId: string; now: Date;
291
+ }): ActiveMilestoneAutonomy {
292
+ const { store, projectId, milestone, actor, now } = options;
293
+ if (!['awaiting_execution_authorization', 'active'].includes(milestone.status) || !milestone.planHash)
294
+ throw new WorkflowError('TRANSITION_BLOCKED', 'Autonomy binding requires a complete active Milestone Plan.');
295
+ const grant = store.readDelegation(projectId, options.grantId);
296
+ if (grant.scope.kind !== 'milestone' || grant.scope.id !== milestone.id)
297
+ throw new WorkflowError('TRANSITION_BLOCKED', 'Autonomy binding requires an exact Milestone grant.');
298
+ for (const transition of AUTONOMY_TRANSITIONS) {
299
+ if (transition !== 'project_memory.approve' && !grant.transitions.includes(transition))
300
+ throw new WorkflowError('TRANSITION_BLOCKED', `Autonomy binding requires ${transition}; request grant expansion.`);
301
+ }
302
+ assertDelegationCanAuthorize(grant, 'milestone.execution_authorize', actor, milestone, now);
303
+ const previous = readMilestoneAutonomyEvents(store, projectId, milestone.id).at(-1);
304
+ if (previous) {
305
+ if (previous.delegationGrantId === grant.id) return requireActiveMilestoneAutonomy(options);
306
+ if (previous.semanticScopeHash !== milestoneSemanticScopeHash(milestone))
307
+ throw new WorkflowError('TRANSITION_BLOCKED', 'Autonomy rebinding cannot change the approved semantic scope.');
308
+ let previousGrant: DelegationGrant | null = null;
309
+ try { previousGrant = store.readDelegation(projectId, previous.delegationGrantId); }
310
+ catch (error) { if (!(error instanceof WorkflowError) || error.code !== 'NOT_FOUND') throw error; }
311
+ if (previousGrant?.status === 'active' && Date.parse(previousGrant.expiresAt) > now.getTime())
312
+ throw new WorkflowError('TRANSITION_BLOCKED', 'Revoke the existing active grant before replacing its autonomy binding.');
313
+ }
314
+ const contract = store.appendSidecarEvent<MilestoneAutonomyEvent>(
315
+ store.milestoneRoot(projectId, milestone.id), AUTONOMY_SIDECAR, {
316
+ eventId: `MAC-${createUlid(now.getTime())}`, recordedAt: now.toISOString(), eventType: 'issued',
317
+ projectId, milestoneId: milestone.id, milestoneRevision: milestone.revision,
318
+ principal: grant.principal, delegate: grant.delegate, issuedAt: now.toISOString(), expiresAt: grant.expiresAt,
319
+ semanticScopeHash: milestoneSemanticScopeHash(milestone), delegationGrantId: grant.id,
320
+ delegationPolicyHash: grant.policyHash,
321
+ }, { validateEvent: candidate => validateMilestoneAutonomyEvent(candidate, projectId, milestone.id) });
322
+ return { contract, grant };
323
+ }
324
+
287
325
  export function requireActiveMilestoneAutonomy(options: {
288
326
  store: FileStateStore;
289
327
  projectId: string;
@@ -1,9 +1,9 @@
1
- import { createHash } from 'node:crypto';
2
- import { existsSync, lstatSync, readFileSync, readdirSync, rmSync } from 'node:fs';
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ import { existsSync, lstatSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from 'node:fs';
3
3
  import path from 'node:path';
4
4
  import os from 'node:os';
5
5
  import { WorkflowError } from '../errors.js';
6
- import { ensureDirectory, writeJsonAtomic, writeTextAtomic } from '../fs-utils.js';
6
+ import { ensureDirectory, writeJsonAtomic } from '../fs-utils.js';
7
7
 
8
8
  type TransactionPhase = 'prepared' | 'applying' | 'applied' | 'rolled_back';
9
9
 
@@ -311,7 +311,16 @@ function restoreSnapshot(file: string, snapshot: Snapshot): void {
311
311
  rmSync(file, { force: true });
312
312
  return;
313
313
  }
314
- writeTextAtomic(file, Buffer.from(snapshot.contentBase64!, 'base64').toString('utf8'));
314
+ // Snapshots preserve bytes; text normalization would corrupt newline-less or binary preimages.
315
+ const directory = path.dirname(file);
316
+ ensureDirectory(directory);
317
+ const temporary = path.join(directory, `.${path.basename(file)}.${randomUUID()}.tmp`);
318
+ try {
319
+ writeFileSync(temporary, Buffer.from(snapshot.contentBase64!, 'base64'), { mode: 0o600 });
320
+ renameSync(temporary, file);
321
+ } finally {
322
+ rmSync(temporary, { force: true });
323
+ }
315
324
  if (!snapshotsEqual(captureSnapshot(file), snapshot)) {
316
325
  throw new WorkflowError('STATE_CORRUPT', `Project transaction snapshot restore failed: ${file}`);
317
326
  }
@@ -12,6 +12,9 @@ const CLI_ACTIONS_LITERAL = {
12
12
  'navigation-source-preflight',
13
13
  'navigation-transport-preflight',
14
14
  'navigation-recover',
15
+ 'failed-checkpoint-source-preflight',
16
+ 'failed-checkpoint-transport-preflight',
17
+ 'failed-checkpoint-recover',
15
18
  'dependency-provenance-preflight',
16
19
  'dependency-provenance-recover',
17
20
  'historical-step-dependency-preflight',
@@ -51,6 +54,7 @@ const CLI_ACTIONS_LITERAL = {
51
54
  'corrective-yield',
52
55
  'corrective-yield-recover',
53
56
  'corrective-replan-prepare',
57
+ 'corrective-replan-authorize',
54
58
  'corrective-replan-confirm',
55
59
  'corrective-replan-execute',
56
60
  'corrective-replan-recover',
@@ -80,6 +84,7 @@ const CLI_ACTIONS_LITERAL = {
80
84
  'scope-change-apply',
81
85
  'autonomy-prepare',
82
86
  'autonomy-grant',
87
+ 'autonomy-bind',
83
88
  'autonomy-evolve',
84
89
  'authorize',
85
90
  'validate',