@cassiomc1/forgeloop 1.13.0 → 1.14.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 (211) hide show
  1. package/AGENT_COMPATIBILITY.md +8 -0
  2. package/DOCS_INDEX.md +35 -3
  3. package/ENG/nodejs-backend-development-eng.md +2 -2
  4. package/ENG/sec-code-eng.md +7 -7
  5. package/EXECUTION_STATE.md +12 -0
  6. package/LOOP_ENGINEERING.md +28 -2
  7. package/ORCHESTRATOR_INTEGRATION.md +9 -5
  8. package/PROTOCOL_INTEGRATION.md +55 -2
  9. package/README.md +40 -25
  10. package/TERMINOLOGY.md +2 -0
  11. package/THREAT_MODEL.md +140 -1
  12. package/completions/_forgeloop +19 -1
  13. package/completions/forgeloop.bash +37 -1
  14. package/completions/forgeloop.fish +123 -1
  15. package/docs/ADVISORY_CONTEXT.md +25 -0
  16. package/docs/AGENT_BROWSER_ADAPTER.md +81 -0
  17. package/docs/AGENT_BROWSER_VERIFICATION.md +6 -0
  18. package/docs/AGENT_PROTOCOL_SUMMARY.md +27 -2
  19. package/docs/AGENT_SKILL.md +66 -0
  20. package/docs/ARTIFACT_REFERENCE.md +123 -0
  21. package/docs/AUDIT_UX.md +46 -0
  22. package/docs/BROWSER_VERIFICATION.md +136 -0
  23. package/docs/CLI_REFERENCE.md +366 -6
  24. package/docs/CODE_ATTESTATION.md +2 -2
  25. package/docs/DOCUMENTATION_GUIDE.md +32 -11
  26. package/docs/JEV_BENCHMARKS.md +31 -0
  27. package/docs/MODEL_ROUTING.md +37 -0
  28. package/docs/OPENSRC_ADAPTER.md +241 -0
  29. package/docs/PACKAGE_CONTENTS.md +35 -8
  30. package/docs/PROVIDERS.md +126 -0
  31. package/docs/PROVIDER_ARCHITECTURE.md +199 -0
  32. package/docs/RECIPES.md +9 -0
  33. package/docs/RELEASE_CHECKLIST.md +38 -5
  34. package/docs/SECURITY_REVIEW.md +71 -0
  35. package/docs/SEMANTIC_DECISION_PLANE.md +71 -0
  36. package/docs/TEST_INTELLIGENCE.md +29 -0
  37. package/docs/TEST_PRUNING.md +14 -0
  38. package/docs/TROUBLESHOOTING.md +198 -1
  39. package/docs/UNIVERSAL_INTEGRATION.md +31 -0
  40. package/docs/assets/diagrams/forgeloop-code-attestation-flow.html +2 -2
  41. package/docs/assets/diagrams/forgeloop-code-attestation-flow.receipt.json +5 -5
  42. package/docs/assets/diagrams/forgeloop-code-attestation-flow.svg +1 -1
  43. package/docs/assets/diagrams/forgeloop-engineering-flow.html +39 -26
  44. package/docs/assets/diagrams/forgeloop-engineering-flow.receipt.json +6 -6
  45. package/docs/assets/diagrams/forgeloop-engineering-flow.svg +26 -26
  46. package/docs/assets/diagrams/forgeloop-verification-trust-flow.html +2 -1
  47. package/docs/assets/diagrams/forgeloop-verification-trust-flow.receipt.json +5 -5
  48. package/docs/assets/diagrams/forgeloop-verification-trust-flow.svg +1 -1
  49. package/docs/diagrams/README.md +13 -9
  50. package/docs/diagrams/forgeloop-code-attestation-flow.workflow.json +1 -1
  51. package/docs/diagrams/forgeloop-engineering-flow.workflow.json +24 -19
  52. package/docs/diagrams/forgeloop-verification-trust-flow.workflow.json +1 -0
  53. package/docs/diagrams/reviews/forgeloop-code-attestation-flow.review.json +4 -4
  54. package/docs/diagrams/reviews/forgeloop-engineering-flow.review.json +4 -4
  55. package/docs/diagrams/reviews/forgeloop-verification-trust-flow.review.json +4 -4
  56. package/docs/documentation-manifest.json +750 -5
  57. package/docs/protocol-requirements.json +24 -0
  58. package/package.json +30 -3
  59. package/schemas/config.schema.json +14 -0
  60. package/schemas/context-plan.schema.json +18 -0
  61. package/schemas/semantic-decision.schema.json +46 -0
  62. package/schemas/test-utility.schema.json +44 -0
  63. package/scripts/CI_VALIDATORS.md +6 -6
  64. package/scripts/benchmark-jev.mjs +5 -0
  65. package/scripts/benchmark-test-intelligence.mjs +4 -0
  66. package/scripts/generate-agent-protocol-summary.mjs +4 -1
  67. package/scripts/generate-forgeloop-skill.mjs +133 -0
  68. package/scripts/jev-smoke.mjs +19 -0
  69. package/skills/forgeloop/README.md +9 -0
  70. package/skills/forgeloop/SKILL.md +77 -0
  71. package/skills/forgeloop/references/lifecycle.md +9 -0
  72. package/skills/forgeloop/references/recovery.md +7 -0
  73. package/skills/forgeloop/references/verification.md +7 -0
  74. package/src/adapters/agent-browser/assertions.js +47 -0
  75. package/src/adapters/agent-browser/commands.js +54 -0
  76. package/src/adapters/agent-browser/index.js +3 -0
  77. package/src/adapters/agent-browser/locator.js +40 -0
  78. package/src/adapters/agent-browser/process.js +215 -0
  79. package/src/adapters/agent-browser/provider.js +313 -0
  80. package/src/adapters/emulated-services/constants.js +24 -0
  81. package/src/adapters/emulated-services/index.js +7 -0
  82. package/src/adapters/emulated-services/process.js +162 -0
  83. package/src/adapters/emulated-services/provider.js +282 -0
  84. package/src/adapters/opensrc/normalize.js +90 -0
  85. package/src/adapters/opensrc/process.js +248 -0
  86. package/src/adapters/opensrc/provider.js +338 -0
  87. package/src/adapters/opensrc/search.js +264 -0
  88. package/src/adapters/typesafe/client.js +28 -0
  89. package/src/adapters/typesafe/engine.js +63 -0
  90. package/src/adapters/typesafe/normalize.js +41 -0
  91. package/src/cli.js +108 -0
  92. package/src/commands/checkpoint-revalidate.js +176 -0
  93. package/src/commands/context-plan.js +38 -0
  94. package/src/commands/contract-create.js +264 -0
  95. package/src/commands/contract-revise.js +236 -0
  96. package/src/commands/decision-show.js +14 -0
  97. package/src/commands/decision-status.js +22 -0
  98. package/src/commands/discover.js +41 -0
  99. package/src/commands/doctor.js +15 -0
  100. package/src/commands/gate-record.js +205 -0
  101. package/src/commands/gate-revalidate.js +137 -0
  102. package/src/commands/model-route.js +32 -0
  103. package/src/commands/route.js +146 -18
  104. package/src/commands/semantic-plan.js +17 -0
  105. package/src/commands/task-abandon.js +224 -0
  106. package/src/commands/task-migrate-contract-bootstrap-repair.js +288 -0
  107. package/src/commands/task-repair-contract-bootstrap.js +263 -0
  108. package/src/commands/test-inventory.js +5 -0
  109. package/src/commands/test-prune-plan.js +5 -0
  110. package/src/commands/test-prune-probe.js +5 -0
  111. package/src/commands/test-utility.js +5 -0
  112. package/src/commands/validate-protocol.js +10 -1
  113. package/src/core/artifact-registry.js +24 -0
  114. package/src/core/audit-ux.js +514 -0
  115. package/src/core/browser-verification/constants.js +149 -0
  116. package/src/core/browser-verification/normalize.js +254 -0
  117. package/src/core/browser-verification/provider.js +519 -0
  118. package/src/core/browser-verification/service.js +115 -0
  119. package/src/core/checkpoint-revalidation.js +319 -0
  120. package/src/core/cli-command-definitions.js +241 -0
  121. package/src/core/command-executors.js +110 -0
  122. package/src/core/command-input.js +115 -43
  123. package/src/core/completion-artifacts.js +14 -5
  124. package/src/core/completion.js +4 -6
  125. package/src/core/config.js +3 -0
  126. package/src/core/context-compiler/budget.js +9 -0
  127. package/src/core/context-compiler/candidates.js +39 -0
  128. package/src/core/context-compiler/compiler.js +63 -0
  129. package/src/core/context-compiler/fingerprint.js +11 -0
  130. package/src/core/context-compiler/policy.js +13 -0
  131. package/src/core/context-compiler/result.js +23 -0
  132. package/src/core/contract-bootstrap-recovery.js +655 -0
  133. package/src/core/contract-revision.js +210 -0
  134. package/src/core/decision/artifact.js +69 -0
  135. package/src/core/decision/benchmarks.js +103 -0
  136. package/src/core/decision/cache.js +27 -0
  137. package/src/core/decision/constants.js +58 -0
  138. package/src/core/decision/cutover.js +34 -0
  139. package/src/core/decision/engine.js +22 -0
  140. package/src/core/decision/errors.js +68 -0
  141. package/src/core/decision/events.js +101 -0
  142. package/src/core/decision/freshness.js +19 -0
  143. package/src/core/decision/normalizers/index.js +115 -0
  144. package/src/core/decision/policy.js +18 -0
  145. package/src/core/decision/projection.js +16 -0
  146. package/src/core/decision/question-registry.js +201 -0
  147. package/src/core/decision/request.js +26 -0
  148. package/src/core/decision/resolver.js +130 -0
  149. package/src/core/decision/result.js +58 -0
  150. package/src/core/decision/service.js +156 -0
  151. package/src/core/decision/state-builder.js +65 -0
  152. package/src/core/decision/task-bindings.js +30 -0
  153. package/src/core/decision/test-provider.js +32 -0
  154. package/src/core/decision/thresholds.js +15 -0
  155. package/src/core/error-codes.js +278 -0
  156. package/src/core/events.js +226 -57
  157. package/src/core/evidence-readiness.js +9 -0
  158. package/src/core/execution-prerequisites.js +14 -0
  159. package/src/core/execution-profile.js +63 -38
  160. package/src/core/gate-provenance.js +124 -0
  161. package/src/core/integration-invocation-policy.js +27 -4
  162. package/src/core/integration-resources.js +86 -61
  163. package/src/core/model-router/constants.js +10 -0
  164. package/src/core/model-router/policy.js +103 -0
  165. package/src/core/model-router/router.js +37 -0
  166. package/src/core/next-action-model.js +58 -0
  167. package/src/core/next-action-phases.js +130 -42
  168. package/src/core/next-action-refresh.js +43 -9
  169. package/src/core/next-action-review-phase.js +7 -2
  170. package/src/core/next-action.js +35 -7
  171. package/src/core/phase.js +128 -10
  172. package/src/core/preflight-consistency.js +23 -9
  173. package/src/core/preflight-loaders.js +37 -5
  174. package/src/core/protocol-info.js +65 -0
  175. package/src/core/protocol.js +20 -0
  176. package/src/core/reconcile-closure.js +128 -52
  177. package/src/core/recovery-history.js +1 -0
  178. package/src/core/resumability.js +154 -44
  179. package/src/core/route-artifact.js +15 -1
  180. package/src/core/router.js +67 -1
  181. package/src/core/runtime-context.js +118 -61
  182. package/src/core/schema-validation.js +3 -0
  183. package/src/core/security-review/constants.js +64 -0
  184. package/src/core/security-review/normalize.js +245 -0
  185. package/src/core/security-review/provider.js +204 -0
  186. package/src/core/security-review/service.js +134 -0
  187. package/src/core/semantic-planning/constants.js +19 -0
  188. package/src/core/semantic-planning/projection.js +94 -0
  189. package/src/core/semantic-planning/service.js +15 -0
  190. package/src/core/sources.js +37 -0
  191. package/src/core/task-claim-state.js +201 -1
  192. package/src/core/task-conflict-inspection.js +31 -5
  193. package/src/core/task-paths.js +13 -0
  194. package/src/core/task-recovery.js +1 -0
  195. package/src/core/templates.js +3 -0
  196. package/src/core/test-intelligence/benchmarks.js +68 -0
  197. package/src/core/test-intelligence/inventory.js +73 -0
  198. package/src/core/test-intelligence/prune.js +90 -0
  199. package/src/core/test-intelligence/semantic-state.js +15 -0
  200. package/src/core/test-intelligence/service.js +40 -0
  201. package/src/core/test-intelligence/utility.js +50 -0
  202. package/src/core/trace.js +11 -7
  203. package/src/core/transaction.js +1 -0
  204. package/src/integration.d.ts +492 -0
  205. package/src/integration.js +54 -0
  206. package/src/providers/README.md +47 -0
  207. package/src/providers/capabilities.js +46 -0
  208. package/src/providers/errors.js +15 -0
  209. package/src/providers/index.js +29 -0
  210. package/src/providers/json-snapshot.js +105 -0
  211. package/src/providers/registry.js +152 -0
