@cassiomc1/forgeloop 1.9.0 → 1.10.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 (103) hide show
  1. package/AGENT_COMPATIBILITY.md +15 -0
  2. package/DELEGATION_PROTOCOL.md +6 -0
  3. package/DOCS_INDEX.md +13 -2
  4. package/LOOP_ENGINEERING.md +17 -4
  5. package/LOOP_SYSTEM_DESIGN.md +56 -0
  6. package/ORCHESTRATOR_INTEGRATION.md +9 -0
  7. package/PROTOCOL_INTEGRATION.md +31 -0
  8. package/QUALITY_SCORECARD.md +2 -2
  9. package/README.md +53 -0
  10. package/TERMINOLOGY.md +12 -0
  11. package/THREAT_MODEL.md +24 -0
  12. package/completions/_forgeloop +2 -1
  13. package/completions/forgeloop.bash +3 -1
  14. package/completions/forgeloop.fish +9 -1
  15. package/docs/ADVISORY_CONTEXT.md +174 -0
  16. package/docs/AGENT_PROTOCOL_SUMMARY.md +28 -2
  17. package/docs/ARTIFACT_REFERENCE.md +29 -0
  18. package/docs/CLI_REFERENCE.md +40 -0
  19. package/docs/CODE_ATTESTATION.md +9 -0
  20. package/docs/CROSS_HARNESS_CONTINUITY.md +85 -0
  21. package/docs/DOCUMENTATION_GUIDE.md +11 -4
  22. package/docs/EXECUTION_PROFILE_BENCHMARKS.md +10 -0
  23. package/docs/GETTING_STARTED.md +22 -0
  24. package/docs/KNOWLEDGE_SOURCES.md +10 -0
  25. package/docs/MCP.md +29 -1
  26. package/docs/PACKAGE_CONTENTS.md +83 -0
  27. package/docs/RECIPES.md +80 -0
  28. package/docs/RELEASE_CHECKLIST.md +22 -0
  29. package/docs/REVISION_PROVIDERS.md +9 -0
  30. package/docs/TROUBLESHOOTING.md +66 -2
  31. package/docs/UNIVERSAL_INTEGRATION.md +60 -0
  32. package/docs/assets/diagrams/forgeloop-code-attestation-flow.html +13 -2
  33. package/docs/assets/diagrams/forgeloop-code-attestation-flow.receipt.json +6 -6
  34. package/docs/assets/diagrams/forgeloop-code-attestation-flow.svg +10 -1
  35. package/docs/assets/diagrams/forgeloop-engineering-flow.html +22 -11
  36. package/docs/assets/diagrams/forgeloop-engineering-flow.receipt.json +6 -6
  37. package/docs/assets/diagrams/forgeloop-engineering-flow.svg +17 -8
  38. package/docs/assets/diagrams/forgeloop-verification-trust-flow.html +14 -3
  39. package/docs/assets/diagrams/forgeloop-verification-trust-flow.receipt.json +6 -6
  40. package/docs/assets/diagrams/forgeloop-verification-trust-flow.svg +10 -1
  41. package/docs/diagrams/README.md +17 -0
  42. package/docs/diagrams/forgeloop-code-attestation-flow.workflow.json +383 -57
  43. package/docs/diagrams/forgeloop-engineering-flow.workflow.json +374 -55
  44. package/docs/diagrams/forgeloop-verification-trust-flow.workflow.json +328 -47
  45. package/docs/diagrams/reviews/forgeloop-code-attestation-flow.review.json +4 -4
  46. package/docs/diagrams/reviews/forgeloop-engineering-flow.review.json +4 -4
  47. package/docs/diagrams/reviews/forgeloop-verification-trust-flow.review.json +4 -4
  48. package/package.json +14 -4
  49. package/schemas/handoff-envelope.schema.json +1 -0
  50. package/scripts/CI_VALIDATORS.md +24 -0
  51. package/scripts/check-changelog-freshness.mjs +27 -3
  52. package/scripts/check-critical-coverage.mjs +9 -0
  53. package/scripts/generate-agent-protocol-summary.mjs +18 -0
  54. package/src/cli.js +6 -0
  55. package/src/commands/doctor.js +11 -10
  56. package/src/commands/handoff-accept.js +36 -0
  57. package/src/commands/handoff-list.js +28 -2
  58. package/src/commands/handoff-show.js +27 -2
  59. package/src/commands/reconcile-continuity.js +4 -0
  60. package/src/core/actions.js +2 -2
  61. package/src/core/advisory-context/constants.js +74 -0
  62. package/src/core/advisory-context/provider.js +287 -0
  63. package/src/core/advisory-context/service.js +140 -0
  64. package/src/core/approvals.js +2 -2
  65. package/src/core/artifacts.js +3 -3
  66. package/src/core/checks.js +0 -33
  67. package/src/core/cli-command-definitions.js +17 -0
  68. package/src/core/command-executors.js +12 -0
  69. package/src/core/command-input.js +11 -1
  70. package/src/core/completion.js +2 -2
  71. package/src/core/continuity-lint.js +89 -0
  72. package/src/core/continuity-reconciliation.js +16 -0
  73. package/src/core/continuity.js +10 -11
  74. package/src/core/error-codes.js +113 -0
  75. package/src/core/events.js +37 -5
  76. package/src/core/execution-profile-context.js +15 -1
  77. package/src/core/execution-profile.js +18 -5
  78. package/src/core/filesystem.js +18 -2
  79. package/src/core/handoff-acceptance.js +277 -0
  80. package/src/core/handoff.js +41 -8
  81. package/src/core/integration-invocation-policy.js +19 -2
  82. package/src/core/integration-resources.js +21 -1
  83. package/src/core/next-action-pending-actions.js +255 -0
  84. package/src/core/next-action-phases.js +26 -764
  85. package/src/core/next-action-planned-phase.js +51 -0
  86. package/src/core/next-action-quality-guidance.js +19 -0
  87. package/src/core/next-action-recovery-phases.js +97 -0
  88. package/src/core/next-action-refresh.js +20 -0
  89. package/src/core/next-action-review-phase.js +189 -0
  90. package/src/core/next-action-verification-phase.js +192 -0
  91. package/src/core/portable-context.js +103 -0
  92. package/src/core/protocol-info.js +18 -2
  93. package/src/core/runtime-context.js +31 -0
  94. package/src/core/task-recovery.js +2 -2
  95. package/src/core/transaction-maintenance.js +70 -0
  96. package/src/core/transaction.js +31 -10
  97. package/src/core/work-state.js +5 -5
  98. package/src/integration.d.ts +135 -3
  99. package/src/integration.js +23 -0
  100. package/src/core/cli-metadata.js +0 -23
  101. package/src/core/decision-classification.js +0 -55
  102. package/src/core/gates.js +0 -57
  103. package/src/core/workflow-compatibility.js +0 -151
