@cassiomc1/forgeloop 1.5.0 → 1.6.0

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 (126) hide show
  1. package/DOCS_INDEX.md +13 -8
  2. package/EXECUTION_STATE.md +20 -0
  3. package/LOOP_ENGINEERING.md +81 -0
  4. package/LOOP_SYSTEM_DESIGN.md +32 -0
  5. package/PROTOCOL_INTEGRATION.md +46 -0
  6. package/QUALITY_SCORECARD.md +2 -0
  7. package/README.md +31 -9
  8. package/THIRD_PARTY_NOTICES.md +15 -0
  9. package/THREAT_MODEL.md +39 -0
  10. package/docs/ARTIFACT_REFERENCE.md +140 -0
  11. package/docs/CLI_REFERENCE.md +294 -3
  12. package/docs/DIAGNOSTIC_MODEL.md +181 -0
  13. package/docs/DOCUMENTATION_GUIDE.md +22 -13
  14. package/docs/EXECUTION_TRACE.md +76 -0
  15. package/docs/MCP.md +33 -0
  16. package/docs/RECIPES.md +67 -0
  17. package/docs/TROUBLESHOOTING.md +106 -2
  18. package/docs/assets/diagrams/forgeloop-engineering-flow.html +13797 -0
  19. package/docs/assets/diagrams/forgeloop-engineering-flow.receipt.json +37 -0
  20. package/docs/assets/diagrams/forgeloop-engineering-flow.svg +5002 -0
  21. package/docs/diagrams/README.md +55 -0
  22. package/docs/diagrams/forgeloop-engineering-flow.workflow.json +122 -0
  23. package/docs/diagrams/manifest.json +42 -0
  24. package/docs/diagrams/reviews/forgeloop-engineering-flow.review.json +20 -0
  25. package/package.json +8 -6
  26. package/schemas/action.schema.json +100 -0
  27. package/schemas/approval.schema.json +51 -0
  28. package/schemas/capability-policy.schema.json +41 -0
  29. package/schemas/diagnostic-case.schema.json +85 -0
  30. package/schemas/execution-receipt.schema.json +16 -0
  31. package/schemas/hypothesis-disposition.schema.json +16 -0
  32. package/schemas/intervention.schema.json +27 -0
  33. package/schemas/policy-lock.schema.json +1 -0
  34. package/schemas/policy-snapshot.schema.json +2 -0
  35. package/schemas/trajectory-evaluation.schema.json +64 -0
  36. package/schemas/trajectory-scenario.schema.json +42 -0
  37. package/src/cli.js +94 -0
  38. package/src/commands/action-authorize.js +41 -0
  39. package/src/commands/action-propose.js +10 -0
  40. package/src/commands/action-reconcile.js +10 -0
  41. package/src/commands/action-record.js +47 -0
  42. package/src/commands/action-show.js +10 -0
  43. package/src/commands/action-verify.js +10 -0
  44. package/src/commands/advance.js +7 -2
  45. package/src/commands/approval-request.js +64 -0
  46. package/src/commands/approval-resolve.js +10 -0
  47. package/src/commands/baseline.js +3 -3
  48. package/src/commands/eval.js +6 -0
  49. package/src/commands/history.js +18 -0
  50. package/src/commands/init.js +2 -2
  51. package/src/commands/inspect.js +49 -0
  52. package/src/commands/metrics.js +7 -0
  53. package/src/commands/next.js +8 -2
  54. package/src/commands/policy-discover.js +2 -2
  55. package/src/commands/record-diagnosis.js +37 -1
  56. package/src/commands/record-hypothesis-disposition.js +45 -0
  57. package/src/commands/record-intervention.js +35 -0
  58. package/src/commands/reflect.js +38 -0
  59. package/src/commands/report.js +9 -1
  60. package/src/commands/run-action.js +18 -0
  61. package/src/commands/trace.js +34 -0
  62. package/src/commands/validate-protocol.js +21 -13
  63. package/src/core/action-authorization.js +106 -0
  64. package/src/core/action-constants.js +86 -0
  65. package/src/core/action-execution.js +105 -0
  66. package/src/core/action-ledger-projection.js +302 -0
  67. package/src/core/action-model.js +581 -0
  68. package/src/core/action-readiness.js +141 -0
  69. package/src/core/action-reconciliation-policy.js +49 -0
  70. package/src/core/action-reconciliation.js +66 -0
  71. package/src/core/action-verification.js +111 -0
  72. package/src/core/actions.js +462 -0
  73. package/src/core/approvals.js +405 -0
  74. package/src/core/artifact-registry.js +48 -0
  75. package/src/core/audit.js +25 -0
  76. package/src/core/bundles.js +15 -0
  77. package/src/core/capability-policy.js +226 -0
  78. package/src/core/cli-command-definitions.js +210 -1
  79. package/src/core/command-executors.js +171 -15
  80. package/src/core/command-runtime.js +12 -1
  81. package/src/core/completion-artifacts.js +37 -12
  82. package/src/core/completion-recovery-rebind.js +194 -0
  83. package/src/core/completion.js +70 -0
  84. package/src/core/continuity-reconciliation.js +24 -5
  85. package/src/core/diagnostic-model.js +396 -0
  86. package/src/core/diagnostic-projection.js +51 -0
  87. package/src/core/diagnostic-record.js +360 -0
  88. package/src/core/error-codes.js +343 -0
  89. package/src/core/events.js +41 -1
  90. package/src/core/execution-prerequisites.js +4 -1
  91. package/src/core/execution.js +26 -188
  92. package/src/core/failure-signature.js +70 -0
  93. package/src/core/failure-surface.js +57 -0
  94. package/src/core/history.js +110 -0
  95. package/src/core/hypothesis-projection.js +85 -0
  96. package/src/core/information-gain-projection.js +283 -0
  97. package/src/core/information-gain.js +138 -0
  98. package/src/core/inspect.js +105 -7
  99. package/src/core/integration-invocation-policy.js +47 -0
  100. package/src/core/integration-resources.js +51 -0
  101. package/src/core/next-action-model.js +35 -1
  102. package/src/core/next-action.js +459 -3
  103. package/src/core/phase.js +40 -21
  104. package/src/core/policy-engine.js +113 -6
  105. package/src/core/preflight-consistency.js +31 -5
  106. package/src/core/preflight.js +19 -2
  107. package/src/core/prepared-execution.js +227 -0
  108. package/src/core/progress.js +41 -4
  109. package/src/core/protocol-info.js +48 -0
  110. package/src/core/protocol.js +14 -0
  111. package/src/core/receipt.js +1 -0
  112. package/src/core/reconcile-closure.js +15 -12
  113. package/src/core/reflection.js +305 -0
  114. package/src/core/resumability.js +57 -3
  115. package/src/core/schema-validation.js +8 -0
  116. package/src/core/strategy-analysis.js +97 -0
  117. package/src/core/task-paths.js +28 -0
  118. package/src/core/task-snapshot.js +53 -0
  119. package/src/core/templates.js +8 -0
  120. package/src/core/trace.js +548 -0
  121. package/src/core/trajectory-evaluation.js +71 -0
  122. package/src/core/trajectory-metrics.js +80 -0
  123. package/src/core/transaction.js +8 -0
  124. package/src/core/work-state.js +10 -5
  125. package/docs/assets/forgeloop-flow.svg +0 -1
  126. package/docs/forgeloop-flow.mmd +0 -51
