@cassiomc1/forgeloop 1.9.0 → 1.10.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 (57) hide show
  1. package/AGENT_COMPATIBILITY.md +15 -0
  2. package/DELEGATION_PROTOCOL.md +6 -0
  3. package/DOCS_INDEX.md +4 -2
  4. package/LOOP_ENGINEERING.md +13 -0
  5. package/LOOP_SYSTEM_DESIGN.md +33 -0
  6. package/ORCHESTRATOR_INTEGRATION.md +9 -0
  7. package/PROTOCOL_INTEGRATION.md +31 -0
  8. package/README.md +40 -0
  9. package/TERMINOLOGY.md +12 -0
  10. package/THREAT_MODEL.md +24 -0
  11. package/completions/_forgeloop +2 -1
  12. package/completions/forgeloop.bash +3 -1
  13. package/completions/forgeloop.fish +9 -1
  14. package/docs/ADVISORY_CONTEXT.md +174 -0
  15. package/docs/AGENT_PROTOCOL_SUMMARY.md +28 -2
  16. package/docs/ARTIFACT_REFERENCE.md +14 -0
  17. package/docs/CLI_REFERENCE.md +40 -0
  18. package/docs/CROSS_HARNESS_CONTINUITY.md +85 -0
  19. package/docs/DOCUMENTATION_GUIDE.md +7 -0
  20. package/docs/GETTING_STARTED.md +22 -0
  21. package/docs/KNOWLEDGE_SOURCES.md +10 -0
  22. package/docs/MCP.md +17 -1
  23. package/docs/RECIPES.md +80 -0
  24. package/docs/RELEASE_CHECKLIST.md +14 -0
  25. package/docs/TROUBLESHOOTING.md +54 -2
  26. package/docs/UNIVERSAL_INTEGRATION.md +60 -0
  27. package/package.json +2 -1
  28. package/schemas/handoff-envelope.schema.json +1 -0
  29. package/scripts/check-changelog-freshness.mjs +27 -3
  30. package/scripts/generate-agent-protocol-summary.mjs +18 -0
  31. package/src/cli.js +6 -0
  32. package/src/commands/handoff-accept.js +36 -0
  33. package/src/commands/handoff-list.js +28 -2
  34. package/src/commands/handoff-show.js +27 -2
  35. package/src/commands/reconcile-continuity.js +4 -0
  36. package/src/core/advisory-context/constants.js +74 -0
  37. package/src/core/advisory-context/provider.js +287 -0
  38. package/src/core/advisory-context/service.js +140 -0
  39. package/src/core/cli-command-definitions.js +17 -0
  40. package/src/core/command-executors.js +12 -0
  41. package/src/core/command-input.js +11 -1
  42. package/src/core/continuity-lint.js +89 -0
  43. package/src/core/continuity-reconciliation.js +16 -0
  44. package/src/core/continuity.js +10 -11
  45. package/src/core/error-codes.js +113 -0
  46. package/src/core/events.js +32 -0
  47. package/src/core/execution-profile-context.js +15 -1
  48. package/src/core/filesystem.js +18 -2
  49. package/src/core/handoff-acceptance.js +277 -0
  50. package/src/core/handoff.js +41 -8
  51. package/src/core/integration-invocation-policy.js +19 -2
  52. package/src/core/integration-resources.js +21 -1
  53. package/src/core/portable-context.js +103 -0
  54. package/src/core/protocol-info.js +18 -2
  55. package/src/core/runtime-context.js +31 -0
  56. package/src/integration.d.ts +116 -0
  57. package/src/integration.js +22 -0
@@ -9,3 +9,18 @@ ForgeLoop is vendor-neutral and does not use a supported-agent allowlist.
9
9
  The canonical integration contract is:
10
10
 
11
11
  [`PROTOCOL_INTEGRATION.md`](./PROTOCOL_INTEGRATION.md)
12
+
13
+ ## Current harness expectations
14
+
15
+ These expectations apply to any compatible harness even though this filename is
16
+ retained as a deprecated compatibility stub:
17
+
18
+ - Feature-detect capability versions from `protocol-info --json` or the stable
19
+ Integration API; do not infer support from a package version.
20
+ - Do not auto-recall advisory context, execute advisory text, or treat it as
21
+ state, evidence, authority, completion, or next-action truth.
22
+ - Do not infer handoff acceptance from receiving a file or message. Run
23
+ `handoff-accept` only when the receiving harness actually consumes the
24
+ immutable handoff.
25
+ - Preserve the distinction between `consumerId`, harness labels, and
26
+ authenticated identity; none grants authority or transfers claims.
@@ -70,6 +70,12 @@ Valid statuses are `complete`, `complete-with-concerns`, `needs-context`, and
70
70
  Complete results also require structured observed or inferred verification
71
71
  evidence.
72
72
 
73
+ Canonical handoff acceptance is not delegation acceptance. A handoff envelope
74
+ and its `HANDOFF_ACCEPTED` operational receipt do not create a delegated task,
75
+ approve a brief, transfer claims, or establish reviewer authority. Delegation
76
+ authority remains in this canonical delegation contract and its validated task
77
+ brief/result relationships.
78
+
73
79
  ## Review and integration
74
80
 
75
81
  An independent reviewer receives the approved brief, resulting diff,
package/DOCS_INDEX.md CHANGED
@@ -15,7 +15,7 @@ integration and guide context. Use this map before editing documentation.
15
15
  | Need | Canonical source | Boundary |
16
16
  | --- | --- | --- |
17
17
  | Getting started tutorial | [`docs/GETTING_STARTED.md`](./docs/GETTING_STARTED.md) | First-time walkthrough from init to completion |
18
- | Cross-harness continuity | [`docs/CROSS_HARNESS_CONTINUITY.md`](./docs/CROSS_HARNESS_CONTINUITY.md) | Operational handoff and multi-tool resumption |
18
+ | Cross-harness continuity | [`docs/CROSS_HARNESS_CONTINUITY.md`](./docs/CROSS_HARNESS_CONTINUITY.md) | Operational resume guidance, immutable handoffs, and multi-tool resumption |
19
19
  | Agent bootstrap summary | [`docs/AGENT_PROTOCOL_SUMMARY.md`](./docs/AGENT_PROTOCOL_SUMMARY.md) | Generated concise navigation aid for protocol invariants and commands |
20
20
  | CLI command reference | [`docs/CLI_REFERENCE.md`](./docs/CLI_REFERENCE.md) | Full syntax, options, and JSON examples for all commands |
21
21
  | Artifact and schema reference | [`docs/ARTIFACT_REFERENCE.md`](./docs/ARTIFACT_REFERENCE.md) | Purpose, mutability, and trust classifications of `.forgeloop/` |