@@ -0,0 +1,83 @@
1
+ # Core npm package contents
2
+
3
+ This page describes the intentional boundary of the published
4
+ `@cassiomc1/forgeloop` package. The [`files`](../package.json) list in
5
+ `package.json` is the packaging source of truth, while the repository's
6
+ `tests/package.test.js` and clean-room `scripts/package_smoke.mjs` checks keep
7
+ the boundary executable. Those test files are repository tooling and are not
8
+ part of the consumer tarball.
9
+
10
+ ## Consumer surface
11
+
12
+ The package exposes the `forgeloop` executable from `src/cli.js` and the
13
+ `@cassiomc1/forgeloop/integration` subpath from `src/integration.js`, with its
14
+ declaration file. The package has no runtime dependencies and requires Node.js
15
+ 20 or newer.
16
+
17
+ ## Included files
18
+
19
+ The published tarball includes the following consumer-facing groups:
20
+
21
+ - **Runtime and protocol:** every maintained JavaScript module under `src/`,
22
+ the guide registry, protocol templates, JSON schemas, completions, and the
23
+ generic CI verifier. Four retired compatibility helpers remain in the
24
+ repository for historical context and are explicitly excluded:
25
+ `src/core/cli-metadata.js`, `src/core/decision-classification.js`,
26
+ `src/core/gates.js`, and `src/core/workflow-compatibility.js`.
27
+ - **Initialization material:** the root protocol and integration documents,
28
+ legal notices, the target profile template, and every path listed by
29
+ `src/core/templates.js`. These files are read by `init` and `update`, so
30
+ they are part of the executable consumer contract even when a document is
31
+ marked deprecated in the documentation manifest.
32
+ - **Benchmark inputs:** execution-profile scenario definitions and their
33
+ README. They make new measurements reproducible; historical measurements
34
+ and generated results are repository evidence and are excluded.
35
+ - **User documentation:** the getting-started, integration, CLI, artifact,
36
+ troubleshooting, release, package-boundary, and related reference pages.
37
+ The typed diagram sources, generated HTML/SVG/receipt artifacts, and
38
+ source-bound review records under `docs/diagrams/` are included together so
39
+ the packaged documentation keeps its visual provenance.
40
+ - **Release tooling:** the selected deterministic generators, validators,
41
+ benchmark helpers, and shell completions needed by maintainers who consume
42
+ the source kit.
43
+
44
+ ## Excluded files
45
+
46
+ The tarball intentionally omits repository-only material:
47
+
48
+ - tests, conformance fixtures, coverage output, and secret-scanning helpers;
49
+ - local `.forgeloop` state, task ledgers, locks, transactions, and execution
50
+ receipts (the `.forgeloop/forgeloop.gitignore` template is the sole
51
+ exception);
52
+ - raw or aggregate benchmark results, package archives, and release train
53
+ contracts;
54
+ - historical release plans and retired MCP adapter sources; the MCP adapter
55
+ is published as its own package;
56
+ - the repository README hero PNG, which is a GitHub-only asset. The packaged
57
+ README remains intentionally text-first around that relative repository
58
+ image reference.
59
+
60
+ The package test checks both required paths and these exclusion classes. It
61
+ also enumerates `src/**/*.js` and fails if a maintained runtime module is
62
+ missing from the candidate tarball or if a retired helper is reintroduced.
63
+ The repository index remains a catalog: links from `DOCS_INDEX.md` to tests,
64
+ proof-of-concept evidence, historical plans, and source trees may intentionally
65
+ resolve only in the full repository and are not package dependencies.
66
+
67
+ ## Verification and publication
68
+
69
+ Run the following checks from a clean checkout before opening a release PR:
70
+
71
+ ```bash
72
+ npm pack --dry-run --json
73
+ npm run pack:check
74
+ npm run pack:smoke
75
+ ```
76
+
77
+ `pack:smoke` installs the candidate tarball into a temporary consumer and
78
+ exercises the CLI, public Integration API, initialization, schemas, and
79
+ packaged documentation references. The tag-triggered publication workflow
80
+ runs the same smoke gate before `npm publish --provenance --access public`.
81
+ Publication therefore remains owned by the trusted GitHub Actions OIDC
82
+ workflow; local package inspection proves the candidate boundary but does not
83
+ publish it.
package/docs/RECIPES.md CHANGED
@@ -457,6 +457,86 @@ operational context only: a handoff is not delegation, authority, independent
457
457
  review evidence, or completion evidence. Use `continuity.json` for mutable
458
458
  resume notes and canonical execution artifacts for proof.
459
459
 