@@ -0,0 +1,76 @@
1
+ # ForgeLoop Execution Trace
2
+
3
+ Reference for `history`, `trace`, `reflect`, and task-level `inspect` observability projections (ForgeLoop 1.6.0+).
4
+
5
+ All views are deterministic read-only projections of canonical artifacts (event ledger + work state). There is no second truth store.
6
+
7
+ ## history
8
+
9
+ ```bash
10
+ forgeloop history --task <id> [--json] [--compact] [--verbose]
11
+ [--type <types>] [--phase <phases>] [--failures] [--checks]
12
+ [--since <ts>] [--until <ts>] [--limit <n>]
13
+ ```
14
+
15
+ Human output shows chronological events with timestamps from the ledger. JSON output includes:
16
+
17
+ - `snapshot`: consistency anchors (`stateRevision`, `ledgerTailSequence`)
18
+ - `summary`: event/check/diagnostic counts
19
+ - `historyQuality`: `COMPLETE | PARTIAL | MINIMAL` with reasons
20
+ - `integrity`: ledger validation result
21
+ - `events`: normalized events (category, phase, provenance, references)
22
+
23
+ Filters are presentation-only; they never weaken integrity validation. Truncation via `--limit` is explicit (`truncated: true`).
24
+
25
+ ## trace
26
+
27
+ ```bash
28
+ forgeloop trace --task <id> --json
29
+ ```
30
+
31
+ Machine-readable reconstruction containing events, lifecycle transitions (including `VERIFICATION_STARTED`), check attempts, diagnostics (legacy diagnoses, structured cases, interventions, dispositions), failure signatures/surfaces, executions, evidence, continuity, recovery, completion, integrity, and snapshot anchors.
32
+
33
+ Failure surfaces include every canonically verified cycle; a successful
34
+ verification appears explicitly as `surface: []`, enabling deterministic
35
+ `REDUCED -> empty` and intervention `IMPROVED` classification.
36
+
37
+ Attempt cardinality comes primarily from ledger chronology: one ledger attempt plus its state checkpoint counts once; two distinct ledger events count twice; a state-only check appears as one fallback attempt (`source: "state-fallback"`). Phases are reconstructed forward from milestone events (`TASK_RECEIVED -> RECEIVED` ... `COMPLETION_VALIDATED -> COMPLETE`); events between milestones carry derived phases (for example failed verification -> `DIAGNOSING`, recorded intervention -> `CORRECTING`) with `phaseQuality: "authoritative" | "derived" | "unknown"`. Determinism: identical canonical artifacts produce identical traces except `snapshot.capturedAt`.
38
+
39
+ ## reflect
40
+
41
+ ```bash
42
+ forgeloop reflect --task <id> [--json]
43
+ ```
44
+
45
+ Whole-task retrospective (gain truth comes from the canonical cycle analysis;
46
+ `stallAnalysis` explains historical repetition without changing the fail-fast
47
+ stall decision): verification cycles, failure surfaces, hypothesis summary, intervention effectiveness (`PENDING | INFORMATIVE | NON_INFORMATIVE | IMPROVED | REGRESSED`), strategy fingerprints, oscillation patterns, signals, and a recommended protocol action. Deterministic — ForgeLoop does not call an LLM.
48
+
49
+ ## inspect --task
50
+
51
+ `forgeloop inspect --task <id>` extends target health with an additive `taskInspection` section: snapshot, lifecycle transitions, history quality, verification attempts per requirement, diagnostic summary, progress evaluation, integrity issues, deterministic explanation reason codes, and the safe next command. Existing top-level inspect fields are unchanged.
52
+
53
+ ## Read-only invariant
54
+
55
+ `history`, `trace`, `reflect`, `inspect`, `progress` never mutate protocol state, acquire ownership, or append events. Test suites enforce this by hashing the complete `.forgeloop` tree before/after invocation.
56
+
57
+ ## Durable actions in the trace
58
+
59
+ `trace --json` adds an `actions` projection with totals, state and capability
60
+ counts, required/verified/failed/ambiguous counts, repeated idempotency-key
61
+ attempts, reconciliation count, and action-event count. The projection reads
62
+ the task action artifacts and the same ledger already used by history; it is
63
+ not a second source of lifecycle truth.
64
+
65
+ An action recorded as `COMMIT_UNKNOWN` is an external-state uncertainty, not a
66
+ diagnostic failure. Reflection surfaces `EXTERNAL_ACTION_RECONCILIATION_REQUIRED`
67
+ and recommends `RECONCILE_EXTERNAL_ACTION` before ordinary retry guidance.
68
+ `FORGELOOP_EXECUTED`, `HOST_REPORTED`, and `EXTERNAL_OBSERVED` remain distinct
69
+ provenance values.
70
+
71
+ `forgeloop metrics --task <id> --json` projects trajectory counts, action
72
+ outcomes, observed executions, and first/last authoritative ledger timestamps.
73
+ Usage fields remain `null` with `source: "UNKNOWN"` when the host did not
74
+ report them. `forgeloop eval --task <id> --scenario <path> --json` evaluates a
75
+ validated current trace against a project-local reference scenario; an
76
+ efficiency ratio is omitted when no positive comparable-step reference exists.
package/docs/MCP.md CHANGED
@@ -46,6 +46,39 @@ Capability flags (process-scoped, immutable after launch):
46
46
  - `forgeloop://task/{taskId}/ownership` — canonical validated ownership