@@ -25,11 +25,13 @@ integration and guide context. Use this map before editing documentation.
25
25
  | Structural quality feedback | [`docs/STRUCTURAL_QUALITY.md`](./docs/STRUCTURAL_QUALITY.md) | Provider-neutral baseline, delta policy, Sentrux boundary, lifecycle integration, and troubleshooting |
26
26
  | Diagnostic model | [`docs/DIAGNOSTIC_MODEL.md`](./docs/DIAGNOSTIC_MODEL.md) | Structured diagnostic cases, interventions, hypothesis dispositions, information gain |
27
27
  | Execution trace and observability | [`docs/EXECUTION_TRACE.md`](./docs/EXECUTION_TRACE.md) | `history`, `trace`, `reflect`, and task-level `inspect` read-only projections |
28
- | Workspace, handoff, responsibility, and scope | [`docs/ARTIFACT_REFERENCE.md`](./docs/ARTIFACT_REFERENCE.md) and [`docs/CLI_REFERENCE.md`](./docs/CLI_REFERENCE.md) | Optional task boundaries and deterministic verification planning |
28
+ | Workspace, handoff, responsibility, and scope | [`docs/ARTIFACT_REFERENCE.md`](./docs/ARTIFACT_REFERENCE.md) and [`docs/CLI_REFERENCE.md`](./docs/CLI_REFERENCE.md) | Optional task boundaries, immutable handoffs, and deterministic verification planning |
29
+ | Handoff acceptance | [`docs/CROSS_HARNESS_CONTINUITY.md`](./docs/CROSS_HARNESS_CONTINUITY.md) | Ledger-backed operational receipt; no claim transfer, evidence, or authority |
29
30
  | Code attestation and revision coverage | [`docs/CODE_ATTESTATION.md`](./docs/CODE_ATTESTATION.md) | Source-content manifests, in-toto statements, signatures, and range verification |
30
31
  | Revision and signing providers | [`docs/REVISION_PROVIDERS.md`](./docs/REVISION_PROVIDERS.md) and [`docs/SIGNING_PROVIDERS.md`](./docs/SIGNING_PROVIDERS.md) | Provider-neutral extension contracts |
31
32
  | Platform adapters | [`docs/PLATFORM_ADAPTERS.md`](./docs/PLATFORM_ADAPTERS.md) | Generic CI boundary and platform mapping guidance |
32
33
  | Universal integration API | [`docs/UNIVERSAL_INTEGRATION.md`](./docs/UNIVERSAL_INTEGRATION.md) | Programmatic integration subpath, envelope semantics, and consumer map |
34
+ | Advisory context providers | [`docs/ADVISORY_CONTEXT.md`](./docs/ADVISORY_CONTEXT.md) | Optional external host context, non-evidence trust boundary, allowlist normalization, and safety rules |
33
35
  | Local-first MCP adapter | [`docs/MCP.md`](./docs/MCP.md) | stdio default, optional strict loopback HTTP; server modes/capabilities and canonical resources |
34
36
  | Adaptive execution-profile benchmarks | [`docs/EXECUTION_PROFILE_BENCHMARKS.md`](./docs/EXECUTION_PROFILE_BENCHMARKS.md) | Measured provider/host runs, robust statistics, paired/distribution deltas, tail status, outliers, and profile-aware host context |
35
37
  | Knowledge integration gap analysis | [`docs/KNOWLEDGE_INTEGRATION_GAP_ANALYSIS.md`](./docs/KNOWLEDGE_INTEGRATION_GAP_ANALYSIS.md) | Repository-only research audit of candidate coverage, proven gaps, canonical homes, context cost, and intentional skip/defer decisions |
@@ -1376,6 +1376,15 @@ completion. `CONTINUITY_CANNOT_GRANT_AUTHORITY`: continuity cannot authorize an
1376
1376
  installation or external action. <a id="FL-CONT-001"></a> **FL-CONT-001 — A receiving harness MUST reconcile**
1377
1377
  continuity against the current work state and checkout before acting on it.
1378
1378
 
1379
+ Canonical handoff acceptance is orthogonal to lifecycle phase transitions. The
1380
+ `HANDOFF_ACCEPTED` event is an exactly-once, ledger-backed operational receipt;
1381
+ it does not add a lifecycle phase, transfer claims, create evidence, authorize
1382
+ work, or approve review. A receiving harness runs `handoff-accept` only when it
1383
+ actually consumes the immutable handoff. Advisory context is also outside the
1384
+ canonical lifecycle: providers are lazy and opt-in through the Integration API,
1385
+ and their output cannot determine state, evidence, authority, completion, or
1386
+ the next action.
1387
+
1379
1388
  ## Optional task boundaries and code attestation
1380
1389
 
1381
1390
  ForgeLoop keeps the following extensions optional so existing task artifacts
@@ -1399,6 +1408,10 @@ review evidence, or prove completion. An optional actor note or recipient hint
1399
1408
  is descriptive metadata only. This envelope is distinct from mutable
1400
1409
  `continuity.json`, which is operational resume context and non-evidence.
1401
1410
 
1411
+ `handoff-accept` records the receiver's operational consumption only. It does
1412
+ not make `consumerId`, `harness`, a recipient hint, or a handoff envelope an
1413
+ authenticated identity, delegation approval, or lifecycle authority.
1414
+
1402
1415
  <a id="FL-SCOPE-001"></a> **FL-SCOPE-001 — A verification scope MUST narrow execution only from**
1403
1416
  current canonical changed paths, effective claims, or an explicit full-project
1404
1417
  requirement. The resolver never guesses impacted tests, and a stale scope is
@@ -465,6 +465,39 @@ The README explains the file set, activation behavior, current/relative/absolute
465
465
  target installation, first-run profile flow, local validation commands, and safe
466
466
  update practice.
467
467
 
468
+ ## Advisory and handoff trust boundaries
469
+
470
+ Optional advisory context remains outside canonical lifecycle state and evidence:
471
+
472
+ ```text
473
+ External advisory provider
474
+ |
475
+ v
476
+ bounded recall input
477
+ |
478
+ v
479
+ allowlist normalization
480
+ |
481
+ v
482
+ ADVISORY / NON_EVIDENCE / NON_EXECUTABLE
483
+ ```
484
+
485
+ Handoff acceptance is a separate operational receipt over an immutable snapshot:
486
+
487
+ ```text
488
+ canonical state + current repository
489
+ |
490
+ v
491
+ immutable handoff
492
+ |
493
+ v
494
+ HANDOFF_ACCEPTED ledger receipt
495
+ ```
496
+
497
+ Neither boundary transfers claims or creates evidence or authority. Advisory
498
+ providers are lazy and opt-in through the Integration API; handoff acceptance
499
+ is orthogonal to lifecycle phases and does not authorize the receiving harness.
500
+
468
501
  ## Out of scope
469
502
 
470
503
  - remote prompt services or databases;
