@cassiomc1/forgeloop 1.13.0 → 2.0.0-rc.2

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 (395) hide show
  1. package/AGENT_COMPATIBILITY.md +8 -0
  2. package/CONTRIBUTING.md +11 -7
  3. package/DOCS_INDEX.md +37 -4
  4. package/ENG/c-development-eng.md +2 -2
  5. package/ENG/cpp-development-eng.md +2 -2
  6. package/ENG/dotnet-aspnetcore-development-eng.md +7 -1
  7. package/ENG/flutter-development-eng.md +4 -2
  8. package/ENG/go-development-eng.md +2 -2
  9. package/ENG/java-development-eng.md +3 -3
  10. package/ENG/nodejs-backend-development-eng.md +10 -6
  11. package/ENG/php-development-eng.md +3 -3
  12. package/ENG/python-development-eng.md +205 -0
  13. package/ENG/rust-development-eng.md +42 -1
  14. package/ENG/sec-code-eng.md +7 -7
  15. package/ENG/sql-development-eng.md +4 -4
  16. package/ENG/swift-development-eng.md +5 -4
  17. package/ENG/test-code-eng.md +1 -1
  18. package/ENG/typescript-development-eng.md +4 -4
  19. package/EXECUTION_STATE.md +12 -0
  20. package/GUIDE_ROUTER.md +6 -0
  21. package/LICENSE +133 -21
  22. package/LOOP_ENGINEERING.md +28 -2
  23. package/LOOP_SYSTEM_DESIGN.md +10 -10
  24. package/ORCHESTRATOR_INTEGRATION.md +9 -5
  25. package/PROTOCOL_INTEGRATION.md +55 -2
  26. package/README.md +63 -59
  27. package/TERMINOLOGY.md +2 -0
  28. package/THIRD_PARTY_NOTICES.md +3 -4
  29. package/THREAT_MODEL.md +140 -1
  30. package/completions/_forgeloop +29 -3
  31. package/completions/forgeloop.bash +55 -3
  32. package/completions/forgeloop.fish +183 -1
  33. package/docs/ADVISORY_CONTEXT.md +25 -0
  34. package/docs/AGENT_BROWSER_ADAPTER.md +81 -0
  35. package/docs/AGENT_BROWSER_VERIFICATION.md +6 -0
  36. package/docs/AGENT_PROTOCOL_SUMMARY.md +74 -39
  37. package/docs/AGENT_SKILL.md +66 -0
  38. package/docs/ARTIFACT_REFERENCE.md +171 -35
  39. package/docs/AUDIT_UX.md +46 -0
  40. package/docs/BROWSER_VERIFICATION.md +136 -0
  41. package/docs/CLI_REFERENCE.md +512 -8
  42. package/docs/CODE_ATTESTATION.md +2 -2
  43. package/docs/DOCUMENTATION_GUIDE.md +34 -11
  44. package/docs/GETTING_STARTED.md +3 -3
  45. package/docs/JEV_BENCHMARKS.md +31 -0
  46. package/docs/MODEL_ROUTING.md +37 -0
  47. package/docs/OPENSRC_ADAPTER.md +241 -0
  48. package/docs/PACKAGE_CONTENTS.md +46 -18
  49. package/docs/PROVIDERS.md +126 -0
  50. package/docs/PROVIDER_ARCHITECTURE.md +199 -0
  51. package/docs/RECIPES.md +9 -0
  52. package/docs/RELEASE_CHECKLIST.md +116 -12
  53. package/docs/SECURITY_REVIEW.md +71 -0
  54. package/docs/SELF_HOSTED_TESTS.md +121 -0
  55. package/docs/SEMANTIC_DECISION_PLANE.md +71 -0
  56. package/docs/TEST_INTELLIGENCE.md +29 -0
  57. package/docs/TEST_PRUNING.md +14 -0
  58. package/docs/TROUBLESHOOTING.md +198 -1
  59. package/docs/UNIVERSAL_INTEGRATION.md +31 -0
  60. package/docs/assets/diagrams/forgeloop-code-attestation-flow.html +2 -2
  61. package/docs/assets/diagrams/forgeloop-code-attestation-flow.receipt.json +5 -5
  62. package/docs/assets/diagrams/forgeloop-code-attestation-flow.svg +1 -1
  63. package/docs/assets/diagrams/forgeloop-engineering-flow.html +39 -26
  64. package/docs/assets/diagrams/forgeloop-engineering-flow.receipt.json +6 -6
  65. package/docs/assets/diagrams/forgeloop-engineering-flow.svg +26 -26
  66. package/docs/assets/diagrams/forgeloop-verification-trust-flow.html +2 -1
  67. package/docs/assets/diagrams/forgeloop-verification-trust-flow.receipt.json +5 -5
  68. package/docs/assets/diagrams/forgeloop-verification-trust-flow.svg +1 -1
  69. package/docs/diagrams/README.md +13 -9
  70. package/docs/diagrams/forgeloop-code-attestation-flow.workflow.json +1 -1
  71. package/docs/diagrams/forgeloop-engineering-flow.workflow.json +24 -19
  72. package/docs/diagrams/forgeloop-verification-trust-flow.workflow.json +1 -0
  73. package/docs/diagrams/reviews/forgeloop-code-attestation-flow.review.json +4 -4
  74. package/docs/diagrams/reviews/forgeloop-engineering-flow.review.json +4 -4
  75. package/docs/diagrams/reviews/forgeloop-verification-trust-flow.review.json +4 -4
  76. package/docs/documentation-manifest.json +774 -16
  77. package/docs/protocol-requirements.json +24 -0
  78. package/package.json +43 -11
  79. package/schemas/config.schema.json +14 -0
  80. package/schemas/context-plan.schema.json +18 -0
  81. package/schemas/semantic-decision.schema.json +46 -0
  82. package/schemas/task-bundle.schema.json +7 -2
  83. package/schemas/test-utility.schema.json +44 -0
  84. package/scripts/CI_VALIDATORS.md +6 -6
  85. package/scripts/benchmark-jev.mjs +5 -0
  86. package/scripts/benchmark-test-intelligence.mjs +4 -0
  87. package/scripts/generate-agent-protocol-summary.mjs +6 -3
  88. package/scripts/generate-forgeloop-skill.mjs +133 -0
  89. package/scripts/jev-smoke.mjs +19 -0
  90. package/scripts/run-mcp-clean-tests.mjs +30 -0
  91. package/skills/forgeloop/README.md +9 -0
  92. package/skills/forgeloop/SKILL.md +77 -0
  93. package/skills/forgeloop/references/lifecycle.md +9 -0
  94. package/skills/forgeloop/references/recovery.md +7 -0
  95. package/skills/forgeloop/references/verification.md +7 -0
  96. package/src/adapters/agent-browser/assertions.js +47 -0
  97. package/src/adapters/agent-browser/commands.js +54 -0
  98. package/src/adapters/agent-browser/index.js +3 -0
  99. package/src/adapters/agent-browser/locator.js +40 -0
  100. package/src/adapters/agent-browser/process.js +215 -0
  101. package/src/adapters/agent-browser/provider.js +316 -0
  102. package/src/adapters/emulated-services/constants.js +24 -0
  103. package/src/adapters/emulated-services/index.js +7 -0
  104. package/src/adapters/emulated-services/process.js +162 -0
  105. package/src/adapters/emulated-services/provider.js +289 -0
  106. package/src/adapters/opensrc/normalize.js +90 -0
  107. package/src/adapters/opensrc/process.js +248 -0
  108. package/src/adapters/opensrc/provider.js +338 -0
  109. package/src/adapters/opensrc/search.js +264 -0
  110. package/src/adapters/temporary-paths.js +18 -0
  111. package/src/adapters/typesafe/client.js +28 -0
  112. package/src/adapters/typesafe/engine.js +63 -0
  113. package/src/adapters/typesafe/normalize.js +41 -0
  114. package/src/cli.js +218 -174
  115. package/src/commands/action-show.js +5 -2
  116. package/src/commands/advance.js +5 -1
  117. package/src/commands/baseline.js +13 -11
  118. package/src/commands/checkpoint-revalidate.js +192 -0
  119. package/src/commands/complete.js +19 -3
  120. package/src/commands/context-plan.js +38 -0
  121. package/src/commands/contract-create.js +266 -0
  122. package/src/commands/contract-revise.js +236 -0
  123. package/src/commands/decision-show.js +14 -0
  124. package/src/commands/decision-status.js +22 -0
  125. package/src/commands/discover.js +41 -0
  126. package/src/commands/doctor.js +51 -13
  127. package/src/commands/gate-record.js +194 -0
  128. package/src/commands/gate-revalidate.js +135 -0
  129. package/src/commands/handoff-list.js +6 -1
  130. package/src/commands/handoff-show.js +6 -1
  131. package/src/commands/migrate-protocol.js +2 -2
  132. package/src/commands/model-route.js +40 -0
  133. package/src/commands/next.js +7 -1
  134. package/src/commands/policy-diff.js +25 -4
  135. package/src/commands/progress.js +17 -11
  136. package/src/commands/record-diagnosis.js +3 -0
  137. package/src/commands/route.js +146 -18
  138. package/src/commands/semantic-plan.js +41 -0
  139. package/src/commands/status.js +6 -1
  140. package/src/commands/storage-backup.js +15 -0
  141. package/src/commands/storage-migrate.js +5 -0
  142. package/src/commands/storage-migration-resume.js +5 -0
  143. package/src/commands/storage-migration-status.js +44 -0
  144. package/src/commands/storage-restore-resume.js +7 -0
  145. package/src/commands/storage-restore.js +8 -0
  146. package/src/commands/task-abandon.js +224 -0
  147. package/src/commands/task-list.js +8 -43
  148. package/src/commands/task-migrate-contract-bootstrap-repair.js +288 -0
  149. package/src/commands/task-migrate.js +3 -3
  150. package/src/commands/task-recover.js +10 -2
  151. package/src/commands/task-repair-contract-bootstrap.js +263 -0
  152. package/src/commands/task-scope.js +18 -2
  153. package/src/commands/task-show.js +16 -2
  154. package/src/commands/test-inventory.js +5 -0
  155. package/src/commands/test-prune-plan.js +5 -0
  156. package/src/commands/test-prune-probe.js +5 -0
  157. package/src/commands/test-utility.js +5 -0
  158. package/src/commands/validate-protocol.js +39 -15
  159. package/src/commands/validate-receipt.js +8 -1
  160. package/src/config/guides.json +4 -0
  161. package/src/core/action-ledger-projection.js +10 -3
  162. package/src/core/actions.js +38 -75
  163. package/src/core/activation.js +11 -3
  164. package/src/core/approvals.js +17 -51
  165. package/src/core/artifact-registry.js +83 -2
  166. package/src/core/artifacts.js +81 -27
  167. package/src/core/attachment-paths.js +45 -0
  168. package/src/core/attestation-coverage.js +6 -1
  169. package/src/core/attestation-verifier.js +21 -2
  170. package/src/core/attestation.js +17 -6
  171. package/src/core/audit-ux.js +514 -0
  172. package/src/core/audit.js +6 -1
  173. package/src/core/browser-verification/constants.js +149 -0
  174. package/src/core/browser-verification/normalize.js +254 -0
  175. package/src/core/browser-verification/provider.js +519 -0
  176. package/src/core/browser-verification/service.js +115 -0
  177. package/src/core/bundles.js +160 -66
  178. package/src/core/checkpoint-revalidation.js +321 -0
  179. package/src/core/cli-command-definitions.js +350 -7
  180. package/src/core/code-manifest.js +9 -3
  181. package/src/core/command-executors.js +274 -108
  182. package/src/core/command-input.js +136 -44
  183. package/src/core/completion-artifacts.js +85 -34
  184. package/src/core/completion-ownership.js +19 -8
  185. package/src/core/completion-recovery-rebind.js +11 -1
  186. package/src/core/completion.js +64 -15
  187. package/src/core/config.js +3 -0
  188. package/src/core/conformance.js +2 -1
  189. package/src/core/context-compiler/budget.js +9 -0
  190. package/src/core/context-compiler/candidates.js +39 -0
  191. package/src/core/context-compiler/compiler.js +63 -0
  192. package/src/core/context-compiler/fingerprint.js +11 -0
  193. package/src/core/context-compiler/policy.js +13 -0
  194. package/src/core/context-compiler/result.js +23 -0
  195. package/src/core/continuity-lint.js +13 -2
  196. package/src/core/continuity-reconciliation.js +16 -3
  197. package/src/core/continuity.js +16 -8
  198. package/src/core/contract-bootstrap-recovery.js +656 -0
  199. package/src/core/contract-revision.js +209 -0
  200. package/src/core/decision/artifact.js +70 -0
  201. package/src/core/decision/benchmarks.js +103 -0
  202. package/src/core/decision/cache.js +27 -0
  203. package/src/core/decision/constants.js +58 -0
  204. package/src/core/decision/cutover.js +34 -0
  205. package/src/core/decision/engine.js +22 -0
  206. package/src/core/decision/errors.js +68 -0
  207. package/src/core/decision/events.js +104 -0
  208. package/src/core/decision/freshness.js +19 -0
  209. package/src/core/decision/normalizers/index.js +115 -0
  210. package/src/core/decision/policy.js +18 -0
  211. package/src/core/decision/projection.js +16 -0
  212. package/src/core/decision/question-registry.js +201 -0
  213. package/src/core/decision/request.js +26 -0
  214. package/src/core/decision/resolver.js +138 -0
  215. package/src/core/decision/result.js +58 -0
  216. package/src/core/decision/service.js +181 -0
  217. package/src/core/decision/state-builder.js +65 -0
  218. package/src/core/decision/task-bindings.js +35 -0
  219. package/src/core/decision/test-provider.js +32 -0
  220. package/src/core/decision/thresholds.js +15 -0
  221. package/src/core/diagnosis-model.js +11 -0
  222. package/src/core/diagnosis.js +10 -1
  223. package/src/core/diagnostic-projection.js +29 -12
  224. package/src/core/diagnostic-record.js +28 -3
  225. package/src/core/efficiency.js +6 -1
  226. package/src/core/error-codes.js +278 -0
  227. package/src/core/events.js +535 -147
  228. package/src/core/evidence-readiness.js +9 -0
  229. package/src/core/execution-prerequisites.js +36 -13
  230. package/src/core/execution-profile.js +63 -38
  231. package/src/core/execution.js +26 -40
  232. package/src/core/filesystem.js +11 -0
  233. package/src/core/gate-artifact.js +105 -19
  234. package/src/core/gate-provenance.js +125 -0
  235. package/src/core/handoff.js +26 -14
  236. package/src/core/history.js +39 -35
  237. package/src/core/hypothesis-projection.js +32 -0
  238. package/src/core/information-gain-projection.js +104 -100
  239. package/src/core/inspect.js +12 -3
  240. package/src/core/integration-invocation-policy.js +37 -4
  241. package/src/core/integration-resources.js +119 -87
  242. package/src/core/ledger-event-collection.js +189 -0
  243. package/src/core/ledger-relations.js +23 -0
  244. package/src/core/model-router/constants.js +10 -0
  245. package/src/core/model-router/policy.js +103 -0
  246. package/src/core/model-router/router.js +37 -0
  247. package/src/core/native-storage.js +12 -0
  248. package/src/core/next-action-continuity.js +31 -9
  249. package/src/core/next-action-model.js +58 -0
  250. package/src/core/next-action-phases.js +131 -43
  251. package/src/core/next-action-refresh.js +43 -9
  252. package/src/core/next-action-review-phase.js +9 -4
  253. package/src/core/next-action-verification-phase.js +2 -1
  254. package/src/core/next-action.js +56 -9
  255. package/src/core/phase.js +266 -103
  256. package/src/core/policy-engine.js +12 -13
  257. package/src/core/preflight-consistency.js +89 -62
  258. package/src/core/preflight-loaders.js +48 -9
  259. package/src/core/preflight-model.js +6 -1
  260. package/src/core/preflight.js +29 -12
  261. package/src/core/progress.js +21 -10
  262. package/src/core/protocol-info.js +68 -0
  263. package/src/core/protocol-migration.js +7 -6
  264. package/src/core/protocol.js +20 -0
  265. package/src/core/reconcile-closure.js +281 -67
  266. package/src/core/recovery-history.js +67 -47
  267. package/src/core/reflection.js +72 -77
  268. package/src/core/responsibility.js +25 -13
  269. package/src/core/resumability.js +154 -44
  270. package/src/core/route-artifact.js +28 -4
  271. package/src/core/router.js +67 -1
  272. package/src/core/runtime-context.js +123 -61
  273. package/src/core/schema-validation.js +11 -3
  274. package/src/core/security-review/constants.js +64 -0
  275. package/src/core/security-review/normalize.js +245 -0
  276. package/src/core/security-review/provider.js +204 -0
  277. package/src/core/security-review/service.js +134 -0
  278. package/src/core/semantic-planning/constants.js +19 -0
  279. package/src/core/semantic-planning/projection.js +94 -0
  280. package/src/core/semantic-planning/service.js +15 -0
  281. package/src/core/settlement.js +12 -1
  282. package/src/core/signing/bundle-file.js +53 -0
  283. package/src/core/signing/bundle-reference.js +15 -0
  284. package/src/core/signing/sigstore.js +60 -33
  285. package/src/core/signing/statement-file.js +27 -0
  286. package/src/core/sources.js +37 -0
  287. package/src/core/storage-runtime-registry.js +41 -0
  288. package/src/core/structural-quality/artifacts.js +20 -14
  289. package/src/core/structural-quality/service.js +81 -56
  290. package/src/core/target-layout.js +1 -1
  291. package/src/core/task-claim-state.js +249 -15
  292. package/src/core/task-command.js +21 -1
  293. package/src/core/task-conflict-inspection.js +133 -102
  294. package/src/core/task-descriptor.js +29 -22
  295. package/src/core/task-discovery.js +288 -90
  296. package/src/core/task-lock.js +66 -306
  297. package/src/core/task-migration-validation.js +5 -5
  298. package/src/core/task-migration.js +17 -287
  299. package/src/core/task-paths.js +13 -0
  300. package/src/core/task-recovery.js +1 -0
  301. package/src/core/task-snapshot.js +51 -8
  302. package/src/core/task-storage-migration.js +18 -0
  303. package/src/core/templates.js +23 -8
  304. package/src/core/test-intelligence/benchmarks.js +68 -0
  305. package/src/core/test-intelligence/inventory.js +73 -0
  306. package/src/core/test-intelligence/prune.js +94 -0
  307. package/src/core/test-intelligence/semantic-state.js +15 -0
  308. package/src/core/test-intelligence/service.js +40 -0
  309. package/src/core/test-intelligence/utility.js +50 -0
  310. package/src/core/trace.js +164 -105
  311. package/src/core/trajectory-evaluation.js +15 -3
  312. package/src/core/trajectory-metrics.js +47 -32
  313. package/src/core/transaction.js +16 -287
  314. package/src/core/verification-scope.js +20 -12
  315. package/src/core/work-state.js +100 -59
  316. package/src/integration.d.ts +492 -0
  317. package/src/integration.js +54 -0
  318. package/src/providers/README.md +47 -0
  319. package/src/providers/capabilities.js +46 -0
  320. package/src/providers/errors.js +15 -0
  321. package/src/providers/index.js +29 -0
  322. package/src/providers/json-snapshot.js +105 -0
  323. package/src/providers/registry.js +152 -0
  324. package/src/repository-index/binary-manager.js +7 -5
  325. package/src/storage/artifact-bytes.js +22 -0
  326. package/src/storage/attachment-binding.js +11 -0
  327. package/src/storage/attachment-files.js +82 -0
  328. package/src/storage/attachment-references.js +36 -0
  329. package/src/storage/backup.js +53 -0
  330. package/src/storage/capabilities.js +31 -0
  331. package/src/storage/connection-owner.js +119 -0
  332. package/src/storage/connection.js +376 -0
  333. package/src/storage/existing-project-scope.js +45 -0
  334. package/src/storage/export-destination.js +44 -0
  335. package/src/storage/exporter.js +284 -0
  336. package/src/storage/file-durability.js +46 -0
  337. package/src/storage/importer.js +461 -0
  338. package/src/storage/index.js +74 -0
  339. package/src/storage/leases.js +63 -0
  340. package/src/storage/ledger-event-snapshot.js +150 -0
  341. package/src/storage/ledger-relations.js +220 -0
  342. package/src/storage/legacy-maintenance-boundary.js +18 -0
  343. package/src/storage/legacy-signature.js +115 -0
  344. package/src/storage/maintenance-handoff.js +129 -0
  345. package/src/storage/maintenance-owner.js +42 -0
  346. package/src/storage/maintenance.js +310 -0
  347. package/src/storage/metadata-json.js +35 -0
  348. package/src/storage/migration-activate.js +59 -0
  349. package/src/storage/migration-archive.js +57 -0
  350. package/src/storage/migration-attachment-root.js +61 -0
  351. package/src/storage/migration-candidate.js +398 -0
  352. package/src/storage/migration-publication.js +143 -0
  353. package/src/storage/migration-rollback-admission.js +54 -0
  354. package/src/storage/migration-rollback-preparation.js +132 -0
  355. package/src/storage/migration-rollback-publication.js +183 -0
  356. package/src/storage/migration-rollback-release.js +66 -0
  357. package/src/storage/migration-rollback-source-stage.js +103 -0
  358. package/src/storage/migration-rollback.js +43 -0
  359. package/src/storage/migration-source-partition.js +56 -0
  360. package/src/storage/migration-source.js +255 -0
  361. package/src/storage/migration-terminal.js +39 -0
  362. package/src/storage/migration-validation.js +75 -0
  363. package/src/storage/migration.js +43 -0
  364. package/src/storage/operational-attachments.js +49 -0
  365. package/src/storage/operational-context.js +50 -0
  366. package/src/storage/project-backup.js +98 -0
  367. package/src/storage/project-bootstrap.js +24 -0
  368. package/src/storage/project-boundary.js +79 -0
  369. package/src/storage/project-read-snapshot.js +18 -0
  370. package/src/storage/project-replacement.js +137 -0
  371. package/src/storage/project-restore.js +203 -0
  372. package/src/storage/record-definitions.js +45 -0
  373. package/src/storage/repository.js +507 -0
  374. package/src/storage/restore-journal.js +62 -0
  375. package/src/storage/restore-layout.js +30 -0
  376. package/src/storage/restore-preparation.js +84 -0
  377. package/src/storage/restore-replacement-archive.js +162 -0
  378. package/src/storage/restore-replacement-owner.js +31 -0
  379. package/src/storage/restore-replacement-preparation.js +128 -0
  380. package/src/storage/restore-replacement.js +142 -0
  381. package/src/storage/restore-terminal.js +32 -0
  382. package/src/storage/runtime.js +31 -0
  383. package/src/storage/schema.js +214 -0
  384. package/src/storage/singleton-import.js +84 -0
  385. package/src/storage/snapshot-continuity.js +16 -0
  386. package/src/storage/snapshot.js +36 -0
  387. package/src/storage/storage-marker.js +79 -0
  388. package/src/storage/task-guards.js +107 -0
  389. package/src/storage/topology.js +42 -0
  390. package/src/storage/transaction.js +179 -0
  391. package/src/storage/unit-of-work.js +663 -0
  392. package/src/storage/windows-process-incarnation.js +206 -0
  393. package/.forgeloop/forgeloop.gitignore +0 -4
  394. package/LICENSE-DOCS.md +0 -13
  395. package/src/core/transaction-maintenance.js +0 -70