package/THREAT_MODEL.md CHANGED
@@ -79,6 +79,7 @@ index location, process lifecycle, and normalized result boundary.
79
79
  | Chronology rewrite | Hides execution before route, gates, or verification | `.forgeloop/events.ndjson` | Append-only local ledger, sequence numbers, hash chaining, and chronology validation without prompts or hidden reasoning | A privileged process can still replace the ledger after validation | `tests/lifecycle.test.js` |
80
80
  | Concurrent protocol mutation | Two writers read the same state or ledger tail and silently overwrite each other | Task state, task event ledger, and transaction journal | Mutations acquire a lease-bearing task lock, stage writes in `.forgeloop/.txn/`, preserve a recovery manifest, and publish only after the callback completes; state mutators use an expected revision, while ledger appends validate a tail checkpoint and stage only a synchronized suffix | The filesystem does not provide a multi-file atomic commit primitive; a process killed during append is recovered by truncating to the journaled pre-append size rather than treated as complete | `tests/state-revision.test.js`, `tests/concurrent-ledger.test.js`, `tests/scale-ledger.test.js`, `tests/transaction.test.js` |
81
81
  | Stale lock theft | A live process loses exclusive ownership because another process removes or replaces its lock | `.forgeloop/locks/<taskKey>.lock` | Locks record hostname, owner instance ID, heartbeat, and lease; inspection distinguishes `NONE`, `LIVE`, `STALE`, `UNKNOWN`, and `CORRUPT`; stale-only release quarantines the observed inode and compares lock ID, heartbeat, and owner instance before deletion | A malicious or separately privileged actor can still delete local locks; an expired lease remains a recovery heuristic rather than remote liveness proof | `tests/task-lock.test.js`, `tests/task-recover.test.js` |