@@ -159,6 +159,15 @@ claims, lifecycle transitions, evidence binding, completion, and fail-closed
159
159
  trust decisions. Workspace binding, responsibility, narrow verification,
160
160
  signing, and MCP are not prerequisites for basic protocol compatibility.
161
161
 
162
+ Handoff acceptance is orthogonal to the lifecycle transition graph. An
163
+ orchestrator may call `handoff-accept` only after the receiving harness has
164
+ actually consumed the immutable snapshot. The resulting `HANDOFF_ACCEPTED`
165
+ event is an exactly-once operational receipt; it does not accept delegation,
166
+ transfer claims, create evidence, authenticate `consumerId` or `harness`, or
167
+ grant lifecycle or review authority. Advisory context is likewise optional,
168
+ lazy, and Integration-API-only; it must not be loaded automatically or used as
169
+ an executable instruction source.
170
+
162
171
  Focused visual fallbacks are maintained in the [Verification Trust
163
172
  Flow](./docs/REVISION_PROVIDERS.md#differential-verification-scope) and [Code
164
173
  Attestation Chain](./docs/CODE_ATTESTATION.md#completion-flow).
@@ -181,6 +181,37 @@ authority, provenance, and safety-floor decisions remain unchanged.
181
181
  validator-backed completion remains unchanged.
182
182
  ```
183
183
 
184
+ ## Capability negotiation
185
+
186
+ The public capability handshake exposes additive capability families separately
187
+ from Protocol v1, schema v1, and Integration API v1:
188
+
189
+ | Capability family | Version | Boundary |
190
+ | --- | --- | --- |
191
+ | `canonicalHandoffs` | v2 | Immutable handoff snapshots with ledger-backed exactly-once operational acceptance |
192
+ | `advisoryContextProviders` | v1 | Lazy, opt-in, provider-neutral Integration API injection only |
193
+
194
+ `canonicalHandoffs` v2 advertises `supported: true`, immutable snapshots,
195
+ `lifecycleAuthority: false`, `evidenceAuthority: false`,
196
+ `exactlyOnceAcceptance: true`, `acceptanceLedgerBacked: true`, and the
197
+ `handoff-accept` command with `OPEN`, `ACCEPTED`, `UNBOUND`, and `INCONSISTENT`
198
+ status projections. Acceptance is an operational receipt only: it does not
199
+ transfer claims or create evidence or authority, and it is orthogonal to phase
200
+ transitions.
201
+
202
+ `advisoryContextProviders` v1 is `integrationApiOnly: true`, lazy, and opt-in.
203
+ Its results are never persisted by ForgeLoop and are never canonical state,
204
+ evidence, authority, completion truth, next-action authority, or executable
205
+ instructions. `protocol-info` may advertise the capability, but advisory
206
+ recall remains a programmatic Integration API operation; there is no stock
207
+ `context-recall` CLI command.
208
+
209
+ A consumer that understands `canonicalHandoffs` v1 but not v2 may disable the
210
+ handoff-specific UI while keeping Protocol v1 core functionality available.
211
+ Consumers must feature-detect the capability family and must not mark the
212
+ whole project incompatible merely because an optional capability version is
213
+ newer.
214
+
184
215
  Optional observability is lazy. Reflection, trajectory evaluation, handoff,
185
216
  responsibility, attestation, benchmark analysis, and continuity artifacts are
186
217
  not required merely because the capability exists; policy, user/host request,
package/README.md CHANGED
@@ -31,6 +31,7 @@ relevant guides.
31
31
  - **Inspect a real ForgeLoop execution** → [`poc/README.md`](./poc/README.md)
32
32
  - **Full protocol specification** → [`LOOP_ENGINEERING.md`](./LOOP_ENGINEERING.md)
33
33
  - **Integrating an AI harness** → [`PROTOCOL_INTEGRATION.md`](./PROTOCOL_INTEGRATION.md)
34
+ - **Optional advisory context providers** → [`docs/ADVISORY_CONTEXT.md`](./docs/ADVISORY_CONTEXT.md)
34
35
  - **Agent bootstrap summary** → [`docs/AGENT_PROTOCOL_SUMMARY.md`](./docs/AGENT_PROTOCOL_SUMMARY.md)
35
36
  - **Continuing another harness's task** → [`docs/CROSS_HARNESS_CONTINUITY.md`](./docs/CROSS_HARNESS_CONTINUITY.md)
36
37
  - **CLI command reference** → [`docs/CLI_REFERENCE.md`](./docs/CLI_REFERENCE.md)
@@ -135,6 +136,14 @@ informational or completion-required. Sentrux is an optional user-managed
135
136
  sensor, not a ForgeLoop dependency or a universal software-quality score. See
136
137
  [`docs/STRUCTURAL_QUALITY.md`](./docs/STRUCTURAL_QUALITY.md).
137
138
 
139
+ ### Optional advisory context
140
+
141
+ ForgeLoop can consume host-provided advisory context through the Integration
142
+ API. Providers are lazy and opt-in, and ForgeLoop does not persist their
143
+ results. Provider output is never lifecycle state, evidence, authority,
144
+ completion truth, or next-action authority, and it is never executable as a
145
+ protocol command. See [`docs/ADVISORY_CONTEXT.md`](./docs/ADVISORY_CONTEXT.md).
146
+
138
147
  ### Optional task boundaries and differential verification
139
148
 
140
149
  Workspace binding, immutable handoff envelopes, and responsibility contracts
@@ -231,6 +240,10 @@ authoritative. Hosts without `task/context` use balanced compatibility behavior
231
240
  and must not invent a local LIGHT heuristic. Optional context usage is
232
241
  host-reported or `UNKNOWN`; values are never estimated.
233
242
 
243
+ `protocol-info --json` advertises the optional `advisoryContextProviders` v1
244
+ capability, but advisory recall remains Integration API only. The stock CLI
245
+ does not auto-recall providers and does not expose a `context-recall` command.
246
+
234
247
  Before npm publication, the same source checkout can be exercised without a
235
248
  network or package lookup:
236
249
 
@@ -303,6 +316,33 @@ forgeloop reconcile-continuity --task example-task --json
303
316
  forgeloop next --task example-task --json
304
317
  ```
305
318
 
319
+ For an explicit immutable handoff, use the complete operational flow:
320
+
321
+ ```bash
322
+ forgeloop handoff-create --task example-task --recipient codex --json
323
+ forgeloop handoff-list --task example-task --json
324
+ forgeloop handoff-show --task example-task --id <handoff-id> --json
325
+ forgeloop handoff-accept \
326
+ --task example-task \
327
+ --handoff <handoff-id> \
328
+ --consumer-id codex-session-42 \
329
+ --harness codex \
330
+ --json
331
+ ```
332
+
333
+ Handoff projections use these statuses:
334
+
335
+ ```text
336
+ OPEN valid bound snapshot awaiting operational acceptance
337
+ ACCEPTED exactly-once operational receipt recorded
338
+ UNBOUND legacy handoff without exact work-state binding
339
+ INCONSISTENT ledger, digest, or acceptance history is not trustworthy
340
+ ```
341
+
342
+ Acceptance is `OPERATIONAL_RECEIPT_ONLY`: it transfers no claims and creates
343
+ no evidence or authority. Same-consumer retries are idempotent; a different
344
+ consumer receives a fail-closed `E_HANDOFF_ALREADY_ACCEPTED` result.
345
+
306
346
  See [`docs/CROSS_HARNESS_CONTINUITY.md`](./docs/CROSS_HARNESS_CONTINUITY.md) for full handoff and recovery procedures.
307
347
 
308
348
  ### Multi-task concurrent project state
package/TERMINOLOGY.md CHANGED
@@ -47,6 +47,18 @@
47
47
  | Attestation statement | A deterministic in-toto Statement v1 binding the code manifest to valid ForgeLoop completion evidence. |
48
48
  | Revision-range coverage | A post-completion result asking whether changed paths between two revisions are covered by valid task attestations. |
49
49
  | Generic CI | The provider-neutral range-verification boundary that thin platform adapters may invoke without adding platform trust rules to the core. |
50
+ | Advisory Context | Optional host-provided information returned for human or agent consideration; it is not canonical task state, evidence, authority, completion truth, or next-action authority. |
51
+ | Advisory Context Provider | A runtime-injected Integration API provider with a declared identity and bounded recall method; providers are lazy, opt-in, and not persisted by ForgeLoop. |
52
+ | Portable Context | Bounded text normalized for transport, with control characters, secrets, unsafe paths, and unsupported fields rejected or discarded according to the canonical boundary. |
53
+ | Handoff Acceptance | An exactly-once, ledger-backed operational receipt that records consumption of an immutable handoff without transferring claims or creating evidence or authority. |
54
+ | Consumer ID | A caller-supplied descriptive key used to make handoff acceptance idempotent; it is not an authenticated identity. |
55
+ | Acceptance Status | The derived handoff projection `OPEN`, `ACCEPTED`, `UNBOUND`, or `INCONSISTENT`; it is not a lifecycle phase. |
56
+ | Continuity Lint | Non-authoritative, non-evidence diagnostics for stale or contradictory operational resume hints. |
57
+
58
+ `consumerId` is not an authenticated identity. A `harness`, recipient hint,
59
+ session label, or transport channel is descriptive metadata, not authority.
60
+ The harness owns execution and presentation; ForgeLoop owns canonical state,
61
+ evidence relationships, and validated lifecycle decisions.
50
62
 
51
63
  | Execution continuity | Bounded current-task implementation context used to resume the same ForgeLoop task across sessions or harnesses. |
52
64
  | Continuity artifact | `.forgeloop/continuity.json`; non-evidence operational context bound to canonical work state. |
package/THREAT_MODEL.md CHANGED
@@ -124,6 +124,30 @@ provide a universal exactly-once guarantee.
124
124
  | Signature confusion | A plain digest or platform publication signal is presented as a cryptographic signature | External signing-provider boundary | `ATTESTED` requires a valid external signature under the requested signer policy; private keys and tokens never enter persisted artifacts | Trust in the external signer and transparency infrastructure remains outside ForgeLoop | `tests/signing-provider.test.js` |
125
125
  | Incomplete revision coverage | A changed source path has no valid task attestation or overlaps another task with a conflicting digest | Provider-neutral range coverage evaluator | Changed, covered, uncovered, and overlapping paths are computed from the selected revision provider; enforcement fails closed on gaps or conflicts | Coverage is limited to the provider's observable revision/content boundary | `tests/attestation-coverage.test.js`, `tests/generic-ci-attestation.test.js` |
126
126
 
127
+ ## Advisory context provider boundary
128
+
129
+ Advisory provider output is untrusted external input. ForgeLoop exposes only a
130
+ bounded, allowlisted, non-evidence and non-executable projection through the
131
+ Integration API. Provider identity and availability are explicit; no provider
132
+ is discovered or invoked by lifecycle commands, and provider text is never
133
+ treated as trusted protocol input.
134
+
135
+ | Threat | Mitigation | Residual limitation | Test evidence |
136
+ | --- | --- | --- | --- |
137
+ | Prompt injection in advisory results | Portable text checks, authority-field stripping, and `actionability: NON_EXECUTABLE` prevent provider text from becoming commands or lifecycle instructions | A host may still choose to display or act on advisory text outside ForgeLoop | `tests/advisory-context-security.test.js`, `tests/portable-context.test.js` |
138
+ | Sensitive provider-output leakage | Secret-like values are rejected in selected portable fields; unknown fields are discarded before logging or projection | Unknown encodings and secrets returned only through an external host remain outside this scanner | `tests/advisory-context-security.test.js` |
139
+ | Provider identity substitution | Registry key and resolved provider `id` must match the declared identity | A host that controls the runtime registry can replace its own provider before the call | `tests/advisory-context-runtime.test.js` |
140
+ | Unbounded provider retrieval | Query, item, total-output, raw-result, and timeout budgets are normalized and enforced before/while provider execution | The host controls provider resource usage outside the bounded call | `tests/advisory-context-service.test.js`, `tests/advisory-context-provider.test.js` |
141
+ | Historical command replay from advisory text | Advisory output cannot satisfy command input, evidence, state, or next-action authority; recall is never automatic | A receiving host must still avoid copying untrusted text into its own command runner | `tests/advisory-context-security.test.js` |
142
+ | Handoff acceptance replay | Acceptance is keyed by the immutable handoff and consumer identity and is checked against the append-only ledger | External systems may still deliver duplicate messages; callers must surface the canonical rejection | `tests/handoff-acceptance.test.js` |
143
+ | Handoff double-consumption race | Serialized ledger append and exactly-once acceptance projection permit one consumer; same-consumer retry is idempotent | Filesystem privilege outside ForgeLoop can still corrupt local artifacts | `tests/handoff-acceptance.test.js`, `tests/concurrent-ledger.test.js` |
144
+ | Stale Git checkout acceptance | Acceptance compares the handoff snapshot with the current branch and HEAD, work-state, contract, route, and changed paths | A separately privileged process can change the checkout immediately after validation | `tests/handoff-acceptance.test.js` |
145
+ | Stale contract/route handoff | Handoff creation and acceptance bind contract and route fingerprints and fail closed on drift | The caller must create a fresh handoff after a legitimate contract or route change | `tests/handoff-envelope.test.js`, `tests/handoff-acceptance.test.js` |
146
+ | Invalid ledger projection | Handoff readers validate digest, event relationships, and the complete ledger; invalid history projects `INCONSISTENT`, never `OPEN` or `ACCEPTED` | Local consistency validation is not remote attestation against a privileged rewrite | `tests/handoff-acceptance.test.js`, `tests/handoff-tamper.test.js` |
147
+
148
+ ForgeLoop does not make advisory text trusted. It makes the boundary explicit,
149
+ bounded, and fail-closed where protocol-owned interpretation is required.
150
+
127
151
  ## Structural-quality provider boundary
128
152
 
129
153
  Structural-quality observations are untrusted external data. The built-in
@@ -1,7 +1,7 @@
1
1
  #compdef forgeloop
2
2
  # Generated by scripts/generate-shell-completions.mjs. Do not edit.
3
3
  _arguments \
4
- '1:command:(action-authorize action-propose action-reconcile action-record action-show action-verify activate advance approval-request approval-resolve attestation-create attestation-status attestation-verify attestation-verify-range audit baseline bundle clear-continuity clear-state complete continuity doctor efficiency eval handoff-create handoff-list handoff-show history init inspect metrics migrate-protocol next policy policy-diff policy-discover policy-status preflight prepare-completion profile-interview progress protocol-info quality-baseline quality-status quality-verify reconcile-closure reconcile-continuity record-check record-continuity record-decision-criterion record-diagnosis record-hypothesis-disposition record-intervention record-terminal-result reflect report responsibility-set responsibility-status route rule-verify run-action run-check status task-create task-list task-lock-status task-migrate task-recover task-repair-legacy-recovery task-resume task-scope task-show task-unlock trace update usage-record validate-protocol validate-receipt validate-state verify-scope workspace-bind workspace-status)' \
4
+ '1:command:(action-authorize action-propose action-reconcile action-record action-show action-verify activate advance approval-request approval-resolve attestation-create attestation-status attestation-verify attestation-verify-range audit baseline bundle clear-continuity clear-state complete continuity doctor efficiency eval handoff-accept handoff-create handoff-list handoff-show history init inspect metrics migrate-protocol next policy policy-diff policy-discover policy-status preflight prepare-completion profile-interview progress protocol-info quality-baseline quality-status quality-verify reconcile-closure reconcile-continuity record-check record-continuity record-decision-criterion record-diagnosis record-hypothesis-disposition record-intervention record-terminal-result reflect report responsibility-set responsibility-status route rule-verify run-action run-check status task-create task-list task-lock-status task-migrate task-recover task-repair-legacy-recovery task-resume task-scope task-show task-unlock trace update usage-record validate-protocol validate-receipt validate-state verify-scope workspace-bind workspace-status)' \
5
5
  '*::options:->options'
6
6
  case $words[2] in
7
7
  action-authorize) _arguments '--action[durable action ID]' '--approval[current fingerprint-bound approval]' '--help[show this help]' '--json[emit structured output as JSON]' '--path[target project directory (default: current directory)]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
