@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.
- package/DOCS_INDEX.md +13 -8
- package/EXECUTION_STATE.md +20 -0
- package/LOOP_ENGINEERING.md +81 -0
- package/LOOP_SYSTEM_DESIGN.md +32 -0
- package/PROTOCOL_INTEGRATION.md +46 -0
- package/QUALITY_SCORECARD.md +2 -0
- package/README.md +31 -9
- package/THIRD_PARTY_NOTICES.md +15 -0
- package/THREAT_MODEL.md +39 -0
- package/docs/ARTIFACT_REFERENCE.md +140 -0
- package/docs/CLI_REFERENCE.md +294 -3
- package/docs/DIAGNOSTIC_MODEL.md +181 -0
- package/docs/DOCUMENTATION_GUIDE.md +22 -13
- package/docs/EXECUTION_TRACE.md +76 -0
- package/docs/MCP.md +33 -0
- package/docs/RECIPES.md +67 -0
- package/docs/TROUBLESHOOTING.md +106 -2
- package/docs/assets/diagrams/forgeloop-engineering-flow.html +13797 -0
- package/docs/assets/diagrams/forgeloop-engineering-flow.receipt.json +37 -0
- package/docs/assets/diagrams/forgeloop-engineering-flow.svg +5002 -0
- package/docs/diagrams/README.md +55 -0
- package/docs/diagrams/forgeloop-engineering-flow.workflow.json +122 -0
- package/docs/diagrams/manifest.json +42 -0
- package/docs/diagrams/reviews/forgeloop-engineering-flow.review.json +20 -0
- package/package.json +8 -6
- package/schemas/action.schema.json +100 -0
- package/schemas/approval.schema.json +51 -0
- package/schemas/capability-policy.schema.json +41 -0
- package/schemas/diagnostic-case.schema.json +85 -0
- package/schemas/execution-receipt.schema.json +16 -0
- package/schemas/hypothesis-disposition.schema.json +16 -0
- package/schemas/intervention.schema.json +27 -0
- package/schemas/policy-lock.schema.json +1 -0
- package/schemas/policy-snapshot.schema.json +2 -0
- package/schemas/trajectory-evaluation.schema.json +64 -0
- package/schemas/trajectory-scenario.schema.json +42 -0
- package/src/cli.js +94 -0
- package/src/commands/action-authorize.js +41 -0
- package/src/commands/action-propose.js +10 -0
- package/src/commands/action-reconcile.js +10 -0
- package/src/commands/action-record.js +47 -0
- package/src/commands/action-show.js +10 -0
- package/src/commands/action-verify.js +10 -0
- package/src/commands/advance.js +7 -2
- package/src/commands/approval-request.js +64 -0
- package/src/commands/approval-resolve.js +10 -0
- package/src/commands/baseline.js +3 -3
- package/src/commands/eval.js +6 -0
- package/src/commands/history.js +18 -0
- package/src/commands/init.js +2 -2
- package/src/commands/inspect.js +49 -0
- package/src/commands/metrics.js +7 -0
- package/src/commands/next.js +8 -2
- package/src/commands/policy-discover.js +2 -2
- package/src/commands/record-diagnosis.js +37 -1
- package/src/commands/record-hypothesis-disposition.js +45 -0
- package/src/commands/record-intervention.js +35 -0
- package/src/commands/reflect.js +38 -0
- package/src/commands/report.js +9 -1
- package/src/commands/run-action.js +18 -0
- package/src/commands/trace.js +34 -0
- package/src/commands/validate-protocol.js +21 -13
- package/src/core/action-authorization.js +106 -0
- package/src/core/action-constants.js +86 -0
- package/src/core/action-execution.js +105 -0
- package/src/core/action-ledger-projection.js +302 -0
- package/src/core/action-model.js +581 -0
- package/src/core/action-readiness.js +141 -0
- package/src/core/action-reconciliation-policy.js +49 -0
- package/src/core/action-reconciliation.js +66 -0
- package/src/core/action-verification.js +111 -0
- package/src/core/actions.js +462 -0
- package/src/core/approvals.js +405 -0
- package/src/core/artifact-registry.js +48 -0
- package/src/core/audit.js +25 -0
- package/src/core/bundles.js +15 -0
- package/src/core/capability-policy.js +226 -0
- package/src/core/cli-command-definitions.js +210 -1
- package/src/core/command-executors.js +171 -15
- package/src/core/command-runtime.js +12 -1
- package/src/core/completion-artifacts.js +37 -12
- package/src/core/completion-recovery-rebind.js +194 -0
- package/src/core/completion.js +70 -0
- package/src/core/continuity-reconciliation.js +24 -5
- package/src/core/diagnostic-model.js +396 -0
- package/src/core/diagnostic-projection.js +51 -0
- package/src/core/diagnostic-record.js +360 -0
- package/src/core/error-codes.js +343 -0
- package/src/core/events.js +41 -1
- package/src/core/execution-prerequisites.js +4 -1
- package/src/core/execution.js +26 -188
- package/src/core/failure-signature.js +70 -0
- package/src/core/failure-surface.js +57 -0
- package/src/core/history.js +110 -0
- package/src/core/hypothesis-projection.js +85 -0
- package/src/core/information-gain-projection.js +283 -0
- package/src/core/information-gain.js +138 -0
- package/src/core/inspect.js +105 -7
- package/src/core/integration-invocation-policy.js +47 -0
- package/src/core/integration-resources.js +51 -0
- package/src/core/next-action-model.js +35 -1
- package/src/core/next-action.js +459 -3
- package/src/core/phase.js +40 -21
- package/src/core/policy-engine.js +113 -6
- package/src/core/preflight-consistency.js +31 -5
- package/src/core/preflight.js +19 -2
- package/src/core/prepared-execution.js +227 -0
- package/src/core/progress.js +41 -4
- package/src/core/protocol-info.js +48 -0
- package/src/core/protocol.js +14 -0
- package/src/core/receipt.js +1 -0
- package/src/core/reconcile-closure.js +15 -12
- package/src/core/reflection.js +305 -0
- package/src/core/resumability.js +57 -3
- package/src/core/schema-validation.js +8 -0
- package/src/core/strategy-analysis.js +97 -0
- package/src/core/task-paths.js +28 -0
- package/src/core/task-snapshot.js +53 -0
- package/src/core/templates.js +8 -0
- package/src/core/trace.js +548 -0
- package/src/core/trajectory-evaluation.js +71 -0
- package/src/core/trajectory-metrics.js +80 -0
- package/src/core/transaction.js +8 -0
- package/src/core/work-state.js +10 -5
- package/docs/assets/forgeloop-flow.svg +0 -1
- package/docs/forgeloop-flow.mmd +0 -51
package/src/core/error-codes.js
CHANGED
|
@@ -50,6 +50,22 @@ export const E_DIAGNOSIS_EVIDENCE_INVALID = "E_DIAGNOSIS_EVIDENCE_INVALID";
|
|
|
50
50
|
export const E_DIAGNOSIS_CYCLE_MISMATCH = "E_DIAGNOSIS_CYCLE_MISMATCH";
|
|
51
51
|
export const E_DIAGNOSIS_NO_NEW_INFORMATION = "E_DIAGNOSIS_NO_NEW_INFORMATION";
|
|
52
52
|
export const E_PROGRESS_STALLED = "E_PROGRESS_STALLED";
|
|
53
|
+
export const E_DIAGNOSTIC_CASE_INVALID = "E_DIAGNOSTIC_CASE_INVALID";
|
|
54
|
+
export const E_DIAGNOSTIC_CASE_CYCLE_MISMATCH = "E_DIAGNOSTIC_CASE_CYCLE_MISMATCH";
|
|
55
|
+
export const E_DIAGNOSTIC_CASE_EVIDENCE_INVALID = "E_DIAGNOSTIC_CASE_EVIDENCE_INVALID";
|
|
56
|
+
export const E_OBSERVATION_INVALID = "E_OBSERVATION_INVALID";
|
|
57
|
+
export const E_CONTRIBUTOR_INVALID = "E_CONTRIBUTOR_INVALID";
|
|
58
|
+
export const E_CONTRIBUTOR_REFERENCE_INVALID = "E_CONTRIBUTOR_REFERENCE_INVALID";
|
|
59
|
+
export const E_HYPOTHESIS_INVALID = "E_HYPOTHESIS_INVALID";
|
|
60
|
+
export const E_HYPOTHESIS_SETTLEMENT_MISSING = "E_HYPOTHESIS_SETTLEMENT_MISSING";
|
|
61
|
+
export const E_HYPOTHESIS_DISPOSITION_INVALID = "E_HYPOTHESIS_DISPOSITION_INVALID";
|
|
62
|
+
export const E_HYPOTHESIS_DISPOSITION_EVIDENCE_INVALID = "E_HYPOTHESIS_DISPOSITION_EVIDENCE_INVALID";
|
|
63
|
+
export const E_INTERVENTION_INVALID = "E_INTERVENTION_INVALID";
|
|
64
|
+
export const E_INTERVENTION_HYPOTHESIS_MISSING = "E_INTERVENTION_HYPOTHESIS_MISSING";
|
|
65
|
+
export const E_INTERVENTION_REFERENCE_INVALID = "E_INTERVENTION_REFERENCE_INVALID";
|
|
66
|
+
export const E_FAILURE_SIGNATURE_INVALID = "E_FAILURE_SIGNATURE_INVALID";
|
|
67
|
+
export const E_NO_INFORMATION_GAIN = "E_NO_INFORMATION_GAIN";
|
|
68
|
+
export const E_STRATEGY_OSCILLATION = "E_STRATEGY_OSCILLATION";
|
|
53
69
|
export const E_DECISION_CRITERION_INVALID = "E_DECISION_CRITERION_INVALID";
|
|
54
70
|
export const E_DECISION_NOT_UNRESOLVED = "E_DECISION_NOT_UNRESOLVED";
|
|
55
71
|
|
|
@@ -62,6 +78,34 @@ export const E_RECONCILE_EVIDENCE_FAILED = "E_RECONCILE_EVIDENCE_FAILED";
|
|
|
62
78
|
export const E_REPOSITORY_CHANGED = "E_REPOSITORY_CHANGED";
|
|
63
79
|
export const E_STATE_REVALIDATION_REQUIRED = "E_STATE_REVALIDATION_REQUIRED";
|
|
64
80
|
|
|
81
|
+
export const E_ACTION_INVALID = "E_ACTION_INVALID";
|
|
82
|
+
export const E_ACTION_NOT_FOUND = "E_ACTION_NOT_FOUND";
|
|
83
|
+
export const E_ACTION_STATE_MISMATCH = "E_ACTION_STATE_MISMATCH";
|
|
84
|
+
export const E_ACTION_IDEMPOTENCY_REQUIRED = "E_ACTION_IDEMPOTENCY_REQUIRED";
|
|
85
|
+
export const E_ACTION_IDEMPOTENCY_CONFLICT = "E_ACTION_IDEMPOTENCY_CONFLICT";
|
|
86
|
+
export const E_ACTION_CAPABILITY_UNKNOWN = "E_ACTION_CAPABILITY_UNKNOWN";
|
|
87
|
+
export const E_ACTION_CAPABILITY_DENIED = "E_ACTION_CAPABILITY_DENIED";
|
|
88
|
+
export const E_ACTION_AUTHORITY_REQUIRED = "E_ACTION_AUTHORITY_REQUIRED";
|
|
89
|
+
export const E_ACTION_APPROVAL_REQUIRED = "E_ACTION_APPROVAL_REQUIRED";
|
|
90
|
+
export const E_ACTION_APPROVAL_NOT_REQUIRED = "E_ACTION_APPROVAL_NOT_REQUIRED";
|
|
91
|
+
export const E_ACTION_COMMIT_UNKNOWN = "E_ACTION_COMMIT_UNKNOWN";
|
|
92
|
+
export const E_ACTION_RECONCILIATION_REQUIRED = "E_ACTION_RECONCILIATION_REQUIRED";
|
|
93
|
+
export const E_ACTION_EVIDENCE_INVALID = "E_ACTION_EVIDENCE_INVALID";
|
|
94
|
+
export const E_ACTION_AUTHORIZATION_INVALID = "E_ACTION_AUTHORIZATION_INVALID";
|
|
95
|
+
export const E_ACTION_VERIFICATION_REQUIRED = "E_ACTION_VERIFICATION_REQUIRED";
|
|
96
|
+
export const E_ACTION_VERIFICATION_INVALID = "E_ACTION_VERIFICATION_INVALID";
|
|
97
|
+
export const E_ACTION_POLICY_DRIFT = "E_ACTION_POLICY_DRIFT";
|
|
98
|
+
export const E_ACTION_POLICY_LOCK_REQUIRED = "E_ACTION_POLICY_LOCK_REQUIRED";
|
|
99
|
+
export const E_ACTION_RECONCILIATION_AUTHORITY_REQUIRED =
|
|
100
|
+
"E_ACTION_RECONCILIATION_AUTHORITY_REQUIRED";
|
|
101
|
+
export const E_ACTION_RECONCILIATION_EVIDENCE_INVALID =
|
|
102
|
+
"E_ACTION_RECONCILIATION_EVIDENCE_INVALID";
|
|
103
|
+
export const E_APPROVAL_INVALID = "E_APPROVAL_INVALID";
|
|
104
|
+
export const E_APPROVAL_STALE = "E_APPROVAL_STALE";
|
|
105
|
+
export const E_APPROVAL_ALREADY_RESOLVED = "E_APPROVAL_ALREADY_RESOLVED";
|
|
106
|
+
export const E_TRAJECTORY_SCENARIO_INVALID = "E_TRAJECTORY_SCENARIO_INVALID";
|
|
107
|
+
export const E_TRAJECTORY_REFERENCE_REQUIRED = "E_TRAJECTORY_REFERENCE_REQUIRED";
|
|
108
|
+
|
|
65
109
|
/**
|
|
66
110
|
* Public, stable ForgeLoop error and reason codes documented for users and harnesses.
|
|
67
111
|
*/
|
|
@@ -381,6 +425,83 @@ export const PUBLIC_ERROR_CODES = Object.freeze({
|
|
|
381
425
|
meaning: "Persisted correction history shows no new diagnostic information.",
|
|
382
426
|
safeResolution: "Use an independent check, revisit assumptions, or record a materially different diagnosis.",
|
|
383
427
|
}),
|
|
428
|
+
E_DIAGNOSTIC_CASE_INVALID: Object.freeze({
|
|
429
|
+
code: "E_DIAGNOSTIC_CASE_INVALID",
|
|
430
|
+
category: "diagnosis",
|
|
431
|
+
classification: "PUBLIC_STABLE",
|
|
432
|
+
meaning: "Structured diagnostic case details or parameters are malformed.",
|
|
433
|
+
safeResolution: "Provide valid observations, contributors, hypotheses with settlement criteria, and nextSafeAction.",
|
|
434
|
+
}),
|
|
435
|
+
E_DIAGNOSTIC_CASE_CYCLE_MISMATCH: Object.freeze({
|
|
436
|
+
code: "E_DIAGNOSTIC_CASE_CYCLE_MISMATCH",
|
|
437
|
+
category: "diagnosis",
|
|
438
|
+
classification: "PUBLIC_STABLE",
|
|
439
|
+
meaning: "Diagnostic case verification cycle does not match the active work state verification cycle.",
|
|
440
|
+
safeResolution: "Record the diagnostic case for the current active verification cycle.",
|
|
441
|
+
}),
|
|
442
|
+
E_DIAGNOSTIC_CASE_EVIDENCE_INVALID: Object.freeze({
|
|
443
|
+
code: "E_DIAGNOSTIC_CASE_EVIDENCE_INVALID",
|
|
444
|
+
category: "diagnosis",
|
|
445
|
+
classification: "PUBLIC_STABLE",
|
|
446
|
+
meaning: "A diagnostic case evidence reference does not match any check from the active verification cycle.",
|
|
447
|
+
safeResolution: "Reference check IDs recorded during the active verification cycle.",
|
|
448
|
+
}),
|
|
449
|
+
E_HYPOTHESIS_SETTLEMENT_MISSING: Object.freeze({
|
|
450
|
+
code: "E_HYPOTHESIS_SETTLEMENT_MISSING",
|
|
451
|
+
category: "diagnosis",
|
|
452
|
+
classification: "PUBLIC_STABLE",
|
|
453
|
+
meaning: "An open hypothesis lacks a falsifiable settlement condition.",
|
|
454
|
+
safeResolution: "Provide a structured settledBy predicate, check status, or observation binding.",
|
|
455
|
+
}),
|
|
456
|
+
E_HYPOTHESIS_DISPOSITION_INVALID: Object.freeze({
|
|
457
|
+
code: "E_HYPOTHESIS_DISPOSITION_INVALID",
|
|
458
|
+
category: "diagnosis",
|
|
459
|
+
classification: "PUBLIC_STABLE",
|
|
460
|
+
meaning: "Hypothesis disposition is malformed or references an unknown hypothesis or disallowed transition.",
|
|
461
|
+
safeResolution: "Record a disposition for a known hypothesis using an allowed status transition.",
|
|
462
|
+
}),
|
|
463
|
+
E_HYPOTHESIS_DISPOSITION_EVIDENCE_INVALID: Object.freeze({
|
|
464
|
+
code: "E_HYPOTHESIS_DISPOSITION_EVIDENCE_INVALID",
|
|
465
|
+
category: "diagnosis",
|
|
466
|
+
classification: "PUBLIC_STABLE",
|
|
467
|
+
meaning: "Hypothesis disposition evidence references do not resolve to checks of the active cycle.",
|
|
468
|
+
safeResolution: "Reference at least one check ID recorded in the active verification cycle.",
|
|
469
|
+
}),
|
|
470
|
+
E_INTERVENTION_INVALID: Object.freeze({
|
|
471
|
+
code: "E_INTERVENTION_INVALID",
|
|
472
|
+
category: "diagnosis",
|
|
473
|
+
classification: "PUBLIC_STABLE",
|
|
474
|
+
meaning: "Intervention record is malformed.",
|
|
475
|
+
safeResolution: "Provide id, kind, statement, and at least one bound hypothesisRef.",
|
|
476
|
+
}),
|
|
477
|
+
E_INTERVENTION_HYPOTHESIS_MISSING: Object.freeze({
|
|
478
|
+
code: "E_INTERVENTION_HYPOTHESIS_MISSING",
|
|
479
|
+
category: "diagnosis",
|
|
480
|
+
classification: "PUBLIC_STABLE",
|
|
481
|
+
meaning: "Intervention does not bind to any hypothesis.",
|
|
482
|
+
safeResolution: "Bind the intervention to at least one recorded hypothesis.",
|
|
483
|
+
}),
|
|
484
|
+
E_INTERVENTION_REFERENCE_INVALID: Object.freeze({
|
|
485
|
+
code: "E_INTERVENTION_REFERENCE_INVALID",
|
|
486
|
+
category: "diagnosis",
|
|
487
|
+
classification: "PUBLIC_STABLE",
|
|
488
|
+
meaning: "Intervention references an unknown hypothesis.",
|
|
489
|
+
safeResolution: "Record the diagnostic case containing the hypothesis before recording the intervention.",
|
|
490
|
+
}),
|
|
491
|
+
E_STRATEGY_OSCILLATION: Object.freeze({
|
|
492
|
+
code: "E_STRATEGY_OSCILLATION",
|
|
493
|
+
category: "progress",
|
|
494
|
+
classification: "PUBLIC_STABLE",
|
|
495
|
+
meaning: "Correction history oscillates between previously exhausted strategies without new information.",
|
|
496
|
+
safeResolution: "Gather a genuinely new observation or test a materially different falsifiable hypothesis.",
|
|
497
|
+
}),
|
|
498
|
+
E_TRACE_SNAPSHOT_INCONSISTENT: Object.freeze({
|
|
499
|
+
code: "E_TRACE_SNAPSHOT_INCONSISTENT",
|
|
500
|
+
category: "diagnosis",
|
|
501
|
+
classification: "PUBLIC_STABLE",
|
|
502
|
+
meaning: "Task artifacts changed while the execution trace was being read.",
|
|
503
|
+
safeResolution: "Rerun the read-only projection to obtain a consistent view.",
|
|
504
|
+
}),
|
|
384
505
|
E_DECISION_CRITERION_INVALID: Object.freeze({
|
|
385
506
|
code: "E_DECISION_CRITERION_INVALID",
|
|
386
507
|
category: "contract",
|
|
@@ -514,6 +635,181 @@ export const PUBLIC_ERROR_CODES = Object.freeze({
|
|
|
514
635
|
meaning: "A canonical ForgeLoop kit destination already exists with content that does not match the shipped canonical template.",
|
|
515
636
|
safeResolution: "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.",
|
|
516
637
|
}),
|
|
638
|
+
E_ACTION_INVALID: Object.freeze({
|
|
639
|
+
code: "E_ACTION_INVALID",
|
|
640
|
+
category: "durable-action",
|
|
641
|
+
classification: "PUBLIC_STABLE",
|
|
642
|
+
meaning: "Durable action artifact or parameters are malformed or schema-invalid.",
|
|
643
|
+
safeResolution: "Correct the action fields reported by the structured error, then retry through forgeloop action-propose or run-action.",
|
|
644
|
+
}),
|
|
645
|
+
E_ACTION_NOT_FOUND: Object.freeze({
|
|
646
|
+
code: "E_ACTION_NOT_FOUND",
|
|
647
|
+
category: "durable-action",
|
|
648
|
+
classification: "PUBLIC_STABLE",
|
|
649
|
+
meaning: "Referenced durable action ID does not exist for the task.",
|
|
650
|
+
safeResolution: "List actions with forgeloop action-show or propose the action first.",
|
|
651
|
+
}),
|
|
652
|
+
E_ACTION_STATE_MISMATCH: Object.freeze({
|
|
653
|
+
code: "E_ACTION_STATE_MISMATCH",
|
|
654
|
+
category: "durable-action",
|
|
655
|
+
classification: "PUBLIC_STABLE",
|
|
656
|
+
meaning: "Requested durable action transition is not part of the canonical state machine.",
|
|
657
|
+
safeResolution: "Inspect current action state with forgeloop action-show and use a legal transition; never edit action artifacts by hand.",
|
|
658
|
+
}),
|
|
659
|
+
E_ACTION_IDEMPOTENCY_REQUIRED: Object.freeze({
|
|
660
|
+
code: "E_ACTION_IDEMPOTENCY_REQUIRED",
|
|
661
|
+
category: "durable-action",
|
|
662
|
+
classification: "PUBLIC_STABLE",
|
|
663
|
+
meaning: "Side-effecting action class requires an idempotency key.",
|
|
664
|
+
safeResolution: "Supply a stable --idempotency-key that identifies the logical external action.",
|
|
665
|
+
}),
|
|
666
|
+
E_ACTION_IDEMPOTENCY_CONFLICT: Object.freeze({
|
|
667
|
+
code: "E_ACTION_IDEMPOTENCY_CONFLICT",
|
|
668
|
+
category: "durable-action",
|
|
669
|
+
classification: "PUBLIC_STABLE",
|
|
670
|
+
meaning: "The idempotency key already binds to a different canonical action fingerprint in this task.",
|
|
671
|
+
safeResolution: "Use a new idempotency key with a new actionId, or reuse the existing logical action unchanged; never relabel an executed effect.",
|
|
672
|
+
}),
|
|
673
|
+
E_ACTION_CAPABILITY_UNKNOWN: Object.freeze({
|
|
674
|
+
code: "E_ACTION_CAPABILITY_UNKNOWN",
|
|
675
|
+
category: "capability-policy",
|
|
676
|
+
classification: "PUBLIC_STABLE",
|
|
677
|
+
meaning: "Action capability is not part of the canonical capability vocabulary.",
|
|
678
|
+
safeResolution: "Use a documented capability from forgeloop protocol-info; unknown capabilities fail closed.",
|
|
679
|
+
}),
|
|
680
|
+
E_ACTION_CAPABILITY_DENIED: Object.freeze({
|
|
681
|
+
code: "E_ACTION_CAPABILITY_DENIED",
|
|
682
|
+
category: "capability-policy",
|
|
683
|
+
classification: "PUBLIC_STABLE",
|
|
684
|
+
meaning: "Capability policy denies this capability.",
|
|
685
|
+
safeResolution: "Obtain an operator policy change outside the task, or do not perform the action.",
|
|
686
|
+
}),
|
|
687
|
+
E_ACTION_AUTHORITY_REQUIRED: Object.freeze({
|
|
688
|
+
code: "E_ACTION_AUTHORITY_REQUIRED",
|
|
689
|
+
category: "authority",
|
|
690
|
+
classification: "PUBLIC_STABLE",
|
|
691
|
+
meaning: "Policy requires host-attested authority that was not supplied through a host trust boundary.",
|
|
692
|
+
safeResolution: "Perform the action through a host integration that supplies trusted authority context; standalone CLI cannot mint it.",
|
|
693
|
+
}),
|
|
694
|
+
E_ACTION_APPROVAL_REQUIRED: Object.freeze({
|
|
695
|
+
code: "E_ACTION_APPROVAL_REQUIRED",
|
|
696
|
+
category: "durable-approval",
|
|
697
|
+
classification: "PUBLIC_STABLE",
|
|
698
|
+
meaning: "Policy requires a current fingerprint-bound approval before this action may proceed.",
|
|
699
|
+
safeResolution: "Request approval with forgeloop approval-request and resolve it via forgeloop approval-resolve, then rerun the action.",
|
|
700
|
+
}),
|
|
701
|
+
E_ACTION_APPROVAL_NOT_REQUIRED: Object.freeze({
|
|
702
|
+
code: "E_ACTION_APPROVAL_NOT_REQUIRED",
|
|
703
|
+
category: "durable-approval",
|
|
704
|
+
classification: "PUBLIC_STABLE",
|
|
705
|
+
meaning: "The current capability policy allows the action without an approval artifact.",
|
|
706
|
+
safeResolution: "Do not create an approval; authorize the action through the current policy path.",
|
|
707
|
+
}),
|
|
708
|
+
E_ACTION_COMMIT_UNKNOWN: Object.freeze({
|
|
709
|
+
code: "E_ACTION_COMMIT_UNKNOWN",
|
|
710
|
+
category: "durable-action",
|
|
711
|
+
classification: "PUBLIC_STABLE",
|
|
712
|
+
meaning: "External commit state of a started action cannot be proven.",
|
|
713
|
+
safeResolution: "Do not retry; reconcile the observed external state with forgeloop action-reconcile.",
|
|
714
|
+
}),
|
|
715
|
+
E_ACTION_RECONCILIATION_REQUIRED: Object.freeze({
|
|
716
|
+
code: "E_ACTION_RECONCILIATION_REQUIRED",
|
|
717
|
+
category: "durable-action",
|
|
718
|
+
classification: "PUBLIC_STABLE",
|
|
719
|
+
meaning: "An action is COMMIT_UNKNOWN and blocks progress until explicitly reconciled.",
|
|
720
|
+
safeResolution: "Observe the external system and run forgeloop action-reconcile --outcome COMMITTED|NOT_COMMITTED|UNKNOWN with evidence references.",
|
|
721
|
+
}),
|
|
722
|
+
E_ACTION_EVIDENCE_INVALID: Object.freeze({
|
|
723
|
+
code: "E_ACTION_EVIDENCE_INVALID",
|
|
724
|
+
category: "durable-action",
|
|
725
|
+
classification: "PUBLIC_STABLE",
|
|
726
|
+
meaning: "Evidence supplied for verification or reconciliation is missing, malformed, or unbounded.",
|
|
727
|
+
safeResolution: "Supply bounded evidence references appropriate to the action type; do not paste raw external output into the ledger.",
|
|
728
|
+
}),
|
|
729
|
+
E_ACTION_AUTHORIZATION_INVALID: Object.freeze({
|
|
730
|
+
code: "E_ACTION_AUTHORIZATION_INVALID",
|
|
731
|
+
category: "durable-action",
|
|
732
|
+
classification: "PUBLIC_STABLE",
|
|
733
|
+
meaning: "Action authorization evidence is missing, incomplete, or was not produced by the canonical authorization service.",
|
|
734
|
+
safeResolution: "Authorize the action through forgeloop run-action or a trusted embedding host; caller surfaces can never mint AUTHORIZED.",
|
|
735
|
+
}),
|
|
736
|
+
E_ACTION_VERIFICATION_REQUIRED: Object.freeze({
|
|
737
|
+
code: "E_ACTION_VERIFICATION_REQUIRED",
|
|
738
|
+
category: "durable-action",
|
|
739
|
+
classification: "PUBLIC_STABLE",
|
|
740
|
+
meaning: "The action cannot reach VERIFIED through this surface; canonical independent postcondition evidence is required.",
|
|
741
|
+
safeResolution: "Run an independent verification check, then record it with forgeloop action-verify; exit code 0 alone is not verification.",
|
|
742
|
+
}),
|
|
743
|
+
E_ACTION_VERIFICATION_INVALID: Object.freeze({
|
|
744
|
+
code: "E_ACTION_VERIFICATION_INVALID",
|
|
745
|
+
category: "durable-action",
|
|
746
|
+
classification: "PUBLIC_STABLE",
|
|
747
|
+
meaning: "Verification evidence does not resolve to a canonical passed ForgeLoop artifact bound to this task and action.",
|
|
748
|
+
safeResolution: "Supply a canonical execution or check reference produced by run-check for this task; arbitrary strings fail closed.",
|
|
749
|
+
}),
|
|
750
|
+
E_ACTION_POLICY_DRIFT: Object.freeze({
|
|
751
|
+
code: "E_ACTION_POLICY_DRIFT",
|
|
752
|
+
category: "capability-policy",
|
|
753
|
+
classification: "PUBLIC_STABLE",
|
|
754
|
+
meaning: "The current capability policy does not match the policy lock or task policy snapshot binding this task.",
|
|
755
|
+
safeResolution: "Restore the policy epoch recorded at task activation or create a new valid lock and snapshot before side effects.",
|
|
756
|
+
}),
|
|
757
|
+
E_ACTION_POLICY_LOCK_REQUIRED: Object.freeze({
|
|
758
|
+
code: "E_ACTION_POLICY_LOCK_REQUIRED",
|
|
759
|
+
category: "capability-policy",
|
|
760
|
+
classification: "PUBLIC_STABLE",
|
|
761
|
+
meaning: "A capability policy is present but no valid policy lock exists to bind authorization identity.",
|
|
762
|
+
safeResolution: "Record a valid policy lock (forgeloop baseline or policy-discover --write) before authorizing durable actions.",
|
|
763
|
+
}),
|
|
764
|
+
E_ACTION_RECONCILIATION_AUTHORITY_REQUIRED: Object.freeze({
|
|
765
|
+
code: "E_ACTION_RECONCILIATION_AUTHORITY_REQUIRED",
|
|
766
|
+
category: "durable-action",
|
|
767
|
+
classification: "PUBLIC_STABLE",
|
|
768
|
+
meaning: "Settling COMMIT_UNKNOWN external state requires trusted host attestation that was not supplied out-of-band.",
|
|
769
|
+
safeResolution: "Reconcile through a trusted embedding host boundary; actor-supplied observations may only record UNKNOWN.",
|
|
770
|
+
}),
|
|
771
|
+
E_ACTION_RECONCILIATION_EVIDENCE_INVALID: Object.freeze({
|
|
772
|
+
code: "E_ACTION_RECONCILIATION_EVIDENCE_INVALID",
|
|
773
|
+
category: "durable-action",
|
|
774
|
+
classification: "PUBLIC_STABLE",
|
|
775
|
+
meaning: "Settling reconciliation requires at least one bounded evidence reference binding the observation to the action.",
|
|
776
|
+
safeResolution: "Supply bounded external-state evidence references alongside trusted authority before settling ambiguity.",
|
|
777
|
+
}),
|
|
778
|
+
E_APPROVAL_INVALID: Object.freeze({
|
|
779
|
+
code: "E_APPROVAL_INVALID",
|
|
780
|
+
category: "durable-approval",
|
|
781
|
+
classification: "PUBLIC_STABLE",
|
|
782
|
+
meaning: "Approval artifact is malformed or does not bind the required fingerprint tuple.",
|
|
783
|
+
safeResolution: "Request a new approval with forgeloop approval-request; never hand-edit approval artifacts.",
|
|
784
|
+
}),
|
|
785
|
+
E_APPROVAL_STALE: Object.freeze({
|
|
786
|
+
code: "E_APPROVAL_STALE",
|
|
787
|
+
category: "durable-approval",
|
|
788
|
+
classification: "PUBLIC_STABLE",
|
|
789
|
+
meaning: "Approval no longer matches the current action fingerprint, contract fingerprint, task revision, or capability.",
|
|
790
|
+
safeResolution: "Request and resolve a fresh approval against the current action revision.",
|
|
791
|
+
}),
|
|
792
|
+
E_APPROVAL_ALREADY_RESOLVED: Object.freeze({
|
|
793
|
+
code: "E_APPROVAL_ALREADY_RESOLVED",
|
|
794
|
+
category: "durable-approval",
|
|
795
|
+
classification: "PUBLIC_STABLE",
|
|
796
|
+
meaning: "Approval is one-time resolvable and has already been approved or rejected.",
|
|
797
|
+
safeResolution: "Request a new approval if another decision is required.",
|
|
798
|
+
}),
|
|
799
|
+
E_TRAJECTORY_SCENARIO_INVALID: Object.freeze({
|
|
800
|
+
code: "E_TRAJECTORY_SCENARIO_INVALID",
|
|
801
|
+
category: "trajectory-evaluation",
|
|
802
|
+
classification: "PUBLIC_STABLE",
|
|
803
|
+
meaning: "Trajectory scenario file is missing required fields or schema-invalid.",
|
|
804
|
+
safeResolution: "Correct the scenario JSON against schemas/trajectory-scenario.schema.json.",
|
|
805
|
+
}),
|
|
806
|
+
E_TRAJECTORY_REFERENCE_REQUIRED: Object.freeze({
|
|
807
|
+
code: "E_TRAJECTORY_REFERENCE_REQUIRED",
|
|
808
|
+
category: "trajectory-evaluation",
|
|
809
|
+
classification: "PUBLIC_STABLE",
|
|
810
|
+
meaning: "Comparative efficiency requires a reference scenario with positive comparableSteps.",
|
|
811
|
+
safeResolution: "Provide --scenario with reference.comparableSteps, or omit efficiency from the result.",
|
|
812
|
+
}),
|
|
517
813
|
});
|
|
518
814
|
|
|
519
815
|
export const E_CHECK_INERT = "E_CHECK_INERT";
|
|
@@ -605,6 +901,53 @@ export const ALL_KNOWN_ERROR_CODES = Object.freeze(new Set([
|
|
|
605
901
|
E_BASELINE_RECORD_DURING_ACTIVE_TASK,
|
|
606
902
|
E_POLICY_INITIALIZATION_FAILED,
|
|
607
903
|
E_INIT_KIT_CONFLICT,
|
|
904
|
+
E_ACTION_INVALID,
|
|
905
|
+
E_ACTION_NOT_FOUND,
|
|
906
|
+
E_ACTION_STATE_MISMATCH,
|
|
907
|
+
E_ACTION_IDEMPOTENCY_REQUIRED,
|
|
908
|
+
E_ACTION_IDEMPOTENCY_CONFLICT,
|
|
909
|
+
E_ACTION_CAPABILITY_UNKNOWN,
|
|
910
|
+
E_ACTION_CAPABILITY_DENIED,
|
|
911
|
+
E_ACTION_AUTHORITY_REQUIRED,
|
|
912
|
+
E_ACTION_APPROVAL_REQUIRED,
|
|
913
|
+
E_ACTION_APPROVAL_NOT_REQUIRED,
|
|
914
|
+
E_ACTION_COMMIT_UNKNOWN,
|
|
915
|
+
E_ACTION_RECONCILIATION_REQUIRED,
|
|
916
|
+
E_ACTION_EVIDENCE_INVALID,
|
|
917
|
+
E_ACTION_AUTHORIZATION_INVALID,
|
|
918
|
+
E_ACTION_VERIFICATION_REQUIRED,
|
|
919
|
+
E_ACTION_VERIFICATION_INVALID,
|
|
920
|
+
E_ACTION_POLICY_DRIFT,
|
|
921
|
+
E_ACTION_POLICY_LOCK_REQUIRED,
|
|
922
|
+
E_ACTION_RECONCILIATION_AUTHORITY_REQUIRED,
|
|
923
|
+
E_ACTION_RECONCILIATION_EVIDENCE_INVALID,
|
|
924
|
+
E_APPROVAL_INVALID,
|
|
925
|
+
E_APPROVAL_STALE,
|
|
926
|
+
E_APPROVAL_ALREADY_RESOLVED,
|
|
927
|
+
E_TRAJECTORY_SCENARIO_INVALID,
|
|
928
|
+
E_TRAJECTORY_REFERENCE_REQUIRED,
|
|
929
|
+
E_DIAGNOSIS_REQUIRED,
|
|
930
|
+
E_DIAGNOSIS_INVALID,
|
|
931
|
+
E_DIAGNOSIS_EVIDENCE_INVALID,
|
|
932
|
+
E_DIAGNOSIS_CYCLE_MISMATCH,
|
|
933
|
+
E_DIAGNOSIS_NO_NEW_INFORMATION,
|
|
934
|
+
E_PROGRESS_STALLED,
|
|
935
|
+
E_DIAGNOSTIC_CASE_INVALID,
|
|
936
|
+
E_DIAGNOSTIC_CASE_CYCLE_MISMATCH,
|
|
937
|
+
E_DIAGNOSTIC_CASE_EVIDENCE_INVALID,
|
|
938
|
+
E_OBSERVATION_INVALID,
|
|
939
|
+
E_CONTRIBUTOR_INVALID,
|
|
940
|
+
E_CONTRIBUTOR_REFERENCE_INVALID,
|
|
941
|
+
E_HYPOTHESIS_INVALID,
|
|
942
|
+
E_HYPOTHESIS_SETTLEMENT_MISSING,
|
|
943
|
+
E_HYPOTHESIS_DISPOSITION_INVALID,
|
|
944
|
+
E_HYPOTHESIS_DISPOSITION_EVIDENCE_INVALID,
|
|
945
|
+
E_INTERVENTION_INVALID,
|
|
946
|
+
E_INTERVENTION_HYPOTHESIS_MISSING,
|
|
947
|
+
E_INTERVENTION_REFERENCE_INVALID,
|
|
948
|
+
E_FAILURE_SIGNATURE_INVALID,
|
|
949
|
+
E_STRATEGY_OSCILLATION,
|
|
950
|
+
"E_TRACE_SNAPSHOT_INCONSISTENT",
|
|
608
951
|
]));
|
|
609
952
|
|
|
610
953
|
/**
|
package/src/core/events.js
CHANGED
|
@@ -14,6 +14,17 @@ import { taskArtifactPath } from "./task-paths.js";
|
|
|
14
14
|
import { getActiveTaskTransaction, withTaskTransaction } from "./transaction.js";
|
|
15
15
|
|
|
16
16
|
import { assertDiagnosisDetails } from "./diagnosis-model.js";
|
|
17
|
+
import {
|
|
18
|
+
assertActionEventDetails,
|
|
19
|
+
assertApprovalEventDetails,
|
|
20
|
+
isActionEventName,
|
|
21
|
+
isApprovalEventName,
|
|
22
|
+
} from "./action-model.js";
|
|
23
|
+
import {
|
|
24
|
+
assertDiagnosticCaseDetails,
|
|
25
|
+
assertInterventionDetails,
|
|
26
|
+
assertHypothesisDispositionDetails,
|
|
27
|
+
} from "./diagnostic-model.js";
|
|
17
28
|
import { assertDecisionCriterionDetails } from "./settlement-model.js";
|
|
18
29
|
import {
|
|
19
30
|
LEGACY_RECOVERY_MIGRATION_EVENT,
|
|
@@ -46,6 +57,7 @@ const REPEATABLE_MILESTONES = new Set([
|
|
|
46
57
|
"VERIFICATION_RECORDED",
|
|
47
58
|
"REVIEW_STARTED",
|
|
48
59
|
"TERMINAL_RESULT_RECORDED",
|
|
60
|
+
"PREFLIGHT_READY",
|
|
49
61
|
]);
|
|
50
62
|
|
|
51
63
|
function eventIndexPath(eventsPath) {
|
|
@@ -98,6 +110,15 @@ export function validateKnownEventDetails(event) {
|
|
|
98
110
|
case "DIAGNOSIS_RECORDED":
|
|
99
111
|
assertDiagnosisDetails(event.details);
|
|
100
112
|
return;
|
|
113
|
+
case "DIAGNOSTIC_CASE_RECORDED":
|
|
114
|
+
assertDiagnosticCaseDetails(event.details);
|
|
115
|
+
return;
|
|
116
|
+
case "INTERVENTION_RECORDED":
|
|
117
|
+
assertInterventionDetails(event.details);
|
|
118
|
+
return;
|
|
119
|
+
case "HYPOTHESIS_DISPOSITION_RECORDED":
|
|
120
|
+
assertHypothesisDispositionDetails(event.details);
|
|
121
|
+
return;
|
|
101
122
|
case "DECISION_CRITERION_RECORDED":
|
|
102
123
|
assertDecisionCriterionDetails(event.details);
|
|
103
124
|
return;
|
|
@@ -120,7 +141,22 @@ export function validateKnownEventDetails(event) {
|
|
|
120
141
|
case "TASK_RECOVERY_RESUMED":
|
|
121
142
|
assertRecoveryResumedDetails(event.details);
|
|
122
143
|
return;
|
|
144
|
+
case "TRAJECTORY_EVALUATED":
|
|
145
|
+
if (!event.details || !/^eval-[A-Za-z0-9_-]+$/.test(event.details.evaluationId ?? "")
|
|
146
|
+
|| typeof event.details.scenarioId !== "string" || !/^[a-f0-9]{64}$/.test(event.details.evaluationFingerprint ?? "")
|
|
147
|
+
|| event.fingerprint !== event.details.evaluationFingerprint) {
|
|
148
|
+
throw protocolError("E_EVENT_INVALID", "TRAJECTORY_EVALUATED requires a bound evaluationId, scenarioId, and fingerprint");
|
|
149
|
+
}
|
|
150
|
+
return;
|
|
123
151
|
default:
|
|
152
|
+
if (isActionEventName(event.event)) {
|
|
153
|
+
assertActionEventDetails(event);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (isApprovalEventName(event.event)) {
|
|
157
|
+
assertApprovalEventDetails(event);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
124
160
|
return;
|
|
125
161
|
}
|
|
126
162
|
}
|
|
@@ -410,7 +446,11 @@ export async function validateEventLedger(target, packageRoot, options = {}) {
|
|
|
410
446
|
code: "E_PHASE_CHRONOLOGY_INVALID",
|
|
411
447
|
message: `${event.event} is missing prerequisite milestone: ${LIFECYCLE_MILESTONES[lastMilestone + 1]}`,
|
|
412
448
|
});
|
|
413
|
-
} else if (milestoneIndex < lastMilestone && event.event !== "VERIFICATION_STARTED"
|
|
449
|
+
} else if (milestoneIndex < lastMilestone && event.event !== "VERIFICATION_STARTED"
|
|
450
|
+
&& event.event !== "PREFLIGHT_READY") {
|
|
451
|
+
// VERIFICATION_STARTED re-enters per verification cycle; PREFLIGHT_READY
|
|
452
|
+
// may be refreshed mid-lifecycle (policy/contract evolution) after its
|
|
453
|
+
// prerequisites were already satisfied by the earlier occurrence.
|
|
414
454
|
errors.push({ code: "E_PHASE_CHRONOLOGY_INVALID", message: `${event.event} is out of lifecycle order` });
|
|
415
455
|
} else if (milestoneIndex === lastMilestone && !REPEATABLE_MILESTONES.has(event.event)) {
|
|
416
456
|
errors.push({ code: "E_PHASE_CHRONOLOGY_INVALID", message: `lifecycle milestone must not repeat: ${event.event}` });
|
|
@@ -102,7 +102,10 @@ function prerequisiteLedgerErrors(ledger, taskId, preflight, route) {
|
|
|
102
102
|
));
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
|
-
|
|
105
|
+
// Bind to the latest PREFLIGHT_READY: an append-only lifecycle may contain an
|
|
106
|
+
// older READY event superseded by a BLOCKED outcome and a fresh READY with
|
|
107
|
+
// current details (see preflight-reactivation recovery).
|
|
108
|
+
const preflightEvent = currentEvents.findLast((event) => event.event === "PREFLIGHT_READY");
|
|
106
109
|
if (preflightEvent && (!sameStringSet(preflightEvent.details?.requiredGates, preflight.requiredGates)
|
|
107
110
|
|| !sameStringSet(preflightEvent.details?.satisfiedGates, preflight.satisfiedGates))) {
|
|
108
111
|
errors.push(issue(
|