82
+ | Active-task abandonment used to release another task's claims | A caller targets the wrong active task or races a lifecycle mutation to steal/release its write scope | Task identity, descriptor, work state, ledger, recovery artifact, project claims lock, and task transaction | `task-abandon` requires an explicit task ID and acknowledgement, validates canonical ownership and ledger integrity, serializes project/task mutation, revalidates phase/revision/ledger sequence/claims, and records append-only `TASK_ABANDONED` evidence without completion authority | A caller with legitimate local mutation authority can intentionally abandon its own task; that is the intended authority boundary | `tests/task-abandon.test.js`, `tests/task-recovery-concurrency.test.js` |
82
83
  | Forged recovery tombstone | A schema-valid fake `recovery.json` makes historical claims disappear without an official recovery event | Task descriptor, recovery artifact, and complete event ledger | The canonical claim-state resolver releases claims only when every artifact field matches one unresolved recovery history cycle; a tombstone alone is `INCONSISTENT`, retains historical claims, and disables mutation | A privileged actor can replace every linked local artifact; validation proves consistency, not remote attestation | `tests/task-claim-state.test.js`, `tests/task-claim-ownership-integration.test.js`, `tests/task-recovery-invariants.test.js` |
83
84
  | Forged completion claim release | An actor changes `work-state.phase` to `COMPLETE` to make write claims disappear without canonical completion | Work state, canonical completion event, and the complete validated event ledger | Claim ownership releases COMPLETE claims only when state and a validated lifecycle ledger prove canonical completion (`COMPLETION_VALIDATED` bound to the task, coherent state/ledger, no contradicting later lifecycle event); otherwise ownership is `INCONSISTENT` with historical claims retained, mutation disabled, and overlapping acquisition blocked (`E_COMPLETION_OWNERSHIP_UNPROVEN`) | A separately privileged actor can rewrite all local artifacts consistently; ForgeLoop provides consistency verification, not external cryptographic attestation | `tests/completion-claim-ownership.test.js`, `tests/task-claim-state.test.js` |
84
85
  | Incomplete task-lock identity theft | A structurally incomplete persisted task lock (missing lockId, owner instance, operation, or lease) with plausible timestamps is classified LIVE/STALE and removed as stale | `.forgeloop/locks/<taskKey>.lock` identity validation | Task lock identity requires `taskId`, `lockId`, `ownerInstanceId`, `operation`, heartbeat, and a positive integer lease; incomplete metadata classifies `UNKNOWN` (never stale-releasable), lease values are never defaulted at validation time, and CAS release additionally requires `lock.taskId === requested taskId` plus unchanged observed identity | A privileged writer can still forge a fully identified lock; classification proves structure, not liveness | `tests/task-lock.test.js` |
@@ -86,6 +87,7 @@ index location, process lifecycle, and normalized result boundary.
86
87
  | Forged legacy-migration authority | A forged `LEGACY_RECOVERY_MIGRATION_RECORDED` claims `HOST_ATTESTED` authority to impersonate a host grant | Migration event authority validation | Legacy migration v1 accepts only `CALLER_ACKNOWLEDGED`; any other authority kind makes the event invalid and the ledger INCONSISTENT | Normal recovery events retain their own host-attestation boundary with trusted grant references | `tests/task-repair-legacy-recovery.test.js` |
87
88
  | MCP project-root substitution | A tool call supplies a different project root to read or mutate an unintended target | Immutable server-pinned project context | The ForgeLoop MCP server realpaths the project root once at startup and freezes it; project root is never a tool input | A privileged local process can still target other roots by launching its own server | `integrations/mcp/tests/` |
88
89
  | MCP claim-projection fork | An adapter derives claim ownership from raw artifacts (task.json, recovery.json) and disagrees with the canonical resolver | Canonical ownership resource | The `task/ownership` resource is derived exclusively from `resolveTaskClaimState()`; forged COMPLETE stays INCONSISTENT with retained claims through the resource surface | Presentation bugs could still mislabel values; the resolver remains the single authority | `integrations/mcp/tests/ownership.test.js`, `tests/integration-resources.test.js` |
90
+ | Audit UX authority confusion or disclosure | A presentation consumer treats a read model as lifecycle authority or receives raw commands, paths, environment values, credentials, or provider output | Versioned bounded `task/audit-view` resource | The projection is read-only, resolver-backed, sequence-bounded, sanitized, and explicitly marks every authority dimension false | Presentation consumers must still preserve the canonical command/API boundary | `tests/audit-ux.test.js`, `tests/integration-capabilities.test.js` |
89
91
  | MCP capability escalation via tool input | Tool input (e.g. `force: true`, `acknowledgeRecovery: true`) elevates a server started without the matching capability | Launch-level capability gates re-checked per invocation | Risk classification is invocation-level; disabled capabilities refuse with `E_MCP_CAPABILITY_DISABLED`; recovery acknowledgement never upgrades launch policy; legacy repair stays hidden by default; deprecated `operatorAuthorized` is absent from schemas | A separately authorized local actor can restart the server in full mode | `integrations/mcp/tests/policy.test.js`, `integrations/mcp/tests/safety.test.js` |
90
92
  | MCP HTTP unauthenticated remote bind | A network-bound MCP endpoint exposes ForgeLoop operations to any reachable client without authentication | Loopback-only bind policy | The HTTP transport refuses every non-loopback bind with `E_MCP_REMOTE_NOT_SUPPORTED`; Host/Origin validation is defense against DNS rebinding, not authentication; remote access stays disabled until a separately designed authenticated boundary exists | A same-host process can still reach the loopback endpoint | `integrations/mcp/tests/http.test.js` |
91
93
  | MCP protocol downgrade / legacy fallback | Legacy-era traffic is silently served, weakening the declared 2026 security posture | Strict modern mode | The HTTP handler is constructed with the SDK strict-modern setting (`legacy: "reject"`); legacy handshakes are answered with an unsupported-protocol-version rejection instead of being served | Stdio remains available for clients that only speak older protocol generations | `integrations/mcp/tests/http.test.js` |
@@ -160,6 +162,13 @@ treated as trusted protocol input.
160
162
  | 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` |
161
163
  | 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` |