@@ -28,6 +28,7 @@ case $words[2] in
28
28
  doctor) _arguments '--adopt[preserve an existing adapter in the manifest]' '--fix[restore missing managed template files]' '--help[show this help]' '--json[emit doctor findings as JSON]' '--path[target project directory (default: current directory)]' '--strict[treat warnings as unhealthy]' '--version[show the installed package version]' ;;
29
29
  efficiency) _arguments '--baseline[optional comparable efficiency baseline JSON]' '--help[show this help]' '--json[emit efficiency metrics as JSON]' '--path[target project directory (default: current directory)]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
30
30
  eval) _arguments '--help[show this help]' '--json[emit evaluation as JSON]' '--path[target project directory (default: current directory)]' '--scenario[project-local trajectory scenario JSON]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
31
+ handoff-accept) _arguments '--consumer-id[consumer identifier accepting the handoff]' '--handoff[handoff identifier]' '--harness[optional harness accepting the handoff]' '--help[show this help]' '--json[emit acceptance result as JSON]' '--path[target project directory (default: current directory)]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
31
32
  handoff-create) _arguments '--help[show this help]' '--json[emit handoff as JSON]' '--note[non-authoritative handoff note]' '--path[target project directory (default: current directory)]' '--recipient[non-authoritative recipient hint]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