@@ -10,7 +10,7 @@ import { completionRelationshipErrors } from "./completion-relationships.js";
10
10
  import { assertSafePath, ensureWithin, fileExists } from "./filesystem.js";
11
11
  import { evaluateStartExecutionPrerequisites, hasExecutionStarted } from "./execution-prerequisites.js";
12
12
  import { isRecoverableCompletionEvidenceCode } from "./completion-recovery.js";
13
- import { evaluateTerminalRequirements } from "./evidence-readiness.js";
13
+ import { evaluateTerminalRequirements, terminalRequirementsForContract } from "./evidence-readiness.js";
14
14
  import { PROJECT_ARTIFACT_PATHS, taskArtifactPath, taskCodeManifestPath } from "./task-paths.js";
15
15
  import { detectPolicyCapability, evaluateTargetPolicy } from "./policy-engine.js";
16
16
  import { listActions } from "./actions.js";
@@ -18,7 +18,9 @@ import { readConfig } from "./config.js";
18
18
  import { resolveResponsibilityStatus } from "./responsibility.js";
19
19
  import { createCodeManifest, readCodeManifest, validateCodeManifestBindings, writeCodeManifest } from "./code-manifest.js";
20
20
  import { getTaskTransaction, withTaskTransaction } from "./transaction.js";