162
164
  | 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` |
165
+ | OpenSrc executable substitution or version drift | Absolute host-selected path with exact lazy `--version` qualification on every recall; no PATH discovery | A host that swaps the binary and version together defeats qualification by definition | `tests/opensrc-advisory-provider.test.js` |
166
+ | Malicious OpenSrc stdout path or cache escape | Exactly-one-line absolute-path rule, realpath canonicalization, cache containment, directory check, and symlink-escape rejection | A host-controlled cache root outside the project is assumed | `tests/opensrc-advisory-provider.test.js` |
167
+ | Prompt injection in fetched source | Inert bounded snippet text under `NON_EXECUTABLE` advisory trust; never executed or converted to authority | A host may still display advisory text outside ForgeLoop | `tests/opensrc-advisory-provider.test.js` |
168
+ | Credential or path leakage in errors and results | No raw stderr, environment, absolute cache path, or credentialed URL in public errors, items, sourceRefs, or transport metadata | Unknown encodings outside scanned fields remain host responsibility | `tests/opensrc-advisory-provider.test.js` |
169
+ | Unbounded source tree or binary ingestion | Sorted traversal, generated directories skipped at any depth, symlink discipline, per-source entry ceiling (5,000, counting skipped entries), per-source read cap, one shared 8 MiB recall read budget, shared recall deadline, and binary skip enforced before further reads | The host controls cache size outside the bounded recall | `tests/opensrc-search.test.js` |
170
+ | OpenSrc network and cache side effects | Explicit host-owned `OPENSRC_HOME`, documented fetch-on-miss, protocol-state side-effect-free recall | Registry access and cache writes are upstream OpenSrc behavior | `docs/OPENSRC_ADAPTER.md` |
171
+ | OpenSrc timeout or output overflow | Shared recall deadline, 64 KiB process ceilings, and SIGTERM/SIGKILL escalation | A hung child holds OS resources until the grace timers fire | `tests/opensrc-process.test.js` |
163
172
  | 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` |
164
173
  | 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` |
165
174
  | 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` |
@@ -169,6 +178,90 @@ treated as trusted protocol input.
169
178
  ForgeLoop does not make advisory text trusted. It makes the boundary explicit,
170
179
  bounded, and fail-closed where protocol-owned interpretation is required.
171
180
 
181
+ ## Provider extension boundary
182
+
183
+ Provider output is untrusted input and the generic provider registry is an
184
+ internal experimental surface. The public `providerExtensions` capability does
185
+ not grant lifecycle, completion, evidence, or installation authority.
186
+
187
+ | Threat | Mitigation |
188
+ | --- | --- |
189
+ | Malicious provider output | Strict JSON snapshot |
190
+ | Mutable result after validation | Detached deep-frozen copy |
191
+ | Getter/accessor execution | Reject accessors |
192
+ | Proxy behavior | Reject proxies |
193
+ | Custom object semantics | Plain JSON boundary |
194
+ | Authority escalation | Reserved authority validation |
195
+ | Error spoofing | Normalize provider exceptions |
196
+ | Hanging factory | Shared deadline |
197
+ | Hanging operation | Shared deadline |
198
+ | Resource leak after timeout | Cooperative abort cleanup |
199
+ | Payload amplification | Byte, depth, and node budgets |
200
+ | Auto-install surprise | No installation authority |
201
+ | Public API confusion | No `./providers` export |
202
+ | False completion | Completion authority false |
203
+ | False evidence | ForgeLoop validation required |
204
+
205
+ ## Security Review provider boundary
206
+
207
+ Security Review is an optional host-injected observation surface. It does not
208
+ install or discover scanners, execute provider text, persist task state, or
209
+ grant lifecycle, evidence, completion, claim, ownership, command, or
210
+ transaction authority. Requests and results are bounded strict snapshots and
211
+ the factory/review pair shares one deadline and cooperative cancellation.
212
+
213
+ | Threat | Mitigation |
214
+ | --- | --- |
215
+ | Malicious finding or fake completion claim | Reserved authority fields are rejected and trust metadata is stamped as observation-only, non-evidence, and non-executable. |
216
+ | Oversized or mutable request/result | Relative-path, string, finding, diagnostic, byte, depth, node, and result-size limits plus detached deep-frozen snapshots fail closed. |
217
+ | Provider hang or late completion | One shared deadline and `AbortSignal` cover lazy factory and review; late results cannot become observations. |
218
+ | Scanner auto-install or ambient execution | Registration is explicit and lazy; ForgeLoop does not discover `PATH`, install tools, invoke shells, or own provider credentials. |
219
+ | Sensitive output or path escape | Findings require bounded project-relative paths and reject secret-like content and absolute/file URLs. |
220
+
221
+ ## Browser verification boundary
222
+
223
+ Browser verification is host-injected and explicit. It is not a browser
224
+ sandbox, lifecycle adapter, or completion bridge.
225
+
226
+ | Threat | Mitigation |
227
+ | --- | --- |
228
+ | Malicious provider or fake PASS/COMPLETE | Provider results cross a strict allowlist and authority-field rejection boundary; ForgeLoop derives status and stamps observation-only trust. |
229
+ | Factory or verify hang | One ForgeLoop-owned deadline covers factory resolution, validation, verify, and normalization; expiry aborts the shared signal and applies bounded cleanup. |
230
+ | Redirect escape or origin confusion | HTTP(S)-only, credential-free `finalUrl` and every reported navigation are checked against exact normalized allowed origins. |
231
+ | Cookie, token, authorization, signed URL, or path leakage | Public provider failures are generic; portable observation fields and artifact refs reject sensitive patterns and absolute/file URLs. |
232
+ | Prompt injection or malicious snapshots | Snapshot and diagnostic text is bounded portable observation only and has no executable or lifecycle semantics. |
233
+ | Screenshot metadata abuse | Artifacts are bounded structured metadata with positive byte length, canonical SHA-256, portable refs, and no raw bytes. |
234
+ | Oversized DOM or output | Bounded steps, assertions, snapshots, diagnostics, artifacts, URLs, and result size limits fail closed. |
235
+ | Arbitrary JavaScript, file/data URLs, upload/download, or credentials | Strict request allowlists reject unsupported fields and non-HTTP(S)/credential-bearing URLs. |
236
+ | Provider session reuse or browser network access | Providers own session cleanup and network behavior; ForgeLoop makes no sandbox claim and does not install or discover browsers. |
237
+
238
+ The optional Agent Browser adapter adds a concrete process boundary without
239
+ changing those claims:
240
+
241
+ | Threat | Mitigation | Residual limitation | Test evidence |
242
+ | --- | --- | --- | --- |
243
+ | Executable substitution or shell injection | Absolute regular executable, `shell:false`, argv arrays, lazy exact-version check, and no PATH discovery | A privileged host can replace its executable between checks | `tests/agent-browser-process.test.js`, `tests/agent-browser-provider.test.js` |
244
+ | Session/profile or ambient credential reuse | Fresh random session, adapter-owned cwd, filtered profile/restore/state/CDP/auto-connect/plugin/auth variables, and close in `finally` | Host-level browser state outside the adapter remains host responsibility | `tests/agent-browser-provider.test.js` |
245
+ | Origin escape or malicious redirect | ForgeLoop exact-origin validation plus Agent Browser hostname allowlist | Host/browser networking is not a general sandbox | `tests/agent-browser-provider.test.js` |
246
+ | Screenshot or process-output leakage | Temporary screenshot bytes, portable digest refs, bounded stdout/stderr, and generic errors | Host process and filesystem policy remain outside ForgeLoop | `tests/agent-browser-process.test.js`, core normalization tests |
247
+ | Incomplete or spoofed command observations | Strict `{success:true,data}` envelopes, typed scalar observations, derived assertion status, and observation-only normalization | A real browser remains an external host capability | `tests/agent-browser-process.test.js`, `tests/agent-browser-provider.test.js` |
248
+ | Temporary workspace overlap | Adapter-owned cwd and rejection of a configured temp root inside the verification target | Symlink and host filesystem policy remain host responsibilities | `tests/agent-browser-provider.test.js` |
249
+
250
+ ## Emulated Services provider boundary
251
+
252
+ The optional Emulated Services adapter is a host-owned observation boundary for
253
+ `vercel-labs/emulate` `0.11.2`. It is explicit and lazy: ForgeLoop neither
254
+ installs nor discovers the executable and never grants the provider lifecycle,
255
+ evidence, installation, or completion authority.
256
+
257
+ | Threat | Mitigation | Residual limitation | Test evidence |
258
+ | --- | --- | --- | --- |
259
+ | Executable substitution or shell injection | Absolute regular executable, exact version qualification, argv-only spawn with `shell:false`, and no PATH discovery | A privileged host can replace its executable between checks | `tests/emulated-services.test.js` |
260
+ | Ambient credential or secret leakage | Minimal environment allowlist, no raw stdout/stderr in public results, and no provider-controlled environment fields | Host process policy remains host responsibility | `tests/emulated-services.test.js` |
261
+ | State overlap or project mutation | Random adapter-owned temporary cwd, target-root separation, and forced recursive cleanup | Host filesystem policy and symlink races remain host responsibilities | `tests/emulated-services.test.js` |
262
+ | Unbounded child, output, or readiness | Bounded timeout, cancellation, stdout/stderr ceilings, readiness polling, SIGTERM/SIGKILL escalation, and fail-closed cleanup | A hostile child may consume resources until the OS releases it | `tests/emulated-services.test.js` |
263
+ | Remote endpoint or authority confusion | Adapter constructs and validates loopback-only HTTP endpoints and returns detached observation-only results | The host controls the local service implementation | `tests/emulated-services.test.js` |
264
+
172
265
  ## Structural-quality provider boundary