32
33
  handoff-list) _arguments '--help[show this help]' '--json[emit handoff list as JSON]' '--path[target project directory (default: current directory)]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
33
34
  handoff-show) _arguments '--help[show this help]' '--id[handoff identifier]' '--json[emit handoff as JSON]' '--path[target project directory (default: current directory)]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
@@ -30,6 +30,7 @@ _forgeloop() {
30
30
  doctor) command="doctor" ;;
31
31
  efficiency) command="efficiency" ;;
32
32
  eval) command="eval" ;;
33
+ handoff-accept) command="handoff-accept" ;;
33
34
  handoff-create) command="handoff-create" ;;
34
35
  handoff-list) command="handoff-list" ;;
35
36
  handoff-show) command="handoff-show" ;;
@@ -91,7 +92,7 @@ _forgeloop() {
91
92
  esac
92
93
  done
93
94
  if [[ -z "\${command}" && "\${cur}" != -* ]]; then
94
- COMPREPLY=( $(compgen -W 'action-authorize action-propose action-reconcile action-record action-show action-verify activate advance approval-request approval-resolve attestation-create attestation-status attestation-verify attestation-verify-range audit baseline bundle clear-continuity clear-state complete continuity doctor efficiency eval handoff-create handoff-list handoff-show history init inspect metrics migrate-protocol next policy policy-diff policy-discover policy-status preflight prepare-completion profile-interview progress protocol-info quality-baseline quality-status quality-verify reconcile-closure reconcile-continuity record-check record-continuity record-decision-criterion record-diagnosis record-hypothesis-disposition record-intervention record-terminal-result reflect report responsibility-set responsibility-status route rule-verify run-action run-check status task-create task-list task-lock-status task-migrate task-recover task-repair-legacy-recovery task-resume task-scope task-show task-unlock trace update usage-record validate-protocol validate-receipt validate-state verify-scope workspace-bind workspace-status' -- "$cur") )
95
+ COMPREPLY=( $(compgen -W 'action-authorize action-propose action-reconcile action-record action-show action-verify activate advance approval-request approval-resolve attestation-create attestation-status attestation-verify attestation-verify-range audit baseline bundle clear-continuity clear-state complete continuity doctor efficiency eval handoff-accept handoff-create handoff-list handoff-show history init inspect metrics migrate-protocol next policy policy-diff policy-discover policy-status preflight prepare-completion profile-interview progress protocol-info quality-baseline quality-status quality-verify reconcile-closure reconcile-continuity record-check record-continuity record-decision-criterion record-diagnosis record-hypothesis-disposition record-intervention record-terminal-result reflect report responsibility-set responsibility-status route rule-verify run-action run-check status task-create task-list task-lock-status task-migrate task-recover task-repair-legacy-recovery task-resume task-scope task-show task-unlock trace update usage-record validate-protocol validate-receipt validate-state verify-scope workspace-bind workspace-status' -- "$cur") )
95
96
  return
96
97
  fi
97
98
  case "\${command}" in
@@ -119,6 +120,7 @@ _forgeloop() {
119
120
  doctor) COMPREPLY=( $(compgen -W '--adopt --fix --help --json --path --strict --version' -- "$cur") );;
120
121
  efficiency) COMPREPLY=( $(compgen -W '--baseline --help --json --path --task --version' -- "$cur") );;