460
+ ### Recipe 18A — Accept an Immutable Handoff Exactly Once
461
+
462
+ After inspecting the snapshot and confirming that the receiving harness is
463
+ actually consuming it, record the operational receipt:
464
+
465
+ ```bash
466
+ forgeloop handoff-accept --task task-001 \
467
+ --handoff <handoffId> \
468
+ --consumer-id agent-session-42 \
469
+ --harness codex \
470
+ --json
471
+ ```
472
+
473
+ Retrying with the same consumer is idempotent. A different consumer receives
474
+ `E_HANDOFF_ALREADY_ACCEPTED`. Acceptance is operational only: it does not
475
+ transfer claims, create evidence, approve delegation, or grant authority.
476
+
477
+ ### Recipe 18B — Diagnose an Inconsistent Handoff
478
+
479
+ Inspect the derived projection and ledger before attempting any repair:
480
+
481
+ ```bash
482
+ forgeloop handoff-list --task task-001 --json
483
+ forgeloop handoff-show --task task-001 --id <handoffId> --json
484
+ forgeloop validate-protocol --task task-001 --json
485
+ ```
486
+
487
+ `INCONSISTENT` is fail-closed. Check the returned reason codes for a stale
488
+ contract/route/repository snapshot, an unbound legacy handoff, a digest mismatch,
489
+ or invalid acceptance history. Do not edit the immutable handoff or
490
+ `events.ndjson`; create a fresh handoff after the canonical issue is resolved.
491
+
492
+ ### Recipe 18C — Use an Advisory Provider from a Host Integration
493
+
494
+ Register a provider in runtime context and invoke recall explicitly:
495
+
496
+ ```javascript
497
+ import {
498
+ createForgeLoopContext,
499
+ recallAdvisoryContext,
500
+ } from "@cassiomc1/forgeloop/integration";
501
+
502
+ const runtimeContext = createForgeLoopContext({
503
+ advisoryContextProviders: {
504
+ "host-context": {
505
+ id: "host-context",
506
+ recall: async ({ query }) => ({ items: await hostLookup(query) }),
507
+ },
508
+ },
509
+ });
510
+
511
+ const result = await recallAdvisoryContext({
512
+ target: ".",
513
+ taskId: "task-001",
514
+ providerName: "host-context",
515
+ query: "current authentication constraints",
516
+ runtimeContext,
517
+ });
518
+ ```
519
+
520
+ Recall is lazy, bounded, opt-in, non-persisted, non-evidence, and
521
+ non-executable. Validate every proposed change against canonical state and
522
+ verification instead of executing provider text.
523
+
524
+ ### Recipe 18D — Resume with Continuity Lint Warnings
525
+
526
+ Treat lint findings as inspection hints only:
527
+
528
+ ```bash
529
+ forgeloop continuity --task task-001 --json
530
+ forgeloop reconcile-continuity --task task-001 --json
531
+ forgeloop next --task task-001 --json
532
+ ```
533
+
534
+ Findings such as `CONTINUITY_REMAINING_ALREADY_COMPLETED`,
535
+ `CONTINUITY_FOCUS_ALREADY_COMPLETED`, `CONTINUITY_ITEM_ROLE_CONFLICT`,
536
+ `CONTINUITY_INSPECT_PATH_MISSING`, and `CONTINUITY_EMPTY_HINT_SET` are
537
+ non-authoritative and non-evidence. Refresh the note with
538
+ `record-continuity` when useful, then follow the canonical next action.
539
+
460
540
  ---
461
541
 
462
542
  ### Recipe 19 — Apply a Responsibility Contract
@@ -13,9 +13,29 @@ preparation and verification checklist; it does not authorize publication.
13
13
  - [ ] `npm pack --dry-run` contains the required scenario definitions but no
14
14
  raw or aggregate benchmark results, tests, local state, or repository
15
15
  metadata.
16
+ - [ ] [`docs/PACKAGE_CONTENTS.md`](./PACKAGE_CONTENTS.md) matches the current
17
+ `package.json` file list and documents intentional inclusions and
18
+ exclusions.
19
+ - [ ] Every maintained `src/**/*.js` module is present in the candidate
20
+ tarball; only the four explicitly retired compatibility helpers are
21
+ excluded.
16
22
 
17
23
  ## Protocol and attestation
18
24
 
25
+ - [ ] `protocol-info` and the Integration API capability contracts agree.
26
+ - [ ] `canonicalHandoffs` v2 is advertised consistently.
27
+ - [ ] `advisoryContextProviders` v1 is advertised consistently.
28
+ - [ ] Advisory context remains Integration-API-only.
29
+ - [ ] `next`, `status`, and `task/context` invoke zero advisory providers.
30
+ - [ ] Advisory request budgets are normalized before provider invocation.
31
+ - [ ] Advisory results are never persisted by ForgeLoop.
32
+ - [ ] Same-consumer handoff acceptance is idempotent.
33
+ - [ ] Different-consumer handoff acceptance fails closed.
34
+ - [ ] Concurrent acceptance creates one `HANDOFF_ACCEPTED` event.
35
+ - [ ] Clean HEAD/branch drift rejects handoff acceptance.
36
+ - [ ] Stale contract/route identity rejects handoff creation or acceptance.
37
+ - [ ] An invalid event ledger projects `INCONSISTENT`.
38
+ - [ ] Continuity lint remains non-authoritative and non-evidence.
19
39
  - [ ] `npm run dependency:policy` passes without adding runtime dependencies.
20
40
  - [ ] `npm run lint` passes.
21
41
  - [ ] `npm test` passes.
@@ -48,6 +68,8 @@ preparation and verification checklist; it does not authorize publication.
48
68
  ## Integration and cross-platform evidence
49
69
 
50
70
  - [ ] `npm run pack:check` and `npm run pack:smoke` pass.
71
+ - [ ] The npm publication workflow runs `npm run pack:smoke` before its
72
+ provenance-backed publish step.
51
73
  - [ ] `npm run mcp:test` either runs the configured MCP tests or reports the
52
74
  single actionable setup prerequisite.
53
75
  - [ ] `npm run mcp:pack:check` passes when MCP dependencies are available.
@@ -134,3 +134,12 @@ provider semantics fail closed.
134
134
  An implementation should be tested for deterministic identity, exact bytes,
135
135
  binary and empty files, Unicode and space-containing paths, symlinks,
136
136
  Gitlinks, deletions, renames, path traversal, and stable error mapping.
137
+
138
+ ### Focused test selection and evidence
139
+
140
+ A test-runner filter chooses what a command executes. It does not establish a
141
+ canonical differential verification scope. Use `run-check` to bind executed
142
+ commands to evidence, and supply a fresh canonical scope reference when the
143
+ checker requires one. A manual observation must declare `manual-review`;
144
+ command metadata alone does not prove that a process ran. Packed TypeScript
145
+ consumer checks and critical lifecycle coverage complement these boundaries.
@@ -761,16 +761,50 @@ explicit operation only when the task's scope permits it.
761
761
 
762
762
  ---
763
763
 