173
266
 
174
267
  Structural-quality observations are untrusted external data. The built-in
@@ -193,6 +286,30 @@ context.
193
286
  ForgeLoop never changes Sentrux analytics preferences, installs the provider,
194
287
  or treats Sentrux Free diagnostics as necessary for score correctness.
195
288
 
289
+ ## Semantic decision safety floor
290
+
291
+ Jev (the pinned TypeSafe `jev-1.13.0` model) is a non-authoritative semantic
292
+ plane: it may rank or exclude only deterministically eligible, non-mandatory
293
+ route guides, and it may raise but never lower the execution-profile safety
294
+ floor. Mandatory safety protection is derived from canonical deterministic route
295
+ reasons (`MANDATORY_SAFETY_REASONS` in `src/core/router.js`: auth surface plus
296
+ the untrusted-input, personal-data, secrets, external-service, and publication
297
+ trust-boundary risks), so a high-confidence semantic exclusion can never remove
298
+ the `security` guide the router selected for a trust boundary; retained
299
+ mandatory guides carry an explicit `MANDATORY_SAFETY_GUIDE` reason and
300
+ low-confidence exclusions are retained as `JEV_LOW_CONFIDENCE_RETAINED`.
301
+ Semantic decisions consume only sanitized bounded state, and credential material
302
+ is excluded from state, artifacts, diagnostics, and logs. A semantic decision
303
+ that cannot be obtained fails closed rather than silently weakening routing.
304
+
305
+ | Threat | Mitigation |
306
+ | --- | --- |
307
+ | High-confidence Jev exclusion removes a deterministic mandatory safety guide | Protection derives from the router's own canonical safety reason set; `external-service` and other trust-boundary reasons retain `security` with `MANDATORY_SAFETY_GUIDE` |
308
+ | Semantic plane drifts from deterministic eligibility | Jev operates only on deterministically eligible guides; it never creates eligibility, lowers the profile floor, or bypasses fail-closed cutover |
309
+
310
+ `tests/execution-profile.test.js`, `tests/jev-decision-enforcement.test.js`,
311
+ `tests/decision-cutover.test.js`.
312
+
196
313
  ## Boundary rules
197
314
 
198
315
  - Safe paths are checked before reading or writing; no protocol field is a
@@ -215,4 +332,26 @@ point at misleading files, claim verification/publication occurred, encode
215
332
  secret material, attempt path traversal, or imply authority. Mitigations are a
216
333
  bounded strict schema, secret-free writes, relative safe paths, task/contract/
217
334
  work-state fingerprint binding, current-checkout reconciliation, explicit
218
- non-evidence semantics, and complete separation from authority grants.
335
+ non-evidence semantics, optional absence handling, and complete separation from
336
+ authority grants. A missing continuity artifact is `NOT_APPLICABLE`; a present
337
+ but malformed artifact remains fail-closed and continuity never supplies
338
+ completion evidence.
339
+
340
+ ## Bootstrap Gate And Contract Provenance
341
+
342
+ Built-in contract preset references are limited to the canonical
343
+ `contract-preset:documentation`, `contract-preset:bug`, `contract-preset:feature`,
344
+ and `contract-preset:release` namespace. Unknown values in that namespace are
345
+ rejected, while mixed contracts still require external source-registry entries.
346
+
347
+ The `gate-record` command accepts only route- or policy-required gates before
348
+ execution. ForgeLoop computes referenced artifact hashes and rejects absolute,
349
+ traversal, missing, directory, and symlink-escaping paths. Gate decisions are
350
+ caller-recorded observations and cannot claim host attestation or ForgeLoop
351
+ execution provenance.
352
+
353
+ The same boundary prevents fake caller digests, stale artifact approval,
354
+ post-execution gate rewrites, and task substitution: digests are computed from
355
+ bytes, preflight revalidates them, mutation freezes at execution, and persisted
356
+ gate task IDs are checked against the active contract. Unknown preset names are
357
+ rejected rather than becoming a spoofable built-in source namespace.
@@ -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-accept handoff-create handoff-list handoff-show history index-rebuild index-setup index-start index-status index-stop 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 search 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 checkpoint-revalidate clear-continuity clear-state complete context-plan continuity contract-create contract-revise decision-show decision-status discover doctor efficiency eval gate-record gate-revalidate handoff-accept handoff-create handoff-list handoff-show history index-rebuild index-setup index-start index-status index-stop init inspect metrics migrate-protocol model-route 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 search semantic-plan status task-abandon task-create task-list task-lock-status task-migrate task-migrate-contract-bootstrap-repair task-recover task-repair-contract-bootstrap task-repair-legacy-recovery task-resume task-scope task-show task-unlock test-inventory test-prune-plan test-prune-probe test-utility 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]' ;;
@@ -21,13 +21,22 @@ case $words[2] in
21
21
  audit) _arguments '--help[show this help]' '--json[emit structured output as JSON]' '--path[target project directory (default: current directory)]' '--strict[require strict protocol compliance]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
22
22
  baseline) _arguments '--help[show this help]' '--json[emit structured output as JSON]' '--path[target project directory (default: current directory)]' '--policy-reset-authorized[explicit operator authority to re-record baseline during active tasks]' '--record[record current violations as brownfield baseline]' '--update[ratchet baseline downward by removing resolved violations]' '--version[show the installed package version]' ;;
23
23
  bundle) _arguments '--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]' ;;
24
+ checkpoint-revalidate) _arguments '--help[show this help]' '--json[emit structured revalidation 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]' ;;
24
25
  clear-continuity) _arguments '--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]' ;;
25
26
  clear-state) _arguments '--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]' ;;
26
27
  complete) _arguments '--help[show this help]' '--json[emit structured output as JSON]' '--path[target project directory (default: current directory)]' '--strict[require strict protocol compliance]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