47
47
  - `forgeloop://task/{taskId}/contract`
48
48
  - `forgeloop://task/{taskId}/continuity`
49
+ - `forgeloop://task/{taskId}/actions`
50
+ - `forgeloop://task/{taskId}/action/{actionId}`
51
+ - `forgeloop://task/{taskId}/approvals`
52
+ - `forgeloop://task/{taskId}/metrics`
53
+ - `forgeloop://task/{taskId}/evaluations`
54
+ - `forgeloop://project/capability-policy`
55
+
56
+ The durable-action resources are read-only projections. The first release does
57
+ not expose `run-action` or host-attestation minting over MCP. An action that is
58
+ `COMMIT_UNKNOWN` is surfaced as an external reconciliation requirement; MCP
59
+ transport/session metadata cannot authorize a retry or manufacture
60
+ `HOST_ATTESTED` authority. Capability policy remains policy, not authority.
61
+
62
+ ### Approval resolution and reconciliation settlement capabilities
63
+
64
+ Two launch flags expose transport surfaces; neither creates host authority:
65
+
66
+ - `--allow-approval-resolution` exposes the `approval-resolve` tool.
67
+ Resolving an approval as `HOST_ATTESTED` still requires a trusted
68
+ out-of-band authority context supplied by the embedding host through
69
+ `createForgeLoopMcpServer({ authorityContextProvider })`. Without a
70
+ provider, `HOST_ATTESTED` resolutions fail closed with
71
+ `E_ACTION_AUTHORITY_REQUIRED`. Tool arguments can never carry the context:
72
+ any actor-supplied `authorityContext` property is stripped before dispatch.
73
+ - `--allow-reconciliation-settlement` exposes settlement-class
74
+ `action-reconcile` invocations (`--outcome COMMITTED|NOT_COMMITTED`).
75
+ Recording an `UNKNOWN` observation needs no special capability, but settling
76
+ external commit state is independently gated and still requires trusted
77
+ host attestation plus evidence at the core layer.
78
+
79
+ Capability introspection reports whether these surfaces are enabled
80
+ (`hostAttestationAvailable: false` by default) but never exposes grant
81
+ content.
49
82
 
50
83
  Raw recovery artifacts, transaction journals, lock files, and unbounded event
51
84
  ledgers are intentionally not exposed.