764
+ ### Symptom: Advisory Context Recall Is Unavailable or Rejected
765
+
766
+ #### Error Codes: `E_ADVISORY_CONTEXT_PROVIDER_INVALID`, `E_ADVISORY_CONTEXT_PROVIDER_UNAVAILABLE`, `E_ADVISORY_CONTEXT_QUERY_INVALID`, `E_ADVISORY_CONTEXT_REQUEST_INVALID`, `E_ADVISORY_CONTEXT_RESULT_INVALID`, `E_ADVISORY_CONTEXT_TIMEOUT`, `E_ADVISORY_CONTEXT_OUTPUT_LIMIT`, `E_PORTABLE_CONTEXT_INVALID`
767
+
768
+ #### What it means
769
+
770
+ The host's optional advisory provider is missing, malformed, unavailable, too
771
+ slow, or returned content outside the bounded portable-context contract. These
772
+ failures never become lifecycle, evidence, completion, or next-action failures.
773
+
774
+ #### Safe recovery
775
+
776
+ Inspect provider registration and normalize the request before retrying through
777
+ the Integration API. Reduce query, item, total-output, and timeout values to the
778
+ documented budgets, remove secrets/control characters, and ensure the provider
779
+ returns only allowlisted item fields. If advisory context is unavailable,
780
+ continue from canonical task state; do not fabricate a provider or execute its
781
+ text.
782
+
783
+ ### Symptom: Continuity Lint Reports a Contradictory Hint
784
+
785
+ Continuity lint is diagnostic only. Its findings do not change reconciliation,
786
+ state, evidence, authority, or completion:
787
+
788
+ | Finding | Meaning | Safe response |
789
+ | --- | --- | --- |
790
+ | `CONTINUITY_REMAINING_ALREADY_COMPLETED` | A remaining-work item is already recorded as completed. | Refresh the operational note; do not change canonical completion evidence. |
791
+ | `CONTINUITY_FOCUS_ALREADY_COMPLETED` | The current focus ID is already completed. | Choose a current inspection focus or clear the hint. |
792
+ | `CONTINUITY_ITEM_ROLE_CONFLICT` | An item appears in both remaining work and known issues. | Remove the contradictory hint through `record-continuity`. |
793
+ | `CONTINUITY_INSPECT_PATH_MISSING` | An `inspectFirst` path is not present in the current target. | Reconcile the checkout and update the path hint. |
794
+ | `CONTINUITY_EMPTY_HINT_SET` | No operational hint was supplied. | Treat the result as informational and follow canonical `next`. |
795
+
764
796
  ### Symptom: Handoff Is Invalid or Tampered
765
797
 
766
- #### Error Codes: `E_HANDOFF_INVALID`, `E_HANDOFF_STATE_UNAVAILABLE`, `E_HANDOFF_TAMPERED`, `E_HANDOFF_NOT_FOUND`
798
+ #### Error Codes: `E_HANDOFF_INVALID`, `E_HANDOFF_STATE_UNAVAILABLE`, `E_HANDOFF_TAMPERED`, `E_HANDOFF_NOT_FOUND`, `E_HANDOFF_STALE`, `E_HANDOFF_ALREADY_ACCEPTED`, `E_HANDOFF_ACCEPTANCE_INCONSISTENT`
767
799
 
768
800
  #### What it means
769
801
 
770
802
  The immutable handoff envelope is malformed, its state is unavailable, its
771
803
  digest no longer matches, or the requested snapshot does not exist. A handoff
772
804
  note is not delegation, authority, independent review evidence, or completion
773
- evidence.
805
+ evidence. Acceptance is exactly-once operational receipt only. The current
806
+ repository branch and HEAD are checked directly, so clean committed checkout
807
+ drift can make a handoff stale even when changed paths are empty.
774
808
 
775
809
  #### Safe recovery
776
810
 
@@ -781,6 +815,12 @@ forgeloop continuity --task <id> --json
781
815
  forgeloop reconcile-continuity --task <id> --json
782
816
  ```
783
817
 
818
+ If `handoff-list` or `handoff-show` reports `INCONSISTENT`, inspect the
819
+ `reasonCodes` field. The commands validate the event ledger before projecting
820
+ acceptance and never turn an unreadable or invalid ledger into an empty ledger.
821
+ Repair the named ledger through the canonical protocol workflow; do not edit
822
+ `events.ndjson` by hand.
823
+
784
824
  Use the last valid handoff or continuity only to focus inspection, then trust
785
825
  the canonical task state and checkout. Never repair a handoff by editing or
786
826
  deleting its JSON file.
@@ -1002,6 +1042,13 @@ current-cycle validation.
1002
1042
  | `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. |
1003
1043
  | `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. |
1004
1044
  | `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. |
1045
+ | `E_ADVISORY_CONTEXT_OUTPUT_LIMIT` | Advisory context output exceeded the configured character or item limit. | Reduce query scope, limit items, or truncate oversized summaries at the provider. |
1046
+ | `E_ADVISORY_CONTEXT_PROVIDER_INVALID` | Advisory context provider configuration or interface implementation is invalid. | Use a provider implementing id, recall(input) with bounded query parameters; advisory context is optional. |
1047
+ | `E_ADVISORY_CONTEXT_PROVIDER_UNAVAILABLE` | Requested advisory context provider is not registered in runtime context. | Register the provider in runtime context before recall, or proceed without advisory context; provider failure never blocks canonical lifecycle. |
1048
+ | `E_ADVISORY_CONTEXT_QUERY_INVALID` | Advisory context query failed portable-context validation or exceeded budget. | Provide a bounded query free of control characters and secret-like values. |
1049
+ | `E_ADVISORY_CONTEXT_REQUEST_INVALID` | Advisory context recall budgets are not finite integer values within the supported request contract. | Provide finite integer limit, maxItemChars, maxTotalChars, and timeoutMs values; oversized valid values are clamped to documented maxima. |
1050
+ | `E_ADVISORY_CONTEXT_RESULT_INVALID` | Advisory context provider returned an invalid result structure. | Ensure provider returns items with string summary and optional title, sourceRef, observedAt, confidence. |
1051
+ | `E_ADVISORY_CONTEXT_TIMEOUT` | Advisory context recall exceeded its execution timeout. | Use a responsive provider or increase timeout within limits; advisory context is optional. |
1005
1052
  | `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. |
1006
1053
  | `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. |
1007
1054
  | `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. |
@@ -1090,8 +1137,12 @@ current-cycle validation.
1090
1137
  | `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. |
1091
1138
  | `E_GATE_STALE` | Referenced gate artifact changed after approval. | Update artifact SHA-256 in gate file. |