28
+ context-plan) _arguments '--decision[persisted Jev decision artifact ID]' '--help[show this help]' '--json[emit the bounded context plan as JSON]' '--path[target project directory (default: current directory)]' '--profile[bounded context budget profile]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
27
29
  continuity) _arguments '--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]' ;;
30
+ contract-create) _arguments '--contract-file[validated JSON contract relative to the target]' '--help[show this help]' '--json[emit structured contract output as JSON]' '--path[target project directory (default: current directory)]' '--preset[bounded contract preset: documentation, bug, feature, or release]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
31
+ contract-revise) _arguments '--contract-file[validated replacement JSON contract relative to the target]' '--help[show this help]' '--json[emit structured contract revision output as JSON]' '--path[target project directory (default: current directory)]' '--preset[bounded replacement contract preset: documentation, bug, feature, or release]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
32
+ decision-show) _arguments '--decision[decision artifact ID]' '--help[show this help]' '--json[emit the decision artifact 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
+ decision-status) _arguments '--health[perform a bounded live Jev health check when credentials are configured]' '--help[show this help]' '--json[emit decision-plane status as JSON]' '--path[target project directory (default: current directory)]' '--version[show the installed package version]' ;;
34
+ discover) _arguments '--help[show this help]' '--json[emit structured discovery 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
35
  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
36
  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
37
  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]' ;;
38
+ gate-record) _arguments '--artifact[project-relative evidence artifact]' '--assumption[approved local assumption]' '--decision[caller-recorded gate decision]' '--evidence-file[bounded local descriptive evidence JSON]' '--gate[required gate name]' '--help[show this help]' '--json[emit structured gate output as JSON]' '--path[target project directory (default: current directory)]' '--status[satisfied, unverified, or blocked]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--unknown[known unresolved item]' '--version[show the installed package version]' ;;
39
+ gate-revalidate) _arguments '--acknowledge-stale[explicitly acknowledge refresh of stale gate artifacts inside active task claims]' '--gate[satisfied gate to refresh after safe artifact drift]' '--help[show this help]' '--json[emit structured gate revalidation 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]' ;;
31
40
  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]' ;;
32
41
  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]' ;;
33
42
  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]' ;;
@@ -42,6 +51,7 @@ case $words[2] in
42
51
  inspect) _arguments '--contract-file[current JSON contract used for freshness comparison]' '--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]' ;;
43
52
  metrics) _arguments '--help[show this help]' '--json[emit trajectory 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]' ;;
44
53
  migrate-protocol) _arguments '--dry-run[show migration actions without writing or deleting artifacts]' '--help[show this help]' '--json[emit structured migration result as JSON]' '--path[target project directory (default: current directory)]' '--to[target supported protocol version]' '--version[show the installed package version]' ;;
54
+ model-route) _arguments '--ambiguous[declare unresolved ambiguity]' '--architecture-change[declare an architectural change]' '--behavior-change[declare behavior change]' '--decision[persisted Jev decision artifact ID]' '--executable-change[declare executable/configuration change]' '--generation-required[declare that generation is required]' '--help[show this help]' '--json[emit model-route projection as JSON]' '--path[target project directory (default: current directory)]' '--platform[affected platform]' '--risk[task risk]' '--surface[affected surface]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' '--work[declared work type]' ;;
45
55
  next) _arguments '--compact[emit a bounded next-action projection]' '--explain[include bounded read-only blocker and recovery explanation]' '--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]' ;;
46
56
  policy) _arguments '--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]' ;;
47
57
  policy-diff) _arguments '--after[path to after policy JSON]' '--before[path to before policy JSON]' '--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]' ;;
@@ -73,17 +83,25 @@ case $words[2] in
73
83
  run-action) _arguments '--[exact command argv; shell mode is never used]' '--action[stable durable action ID]' '--approval[current fingerprint-bound approval]' '--capability[canonical action capability]' '--effect-class[durable action effect class]' '--help[show this help]' '--idempotency-key[immutable logical action idempotency key]' '--json[emit structured output as JSON]' '--path[target project directory (default: current directory)]' '--required-for-completion[mark the action as required for completion]' '--requirement[bound completion requirement]' '--target[bounded external action target]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--timeout-ms[maximum command duration before termination]' '--version[show the installed package version]' ;;
74
84
  run-check) _arguments '--[exact command argv to classify, execute, and attest]' '--details[additional structured check details]' '--help[show this help]' '--id[stable check identifier]' '--json[emit structured output as JSON]' '--path[target project directory (default: current directory)]' '--requirement[completion requirement covered by the check]' '--scope-ref[current verification-scope.json to bind to execution evidence]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--timeout-ms[maximum command duration before termination]' '--version[show the installed package version]' ;;
75
85
  search) _arguments '--after-context[lines of context after matches]' '--before-context[lines of context before matches]' '--context[lines of context before and after matches]' '--files-with-matches[return matching file paths only]' '--fixed-strings[treat the pattern as a literal string]' '--glob[include files matching a glob]' '--help[show this help]' '--ignore-case[search case-insensitively]' '--json[emit normalized provider-neutral search JSON]' '--max-count[maximum matches per file]' '--path[target project directory (default: current directory)]' '--smart-case[use case-insensitive search only for lowercase patterns]' '--stats[include observed native search statistics]' '--type[include files of a tgrep type]' '--version[show the installed package version]' '--word-regexp[match whole words only]' ;;
86
+ semantic-plan) _arguments '--decision[persisted Jev decision artifact ID]' '--help[show this help]' '--input[bounded failure, diagnosis, or review context]' '--json[emit semantic plan projection as JSON]' '--kind[bounded semantic planning projection]' '--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]' ;;
76
87
  status) _arguments '--contract-file[current JSON contract used for freshness comparison]' '--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]' ;;
88
+ task-abandon) _arguments '--acknowledge-abandonment[explicitly acknowledge abandonment of an active task (required; not completion authority)]' '--help[show this help]' '--json[emit structured abandonment 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]' ;;
77
89
  task-create) _arguments '--claim[scoped file path or directory prefix claimed for mutation]' '--contract-file[path to initial contract file]' '--help[show this help]' '--json[emit structured output as JSON]' '--path[target project directory (default: current directory)]' '--preset[bounded contract preset: documentation, bug, feature, or release]' '--preview[preview the contract without creating lifecycle state]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
78
90
  task-list) _arguments '--active[only return healthy tasks with active ownership and a non-terminal phase]' '--help[show this help]' '--json[emit structured output as JSON]' '--limit[maximum tasks to return]' '--offset[number of sorted tasks to skip]' '--path[target project directory (default: current directory)]' '--phase[only return tasks in this lifecycle phase]' '--version[show the installed package version]' ;;
79
91
  task-lock-status) _arguments '--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]' ;;
80
92
  task-migrate) _arguments '--dry-run[show planned migration actions without moving files]' '--help[show this help]' '--json[emit structured output as JSON]' '--path[target project directory (default: current directory)]' '--version[show the installed package version]' ;;
93
+ task-migrate-contract-bootstrap-repair) _arguments '--acknowledge-migration[fresh explicit caller acknowledgement of the exact legacy marker migration (required)]' '--help[show this help]' '--json[emit structured migration 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]' ;;
81
94
  task-recover) _arguments '--acknowledge-recovery[acknowledge release of claims for a STALE or ABANDONED task (required; not host attestation)]' '--help[show this help]' '--json[emit structured output as JSON]' '--operator-authorized[deprecated alias for --acknowledge-recovery; does not attest operator authority]' '--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]' ;;