121
122
  eval) COMPREPLY=( $(compgen -W '--help --json --path --scenario --task --version' -- "$cur") );;
123
+ handoff-accept) COMPREPLY=( $(compgen -W '--consumer-id --handoff --harness --help --json --path --task --version' -- "$cur") );;
122
124
  handoff-create) COMPREPLY=( $(compgen -W '--help --json --note --path --recipient --task --version' -- "$cur") );;
123
125
  handoff-list) COMPREPLY=( $(compgen -W '--help --json --path --task --version' -- "$cur") );;
124
126
  handoff-show) COMPREPLY=( $(compgen -W '--help --id --json --path --task --version' -- "$cur") );;
@@ -1,5 +1,5 @@
1
1
  # Generated by scripts/generate-shell-completions.mjs. Do not edit.
2
- complete -c forgeloop -f -n '__fish_use_subcommand' -a 'action-authorize action-propose action-reconcile action-record action-show action-verify activate advance approval-request approval-resolve attestation-create attestation-status attestation-verify attestation-verify-range audit baseline bundle clear-continuity clear-state complete continuity doctor efficiency eval handoff-create handoff-list handoff-show history init inspect metrics migrate-protocol next policy policy-diff policy-discover policy-status preflight prepare-completion profile-interview progress protocol-info quality-baseline quality-status quality-verify reconcile-closure reconcile-continuity record-check record-continuity record-decision-criterion record-diagnosis record-hypothesis-disposition record-intervention record-terminal-result reflect report responsibility-set responsibility-status route rule-verify run-action run-check status task-create task-list task-lock-status task-migrate task-recover task-repair-legacy-recovery task-resume task-scope task-show task-unlock trace update usage-record validate-protocol validate-receipt validate-state verify-scope workspace-bind workspace-status'
2
+ complete -c forgeloop -f -n '__fish_use_subcommand' -a 'action-authorize action-propose action-reconcile action-record action-show action-verify activate advance approval-request approval-resolve attestation-create attestation-status attestation-verify attestation-verify-range audit baseline bundle clear-continuity clear-state complete continuity doctor efficiency eval handoff-accept handoff-create handoff-list handoff-show history init inspect metrics migrate-protocol next policy policy-diff policy-discover policy-status preflight prepare-completion profile-interview progress protocol-info quality-baseline quality-status quality-verify reconcile-closure reconcile-continuity record-check record-continuity record-decision-criterion record-diagnosis record-hypothesis-disposition record-intervention record-terminal-result reflect report responsibility-set responsibility-status route rule-verify run-action run-check status task-create task-list task-lock-status task-migrate task-recover task-repair-legacy-recovery task-resume task-scope task-show task-unlock trace update usage-record validate-protocol validate-receipt validate-state verify-scope workspace-bind workspace-status'
3
3
  complete -c forgeloop -f -n '__fish_seen_subcommand_from action-authorize' -l 'action' -d 'durable action ID'
4
4
  complete -c forgeloop -f -n '__fish_seen_subcommand_from action-authorize' -l 'approval' -d 'current fingerprint-bound approval'
5
5
  complete -c forgeloop -f -n '__fish_seen_subcommand_from action-authorize' -l 'help' -d 'show this help'
@@ -173,6 +173,14 @@ complete -c forgeloop -f -n '__fish_seen_subcommand_from eval' -l 'path' -d 'tar
173
173
  complete -c forgeloop -f -n '__fish_seen_subcommand_from eval' -l 'scenario' -d 'project-local trajectory scenario JSON'
174
174
  complete -c forgeloop -f -n '__fish_seen_subcommand_from eval' -l 'task' -d 'task ID to operate on (when omitted, resolved from context or single active task)'
175
175
  complete -c forgeloop -f -n '__fish_seen_subcommand_from eval' -l 'version' -d 'show the installed package version'
176
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from handoff-accept' -l 'consumer-id' -d 'consumer identifier accepting the handoff'
177
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from handoff-accept' -l 'handoff' -d 'handoff identifier'
178
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from handoff-accept' -l 'harness' -d 'optional harness accepting the handoff'
179
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from handoff-accept' -l 'help' -d 'show this help'
180
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from handoff-accept' -l 'json' -d 'emit acceptance result as JSON'
181
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from handoff-accept' -l 'path' -d 'target project directory (default: current directory)'
182
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from handoff-accept' -l 'task' -d 'task ID to operate on (when omitted, resolved from context or single active task)'
183
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from handoff-accept' -l 'version' -d 'show the installed package version'
176
184
  complete -c forgeloop -f -n '__fish_seen_subcommand_from handoff-create' -l 'help' -d 'show this help'
177
185
  complete -c forgeloop -f -n '__fish_seen_subcommand_from handoff-create' -l 'json' -d 'emit handoff as JSON'
178
186
  complete -c forgeloop -f -n '__fish_seen_subcommand_from handoff-create' -l 'note' -d 'non-authoritative handoff note'