1092
1139
  | `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. |
1140
+ | `E_HANDOFF_ACCEPTANCE_INCONSISTENT` | Handoff acceptance disagrees with task event ledger history. | Verify ledger integrity and require a preceding valid HANDOFF_CREATED event. |
1141
+ | `E_HANDOFF_ACCEPTANCE_UNBOUND` | Handoff snapshot lacks required workStateFingerprint binding. | Create a fresh handoff from the current ForgeLoop version before accepting it. |
1142
+ | `E_HANDOFF_ALREADY_ACCEPTED` | Handoff was already accepted by a different consumer. | Create a new handoff for the new consumer; do not manually edit acceptance events. |
1093
1143
  | `E_HANDOFF_INVALID` | A ForgeLoop boundary, artifact, provider, or attestation validation condition was not satisfied. | Inspect the structured command result, correct the named boundary or artifact, then retry the canonical command. |
1094
1144
  | `E_HANDOFF_NOT_FOUND` | A ForgeLoop boundary, artifact, provider, or attestation validation condition was not satisfied. | Inspect the structured command result, correct the named boundary or artifact, then retry the canonical command. |
1145
+ | `E_HANDOFF_STALE` | Handoff snapshot has drifted from the current canonical task state or repository. | Create a new fresh handoff from the current task state instead of accepting a stale snapshot. |
1095
1146
  | `E_HANDOFF_STATE_UNAVAILABLE` | A ForgeLoop boundary, artifact, provider, or attestation validation condition was not satisfied. | Inspect the structured command result, correct the named boundary or artifact, then retry the canonical command. |
1096
1147
  | `E_HANDOFF_TAMPERED` | A ForgeLoop boundary, artifact, provider, or attestation validation condition was not satisfied. | Inspect the structured command result, correct the named boundary or artifact, then retry the canonical command. |
1097
1148
  | `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. |
@@ -1124,6 +1175,7 @@ current-cycle validation.
1124
1175
  | `E_POLICY_PROOF_STALE` | Mutation verification proof is stale due to checker or fixture modifications. | Re-run forgeloop rule-verify to refresh mutation proof. |
1125
1176
  | `E_POLICY_SNAPSHOT_WRITE_FAILED` | Failed to persist task policy snapshot during preflight. | Ensure the target task directory is writable and repair filesystem permissions. |
1126
1177
  | `E_POLICY_WEAKENING` | Policy rules were weakened during task execution without explicit authority. | Restore the original policy configuration. |
1178
+ | `E_PORTABLE_CONTEXT_INVALID` | Text or object failed portable-context safety, character, or secret limits. | Ensure text is bounded, contains no control characters, and contains no secret-like values. |
1127
1179
  | `E_PREFLIGHT_EVENT_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. |
1128
1180
  | `E_PREFLIGHT_GATES_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. |