95
+ task-repair-contract-bootstrap) _arguments '--acknowledge-repair[explicit caller acknowledgement of the exact append-only repair (required)]' '--help[show this help]' '--json[emit structured repair 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]' ;;
82
96
  task-repair-legacy-recovery) _arguments '--acknowledge-recovery[fresh explicit acknowledgement of the legacy boundary migration (required)]' '--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]' ;;
83
97
  task-resume) _arguments '--claim[write claim to reacquire (defaults to all released claims)]' '--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]' ;;
84
98
  task-scope) _arguments '--claim[scoped file path or directory prefix claimed for mutation]' '--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]' ;;
85
99
  task-show) _arguments '--compact[emit a bounded task-status projection]' '--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]' ;;
86
100
  task-unlock) _arguments '--force[force release of an orphaned task lock]' '--help[show this help]' '--json[emit structured output as JSON]' '--path[target project directory (default: current directory)]' '--stale-only[release only a lock whose lease is expired]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
101
+ test-inventory) _arguments '--help[show this help]' '--json[emit deterministic test inventory as JSON]' '--path[target project directory (default: current directory)]' '--version[show the installed package version]' ;;
102
+ test-prune-plan) _arguments '--help[show this help]' '--json[emit test prune plan 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]' ;;
103
+ test-prune-probe) _arguments '--help[show this help]' '--json[emit test prune probe as JSON]' '--path[target project directory (default: current directory)]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--test[stable test ID to probe in isolation]' '--version[show the installed package version]' ;;
104
+ test-utility) _arguments '--help[show this help]' '--json[emit test utility analysis 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]' ;;
87
105
  trace) _arguments '--help[show this help]' '--json[emit structured trace output as JSON (default rendering is a summary)]' '--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]' ;;
88
106
  update) _arguments '--dry-run[perform deterministic update planning and conflict detection without writing]' '--help[show this help]' '--path[target project directory (default: current directory)]' '--version[show the installed package version]' ;;
89
107
  usage-record) _arguments '--cache-read-tokens[provider-reported cache-read token count]' '--cache-write-tokens[provider-reported cache-write token count]' '--cost-usd[provider-reported cost in USD; never estimated]' '--help[show this help]' '--input-tokens[provider-reported input token count]' '--json[emit usage telemetry as JSON]' '--model[model name reported by the actor]' '--output-tokens[provider-reported output token count]' '--path[target project directory (default: current directory)]' '--provider[provider name reported by the actor]' '--source[usage source; CLI fallback accepts only ACTOR_REPORTED]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--total-tokens[provider-reported total token count; never estimated]' '--version[show the installed package version]' ;;
@@ -23,13 +23,22 @@ _forgeloop() {
23
23
  audit) command="audit" ;;
24
24
  baseline) command="baseline" ;;
25
25
  bundle) command="bundle" ;;
26
+ checkpoint-revalidate) command="checkpoint-revalidate" ;;
26
27
  clear-continuity) command="clear-continuity" ;;
27
28
  clear-state) command="clear-state" ;;
28
29
  complete) command="complete" ;;
30
+ context-plan) command="context-plan" ;;
29
31
  continuity) command="continuity" ;;
32
+ contract-create) command="contract-create" ;;
33
+ contract-revise) command="contract-revise" ;;
34
+ decision-show) command="decision-show" ;;
35
+ decision-status) command="decision-status" ;;
36
+ discover) command="discover" ;;
30
37
  doctor) command="doctor" ;;
31
38
  efficiency) command="efficiency" ;;
32
39
  eval) command="eval" ;;
40
+ gate-record) command="gate-record" ;;
41
+ gate-revalidate) command="gate-revalidate" ;;
33
42
  handoff-accept) command="handoff-accept" ;;
34
43
  handoff-create) command="handoff-create" ;;
35
44
  handoff-list) command="handoff-list" ;;
@@ -44,6 +53,7 @@ _forgeloop() {
44
53
  inspect) command="inspect" ;;
45
54
  metrics) command="metrics" ;;
46
55
  migrate-protocol) command="migrate-protocol" ;;
56
+ model-route) command="model-route" ;;
47
57
  next) command="next" ;;
48
58
  policy) command="policy" ;;
49
59
  policy-diff) command="policy-diff" ;;
@@ -75,17 +85,25 @@ _forgeloop() {
75
85
  run-action) command="run-action" ;;
76
86
  run-check) command="run-check" ;;
77
87
  search) command="search" ;;
88
+ semantic-plan) command="semantic-plan" ;;
78
89
  status) command="status" ;;
90
+ task-abandon) command="task-abandon" ;;
79
91
  task-create) command="task-create" ;;
80
92
  task-list) command="task-list" ;;
81
93
  task-lock-status) command="task-lock-status" ;;
82
94
  task-migrate) command="task-migrate" ;;
95
+ task-migrate-contract-bootstrap-repair) command="task-migrate-contract-bootstrap-repair" ;;
83
96
  task-recover) command="task-recover" ;;
97
+ task-repair-contract-bootstrap) command="task-repair-contract-bootstrap" ;;
84
98
  task-repair-legacy-recovery) command="task-repair-legacy-recovery" ;;
85
99
  task-resume) command="task-resume" ;;
86
100
  task-scope) command="task-scope" ;;
87
101
  task-show) command="task-show" ;;
88
102
  task-unlock) command="task-unlock" ;;
103
+ test-inventory) command="test-inventory" ;;
104
+ test-prune-plan) command="test-prune-plan" ;;
105
+ test-prune-probe) command="test-prune-probe" ;;
106
+ test-utility) command="test-utility" ;;
89
107
  trace) command="trace" ;;
90
108
  update) command="update" ;;
91
109
  usage-record) command="usage-record" ;;
@@ -98,7 +116,7 @@ _forgeloop() {
98
116
  esac
99
117
  done
100
118
  if [[ -z "\${command}" && "\${cur}" != -* ]]; then
101
- 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 index-rebuild index-setup index-start index-status index-stop 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 search 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") )
119
+ 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 checkpoint-revalidate clear-continuity clear-state complete context-plan continuity contract-create contract-revise decision-show decision-status discover doctor efficiency eval gate-record gate-revalidate handoff-accept handoff-create handoff-list handoff-show history index-rebuild index-setup index-start index-status index-stop init inspect metrics migrate-protocol model-route 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 search semantic-plan status task-abandon task-create task-list task-lock-status task-migrate task-migrate-contract-bootstrap-repair task-recover task-repair-contract-bootstrap task-repair-legacy-recovery task-resume task-scope task-show task-unlock test-inventory test-prune-plan test-prune-probe test-utility trace update usage-record validate-protocol validate-receipt validate-state verify-scope workspace-bind workspace-status' -- "$cur") )
102
120
  return
103
121
  fi
104
122
  case "\${command}" in
@@ -119,13 +137,22 @@ _forgeloop() {
119
137
  audit) COMPREPLY=( $(compgen -W '--help --json --path --strict --task --version' -- "$cur") );;
120
138
  baseline) COMPREPLY=( $(compgen -W '--help --json --path --policy-reset-authorized --record --update --version' -- "$cur") );;
121
139
  bundle) COMPREPLY=( $(compgen -W '--help --json --path --task --version' -- "$cur") );;