package/docs/RECIPES.md CHANGED
@@ -21,6 +21,7 @@ Concise, copy-paste friendly recipes for common ForgeLoop tasks.
21
21
  13. [Record Decision Settlement Criteria](#recipe-13--record-decision-settlement-criteria)
22
22
  14. [Executable Policy, Baseline Ratchet, and Recovery](#recipe-14--executable-policy-baseline-ratchet-and-recovery)
23
23
  15. [Release and Reacquire Claims for an Abandoned Task](#recipe-15--release-and-reacquire-claims-for-an-abandoned-task)
24
+ 16. [Execute a Durable External Action Safely](#recipe-16--execute-a-durable-external-action-safely)
24
25
 
25
26
  ---
26
27
 
@@ -346,6 +347,72 @@ artifact against the complete ledger history. If `next` returns
346
347
  `RESOLVE_RECOVERY_INCONSISTENCY`, run `validate-protocol`; do not create, edit,
347
348
  or delete `recovery.json` manually.
348
349
 
350
+ ---
351
+
352
+ ### Recipe 16 — Execute a Durable External Action Safely
353
+
354
+ Record the intended external effect before execution, satisfy the capability
355
+ policy and fingerprint-bound approval, and execute with an exact argument list:
356
+
357
+ ```bash
358
+ forgeloop action-propose --task release --id action-publish --capability external.publish --effect-class EXTERNAL_PUBLICATION --target registry/release --operation "publish release" --idempotency-key release:publish:v1 --required-for-completion
359
+ forgeloop approval-request --task release --approval approval-publish --action action-publish --reason "reviewed release"
360
+ forgeloop approval-resolve --task release --approval approval-publish --decision APPROVED --authority CALLER_ACKNOWLEDGED
361
+ forgeloop run-action --task release --action action-publish --capability external.publish --effect-class EXTERNAL_PUBLICATION --target registry/release --idempotency-key release:publish:v1 --required-for-completion -- npm publish
362
+ # If the external outcome cannot be proven after start, do not retry:
363
+ forgeloop action-reconcile --task release --action action-publish --outcome UNKNOWN
364
+ ```
365
+
366
+ Provenance and authority truths for this recipe:
367
+
368
+ - `CALLER_ACKNOWLEDGED` approval resolution records an acknowledgement; if the
369
+ capability policy requires `REQUIRE_APPROVAL`, only a fresh `HOST_ATTESTED`
370
+ approval resolved through a trusted embedding-host boundary authorizes the
371
+ action. The standalone CLI can never mint it.
372
+ - `forgeloop next` evaluates the current capability policy before inspecting
373
+ approval state, but only after validating that the capability artifact is
374
+ bound to the active policy lock and task snapshot. Historical or stale
375
+ approvals never override `ALLOW`, `DENY`, or `REQUIRE_AUTHORITY`; only a
376
+ currently applicable `REQUIRE_APPROVAL` decision can make a pending approval
377
+ the active resolver target.
378
+ - `commands` in next-action guidance are safe standalone CLI commands. A
379
+ host-only authorization is returned with `commands: []` and structured
380
+ `hostActionRequired`/`authorityRequired` data so an embedding host can invoke
381
+ `action-authorize` while preserving its trusted authority context.
382
+ - `approval-request` is policy-aware: it creates a pending approval only for
383
+ `REQUIRE_APPROVAL`; `ALLOW`, `DENY`, and `REQUIRE_AUTHORITY` reject the request
384
+ without creating an approval artifact. A changed `capabilities.json` alone is
385
+ not a valid policy update: restore the recorded epoch or refresh the lock and
386
+ task snapshot through the supported policy lifecycle first.
387
+ - `COMMIT_UNKNOWN` is an explicit reconciliation boundary, not a failed retry.
388
+ Recording `UNKNOWN` keeps the action ambiguous. Settling `COMMITTED` or
389
+ `NOT_COMMITTED` requires trusted host attestation plus evidence through a
390
+ trusted integration boundary. A trusted `NOT_COMMITTED` returns the action
391
+ to `PROPOSED` so authorization is re-evaluated before any retry.
392
+
393
+ After commit ambiguity is settled as `COMMITTED`, verify the independent
394
+ postcondition before completion:
395
+
396
+ ```bash
397
+ forgeloop run-check --task release --id check-release-live --requirement publication -- node scripts/check-release-live.js
398
+ forgeloop action-verify --task release --action action-publish --evidence <execution-ref>
399
+ ```
400
+
401
+ `COMMITTED != VERIFIED`: exit code 0 from the action command proves local
402
+ completion only. Verification requires canonical evidence from an independent
403
+ check execution.
404
+
405
+ Inspect the observed trajectory without inventing usage data:
406
+
407
+ ```bash
408
+ forgeloop metrics --task release --json
409
+ forgeloop eval --task release --scenario scenarios/release.json --json
410
+ ```
411
+
412
+ The efficiency comparison is present only when the scenario declares a
413
+ positive `reference.comparableSteps`; absent host token/cost/model data stays
414
+ unknown.
415
+
349
416
  ## Run ForgeLoop through MCP (safe mode)
350
417
 
351
418
  Start the local MCP adapter and inspect what it exposes:
@@ -19,6 +19,7 @@ This guide provides symptom-first recovery procedures for common ForgeLoop proto
19
19
  - [`forgeloop complete` returns `INCOMPLETE`](#symptom-forgeloop-complete-returns-incomplete)
20
20
  - [`forgeloop complete` returns `INVALID`](#symptom-forgeloop-complete-returns-invalid)
21
21
  - [Policy lock mismatch (`E_POLICY_LOCK_MISMATCH`)](#symptom-policy-lock-mismatch)
22
+ - [Capability policy epoch drift (`E_ACTION_POLICY_DRIFT`)](#symptom-capability-policy-epoch-drift)
22
23
  - [Invalid policy artifacts fail closed (`E_POLICY_INVALID`)](#symptom-invalid-policy-artifacts-fail-closed)
23
24
  - [Policy weakening detected (`E_POLICY_WEAKENING`)](#symptom-policy-weakening-detected)
24
25
  - [Baseline re-record blocked during active task (`E_BASELINE_RECORD_DURING_ACTIVE_TASK`)](#symptom-baseline-re-record-blocked-during-active-task)
@@ -34,7 +35,7 @@ This guide provides symptom-first recovery procedures for common ForgeLoop proto
34
35
  Confirm the local CLI's public metadata before diagnosing a harness/version
35
36
  mismatch. This check does not create or mutate task state.
36
37
 
37
- <!-- FORGELOOP EXAMPLE: troubleshooting:protocol-info | exit=0 | json.errors.0.code=E_AUTHORITY_INVALID -->
38
+ <!-- FORGELOOP EXAMPLE: troubleshooting:protocol-info | exit=0 | json.errors.0.code=E_ACTION_APPROVAL_NOT_REQUIRED -->
38
39
  ```bash
39
40
  forgeloop protocol-info --json
40
41
  ```
@@ -203,6 +204,20 @@ forgeloop status --task <id> --json
203
204
  forgeloop validate-protocol --task <id> --json
204
205
  ```
205
206
 
207
+ If a checkpoint must be recreated after `clear-state` (or loss), `preflight`
208
+ rebuilds a resumable checkpoint from the preserved contract and route artifacts.
209
+ The resume phase is derived from the validated ledger chronology: a ledger that
210
+ already records `EXECUTION_STARTED` (or a later verification milestone) resumes
211
+ at the phase that chronology supports instead of restarting at `ROUTED`, so no
212
+ duplicate non-repeatable lifecycle milestone is ever appended.
213
+
214
+ A `PREFLIGHT_READY` that was superseded by a later `PREFLIGHT_BLOCKED` outcome
215
+ (contract evolution, added gate requirement) does not block re-readiness: once
216
+ the blocked preflight is resolved, `preflight` appends a fresh
217
+ `PREFLIGHT_READY` bound to the current contract and route. A READY refresh whose
218
+ details differ *without* an intervening BLOCKED outcome is still refused with
219
+ `E_PHASE_CHRONOLOGY_INVALID`.
220
+
206
221
  ---
207
222
 
208
223
  ### Symptom: `EXECUTING`/`VERIFYING` task is stale because the repository moved (`E_REPOSITORY_CHANGED`)
@@ -220,7 +235,7 @@ forgeloop reconcile-closure --task <id> --id <verification-id> \
220
235
 
221
236
  `reconcile-closure` requires:
222
237
 
223
- 1. The task is `EXECUTING` or `VERIFYING` (later phases are not reconcilable; work must return to a verification phase first).
238
+ 1. The task is `EXECUTING`, `VERIFYING`, or `REVIEWING`. A `REVIEWING` task additionally requires authorized completion recovery (a persisted evidence-only rejection bound to the current checkpoint), or a rejection snapshot that can be rebound (see below).
224
239
  2. The only drift is `REPOSITORY_CHANGED` (contract or required-artifact drift stays blocked).
225
240
  3. The append-only event ledger is valid.
226
241
  4. `--id` and `--requirement` exactly match a `VERIFICATION` item of the task contract, and the executed command exits 0, proving the objective is present in the current repository.
@@ -235,6 +250,28 @@ forgeloop advance --task <id> --to REVIEWING
235
250
  forgeloop complete --task <id>
236
251
  ```
237
252
 
253
+ #### Drifted completion-rejection snapshots (`E_COMPLETION_REJECTION_STATE_FINGERPRINT_MISMATCH`)
254
+
255
+ A `REVIEWING` task with a persisted evidence-only completion rejection can lose
256
+ its snapshot binding when the checkpoint is mutated after the rejection (for
257
+ example by a recovery/resume cycle or a repository move). Both sanctioned
258
+ closure paths — `reconcile-closure` from `REVIEWING` and the
259
+ `REVIEWING -> VERIFYING` recovery transition — then fail with
260
+ `E_COMPLETION_REJECTION_STATE_FINGERPRINT_MISMATCH`, while `complete` cannot
261
+ persist a fresh snapshot because it deduplicates logically identical rejections.
262
+ This deadlocks the task.
263
+
264
+ ForgeLoop resolves this with an append-only **rejection rebind**: when the only
265
+ authorization failures are state/receipt fingerprint mismatches and the
266
+ rejection's logical fields (`verificationCycle`, sorted `reasonCodes`, sorted
267
+ `missingRequirementIds`) are still identical between work-state and the latest
268
+ matching ledger rejection, the recovery surfaces automatically append a rebound
269
+ `COMPLETION_REJECTED` event carrying the current fingerprints (referencing the
270
+ snapshot it supersedes via `reboundFromStateFingerprint`) and re-bind the
271
+ execution receipt. The original rejection is never modified, any logical
272
+ difference is still refused, and closure must still produce fresh observed
273
+ evidence in the current repository.
274
+
238
275
  Write claims release only when completion is validator-backed (`COMPLETE`).
239
276
  A `phase: COMPLETE` that was never produced by the official completion pipeline
240
277
  is not sufficient: the ownership resolver requires canonical lifecycle proof (a
@@ -540,6 +577,32 @@ forgeloop policy-status --json
540
577
 
541
578
  ---
542
579
 
580
+ ### Symptom: Capability Policy Epoch Drift
581
+
582
+ #### Error Code: `E_ACTION_POLICY_DRIFT`
583
+
584
+ #### What it means
585
+
586
+ The current capability-policy artifact no longer matches the policy lock or
587
+ the task-scoped policy snapshot. The same guard is enforced by
588
+ `action-authorize`, `next`, and `approval-request`.
589
+
590
+ #### Safe recovery
591
+
592
+ ForgeLoop fails closed before authorization guidance or approval creation. Do
593
+ not create an approval manually or retry `action-authorize` against the
594
+ modified file. Restore the policy epoch recorded at task activation, or use
595
+ the supported policy update flow to create a new lock and task snapshot, then
596
+ rerun:
597
+
598
+ ```bash
599
+ forgeloop next --task <id> --json
600
+ ```
601
+
602
+ Changing `capabilities.json` alone is not a valid policy update.
603
+
604
+ ---
605
+
543
606
  ### Symptom: Invalid Policy Artifacts Fail Closed
544
607
 
545
608
  #### Error Code: `E_POLICY_INVALID`
@@ -669,6 +732,29 @@ forgeloop next --task <id> --json
669
732
 
670
733
  | Code | Meaning | Safe Resolution |
671
734
  | --- | --- | --- |
735
+ | `E_ACTION_APPROVAL_NOT_REQUIRED` | The current capability policy allows the action without an approval artifact. | Do not create an approval; authorize the action through the current policy path. |
736
+ | `E_ACTION_APPROVAL_REQUIRED` | Policy requires a current fingerprint-bound approval before this action may proceed. | Request approval with forgeloop approval-request and resolve it via forgeloop approval-resolve, then rerun the action. |
737
+ | `E_ACTION_AUTHORITY_REQUIRED` | Policy requires host-attested authority that was not supplied through a host trust boundary. | Perform the action through a host integration that supplies trusted authority context; standalone CLI cannot mint it. |
738
+ | `E_ACTION_AUTHORIZATION_INVALID` | Action authorization evidence is missing, incomplete, or was not produced by the canonical authorization service. | Authorize the action through forgeloop run-action or a trusted embedding host; caller surfaces can never mint AUTHORIZED. |
739
+ | `E_ACTION_CAPABILITY_DENIED` | Capability policy denies this capability. | Obtain an operator policy change outside the task, or do not perform the action. |
740
+ | `E_ACTION_CAPABILITY_UNKNOWN` | Action capability is not part of the canonical capability vocabulary. | Use a documented capability from forgeloop protocol-info; unknown capabilities fail closed. |
741
+ | `E_ACTION_COMMIT_UNKNOWN` | External commit state of a started action cannot be proven. | Do not retry; reconcile the observed external state with forgeloop action-reconcile. |
742
+ | `E_ACTION_EVIDENCE_INVALID` | Evidence supplied for verification or reconciliation is missing, malformed, or unbounded. | Supply bounded evidence references appropriate to the action type; do not paste raw external output into the ledger. |
743
+ | `E_ACTION_IDEMPOTENCY_CONFLICT` | The idempotency key already binds to a different canonical action fingerprint in this task. | Use a new idempotency key with a new actionId, or reuse the existing logical action unchanged; never relabel an executed effect. |
744
+ | `E_ACTION_IDEMPOTENCY_REQUIRED` | Side-effecting action class requires an idempotency key. | Supply a stable --idempotency-key that identifies the logical external action. |
745
+ | `E_ACTION_INVALID` | Durable action artifact or parameters are malformed or schema-invalid. | Correct the action fields reported by the structured error, then retry through forgeloop action-propose or run-action. |
746
+ | `E_ACTION_NOT_FOUND` | Referenced durable action ID does not exist for the task. | List actions with forgeloop action-show or propose the action first. |
747
+ | `E_ACTION_POLICY_DRIFT` | The current capability policy does not match the policy lock or task policy snapshot binding this task. | Restore the policy epoch recorded at task activation or create a new valid lock and snapshot before side effects. |
748
+ | `E_ACTION_POLICY_LOCK_REQUIRED` | A capability policy is present but no valid policy lock exists to bind authorization identity. | Record a valid policy lock (forgeloop baseline or policy-discover --write) before authorizing durable actions. |
749
+ | `E_ACTION_RECONCILIATION_AUTHORITY_REQUIRED` | Settling COMMIT_UNKNOWN external state requires trusted host attestation that was not supplied out-of-band. | Reconcile through a trusted embedding host boundary; actor-supplied observations may only record UNKNOWN. |
750
+ | `E_ACTION_RECONCILIATION_EVIDENCE_INVALID` | Settling reconciliation requires at least one bounded evidence reference binding the observation to the action. | Supply bounded external-state evidence references alongside trusted authority before settling ambiguity. |
751
+ | `E_ACTION_RECONCILIATION_REQUIRED` | An action is COMMIT_UNKNOWN and blocks progress until explicitly reconciled. | Observe the external system and run forgeloop action-reconcile --outcome COMMITTED\|NOT_COMMITTED\|UNKNOWN with evidence references. |
752
+ | `E_ACTION_STATE_MISMATCH` | Requested durable action transition is not part of the canonical state machine. | Inspect current action state with forgeloop action-show and use a legal transition; never edit action artifacts by hand. |
753
+ | `E_ACTION_VERIFICATION_INVALID` | Verification evidence does not resolve to a canonical passed ForgeLoop artifact bound to this task and action. | Supply a canonical execution or check reference produced by run-check for this task; arbitrary strings fail closed. |
754
+ | `E_ACTION_VERIFICATION_REQUIRED` | The action cannot reach VERIFIED through this surface; canonical independent postcondition evidence is required. | Run an independent verification check, then record it with forgeloop action-verify; exit code 0 alone is not verification. |
755
+ | `E_APPROVAL_ALREADY_RESOLVED` | Approval is one-time resolvable and has already been approved or rejected. | Request a new approval if another decision is required. |
756
+ | `E_APPROVAL_INVALID` | Approval artifact is malformed or does not bind the required fingerprint tuple. | Request a new approval with forgeloop approval-request; never hand-edit approval artifacts. |
757
+ | `E_APPROVAL_STALE` | Approval no longer matches the current action fingerprint, contract fingerprint, task revision, or capability. | Request and resolve a fresh approval against the current action revision. |
672
758
  | `E_AUTHORITY_INVALID` | Authority grant file is malformed or expired. | Obtain a valid authority grant from host operator. |
673
759
  | `E_AUTHORITY_SCOPE_MISMATCH` | Authority grant does not cover the requested package. | Request updated authority scope. |
674
760
  | `E_AUTHORITY_UNTRUSTED_SOURCE` | Authority file placed inside untrusted project tree. | Place authority file in host-managed trusted location. |
@@ -698,6 +784,8 @@ forgeloop next --task <id> --json
698
784
  | `E_CONTRACT_MISSING` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
699
785
  | `E_CONTRACT_STALE` | Contract modified after downstream artifacts were generated. | Re-run forgeloop route and forgeloop preflight. |
700
786
  | `E_CONTRACT_UNRESOLVED_DECISION` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
787
+ | `E_CONTRIBUTOR_INVALID` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
788
+ | `E_CONTRIBUTOR_REFERENCE_INVALID` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
701
789
  | `E_DECISION_CRITERION_INVALID` | Decision settlement criterion details or parameters are malformed. | Provide non-empty decision text and settledBy criterion. |
702
790
  | `E_DECISION_NOT_UNRESOLVED` | A settlement criterion referenced a decision not present in current unresolvedDecisions. | Use the exact current unresolved decision text or update the contract first. |
703
791
  | `E_DIAGNOSIS_CYCLE_MISMATCH` | Diagnosis verification cycle does not match the active work state verification cycle. | Record diagnosis for the current active verification cycle. |
@@ -705,6 +793,9 @@ forgeloop next --task <id> --json
705
793
  | `E_DIAGNOSIS_INVALID` | Diagnosis record details or parameters are malformed. | Provide valid failureClass, hypothesis, evidenceRefs, settledBy, and nextSafeAction. |
706
794
  | `E_DIAGNOSIS_NO_NEW_INFORMATION` | The proposed retry repeats the previous hypothesis with the same evidence. | Change the hypothesis, collect independent evidence, or change strategy. |
707
795
  | `E_DIAGNOSIS_REQUIRED` | Current correction cycle has no append-only diagnosis record. | Run forgeloop record-diagnosis with current failed evidence before correcting. |
796
+ | `E_DIAGNOSTIC_CASE_CYCLE_MISMATCH` | Diagnostic case verification cycle does not match the active work state verification cycle. | Record the diagnostic case for the current active verification cycle. |
797
+ | `E_DIAGNOSTIC_CASE_EVIDENCE_INVALID` | A diagnostic case evidence reference does not match any check from the active verification cycle. | Reference check IDs recorded during the active verification cycle. |
798
+ | `E_DIAGNOSTIC_CASE_INVALID` | Structured diagnostic case details or parameters are malformed. | Provide valid observations, contributors, hypotheses with settlement criteria, and nextSafeAction. |
708
799
  | `E_EVIDENCE_COVERAGE_INVALID` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
709
800
  | `E_EVIDENCE_COVERAGE_PARTIAL` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
710
801
  | `E_EVIDENCE_INVALID` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
@@ -713,13 +804,21 @@ forgeloop next --task <id> --json
713
804
  | `E_EVIDENCE_REQUIRED` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
714
805
  | `E_EVIDENCE_STALE` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
715
806
  | `E_EXECUTION_REF_INVALID` | Referenced execution ID does not exist. | Re-run check via forgeloop run-check. |
807
+ | `E_FAILURE_SIGNATURE_INVALID` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
716
808
  | `E_FUTURE_LIFECYCLE_EVIDENCE` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
717
809
  | `E_FUTURE_TERMINAL_EVIDENCE` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
718
810
  | `E_GATE_REQUIRED` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
719
811
  | `E_GATE_STALE` | Referenced gate artifact changed after approval. | Update artifact SHA-256 in gate file. |
720
812
  | `E_GATE_UNVERIFIED` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
813
+ | `E_HYPOTHESIS_DISPOSITION_EVIDENCE_INVALID` | Hypothesis disposition evidence references do not resolve to checks of the active cycle. | Reference at least one check ID recorded in the active verification cycle. |
814
+ | `E_HYPOTHESIS_DISPOSITION_INVALID` | Hypothesis disposition is malformed or references an unknown hypothesis or disallowed transition. | Record a disposition for a known hypothesis using an allowed status transition. |
815
+ | `E_HYPOTHESIS_INVALID` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
816
+ | `E_HYPOTHESIS_SETTLEMENT_MISSING` | An open hypothesis lacks a falsifiable settlement condition. | Provide a structured settledBy predicate, check status, or observation binding. |
721
817
  | `E_INIT_KIT_CONFLICT` | A canonical ForgeLoop kit destination already exists with content that does not match the shipped canonical template. | Inspect the conflicting `.forgeloop/kit/...` file. If it is stale or partial ForgeLoop output, remove or restore it and rerun `forgeloop init`. Do not overwrite unknown content automatically. |
722
818
  | `E_INSTALLATION_AUTHORITY_REQUIRED` | Attempted software installation without host authority grant. | Use local non-installing binaries or request host authority grant. |
819
+ | `E_INTERVENTION_HYPOTHESIS_MISSING` | Intervention does not bind to any hypothesis. | Bind the intervention to at least one recorded hypothesis. |
820
+ | `E_INTERVENTION_INVALID` | Intervention record is malformed. | Provide id, kind, statement, and at least one bound hypothesisRef. |
821
+ | `E_INTERVENTION_REFERENCE_INVALID` | Intervention references an unknown hypothesis. | Record the diagnostic case containing the hypothesis before recording the intervention. |
723
822
  | `E_LEGACY_RECOVERY_MIGRATION_INVALID` | The legacy recovery-event repair was refused because the ledger does not match the exact known legacy defect signature, has incompatible later activity, holds a live lock, or is otherwise ambiguous. | Inspect the structured plan/errors; ambiguous or tampered ledgers stay INCONSISTENT and are never migrated. |
724
823
  | `E_MIGRATION_INCOMPLETE` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
725
824
  | `E_MIGRATION_WRITE_VERIFY` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
@@ -727,6 +826,7 @@ forgeloop next --task <id> --json
727
826
  | `E_NATIVE_ADAPTER_STALE` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
728
827
  | `E_NATIVE_ADAPTER_TARGET_MISSING` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
729
828
  | `E_NEW_POLICY_VIOLATION` | New executable policy violation detected that is not present in brownfield baseline. | Fix the violation before completing the task. |
829
+ | `E_OBSERVATION_INVALID` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
730
830
  | `E_PHASE_CHRONOLOGY_INVALID` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
731
831
  | `E_PHASE_PREREQUISITE_MISSING` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
732
832
  | `E_PHASE_TRANSITION_INVALID` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
@@ -782,6 +882,7 @@ forgeloop next --task <id> --json
782
882
  | `E_STATE_MISSING_AFTER_PREFLIGHT_READY` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
783
883
  | `E_STATE_REVALIDATION_REQUIRED` | The work-state checkpoint must be revalidated before the lifecycle can continue. | Run forgeloop reconcile-closure for externally satisfied EXECUTING tasks, or inspect the freshness reasons for other drift. |
784
884
  | `E_STATE_TASK_MISMATCH` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
885
+ | `E_STRATEGY_OSCILLATION` | Correction history oscillates between previously exhausted strategies without new information. | Gather a genuinely new observation or test a materially different falsifiable hypothesis. |
785
886
  | `E_TASK_ALREADY_EXISTS` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
786
887
  | `E_TASK_ALREADY_RECOVERED` | The task already has active durable recovered state. | Inspect the existing recovery metadata; use task-resume to reacquire claims or leave the task recovered. |
787
888
  | `E_TASK_AMBIGUOUS` | Multiple tasks exist in the project but no task selector was provided. | Select a task explicitly using --task <id> or FORGELOOP_TASK=<id>. |
@@ -816,6 +917,9 @@ forgeloop next --task <id> --json
816
917
  | `E_TERMINAL_REQUIREMENT_TYPE_MISMATCH` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
817
918
  | `E_TERMINAL_REQUIREMENT_UNKNOWN` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
818
919
  | `E_TERMINAL_STATUS_REGRESSION` | A ForgeLoop protocol validation or lifecycle condition was not satisfied. | Inspect the structured command result, correct the named artifact or prerequisite, then run forgeloop next --json. |
920
+ | `E_TRACE_SNAPSHOT_INCONSISTENT` | Task artifacts changed while the execution trace was being read. | Rerun the read-only projection to obtain a consistent view. |
921
+ | `E_TRAJECTORY_REFERENCE_REQUIRED` | Comparative efficiency requires a reference scenario with positive comparableSteps. | Provide --scenario with reference.comparableSteps, or omit efficiency from the result. |
922
+ | `E_TRAJECTORY_SCENARIO_INVALID` | Trajectory scenario file is missing required fields or schema-invalid. | Correct the scenario JSON against schemas/trajectory-scenario.schema.json. |
819
923
  | `E_VERIFICATION_TOOL_UNAVAILABLE` | Required verification executable is missing in environment. | Use local equivalent, obtain host authority, or record NOT_VERIFIED. |
820
924
 
821
925
  <!-- END FORGELOOP GENERATED: public-error-codes -->