21
+ import { operationalArtifactExists } from "../storage/operational-context.js";
21
22
  import { validateStructuralQualityCheckProvenance } from "./structural-quality/service.js";
23
+ import { withNativeReadScope } from "./native-storage.js";
22
24
 
23
25
  async function attestationConfiguration(target, packageRoot, errors) {
24
26
  try {
@@ -79,6 +81,12 @@ function issue(code, message, artifacts = [], details = {}) {
79
81
  return { code, message, artifacts, ...details };
80
82
  }
81
83
 
84
+ export function receiptReadFailure(error, relativePath) {
85
+ return error.taskIdentityMismatch
86
+ ? issue("E_RECEIPT_TASK_MISMATCH", "Execution receipt does not belong to the current contract task", [relativePath])
87
+ : issue("E_RECEIPT_INVALID", `Repair or remove the invalid execution receipt before continuing: ${error.message}`, [relativePath]);
88
+ }
89
+
82
90
  export function completionIdentityErrors({ contract, state, receipt } = {}) {
83
91
  return completionRelationshipErrors({ contract, state, receipt })
84
92
  .filter((error) => ["E_STATE_TASK_MISMATCH", "E_RECEIPT_TASK_MISMATCH"].includes(error.code));
@@ -226,6 +234,10 @@ async function loadRequired(readArtifact, errorCode, errorMessage, artifacts, er
226
234
  try {
227
235
  return await readArtifact();
228
236
  } catch (error) {
237
+ if (errorCode === "E_RECEIPT_MISSING" && error.taskIdentityMismatch) {
238
+ errors.push(receiptReadFailure(error, artifacts[0]));
239
+ return null;
240
+ }
229
241
  if (error.code === "ARTIFACT_MISSING") {
230
242
  errors.push(issue(errorCode, errorMessage, artifacts));
231
243
  return null;
@@ -235,6 +247,19 @@ async function loadRequired(readArtifact, errorCode, errorMessage, artifacts, er
235
247
  }
236
248
  }
237
249
 
250
+ async function loadCompletionActions(target, packageRoot, taskId, errors) {
251
+ const { evaluateRequiredActionReadiness } = await import("./action-readiness.js");
252
+ const evidence = taskId ? await loadRequired(async () => ({
253
+ actions: await listActions(target, { packageRoot, taskId }),
254
+ readiness: await evaluateRequiredActionReadiness({ target, packageRoot, taskId }),
255
+ }), "E_ACTION_INVALID", "Durable action evidence is not available", [taskArtifactPath(taskId, "actions")], errors) : null;
256
+ return {
257
+ actions: evidence?.actions ?? [],
258
+ readiness: evidence?.readiness
259
+ ?? { total: 0, satisfied: 0, unresolved: 0, ambiguous: 0, failed: 0, untrusted: 0, actions: [] },
260
+ };
261
+ }
262
+
238
263
  function publicationStatus(receipt) {
239
264
  if (receipt.publicationStatus) return receipt.publicationStatus;
240
265
  if (receipt.publication?.deployed) return "deployed";
@@ -246,9 +271,10 @@ function publicationStatus(receipt) {
246
271
  async function validateLedger(target, scopedTaskId, contractTaskId, state, errors, packageRoot, options = {}) {
247
272
  const eventsRel = options.eventsPath ?? (scopedTaskId ? taskArtifactPath(scopedTaskId, "events") : ARTIFACT_PATHS.events);
248
273
  const stateRel = options.statePath ?? (scopedTaskId ? taskArtifactPath(scopedTaskId, "state") : ARTIFACT_PATHS.state);
249
- await assertSafePath(target, eventsRel);
274
+ const operationalExists = operationalArtifactExists(target, eventsRel);
275
+ if (operationalExists === null) await assertSafePath(target, eventsRel);
250
276
  const eventsFilePath = ensureWithin(target, eventsRel);
251
- if (!(await fileExists(eventsFilePath))) {
277
+ if (operationalExists === false || (operationalExists === null && !(await fileExists(eventsFilePath)))) {
252
278
  errors.push(issue("E_PHASE_CHRONOLOGY_INVALID", "Protocol event ledger is required before completion", [eventsRel]));
253
279
  return { valid: false, events: [], errors: [] };
254
280
  }
@@ -286,6 +312,35 @@ export async function evaluateCompletion({
286
312
  receiptPath = null,
287
313
  eventsPath = null,
288
314
  preflightPath = null,
315
+ } = {}) {
316
+ const options = { target, packageRoot, strict, authorityContext, runtimeContext, taskId, contractPath, routePath, statePath, receiptPath, eventsPath, preflightPath };
317
+ return withNativeReadScope(target, async () => evaluateSelectedCompletion(await resolveCompletionTaskOptions(options)));
318
+ }
319
+
320
+ async function resolveCompletionTaskOptions(options) {
321
+ if (options.taskId) return options;
322
+ try {
323
+ const state = await readWorkState(options.target, { packageRoot: options.packageRoot, statePath: options.statePath });
324
+ return state ? { ...options, taskId: state.taskId } : options;
325
+ } catch {
326
+ // Preserve the evaluator's structured missing/invalid-state diagnostics.
327
+ return options;
328
+ }
329
+ }
330
+
331
+ async function evaluateSelectedCompletion({
332
+ target,
333
+ packageRoot,
334
+ strict = false,
335
+ authorityContext,
336
+ runtimeContext,
337
+ taskId = null,
338
+ contractPath = null,
339
+ routePath = null,
340
+ statePath = null,
341
+ receiptPath = null,
342
+ eventsPath = null,
343
+ preflightPath = null,
289
344
  } = {}) {
290
345
  const errors = [];
291
346
  const preflight = await evaluatePreflight({ target, packageRoot, strict, taskId, contractPath, routePath, statePath });
@@ -500,12 +555,10 @@ export async function evaluateCompletion({
500
555
  const publication = receiptValue ? publicationStatus(receiptValue) : "not-published";
501
556
 
502
557
  if (contract) {
503
- const allContractReqs = [
504
- ...(contract.value.verification ?? []),
505
- ...(contract.value.successCriteria ?? []),
506
- ];
507
558
  const terminalEval = evaluateTerminalRequirements({
508
- requirements: allContractReqs,
559
+ requirements: terminalRequirementsForContract(contract.value, {
560
+ additionalEvidence: preflight.policy?.requiredEvidence ?? [],
561
+ }),
509
562
  receipt: receiptValue,
510
563
  });
511
564
  for (const termErr of terminalEval.errors) {
@@ -559,19 +612,14 @@ export async function evaluateCompletion({
559
612
  }
560
613
 
561
614
  const actionTaskId = contract?.value?.taskId ?? taskId;
562
- const durableActions = actionTaskId
563
- ? await listActions(target, { packageRoot, taskId: actionTaskId })
564
- : [];
615
+
565
616
  const contractRequirements = new Set([
566
617
  ...(contract?.value?.verification ?? []), ...(contract?.value?.successCriteria ?? []),
567
618
  ]);
568
619
  // Completion truth consumes the canonical action-readiness projection, not
569
620
  // raw state labels: a forged VERIFIED label can never satisfy a required
570
621
  // action (INV-VERIFY-02).
571
- const { evaluateRequiredActionReadiness } = await import("./action-readiness.js");
572
- const requiredActionReadiness = actionTaskId
573
- ? await evaluateRequiredActionReadiness({ target, packageRoot, taskId: actionTaskId })
574
- : { total: 0, satisfied: 0, unresolved: 0, ambiguous: 0, failed: 0, untrusted: 0, actions: [] };
622
+ const { actions: durableActions, readiness: requiredActionReadiness } = await loadCompletionActions(target, packageRoot, actionTaskId, errors);
575
623
  for (const readiness of requiredActionReadiness.actions) {
576
624
  if (readiness.status === "SATISFIED") continue;
577
625
  const action = durableActions.find((candidate) => candidate.actionId === readiness.actionId);
@@ -855,6 +903,7 @@ async function runCompleteInternal({
855
903
  }
856
904
 
857
905
  export async function runComplete(options = {}) {
906
+ options = await resolveCompletionTaskOptions(options);
858
907
  const taskId = options.taskId ?? null;
859
908
  if (options.persist !== false && taskId && !(await getTaskTransaction(options.target))) {
860
909
  return withTaskTransaction({
@@ -4,6 +4,7 @@ import { E_ATTESTATION_CONFIGURATION_INVALID } from "./error-codes.js";
4
4
  import { normalizeVerificationConfiguration } from "./verification-scope-capability.js";
5
5
  import { EXECUTION_PROFILE_REQUESTS } from "./execution-profile.js";
6
6
  import { normalizeStructuralQualityConfig } from "./structural-quality/policy.js";
7
+ import { normalizeDecisionPolicy } from "./decision/policy.js";
7
8
 
8
9
  export const CONFIG_SCHEMA_VERSION = 1;
9
10
  export const COMPLIANCE_MODES = Object.freeze(["advisory", "standard", "strict"]);
@@ -82,6 +83,7 @@ export function createConfig(input = {}) {
82
83
  executionProfile = input.executionProfile;
83
84
  }
84
85
  const structuralQuality = normalizeStructuralQualityConfig(input.structuralQuality);
86
+ const decisionEngine = normalizeDecisionPolicy(input.decisionEngine);
85
87
  return {
86
88
  schemaVersion: CONFIG_SCHEMA_VERSION,
87
89
  protocolVersion: PROTOCOL_VERSION,
@@ -93,6 +95,7 @@ export function createConfig(input = {}) {
93
95
  ...(attestation ? { attestation } : {}),
94
96
  ...(executionProfile ? { executionProfile } : {}),
95
97
  ...(structuralQuality !== undefined ? { structuralQuality } : {}),
98
+ decisionEngine,
96
99
  };
97
100
  }
98
101
 
@@ -1,3 +1,4 @@
1
+ import { isLedgerEventCollection } from "./ledger-event-collection.js";
1
2
  import { PROTOCOL_VERSION } from "./protocol.js";
2
3
  import { createEvidence } from "./evidence.js";
3
4
  import { canonicalFingerprint } from "./artifacts.js";
@@ -36,7 +37,7 @@ export function delegationIsInScope({
36
37
  if (state?.delegatedTasks && state.delegatedTasks.length > 0) return true;
37
38
  if (state?.delegatedTaskIds && state.delegatedTaskIds.length > 0) return true;
38
39
  if (receipt?.delegatedTasks && receipt.delegatedTasks.length > 0) return true;
39
- if (Array.isArray(events) && events.some((event) => typeof event?.type === "string" && event.type.toLowerCase().includes("delegat"))) {
40
+ if (isLedgerEventCollection(events) && events.some((event) => typeof event?.type === "string" && event.type.toLowerCase().includes("delegat"))) {
40
41
  return true;
41
42
  }
42
43
  return false;
@@ -0,0 +1,9 @@
1
+ export const CONTEXT_BUDGETS = Object.freeze({
2
+ light: Object.freeze({ maxItems: 12, maxChars: 24_000 }),
3
+ balanced: Object.freeze({ maxItems: 32, maxChars: 64_000 }),
4
+ full: Object.freeze({ maxItems: 96, maxChars: 160_000 }),
5
+ });
6
+
7
+ export function contextBudget(profile = "balanced") {
8
+ return CONTEXT_BUDGETS[profile] ?? CONTEXT_BUDGETS.balanced;
9
+ }
@@ -0,0 +1,39 @@
1
+ import { canonicalFingerprint } from "../artifacts.js";
2
+ import { buildDecisionState } from "../decision/state-builder.js";
3
+
4
+ const INJECTION_PATTERN = /(ignore|disregard|override)\s+(?:all|previous|forge|system|developer)|exfiltrat|reveal\s+(?:the|all)\s+(?:secret|token|key)|execute\s+(?:this|the)\s+command/i;
5
+
6
+ export function normalizeContextCandidate(input = {}) {
7
+ const safe = buildDecisionState({
8
+ id: input.id ?? null,
9
+ sourceRef: input.sourceRef ?? null,
10
+ kind: input.kind ?? "UNKNOWN",
11
+ summary: input.summary ?? "",
12
+ required: input.required === true,
13
+ mandatory: input.mandatory === true,
14
+ risk: input.risk ?? "NORMAL",
15
+ trust: input.trust ?? "UNTRUSTED",
16
+ });
17
+ const summary = typeof safe.summary === "string" ? safe.summary : "";
18
+ const id = typeof safe.id === "string" && safe.id ? safe.id : `candidate-${canonicalFingerprint(safe).slice(0, 16)}`;
19
+ return {
20
+ ...safe,
21
+ id,
22
+ summary,
23
+ chars: summary.length,
24
+ promptInjection: INJECTION_PATTERN.test(summary),
25
+ };
26
+ }
27
+
28
+ export function normalizeContextCandidates(candidates = []) {
29
+ const seen = new Set();
30
+ const normalized = [];
31
+ for (const candidate of candidates) {
32
+ const value = normalizeContextCandidate(candidate);
33
+ const identity = `${value.id}:${value.sourceRef ?? ""}`;
34
+ if (seen.has(identity)) continue;
35
+ seen.add(identity);
36
+ normalized.push(value);
37
+ }
38
+ return normalized;
39
+ }
@@ -0,0 +1,63 @@
1
+ import { contextBudget } from "./budget.js";
2
+ import { normalizeContextCandidates } from "./candidates.js";
3
+ import { contextPlanFingerprint } from "./fingerprint.js";
4
+ import { canonicalFingerprint } from "../artifacts.js";
5
+ import { assertContextCompilerPolicy, candidatePriority } from "./policy.js";
6
+ import { contextPlanResult } from "./result.js";
7
+
8
+ function orderCandidates(candidates, rankedIds = []) {
9
+ const ranks = new Map(rankedIds.map((id, index) => [id, rankedIds.length - index]));
10
+ return [...candidates].sort((a, b) => (b.mandatory - a.mandatory)
11
+ || (b.required - a.required)
12
+ || ((ranks.get(b.id) ?? 0) - (ranks.get(a.id) ?? 0))
13
+ || (candidatePriority(b) - candidatePriority(a))
14
+ || a.id.localeCompare(b.id));
15
+ }
16
+
17
+ export function compileContext({ candidates = [], profile = "balanced", mandatoryIds = [], semanticRanker = null } = {}) {
18
+ const policy = assertContextCompilerPolicy({ profile, mandatoryIds });
19
+ const normalized = normalizeContextCandidates(candidates);
20
+ const candidateSetFingerprint = canonicalFingerprint(normalized.map((candidate) => ({
21
+ id: candidate.id,
22
+ sourceRef: candidate.sourceRef,
23
+ summary: candidate.summary,
24
+ required: candidate.required,
25
+ mandatory: candidate.mandatory,
26
+ })));
27
+ const mandatory = new Set(policy.mandatoryIds);
28
+ const marked = normalized.map((candidate) => ({ ...candidate, mandatory: candidate.mandatory || mandatory.has(candidate.id) }));
29
+ const semantic = typeof semanticRanker === "function" ? semanticRanker(marked.filter((item) => !item.promptInjection).map((item) => ({ id: item.id, summary: item.summary }))) : [];
30
+ const rankedIds = Array.isArray(semantic) ? semantic : (semantic?.rankedIds ?? []);
31
+ const excludedIds = new Set(Array.isArray(semantic) ? [] : (semantic?.excludedIds ?? []));
32
+ const ordered = orderCandidates(marked, Array.isArray(rankedIds) ? rankedIds : []);
33
+ const budget = contextBudget(profile);
34
+ const selected = [];
35
+ const omitted = [];
36
+ let chars = 0;
37
+ for (const candidate of ordered) {
38
+ const mustKeep = candidate.mandatory || candidate.required;
39
+ if (excludedIds.has(candidate.id) && !mustKeep) {
40
+ omitted.push(candidate);
41
+ continue;
42
+ }
43
+ const fits = selected.length < budget.maxItems && chars + candidate.chars <= budget.maxChars;
44
+ if (fits || mustKeep) {
45
+ selected.push(candidate);
46
+ chars += candidate.chars;
47
+ } else omitted.push(candidate);
48
+ }
49
+ const promptInjectionIds = marked.filter((item) => item.promptInjection).map((item) => item.id).sort();
50
+ const result = contextPlanResult({
51
+ profile,
52
+ candidates: marked,
53
+ selected,
54
+ omitted,
55
+ mandatoryIds: [...new Set([...policy.mandatoryIds, ...marked.filter((item) => item.mandatory).map((item) => item.id)])].sort(),
56
+ promptInjectionIds,
57
+ fingerprint: null,
58
+ budget,
59
+ candidateSetFingerprint,
60
+ });
61
+ result.decisionFingerprint = contextPlanFingerprint(result);
62
+ return result;
63
+ }
@@ -0,0 +1,11 @@
1
+ import { canonicalFingerprint } from "../artifacts.js";
2
+
3
+ export function contextPlanFingerprint(plan) {
4
+ return canonicalFingerprint({
5
+ profile: plan.profile,
6
+ selectedIds: plan.selected.map((item) => item.id),
7
+ omittedIds: plan.omitted.map((item) => item.id),
8
+ mandatoryIds: plan.mandatoryIds,
9
+ promptInjectionIds: plan.promptInjectionIds,
10
+ });
11
+ }
@@ -0,0 +1,13 @@
1
+ import { decisionError, DECISION_ERROR_CODES } from "../decision/errors.js";
2
+
3
+ const RISK_ORDER = Object.freeze({ CRITICAL: 4, HIGH: 3, NORMAL: 2, LOW: 1 });
4
+
5
+ export function assertContextCompilerPolicy({ profile = "balanced", mandatoryIds = [] } = {}) {
6
+ if (!["light", "balanced", "full"].includes(profile)) throw decisionError(DECISION_ERROR_CODES.POLICY_INVALID, "Context compiler profile is invalid.");
7
+ if (!Array.isArray(mandatoryIds) || mandatoryIds.some((id) => typeof id !== "string" || !id)) throw decisionError(DECISION_ERROR_CODES.POLICY_INVALID, "Context compiler mandatory IDs are invalid.");
8
+ return { profile, mandatoryIds: [...new Set(mandatoryIds)] };
9
+ }
10
+
11
+ export function candidatePriority(candidate) {
12
+ return (candidate.mandatory || candidate.required ? 100 : 0) + (candidate.promptInjection ? -50 : 0) + (RISK_ORDER[candidate.risk] ?? 0);
13
+ }
@@ -0,0 +1,23 @@
1
+ export function contextPlanResult({ profile, candidates, selected, omitted, mandatoryIds, promptInjectionIds, fingerprint, budget, candidateSetFingerprint }) {
2
+ return {
3
+ schemaVersion: 1,
4
+ protocolVersion: 1,
5
+ profile,
6
+ budget,
7
+ candidateItems: candidates.length,
8
+ selectedItems: selected.length,
9
+ candidateChars: candidates.reduce((total, item) => total + item.chars, 0),
10
+ selectedChars: selected.reduce((total, item) => total + item.chars, 0),
11
+ selected,
12
+ omitted,
13
+ mandatoryIds,
14
+ promptInjectionIds,
15
+ candidateSetFingerprint,
16
+ tokenUsage: { inputTokens: null, outputTokens: null, reportedBy: "UNKNOWN" },
17
+ decisionFingerprint: fingerprint,
18
+ authority: "SEMANTIC_DECISION",
19
+ evidenceAuthority: "NONE",
20
+ lifecycleAuthority: false,
21
+ completionAuthority: false,
22
+ };
23
+ }
@@ -1,4 +1,6 @@
1
1
  import { assertSafePath, ensureWithin, fileExists } from "./filesystem.js";
2
+ import { operationalArtifactExists } from "../storage/operational-context.js";
3
+ import { withProjectReadSnapshot } from "../storage/project-read-snapshot.js";
2
4
 
3
5
  function finding(code, severity, field, itemId = null) {
4
6
  return { code, severity, field, itemId };
@@ -15,7 +17,16 @@ function hasOperationalHints(continuity) {
15
17
  );
16
18
  }
17
19
 
18
- export async function lintContinuity({ target, continuity, state } = {}) {
20
+ async function inspectPathExists(target, relativePath) {
21
+ return operationalArtifactExists(target, relativePath) ?? await fileExists(ensureWithin(target, relativePath));
22
+ }
23
+
24
+ export async function lintContinuity(options = {}) {
25
+ if (typeof options.target !== "string" || options.target.trim() === "") return lintSelectedContinuity(options);
26
+ return withProjectReadSnapshot(options.target, () => lintSelectedContinuity(options));
27
+ }
28
+
29
+ async function lintSelectedContinuity({ target, continuity, state } = {}) {
19
30
  const findings = [];
20
31
  if (!continuity || typeof continuity !== "object" || Array.isArray(continuity)) {
21
32
  return { status: "PASS", findings };
@@ -64,7 +75,7 @@ export async function lintContinuity({ target, continuity, state } = {}) {
64
75
  for (const [index, inspectPath] of (continuity.inspectFirst ?? []).entries()) {
65
76
  try {
66
77
  await assertSafePath(target, inspectPath);
67
- if (!(await fileExists(ensureWithin(target, inspectPath)))) {
78
+ if (!(await inspectPathExists(target, inspectPath))) {
68
79
  findings.push(finding(
69
80
  "CONTINUITY_INSPECT_PATH_MISSING",
70
81
  "WARN",
@@ -1,7 +1,10 @@
1
+ import { getOperationalStore } from "../storage/operational-context.js";
2
+ import { withEventLedgerAudit } from "./events.js";
1
3
  import { canonicalFingerprint } from "./artifacts.js";
2
4
  import { assertContinuitySemantics, readContinuity } from "./continuity.js";
3
5
  import { WORK_TRANSITIONS } from "./protocol.js";
4
6
  import { lintContinuity } from "./continuity-lint.js";
7
+ import { withNativeReadScope } from "./native-storage.js";
5
8
 
6
9
  const RECONCILIATION_CODE = "E_CONTINUITY_RECONCILIATION_REQUIRED";
7
10
 
@@ -171,6 +174,14 @@ export function classifyContinuity({
171
174
  }
172
175
 
173
176
  export async function reconcileContinuity({ target, packageRoot, taskId = null } = {}) {
177
+ const read = () => reconcileLoadedContinuity({ target, packageRoot, taskId });
178
+ return withNativeReadScope(target, () => {
179
+ if (getOperationalStore(target) && taskId) return withEventLedgerAudit(target, packageRoot, { taskId }, read);
180
+ return read();
181
+ });
182
+ }
183
+
184
+ async function reconcileLoadedContinuity({ target, packageRoot, taskId }) {
174
185
  const [{ readWorkState }, { readContract }, repository] = await Promise.all([
175
186
  import("./work-state.js"),
176
187
  import("./contract.js"),
@@ -267,12 +278,14 @@ async function resolveLatestHandoffSafe(target, { packageRoot, taskId } = {}) {
267
278
 
268
279
  async function deriveDiagnosticContextSafe({ target, packageRoot, state }) {
269
280
  try {
270
- const [{ readEvents }, { deriveDiagnosticContext }] = await Promise.all([
281
+ const [{ withEventLedgerAudit }, { deriveDiagnosticContext }] = await Promise.all([
271
282
  import("./events.js"),
272
283
  import("./reflection.js"),
273
284
  ]);
274
- const events = await readEvents(target, packageRoot, { taskId: state?.taskId ?? null });
275
- return { present: true, ...deriveDiagnosticContext(events, state) };
285
+ return await withEventLedgerAudit(target, packageRoot, { taskId: state?.taskId ?? null }, audit => {
286
+ if (!audit.valid) return { present: false };
287
+ return { present: true, ...deriveDiagnosticContext(audit.events, state) };
288
+ });
276
289
  } catch {
277
290
  return { present: false };
278
291
  }
@@ -1,4 +1,4 @@
1
- import { unlink } from "node:fs/promises";
1
+ import { withExistingProjectScope } from "../storage/existing-project-scope.js";
2
2
  import path from "node:path";
3
3
 
4
4
  import {
@@ -7,11 +7,12 @@ import {
7
7
  readJsonArtifact,
8
8
  writeJsonArtifact,
9
9
  } from "./artifacts.js";
10
- import { assertSafePath, ensureWithin, fileExists } from "./filesystem.js";
11
10
  import { PROTOCOL_VERSION, WORK_PHASES } from "./protocol.js";
12
11
  import { normalizePortableText, assertPortableContextSafe } from "./portable-context.js";
13
12
  import { getPackageRoot } from "./templates.js";
14
13
  import { taskArtifactPath } from "./task-paths.js";
14
+ import { getOperationalStore, readOperationalText } from "../storage/operational-context.js";
15
+ import { withTaskTransaction } from "./transaction.js";
15
16
 
16
17
  export const CONTINUITY_PATH = ARTIFACT_PATHS.continuity;
17
18
  export const CONTINUITY_SCHEMA_VERSION = 1;
@@ -242,10 +243,17 @@ export async function writeContinuity(target, operationalInput = {}, options = {
242
243
  }
243
244
 
244
245
  export async function clearContinuity(target, options = {}) {
245
- const relPath = options.continuityPath ?? options.relativePath ?? (options.taskId ? taskArtifactPath(options.taskId, "continuity") : CONTINUITY_PATH);
246
- await assertSafePath(target, relPath);
247
- const artifactPath = ensureWithin(target, relPath);
248
- if (!(await fileExists(artifactPath))) return { removed: false, path: relPath };
249
- await unlink(artifactPath);
250
- return { removed: true, path: relPath };
246
+ if (!options.taskId) throw Object.assign(new Error("Canonical artifact clearing requires a task identity"), { code: "E_STORAGE_OPERATION_UNSUPPORTED" });
247
+ const relPath = taskArtifactPath(options.taskId, "continuity");
248
+ const requested = options.continuityPath ?? options.relativePath ?? relPath;
249
+ if (requested !== relPath) throw Object.assign(new Error("Artifact clearing requires the canonical task path; portable exports are independent files"), { code: "E_STORAGE_OPERATION_UNSUPPORTED", artifacts: [requested] });
250
+ if (!getOperationalStore(target)) {
251
+ return withExistingProjectScope(target, () => clearContinuity(target, options));
252
+ }
253
+ const operational = readOperationalText(target, relPath);
254
+ if (operational.text === null) return { removed: false, path: relPath };
255
+ return withTaskTransaction({ target, taskId: options.taskId, operation: "clear-continuity", packageRoot: options.packageRoot }, async transaction => {
256
+ transaction.stageDelete(relPath);
257
+ return { removed: true, path: relPath };
258
+ });
251
259
  }