140
+ checkpoint-revalidate) COMPREPLY=( $(compgen -W '--help --json --path --task --version' -- "$cur") );;
122
141
  clear-continuity) COMPREPLY=( $(compgen -W '--help --json --path --task --version' -- "$cur") );;
123
142
  clear-state) COMPREPLY=( $(compgen -W '--help --json --path --task --version' -- "$cur") );;
124
143
  complete) COMPREPLY=( $(compgen -W '--help --json --path --strict --task --version' -- "$cur") );;
144
+ context-plan) COMPREPLY=( $(compgen -W '--decision --help --json --path --profile --task --version' -- "$cur") );;
125
145
  continuity) COMPREPLY=( $(compgen -W '--help --json --path --task --version' -- "$cur") );;
146
+ contract-create) COMPREPLY=( $(compgen -W '--contract-file --help --json --path --preset --task --version' -- "$cur") );;
147
+ contract-revise) COMPREPLY=( $(compgen -W '--contract-file --help --json --path --preset --task --version' -- "$cur") );;
148
+ decision-show) COMPREPLY=( $(compgen -W '--decision --help --json --path --task --version' -- "$cur") );;
149
+ decision-status) COMPREPLY=( $(compgen -W '--health --help --json --path --version' -- "$cur") );;
150
+ discover) COMPREPLY=( $(compgen -W '--help --json --path --task --version' -- "$cur") );;
126
151
  doctor) COMPREPLY=( $(compgen -W '--adopt --fix --help --json --path --strict --version' -- "$cur") );;
127
152
  efficiency) COMPREPLY=( $(compgen -W '--baseline --help --json --path --task --version' -- "$cur") );;
128
153
  eval) COMPREPLY=( $(compgen -W '--help --json --path --scenario --task --version' -- "$cur") );;
154
+ gate-record) COMPREPLY=( $(compgen -W '--artifact --assumption --decision --evidence-file --gate --help --json --path --status --task --unknown --version' -- "$cur") );;
155
+ gate-revalidate) COMPREPLY=( $(compgen -W '--acknowledge-stale --gate --help --json --path --task --version' -- "$cur") );;
129
156
  handoff-accept) COMPREPLY=( $(compgen -W '--consumer-id --handoff --harness --help --json --path --task --version' -- "$cur") );;
130
157
  handoff-create) COMPREPLY=( $(compgen -W '--help --json --note --path --recipient --task --version' -- "$cur") );;
131
158
  handoff-list) COMPREPLY=( $(compgen -W '--help --json --path --task --version' -- "$cur") );;
@@ -140,6 +167,7 @@ _forgeloop() {
140
167
  inspect) COMPREPLY=( $(compgen -W '--contract-file --help --json --path --task --version' -- "$cur") );;
141
168
  metrics) COMPREPLY=( $(compgen -W '--help --json --path --task --version' -- "$cur") );;
142
169
  migrate-protocol) COMPREPLY=( $(compgen -W '--dry-run --help --json --path --to --version' -- "$cur") );;
170
+ model-route) COMPREPLY=( $(compgen -W '--ambiguous --architecture-change --behavior-change --decision --executable-change --generation-required --help --json --path --platform --risk --surface --task --version --work' -- "$cur") );;
143
171
  next) COMPREPLY=( $(compgen -W '--compact --explain --help --json --path --task --version' -- "$cur") );;
144
172
  policy) COMPREPLY=( $(compgen -W '--help --json --path --task --version' -- "$cur") );;
145
173
  policy-diff) COMPREPLY=( $(compgen -W '--after --before --help --json --path --task --version' -- "$cur") );;
@@ -171,17 +199,25 @@ _forgeloop() {
171
199
  run-action) COMPREPLY=( $(compgen -W '-- --action --approval --capability --effect-class --help --idempotency-key --json --path --required-for-completion --requirement --target --task --timeout-ms --version' -- "$cur") );;
172
200
  run-check) COMPREPLY=( $(compgen -W '-- --details --help --id --json --path --requirement --scope-ref --task --timeout-ms --version' -- "$cur") );;
173
201
  search) COMPREPLY=( $(compgen -W '--after-context --before-context --context --files-with-matches --fixed-strings --glob --help --ignore-case --json --max-count --path --smart-case --stats --type --version --word-regexp' -- "$cur") );;
202
+ semantic-plan) COMPREPLY=( $(compgen -W '--decision --help --input --json --kind --path --task --version' -- "$cur") );;
174
203
  status) COMPREPLY=( $(compgen -W '--contract-file --help --json --path --task --version' -- "$cur") );;
204
+ task-abandon) COMPREPLY=( $(compgen -W '--acknowledge-abandonment --help --json --path --task --version' -- "$cur") );;
175
205
  task-create) COMPREPLY=( $(compgen -W '--claim --contract-file --help --json --path --preset --preview --task --version' -- "$cur") );;
176
206
  task-list) COMPREPLY=( $(compgen -W '--active --help --json --limit --offset --path --phase --version' -- "$cur") );;
177
207
  task-lock-status) COMPREPLY=( $(compgen -W '--help --json --path --task --version' -- "$cur") );;
178
208
  task-migrate) COMPREPLY=( $(compgen -W '--dry-run --help --json --path --version' -- "$cur") );;
209
+ task-migrate-contract-bootstrap-repair) COMPREPLY=( $(compgen -W '--acknowledge-migration --help --json --path --task --version' -- "$cur") );;
179
210
  task-recover) COMPREPLY=( $(compgen -W '--acknowledge-recovery --help --json --operator-authorized --path --task --version' -- "$cur") );;
211
+ task-repair-contract-bootstrap) COMPREPLY=( $(compgen -W '--acknowledge-repair --help --json --path --task --version' -- "$cur") );;
180
212
  task-repair-legacy-recovery) COMPREPLY=( $(compgen -W '--acknowledge-recovery --help --json --path --task --version' -- "$cur") );;
181
213
  task-resume) COMPREPLY=( $(compgen -W '--claim --help --json --path --task --version' -- "$cur") );;
182
214
  task-scope) COMPREPLY=( $(compgen -W '--claim --help --json --path --task --version' -- "$cur") );;
183
215
  task-show) COMPREPLY=( $(compgen -W '--compact --help --json --path --task --version' -- "$cur") );;
184
216
  task-unlock) COMPREPLY=( $(compgen -W '--force --help --json --path --stale-only --task --version' -- "$cur") );;
217
+ test-inventory) COMPREPLY=( $(compgen -W '--help --json --path --version' -- "$cur") );;
218
+ test-prune-plan) COMPREPLY=( $(compgen -W '--help --json --path --task --version' -- "$cur") );;
219
+ test-prune-probe) COMPREPLY=( $(compgen -W '--help --json --path --task --test --version' -- "$cur") );;
220
+ test-utility) COMPREPLY=( $(compgen -W '--help --json --path --task --version' -- "$cur") );;
185
221
  trace) COMPREPLY=( $(compgen -W '--help --json --path --task --version' -- "$cur") );;
186
222
  update) COMPREPLY=( $(compgen -W '--dry-run --help --path --version' -- "$cur") );;
187
223
  usage-record) COMPREPLY=( $(compgen -W '--cache-read-tokens --cache-write-tokens --cost-usd --help --input-tokens --json --model --output-tokens --path --provider --source --task --total-tokens --version' -- "$cur") );;