1129
1181
  | `E_PREFLIGHT_GATE_EVENT_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. |
@@ -1247,3 +1299,15 @@ current-cycle validation.
1247
1299
  | `E_WORKSPACE_IDENTITY_UNAVAILABLE` | A ForgeLoop boundary, artifact, provider, or attestation validation condition was not satisfied. | Inspect the structured command result, correct the named boundary or artifact, then retry the canonical command. |
1248
1300
 
1249
1301
  <!-- END FORGELOOP GENERATED: public-error-codes -->
1302
+
1303
+ ## Revised contract after a blocked preflight
1304
+
1305
+ Before execution starts, a revised contract and route can leave the old
1306
+ checkpoint stale. Run `forgeloop next --task <id> --json`. When the validated
1307
+ history ends in a blocked preflight and the new route binds the revised
1308
+ contract, it offers `clear-state` followed by `preflight`. Execute those in
1309
+ that order, satisfy any remaining gates, and require `READY` again.
1310
+
1311
+ This recovery guidance is unavailable after execution has started, for an
1312
+ invalid ledger, or when the new route does not match the contract. Preserve
1313
+ those barriers and follow the task's canonical recovery guidance.
@@ -93,6 +93,66 @@ commands in [`EXECUTION_PROFILE_BENCHMARKS.md`](./EXECUTION_PROFILE_BENCHMARKS.m
93
93
  The benchmark source policy accepts provider or host observations only and
94
94
  keeps unavailable or non-comparable measurements out of efficiency claims.
95
95
 
96
+ ### Advisory Context & Handoff Acceptance
97
+
98
+ Capability negotiation is feature-first: `canonicalHandoffs` is v2 and
99
+ `advisoryContextProviders` is v1. These capability-family versions are
100
+ independent of Protocol v1, schema v1, and Integration API v1. The programmatic
101
+ integration API exposes lazy advisory context querying and exactly-once handoff
102
+ acceptance:
103
+
104
+ ```javascript
105
+ import {
106
+ createForgeLoopContext,
107
+ recallAdvisoryContext,
108
+ acceptCanonicalHandoff,
109
+ resolveHandoffAcceptance,
110
+ } from "@cassiomc1/forgeloop/integration";
111
+
112
+ // 1. Register host-provided advisory context
113
+ const runtimeContext = createForgeLoopContext({
114
+ advisoryContextProviders: {
115
+ "host-memory": {
116
+ id: "host-memory",
117
+ recall: async ({ query }) => ({ items: [...] }),
118
+ },
119
+ },
120
+ });
121
+
122
+ // 2. Explicitly query advisory context (strictly non-evidence, non-executable)
123
+ const advisoryResult = await recallAdvisoryContext({
124
+ target: ".",
125
+ taskId: "task-1",
126
+ providerName: "host-memory",
127
+ query: "authentication tokens",
128
+ runtimeContext,
129
+ });
130
+
131
+ // 3. Exactly-once handoff acceptance
132
+ const acceptance = await acceptCanonicalHandoff(".", {
133
+ taskId: "task-1",
134
+ handoffId: "handoff-001",
135
+ consumerId: "agent-session-42",
136
+ harness: "cursor",
137
+ });
138
+ ```
139
+
140
+ See [`ADVISORY_CONTEXT.md`](./ADVISORY_CONTEXT.md) for full trust boundary specifications, portable text sanitization rules, and budget enforcement.
141
+
142
+ Advisory recall budgets are normalized before provider dispatch: valid oversized
143
+ integer requests are clamped, while invalid finite/integer/minimum types fail
144
+ with `E_ADVISORY_CONTEXT_REQUEST_INVALID` before provider lookup. The registry
145
+ key and resolved provider `id` must match. Handoff acceptance independently
146
+ checks canonical state and the current repository branch/HEAD, and remains an
147
+ exactly-once operational receipt with no evidence, claim transfer, or authority.
148
+
149
+ Advisory context is not a canonical resource unless a future explicitly
150
+ versioned resource introduces one. `protocol-info` advertises the optional
151
+ provider capability, but the stock CLI never recalls it automatically and
152
+ there is no stock `context-recall` command. A consumer that only understands
153
+ `canonicalHandoffs` v1 may disable only the handoff-specific UI while retaining
154
+ the rest of Protocol v1 functionality.
155
+
96
156
  ## Consumers
97
157
 
98
158
  | Surface | Entry |
@@ -1,7 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en" data-theme="dark" data-preset="signal-flow" data-present="true">
3
3
  <head>
4
- <meta name="forgeloop-diagram-source-sha256" content="669966fba9e69df0525a3581baa4e90075923dbe3069f81f706761a40abf9073">
4
+ <meta name="forgeloop-diagram-source-sha256" content="33bb9c3c4f3fb4a793febeab34b2d07ca7bf2c058d4f5e7575dba3a6065eedeb">
5
5
  <meta name="forgeloop-diagram-renderer" content="archify@2.15.0 (e1ac748f19cf805e44bf74fb93c796662152e273)">
6
6
  <meta charset="UTF-8">
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
@@ -40,6 +40,15 @@
40
40
  <style>
41
41
  /* Keep boundary labels clear of the first node in each group. */
42
42
  [data-composition-frame-kind="group"] + text { transform: translateY(-18px); }
43
+ @media (max-width: 720px) {
44
+ html:not([data-present="true"]) .toolbar {
45
+ top: 0;
46
+ right: 0;
47
+ width: 100%;
48
+ flex-wrap: wrap;
49
+ justify-content: flex-start;
50
+ }
51
+ }
43
52
 
44
53
  /* ==========================================================
45
54
  THEME VARIABLES — switch by toggling [data-theme] on <html>
@@ -4868,7 +4877,7 @@
4868
4877
  <p class="subtitle">Exact content binding from valid completion to read-only trust results</p>
4869
4878
  </div>
4870
4879
 
4871
- <script id="archify-guided-views-data" type="application/json">[{"id":"completion-to-manifest","label":"Completion to manifest","focus":["complete","receipt","manifest","captured"],"note":"Follow the transactional binding between valid completion evidence and exact source content."},{"id":"manifest-to-statement","label":"Manifest to statement","focus":["manifest","captured","statement","signing","bundle"],"note":"See how the deterministic code manifest becomes an in-toto Statement v1 and optional signature bundle."},{"id":"revision-range-coverage","label":"Revision-range coverage","focus":["base","provider","changed","attestations","union","range"],"note":"Inspect the separate changed-path coverage question and its gap or conflict result."}]</script>
4880
+ <script id="archify-guided-views-data" type="application/json">[{"id":"completion-to-manifest","label":"Completion to manifest","focus":["complete","receipt","manifest","captured"],"note":"Completion and exact-content evidence bind to the project and task. No supplied CI receipt means NOT_VERIFIED."},{"id":"manifest-to-statement","label":"Manifest to statement","focus":["manifest","captured","statement","signing","bundle"],"note":"See how the deterministic code manifest becomes an in-toto Statement v1 and optional signature bundle."},{"id":"revision-range-coverage","label":"Revision-range coverage","focus":["base","provider","changed","attestations","union","range"],"note":"Inspect the separate changed-path coverage question and its gap or conflict result."}]</script>
4872
4881
 
4873
4882
  <div class="guided-views no-print" id="guided-views" hidden aria-label="Guided diagram views">
4874
4883
  <button id="guided-view-prev" type="button" aria-label="Previous guided view" title="Previous guided view ([)">&#8592;</button>
@@ -5426,6 +5435,7 @@
5426
5435
  <li>&bull; PROCESSED means artifacts exist and parse</li>
5427
5436
  <li>&bull; VERIFIED means completion, evidence, manifest, and content bindings validate</li>
5428
5437
  <li>&bull; ATTESTED additionally requires a valid external signature policy</li>
5438
+ <li>&bull; No supplied CI receipt means NOT_VERIFIED, not a trust level</li>
5429
5439
  </ul>
5430
5440
  </div>
5431
5441
 
@@ -5438,6 +5448,7 @@
5438
5448
  <li>&bull; The manifest records one SHA-256 digest per changed source entry</li>
5439
5449
  <li>&bull; The in-toto statement binds the manifest to completion evidence</li>
5440
5450
  <li>&bull; Read-only verification never rewrites task state or ledger events</li>
5451
+ <li>&bull; Compaction preserves transaction manifests and event history</li>
5441
5452
  </ul>
5442
5453
  </div>
5443
5454
 
@@ -15,17 +15,17 @@
15
15
  "license": "MIT"
16
16
  },
17
17
  "input": {
18
- "sha256": "669966fba9e69df0525a3581baa4e90075923dbe3069f81f706761a40abf9073",
19
- "bytes": 7744
18
+ "sha256": "33bb9c3c4f3fb4a793febeab34b2d07ca7bf2c058d4f5e7575dba3a6065eedeb",
19
+ "bytes": 9857
20
20
  },
21
21
  "artifacts": {
22
22
  "html": {
23
- "sha256": "62666342ec4efbc295ed65f4450008ca5a39072d8a11ff7b8b675ab258711286",
24
- "bytes": 652836
23
+ "sha256": "85bb7abf910d3f6dd12037cfcd90c4b67f0aad4dca2b4cb21be1b0112cbdd92e",
24
+ "bytes": 653258
25
25
  },
26
26
  "svg": {
27
- "sha256": "0af63dd51683d07981fc681042c437377a78ae8a7e6a7175c18a1def02e6280a",
28
- "bytes": 216313
27
+ "sha256": "3a768148886ffdfcce75221c11e51ee77a3702510e90917bf6e8ba0581ebdb44",
28
+ "bytes": 216543
29
29
  }
30
30
  },
31
31
  "staticSvg": {
@@ -1,8 +1,17 @@
1
- <svg data-archify-version="2.15.0" data-forgeloop-source-sha256="669966fba9e69df0525a3581baa4e90075923dbe3069f81f706761a40abf9073" data-theme="dark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 1024" role="img" aria-labelledby="archify-diagram-title archify-diagram-description" data-animation="trace" data-preset="signal-flow" data-quality-profile="showcase">
1
+ <svg data-archify-version="2.15.0" data-forgeloop-source-sha256="33bb9c3c4f3fb4a793febeab34b2d07ca7bf2c058d4f5e7575dba3a6065eedeb" data-theme="dark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 1024" role="img" aria-labelledby="archify-diagram-title archify-diagram-description" data-animation="trace" data-preset="signal-flow" data-quality-profile="showcase">
2
2
  <style>
3
3
  .c-bg-rect { fill: var(--bg); }
4
4
  /* Keep boundary labels clear of the first node in each group. */
5
5
  [data-composition-frame-kind="group"] + text { transform: translateY(-18px); }
6
+ @media (max-width: 720px) {
7
+ html:not([data-present="true"]) .toolbar {
8
+ top: 0;
9
+ right: 0;
10
+ width: 100%;
11
+ flex-wrap: wrap;
12
+ justify-content: flex-start;
13
+ }
14
+ }
6
15
 
7
16
  /* ==========================================================
8
17
  THEME VARIABLES — switch by toggling [data-theme] on &lt;html>
@@ -1,7 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en" data-theme="dark" data-preset="signal-flow" data-present="true">
3
3
  <head>
4
- <meta name="forgeloop-diagram-source-sha256" content="a83128a8639db5db497ac552cfdbc318839e6451c718581fbfcd064e3e869981">
4
+ <meta name="forgeloop-diagram-source-sha256" content="0bfd5bbf8d6bbeaec23db543deb1e99844321c77b3c7feb21ee0cc877bbba9a9">
5
5
  <meta name="forgeloop-diagram-renderer" content="archify@2.15.0 (e1ac748f19cf805e44bf74fb93c796662152e273)">
6
6
  <meta charset="UTF-8">
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
@@ -40,6 +40,15 @@
40
40
  <style>
41
41
  /* Keep boundary labels clear of the first node in each group. */
42
42
  [data-composition-frame-kind="group"] + text { transform: translateY(-18px); }
43
+ @media (max-width: 720px) {
44
+ html:not([data-present="true"]) .toolbar {
45
+ top: 0;
46
+ right: 0;
47
+ width: 100%;
48
+ flex-wrap: wrap;
49
+ justify-content: flex-start;
50
+ }
51
+ }
43
52
 
44
53
  /* ==========================================================
45
54
  THEME VARIABLES — switch by toggling [data-theme] on <html>
@@ -4865,10 +4874,10 @@
4865
4874
  <div class="pulse-dot"></div>
4866
4875
  <h1>ForgeLoop Evidence-First Engineering Flow</h1>
4867
4876
  </div>
4868
- <p class="subtitle">Typed intent → scoped work → observed evidence → validator-backed closure</p>
4877
+ <p class="subtitle">Structured intent → project-bound work → observed evidence → valid closure</p>
4869
4878
  </div>
4870
4879
 
4871
- <script id="archify-guided-views-data" type="application/json">[{"id":"contract-to-work","label":"Contract to work","focus":["request","profile","contract","route","gates","preflight","work"],"note":"Follow how a request becomes scoped, routed, and safe to execute."},{"id":"evidence-to-close","label":"Evidence to close","focus":["work","evidence","review","valid"],"note":"See the evidence and review boundary that makes completion trustworthy."},{"id":"recovery-loop","label":"Recovery loop","focus":["evidence","diagnose","correct","preflight","blocked"],"note":"Failures return to diagnosis and correction before another claim is made."}]</script>
4880
+ <script id="archify-guided-views-data" type="application/json">[{"id":"contract-to-work","label":"Contract to work","focus":["request","profile","contract","route","gates","preflight","work"],"note":"Structured obligations and explicit risks set the profile; exclusions do not create required actions."},{"id":"evidence-to-close","label":"Evidence to close","focus":["work","evidence","review","valid"],"note":"See the evidence and review boundary that makes completion trustworthy."},{"id":"recovery-loop","label":"Recovery loop","focus":["evidence","diagnose","correct","preflight","blocked"],"note":"Before execution, blocked refresh needs a valid ledger and revised route. Later failures use diagnosis and correction."}]</script>
4872
4881
 
4873
4882
  <div class="guided-views no-print" id="guided-views" hidden aria-label="Guided diagram views">
4874
4883
  <button id="guided-view-prev" type="button" aria-label="Previous guided view" title="Previous guided view ([)">&#8592;</button>
@@ -4911,9 +4920,9 @@
4911
4920
 
4912
4921
  <!-- Main Diagram -->
4913
4922
  <div class="diagram-container" data-detail-level="read">
4914
- <svg viewBox="0 0 720 900" role="img" aria-labelledby="archify-diagram-title archify-diagram-description" data-animation="trace" data-preset="signal-flow" data-quality-profile="showcase">
4923
+ <svg viewBox="0 0 850 900" role="img" aria-labelledby="archify-diagram-title archify-diagram-description" data-animation="trace" data-preset="signal-flow" data-quality-profile="showcase">
4915
4924
  <title id="archify-diagram-title">ForgeLoop Evidence-First Engineering Flow</title>
4916
- <desc id="archify-diagram-description">Typed intent → scoped work → observed evidence → validator-backed closure</desc>
4925
+ <desc id="archify-diagram-description">Structured intent → project-bound work → observed evidence → valid closure</desc>
4917
4926
  <!-- Definitions -->
4918
4927
  <defs>
4919
4928
  <marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
@@ -5065,19 +5074,19 @@
5065
5074
  <text data-detail="fine" x="500" y="265" class="t-security" font-size="7" text-anchor="middle">Preflight</text>
5066
5075
  </g>
5067
5076
 
5068
- <g id="node-work" data-node-id="work" data-node-label="Execution" tabindex="0" role="button" aria-label="Focus Execution, checkpoint, Resumable Execution › Route + authorize" aria-pressed="false" data-node-kind="backend" data-node-sublabel="checkpoint" data-node-context="Resumable Execution › Route + authorize">
5069
- <title>Execution · checkpoint · Resumable Execution › Route + authorize</title>
5077
+ <g id="node-work" data-node-id="work" data-node-label="Execution" tabindex="0" role="button" aria-label="Focus Execution, root + task, Resumable Execution › Route + authorize" aria-pressed="false" data-node-kind="backend" data-node-sublabel="root + task" data-node-context="Resumable Execution › Route + authorize">
5078
+ <title>Execution · root + task · Resumable Execution › Route + authorize</title>
5070
5079
  <rect x="469" y="341" width="62" height="52" rx="6" class="c-mask"/>
5071
5080
  <rect x="469" y="341" width="62" height="52" rx="6" class="c-backend" data-animate="node" style="--step:6" stroke-width="1.5"/>
5072
5081
  <g aria-hidden="true" data-semantic-sigil="backend" class="semantic-sigil s-backend" transform="translate(475 347) scale(0.6875)">
5073
5082
  <path d="M6 3 3 8l3 5M10 3l3 5-3 5"/>
5074
5083
  </g>
5075
5084
  <text data-detail-anchor x="500" y="362" class="t-primary" font-size="10" font-weight="600" text-anchor="middle">Execution</text>
5076
- <text data-detail="context" x="500" y="379" class="t-muted" font-size="8" text-anchor="middle">checkpoint</text>
5085
+ <text data-detail="context" x="500" y="379" class="t-muted" font-size="8" text-anchor="middle">root + task</text>
5077
5086
  </g>
5078
5087
 
5079
- <g id="node-evidence" data-node-id="evidence" data-node-label="Evidence" tabindex="0" role="button" aria-label="Focus Evidence, scope + checks, Evidence Ledger › Evidence boundary › Route + authorize" aria-pressed="false" data-node-kind="database" data-node-sublabel="scope + checks" data-node-tag="observed" data-node-context="Evidence Ledger › Evidence boundary › Route + authorize">
5080
- <title>Evidence · scope + checks · Evidence Ledger › Evidence boundary › Route + authorize · observed</title>
5088
+ <g id="node-evidence" data-node-id="evidence" data-node-label="Evidence" tabindex="0" role="button" aria-label="Focus Evidence, run-check, Evidence Ledger › Evidence boundary › Route + authorize" aria-pressed="false" data-node-kind="database" data-node-sublabel="run-check" data-node-tag="observed" data-node-context="Evidence Ledger › Evidence boundary › Route + authorize">
5089
+ <title>Evidence · run-check · Evidence Ledger › Evidence boundary › Route + authorize · observed</title>
5081
5090
  <rect x="465" y="457" width="70" height="68" rx="6" class="c-mask"/>
5082
5091
  <rect x="465" y="457" width="70" height="68" rx="6" class="c-database" data-animate="node" style="--step:7" stroke-width="1.5"/>
5083
5092
  <g aria-hidden="true" data-semantic-sigil="database" class="semantic-sigil s-database" transform="translate(471 463) scale(0.6875)">
@@ -5085,7 +5094,7 @@
5085
5094
  <path d="M3 4v8c0 1.1 2.2 2 5 2s5-.9 5-2V4M3 8c0 1.1 2.2 2 5 2s5-.9 5-2"/>
5086
5095
  </g>
5087
5096
  <text data-detail-anchor x="500" y="478" class="t-primary" font-size="11" font-weight="600" text-anchor="middle">Evidence</text>
5088
- <text data-detail="context" x="500" y="495" class="t-muted" font-size="7.3" text-anchor="middle">scope + checks</text>
5097
+ <text data-detail="context" x="500" y="495" class="t-muted" font-size="8" text-anchor="middle">run-check</text>
5089
5098
  <text data-detail="fine" x="500" y="513" class="t-database" font-size="7" text-anchor="middle">observed</text>
5090
5099
  </g>
5091
5100
 
@@ -5383,6 +5392,7 @@
5383
5392
  <li>&bull; Workspace binding is optional but blocks mismatched execution</li>
5384
5393
  <li>&bull; Failures return to diagnosis before another claim</li>
5385
5394
  <li>&bull; Completion is validator-backed, not inferred from a screenshot</li>
5395
+ <li>&bull; Blocked pre-execution refresh requires a valid ledger and revised route</li>
5386
5396
  </ul>
5387
5397
  </div>
5388
5398
 
@@ -5396,6 +5406,7 @@
5396
5406
  <li>&bull; run-check binds exact commands to an execution reference</li>
5397
5407
  <li>&bull; record-check covers manual observations</li>
5398
5408
  <li>&bull; Drift reopens verification instead of being hidden</li>
5409
+ <li>&bull; Matching task IDs never authorize cross-project transaction reuse</li>
5399
5410
  </ul>
5400
5411
  </div>
5401
5412
 
@@ -15,17 +15,17 @@
15
15
  "license": "MIT"
16
16
  },
17
17
  "input": {
18
- "sha256": "a83128a8639db5db497ac552cfdbc318839e6451c718581fbfcd064e3e869981",
19
- "bytes": 7610
18
+ "sha256": "0bfd5bbf8d6bbeaec23db543deb1e99844321c77b3c7feb21ee0cc877bbba9a9",
19
+ "bytes": 9779
20
20
  },
21
21
  "artifacts": {
22
22
  "html": {
23
- "sha256": "55d71098d15a46778454d53690110195e0e923d37f34cb6c57fcc5e6601ab7ec",
24
- "bytes": 647796
23
+ "sha256": "251e09f3cc36d54c4b8567dd3e6dd8a890a2621cdd12667fb80cc61e7dbf4b7c",
24
+ "bytes": 648281
25
25
  },
26
26
  "svg": {
27
- "sha256": "37244a07cc862e3fe4a7188f5236a509a4adf565d5b785ba3c0932057ac6f3a8",
28
- "bytes": 211160
27
+ "sha256": "ef3effe7e756494c7dffef9ee315e970bbbdb9fddc0ee0a1e4bfccfbb0c05534",
28
+ "bytes": 211373
29
29
  }
30
30
  },
31
31
  "staticSvg": {