@@ -0,0 +1,174 @@
1
+ # Advisory Context & External Provider Boundary
2
+
3
+ ## Overview
4
+
5
+ ForgeLoop treats external advisory context as **optional, host-injected, lazy,
6
+ and strictly advisory**.
7
+
8
+ The core invariant of the protocol is:
9
+
10
+ ```
11
+ MEMORY != STATE
12
+ MEMORY != EVIDENCE
13
+ MEMORY != AUTHORITY
14
+ MEMORY != COMPLETION
15
+ MEMORY != NEXT ACTION
16
+ ```
17
+
18
+ ForgeLoop contains **no built-in vector database, SQLite engine, or full-text search (FTS)** dependencies. Memory systems belong to hosts, IDEs, orchestrators, and harnesses. ForgeLoop provides the hardened runtime contract, trust boundary, portable text sanitization, and allowlist normalization.
19
+
20
+ ## Architectural Boundaries
21
+
22
+ 1. **Non-Authoritative (`ADVISORY`)**: Advisory memory can provide context or suggestions to an agent, but cannot dictate lifecycle state, phase transitions, or next actions.
23
+ 2. **Non-Evidence (`evidenceAuthority: "NONE"`)**: Stored memories or suggestions cannot satisfy verification requirements, pass gates, or serve as execution receipts.
24
+ 3. **Non-Executable (`actionability: "NON_EXECUTABLE"`)**: Output items cannot be executed directly as protocol commands.
25
+ 4. **Ephemeral & Unpersisted (`persisted: false`)**: ForgeLoop never persists external recall results to `.forgeloop/` state or the event ledger.
26
+ 5. **Lazy Provider Evaluation**: ForgeLoop runtime commands (`next`, `status`, `preflight`, `complete`, `task-show`, etc.) never invoke advisory memory providers. Recall occurs only when a host explicitly invokes the integration recall service.
27
+
28
+ ## Registering Providers
29
+
30
+ Hosts configure providers through the runtime context:
31
+
32
+ ```javascript
33
+ import { createForgeLoopContext } from "@cassiomc1/forgeloop/integration";
34
+
35
+ const runtimeContext = createForgeLoopContext({
36
+ advisoryContextProviders: {
37
+ "my-memory": {
38
+ id: "my-memory",
39
+ version: "1.0.0",
40
+ async recall({ projectPath, taskId, query, limit, maxItemChars, maxTotalChars, timeoutMs }) {
41
+ // Query host vector database, knowledge base, or memory cache
42
+ return {
43
+ items: [
44
+ {
45
+ title: "Previous Architecture Decision",
46
+ summary: "Decided to use rotating refresh tokens with 15-minute expiry.",
47
+ sourceRef: "docs/decisions/auth-tokens.md",
48
+ confidence: 0.95,
49
+ },
50
+ ],
51
+ };
52
+ },
53
+ },
54
+ },
55
+ });
56
+ ```
57
+
58
+ Provider IDs must match `^[a-z0-9][a-z0-9_-]*$`. Providers may be plain objects or async factory functions. The registry key and the resolved provider `id` must match exactly; a factory that resolves to another identity fails with `E_ADVISORY_CONTEXT_PROVIDER_INVALID` before `recall` is called.
59
+
60
+ ## Querying Advisory Context
61
+
62
+ Hosts explicitly invoke `recallAdvisoryContext`:
63
+
64
+ ```javascript
65
+ import { recallAdvisoryContext } from "@cassiomc1/forgeloop/integration";
66
+
67
+ const result = await recallAdvisoryContext({
68
+ target: "/path/to/project",
69
+ taskId: "auth-impl-42",
70
+ providerName: "my-memory",
71
+ query: "token refresh strategy",
72
+ limit: 5,
73
+ runtimeContext,
74
+ });
75
+ ```
76
+
77
+ ### Result Schema
78
+
79
+ Every returned result is normalized, frozen, and stamped with immutable trust metadata:
80
+
81
+ ```json
82
+ {
83
+ "provider": {
84
+ "id": "my-memory",
85
+ "version": "1.0.0"
86
+ },
87
+ "taskId": "auth-impl-42",
88
+ "authority": "ADVISORY",
89
+ "evidenceAuthority": "NONE",
90
+ "actionability": "NON_EXECUTABLE",
91
+ "trustRole": "NON_EVIDENCE_ADVISORY_CONTEXT",
92
+ "persisted": false,
93
+ "items": [
94
+ {
95
+ "title": "Previous Architecture Decision",
96
+ "summary": "Decided to use rotating refresh tokens with 15-minute expiry.",
97
+ "sourceRef": "docs/decisions/auth-tokens.md",
98
+ "confidence": 0.95,
99
+ "itemFingerprint": "4a7d...3b1f"
100
+ }
101
+ ]
102
+ }
103
+ ```
104
+
105
+ ## Normalization & Authority Stripping
106
+
107
+ ForgeLoop checks the raw result shape and item count, then selects bounded items and projects only allowlisted fields before portable safety inspection. Unknown raw fields—including secret-like or cyclic metadata—are discarded and are never copied or logged. A secret in a selected field still fails closed.
108
+
109
+ Any raw fields returned by a provider that attempt to assert protocol authority are completely stripped during normalization:
110
+
111
+ - `nextAction`, `command`, `phase`
112
+ - `evidence`, `approval`, `authority`
113
+ - `writeClaims`, `changedPaths`, `checkIds`
114
+
115
+ Only allowlisted fields (`title`, `summary`, `sourceRef`, `observedAt`, `confidence`) survive. Each item receives a deterministic SHA-256 `itemFingerprint`.
116
+
117
+ ## Portable Safety Boundary
118
+
119
+ All text flowing into or out of advisory recall is verified:
120
+
121
+ - **Control Character Rejection**: ASCII control characters (`\x00-\x08`, `\x0B-\x0C`, `\x0E-\x1F`, `\x7F`) throw `E_PORTABLE_CONTEXT_INVALID`.
122
+ - **Secret Scanning**: Inputs and outputs containing secret tokens (e.g., `Bearer <token>`, `ghp_`, AWS keys, private keys) throw `E_PORTABLE_CONTEXT_INVALID`.
123
+ - **Budget Enforcements**:
124
+
125
+ - Max query characters: 1,000 chars (`E_ADVISORY_CONTEXT_QUERY_INVALID`)
126
+ - Max item summary: 4,000 chars (`E_ADVISORY_CONTEXT_OUTPUT_LIMIT`)
127
+ - Default item limit: 6 items (max 20)
128
+ - Default total characters: 6,000 chars (max 16,000) (`E_ADVISORY_CONTEXT_OUTPUT_LIMIT`)
129
+ - Raw provider result ceiling: 100 items (`E_ADVISORY_CONTEXT_OUTPUT_LIMIT`)
130
+ - Default timeout: 5,000 ms, max 30,000 ms (`E_ADVISORY_CONTEXT_TIMEOUT`)
131
+
132
+ ForgeLoop normalizes recall limits before provider dispatch. Valid oversized
133
+ integer requests are clamped to the canonical maxima, and non-finite,
134
+ non-integer, below-minimum, string, boolean, object, or null values fail before
135
+ provider lookup with `E_ADVISORY_CONTEXT_REQUEST_INVALID`. Providers therefore
136
+ never receive caller-requested budgets above ForgeLoop's supported maxima.
137
+
138
+ ## Replay safety and failure handling
139
+
140
+ Advisory recall is an explicit host operation. ForgeLoop does not record a
141
+ provider query, provider response, or item fingerprint in the task event ledger,
142
+ and a later recall is never treated as proof that an earlier response was
143
+ current. Hosts should re-query when context is needed and must independently
144
+ validate any proposed action or lifecycle step against canonical state.
145
+
146
+ Provider failures remain advisory failures and do not block the canonical loop.
147
+ The public boundary reports these stable codes:
148
+
149
+ | Code | Meaning |
150
+ | --- | --- |
151
+ | `E_ADVISORY_CONTEXT_PROVIDER_INVALID` | Provider identity or recall contract is invalid. |
152
+ | `E_ADVISORY_CONTEXT_PROVIDER_UNAVAILABLE` | The requested provider is not registered in the runtime context. |
153
+ | `E_ADVISORY_CONTEXT_QUERY_INVALID` | The query is empty, unsafe, or exceeds the query budget. |
154
+ | `E_ADVISORY_CONTEXT_REQUEST_INVALID` | A recall budget has an invalid type, range, or numeric value. |
155
+ | `E_ADVISORY_CONTEXT_RESULT_INVALID` | The provider returned an invalid result shape. |
156
+ | `E_ADVISORY_CONTEXT_TIMEOUT` | Provider recall exceeded the bounded timeout. |
157
+ | `E_ADVISORY_CONTEXT_OUTPUT_LIMIT` | The raw or normalized provider output exceeded a bounded limit. |
158
+ | `E_PORTABLE_CONTEXT_INVALID` | Portable text contains unsafe controls, secrets, or unsupported content. |
159
+
160
+ ## What ForgeLoop Never Does Automatically
161
+
162
+ - It does not look up a provider on startup.
163
+ - It does not look up a provider for `status`, `next`, `preflight`, `complete`,
164
+ `task-show`, or the read-only `task/context` resource.
165
+ - It does not persist provider results, queries, or provider metadata in
166
+ `.forgeloop/` or the event ledger.
167
+ - It does not turn provider text into a command, lifecycle transition, check,
168
+ evidence record, approval, claim, or next action.
169
+ - It does not infer provider trust from a package version, a source path, or a
170
+ host label. The provider identity contract is resolved at the Integration
171
+ API boundary and remains descriptive rather than authenticated authority.
172
+
173
+ The host owns whether and when to display or use advisory context. ForgeLoop
174
+ owns only the bounded normalization and trust-role projection.
@@ -7,7 +7,7 @@
7
7
  ForgeLoop is a portable protocol and support CLI for verifiable engineering workflows. It records and validates task state, contracts, routing, checks, evidence, continuity, and optional code attestations. It does not become an agent scheduler, delegation service, source-control authority, or secret manager.
8
8
 
9
9
  Protocol version: 1
10
- Package version: 1.9.0
10
+ Package version: 1.10.0
11
11
 
12
12
  ## Canonical loop
13
13
 
@@ -74,7 +74,8 @@ Phases: RECEIVED, DISCOVERING, CONTRACT_READY, ROUTED, DESIGNING, PLANNED, EXECU
74
74
  | Feature | Version | Supported |
75
75
  | --- | --- | --- |
76
76
  | adaptiveExecutionProfiles | 1 | yes |
77
- | canonicalHandoffs | 1 | yes |
77
+ | advisoryContextProviders | 1 | yes |
78
+ | canonicalHandoffs | 2 | yes |
78
79
  | capabilityPolicy | 1 | yes |
79
80
  | codeAttestation | 1 | yes |
80
81
  | compactLifecycleOutput | 1 | yes |
@@ -100,6 +101,21 @@ Phases: RECEIVED, DISCOVERING, CONTRACT_READY, ROUTED, DESIGNING, PLANNED, EXECU
100
101
  | verificationExecutionIsolation | 1 | yes |
101
102
  | workspaceBinding | 1 | yes |
102
103
 
104
+ ## Capability contracts
105
+
106
+ - `canonicalHandoffs` v2: immutable, supported, and
107
+ ledger-backed for exactly-once operational acceptance through
108
+ `handoff-accept`. Acceptance statuses are
109
+ `OPEN` / `ACCEPTED` / `UNBOUND` / `INCONSISTENT`; it creates no claims,
110
+ evidence, or lifecycle authority.
111
+ - `advisoryContextProviders` v1: provider-neutral,
112
+ Integration-API-only, lazy, and opt-in. Provider results are not persisted by
113
+ ForgeLoop and are never lifecycle state, evidence, authority, or executable
114
+ instructions.
115
+
116
+ Protocol v1, schema v1, and Integration API v1 remain independent of these
117
+ capability-family versions.
118
+
103
119
  ## Public artifact registry
104
120
 
105
121
  | Key | Scope | Path | Schema | Trust role |
@@ -248,6 +264,12 @@ Phases: RECEIVED, DISCOVERING, CONTRACT_READY, ROUTED, DESIGNING, PLANNED, EXECU
248
264
  | responsibility-set | MUTATING | Creates immutable, mechanically verifiable constraints for a task pass. |
249
265
  | responsibility-status | READ_ONLY | Validates active responsibility constraints against current paths, inputs, and checks. |
250
266
 
267
+ ### task
268
+
269
+ | Command | Mutation | Purpose |
270
+ | --- | --- | --- |
271
+ | handoff-accept | MUTATING | Accepts an immutable handoff exactly once in the task event ledger. |
272
+
251
273
  ### verification
252
274
 
253
275
  | Command | Mutation | Purpose |
@@ -301,8 +323,12 @@ Phases: RECEIVED, DISCOVERING, CONTRACT_READY, ROUTED, DESIGNING, PLANNED, EXECU
301
323
  | E_ATTESTATION_TARGET_REF_INVALID | A ForgeLoop boundary, artifact, provider, or attestation validation condition was not satisfied. |
302
324
  | E_ATTESTATION_UNSIGNED | A ForgeLoop boundary, artifact, provider, or attestation validation condition was not satisfied. |
303
325
  | E_CLI_INVOCATION_INVALID | A ForgeLoop boundary, artifact, provider, or attestation validation condition was not satisfied. |
326
+ | E_HANDOFF_ACCEPTANCE_INCONSISTENT | Handoff acceptance disagrees with task event ledger history. |
327
+ | E_HANDOFF_ACCEPTANCE_UNBOUND | Handoff snapshot lacks required workStateFingerprint binding. |
328
+ | E_HANDOFF_ALREADY_ACCEPTED | Handoff was already accepted by a different consumer. |
304
329
  | E_HANDOFF_INVALID | A ForgeLoop boundary, artifact, provider, or attestation validation condition was not satisfied. |
305
330
  | E_HANDOFF_NOT_FOUND | A ForgeLoop boundary, artifact, provider, or attestation validation condition was not satisfied. |
331
+ | E_HANDOFF_STALE | Handoff snapshot has drifted from the current canonical task state or repository. |
306
332
  | E_HANDOFF_STATE_UNAVAILABLE | A ForgeLoop boundary, artifact, provider, or attestation validation condition was not satisfied. |
307
333
  | E_HANDOFF_TAMPERED | A ForgeLoop boundary, artifact, provider, or attestation validation condition was not satisfied. |
308
334
  | E_RESPONSIBILITY_FROZEN_INPUT_DRIFT | A ForgeLoop boundary, artifact, provider, or attestation validation condition was not satisfied. |