@cassiomc1/forgeloop 1.14.0 → 2.0.0-rc.4

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 (250) hide show
  1. package/CONTRIBUTING.md +11 -7
  2. package/DOCS_INDEX.md +2 -1
  3. package/ENG/c-development-eng.md +2 -2
  4. package/ENG/cpp-development-eng.md +2 -2
  5. package/ENG/dotnet-aspnetcore-development-eng.md +7 -1
  6. package/ENG/flutter-development-eng.md +4 -2
  7. package/ENG/go-development-eng.md +2 -2
  8. package/ENG/java-development-eng.md +3 -3
  9. package/ENG/nodejs-backend-development-eng.md +8 -4
  10. package/ENG/php-development-eng.md +3 -3
  11. package/ENG/python-development-eng.md +205 -0
  12. package/ENG/rust-development-eng.md +42 -1
  13. package/ENG/sql-development-eng.md +4 -4
  14. package/ENG/swift-development-eng.md +5 -4
  15. package/ENG/test-code-eng.md +1 -1
  16. package/ENG/typescript-development-eng.md +4 -4
  17. package/GUIDE_ROUTER.md +6 -0
  18. package/LICENSE +133 -21
  19. package/LOOP_SYSTEM_DESIGN.md +10 -10
  20. package/README.md +30 -40
  21. package/THIRD_PARTY_NOTICES.md +3 -4
  22. package/completions/_forgeloop +11 -3
  23. package/completions/forgeloop.bash +19 -3
  24. package/completions/forgeloop.fish +61 -1
  25. package/docs/AGENT_PROTOCOL_SUMMARY.md +50 -40
  26. package/docs/ARTIFACT_REFERENCE.md +50 -37
  27. package/docs/CLI_REFERENCE.md +147 -3
  28. package/docs/DOCUMENTATION_GUIDE.md +6 -4
  29. package/docs/GETTING_STARTED.md +3 -3
  30. package/docs/PACKAGE_CONTENTS.md +14 -13
  31. package/docs/RELEASE_CHECKLIST.md +110 -10
  32. package/docs/SELF_HOSTED_TESTS.md +121 -0
  33. package/docs/TROUBLESHOOTING.md +33 -0
  34. package/docs/documentation-manifest.json +25 -12
  35. package/package.json +15 -10
  36. package/schemas/task-bundle.schema.json +7 -2
  37. package/scripts/generate-agent-protocol-summary.mjs +2 -2
  38. package/scripts/run-mcp-clean-tests.mjs +30 -0
  39. package/src/adapters/agent-browser/provider.js +14 -11
  40. package/src/adapters/emulated-services/provider.js +11 -4
  41. package/src/adapters/temporary-paths.js +18 -0
  42. package/src/cli.js +146 -210
  43. package/src/commands/action-show.js +5 -2
  44. package/src/commands/advance.js +5 -1
  45. package/src/commands/baseline.js +13 -11
  46. package/src/commands/checkpoint-revalidate.js +24 -8
  47. package/src/commands/complete.js +19 -3
  48. package/src/commands/contract-create.js +3 -1
  49. package/src/commands/doctor.js +36 -13
  50. package/src/commands/gate-record.js +20 -31
  51. package/src/commands/gate-revalidate.js +11 -13
  52. package/src/commands/handoff-list.js +6 -1
  53. package/src/commands/handoff-show.js +6 -1
  54. package/src/commands/migrate-protocol.js +2 -2
  55. package/src/commands/model-route.js +9 -1
  56. package/src/commands/next.js +7 -1
  57. package/src/commands/policy-diff.js +25 -4
  58. package/src/commands/progress.js +17 -11
  59. package/src/commands/record-diagnosis.js +3 -0
  60. package/src/commands/semantic-plan.js +26 -2
  61. package/src/commands/status.js +6 -1
  62. package/src/commands/storage-backup.js +15 -0
  63. package/src/commands/storage-migrate.js +5 -0
  64. package/src/commands/storage-migration-resume.js +5 -0
  65. package/src/commands/storage-migration-status.js +44 -0
  66. package/src/commands/storage-restore-resume.js +7 -0
  67. package/src/commands/storage-restore.js +8 -0
  68. package/src/commands/task-abandon.js +1 -1
  69. package/src/commands/task-list.js +8 -43
  70. package/src/commands/task-migrate.js +3 -3
  71. package/src/commands/task-recover.js +10 -2
  72. package/src/commands/task-scope.js +18 -2
  73. package/src/commands/task-show.js +16 -2
  74. package/src/commands/validate-protocol.js +29 -14
  75. package/src/commands/validate-receipt.js +8 -1
  76. package/src/config/guides.json +4 -0
  77. package/src/core/action-ledger-projection.js +10 -3
  78. package/src/core/actions.js +38 -75
  79. package/src/core/activation.js +11 -3
  80. package/src/core/approvals.js +17 -51
  81. package/src/core/artifact-registry.js +59 -2
  82. package/src/core/artifacts.js +81 -27
  83. package/src/core/attachment-paths.js +45 -0
  84. package/src/core/attestation-coverage.js +6 -1
  85. package/src/core/attestation-verifier.js +21 -2
  86. package/src/core/attestation.js +17 -6
  87. package/src/core/audit.js +6 -1
  88. package/src/core/bundles.js +160 -66
  89. package/src/core/checkpoint-revalidation.js +12 -10
  90. package/src/core/cli-command-definitions.js +109 -7
  91. package/src/core/code-manifest.js +9 -3
  92. package/src/core/command-executors.js +182 -126
  93. package/src/core/command-input.js +21 -1
  94. package/src/core/completion-artifacts.js +85 -36
  95. package/src/core/completion-ownership.js +19 -8
  96. package/src/core/completion-recovery-rebind.js +11 -1
  97. package/src/core/completion.js +60 -9
  98. package/src/core/conformance.js +2 -1
  99. package/src/core/continuity-lint.js +13 -2
  100. package/src/core/continuity-reconciliation.js +16 -3
  101. package/src/core/continuity.js +16 -8
  102. package/src/core/contract-bootstrap-recovery.js +42 -41
  103. package/src/core/contract-revision.js +8 -9
  104. package/src/core/decision/artifact.js +2 -1
  105. package/src/core/decision/events.js +9 -6
  106. package/src/core/decision/resolver.js +19 -11
  107. package/src/core/decision/service.js +63 -38
  108. package/src/core/decision/task-bindings.js +6 -1
  109. package/src/core/diagnosis-model.js +11 -0
  110. package/src/core/diagnosis.js +10 -1
  111. package/src/core/diagnostic-projection.js +29 -12
  112. package/src/core/diagnostic-record.js +28 -3
  113. package/src/core/efficiency.js +6 -1
  114. package/src/core/events.js +316 -97
  115. package/src/core/execution-prerequisites.js +22 -13
  116. package/src/core/execution.js +26 -40
  117. package/src/core/filesystem.js +11 -0
  118. package/src/core/gate-artifact.js +105 -19
  119. package/src/core/gate-provenance.js +6 -5
  120. package/src/core/handoff.js +26 -14
  121. package/src/core/history.js +39 -35
  122. package/src/core/hypothesis-projection.js +32 -0
  123. package/src/core/information-gain-projection.js +104 -100
  124. package/src/core/inspect.js +12 -3
  125. package/src/core/integration-invocation-policy.js +10 -0
  126. package/src/core/integration-resources.js +41 -34
  127. package/src/core/ledger-event-collection.js +189 -0
  128. package/src/core/ledger-relations.js +23 -0
  129. package/src/core/native-storage.js +12 -0
  130. package/src/core/next-action-continuity.js +31 -9
  131. package/src/core/next-action-phases.js +1 -1
  132. package/src/core/next-action-review-phase.js +2 -2
  133. package/src/core/next-action-verification-phase.js +2 -1
  134. package/src/core/next-action.js +21 -2
  135. package/src/core/phase.js +138 -93
  136. package/src/core/policy-engine.js +12 -13
  137. package/src/core/preflight-consistency.js +72 -59
  138. package/src/core/preflight-loaders.js +19 -12
  139. package/src/core/preflight-model.js +6 -1
  140. package/src/core/preflight.js +29 -12
  141. package/src/core/progress.js +21 -10
  142. package/src/core/protocol-info.js +3 -0
  143. package/src/core/protocol-migration.js +7 -6
  144. package/src/core/reconcile-closure.js +162 -24
  145. package/src/core/recovery-history.js +66 -47
  146. package/src/core/reflection.js +72 -77
  147. package/src/core/responsibility.js +25 -13
  148. package/src/core/route-artifact.js +13 -3
  149. package/src/core/runtime-context.js +5 -0
  150. package/src/core/schema-validation.js +8 -3
  151. package/src/core/settlement.js +12 -1
  152. package/src/core/signing/bundle-file.js +53 -0
  153. package/src/core/signing/bundle-reference.js +15 -0
  154. package/src/core/signing/sigstore.js +60 -33
  155. package/src/core/signing/statement-file.js +27 -0
  156. package/src/core/storage-runtime-registry.js +41 -0
  157. package/src/core/structural-quality/artifacts.js +20 -14
  158. package/src/core/structural-quality/service.js +81 -56
  159. package/src/core/target-layout.js +1 -1
  160. package/src/core/task-claim-state.js +52 -18
  161. package/src/core/task-command.js +21 -1
  162. package/src/core/task-conflict-inspection.js +112 -107
  163. package/src/core/task-descriptor.js +29 -22
  164. package/src/core/task-discovery.js +288 -90
  165. package/src/core/task-lock.js +66 -306
  166. package/src/core/task-migration-validation.js +5 -5
  167. package/src/core/task-migration.js +17 -287
  168. package/src/core/task-snapshot.js +51 -8
  169. package/src/core/task-storage-migration.js +18 -0
  170. package/src/core/templates.js +20 -8
  171. package/src/core/test-intelligence/prune.js +5 -1
  172. package/src/core/trace.js +154 -99
  173. package/src/core/trajectory-evaluation.js +15 -3
  174. package/src/core/trajectory-metrics.js +47 -32
  175. package/src/core/transaction.js +16 -288
  176. package/src/core/verification-scope.js +20 -12
  177. package/src/core/work-state.js +100 -59
  178. package/src/repository-index/binary-manager.js +15 -7
  179. package/src/storage/artifact-bytes.js +22 -0
  180. package/src/storage/attachment-binding.js +11 -0
  181. package/src/storage/attachment-files.js +82 -0
  182. package/src/storage/attachment-references.js +36 -0
  183. package/src/storage/backup.js +53 -0
  184. package/src/storage/capabilities.js +31 -0
  185. package/src/storage/connection-owner.js +119 -0
  186. package/src/storage/connection.js +376 -0
  187. package/src/storage/existing-project-scope.js +45 -0
  188. package/src/storage/export-destination.js +44 -0
  189. package/src/storage/exporter.js +284 -0
  190. package/src/storage/file-durability.js +46 -0
  191. package/src/storage/importer.js +461 -0
  192. package/src/storage/index.js +74 -0
  193. package/src/storage/leases.js +63 -0
  194. package/src/storage/ledger-event-snapshot.js +150 -0
  195. package/src/storage/ledger-relations.js +220 -0
  196. package/src/storage/legacy-maintenance-boundary.js +18 -0
  197. package/src/storage/legacy-signature.js +115 -0
  198. package/src/storage/maintenance-handoff.js +129 -0
  199. package/src/storage/maintenance-owner.js +42 -0
  200. package/src/storage/maintenance.js +310 -0
  201. package/src/storage/metadata-json.js +35 -0
  202. package/src/storage/migration-activate.js +59 -0
  203. package/src/storage/migration-archive.js +57 -0
  204. package/src/storage/migration-attachment-root.js +61 -0
  205. package/src/storage/migration-candidate.js +398 -0
  206. package/src/storage/migration-publication.js +143 -0
  207. package/src/storage/migration-rollback-admission.js +54 -0
  208. package/src/storage/migration-rollback-preparation.js +132 -0
  209. package/src/storage/migration-rollback-publication.js +183 -0
  210. package/src/storage/migration-rollback-release.js +66 -0
  211. package/src/storage/migration-rollback-source-stage.js +103 -0
  212. package/src/storage/migration-rollback.js +43 -0
  213. package/src/storage/migration-source-partition.js +56 -0
  214. package/src/storage/migration-source.js +255 -0
  215. package/src/storage/migration-terminal.js +39 -0
  216. package/src/storage/migration-validation.js +75 -0
  217. package/src/storage/migration.js +43 -0
  218. package/src/storage/operational-attachments.js +49 -0
  219. package/src/storage/operational-context.js +50 -0
  220. package/src/storage/project-backup.js +98 -0
  221. package/src/storage/project-bootstrap.js +24 -0
  222. package/src/storage/project-boundary.js +79 -0
  223. package/src/storage/project-read-snapshot.js +18 -0
  224. package/src/storage/project-replacement.js +137 -0
  225. package/src/storage/project-restore.js +203 -0
  226. package/src/storage/record-definitions.js +45 -0
  227. package/src/storage/repository.js +507 -0
  228. package/src/storage/restore-execution-provenance.js +26 -0
  229. package/src/storage/restore-journal.js +62 -0
  230. package/src/storage/restore-layout.js +30 -0
  231. package/src/storage/restore-preparation.js +84 -0
  232. package/src/storage/restore-replacement-archive.js +162 -0
  233. package/src/storage/restore-replacement-owner.js +31 -0
  234. package/src/storage/restore-replacement-preparation.js +128 -0
  235. package/src/storage/restore-replacement.js +142 -0
  236. package/src/storage/restore-terminal.js +32 -0
  237. package/src/storage/runtime.js +31 -0
  238. package/src/storage/schema.js +214 -0
  239. package/src/storage/singleton-import.js +84 -0
  240. package/src/storage/snapshot-continuity.js +16 -0
  241. package/src/storage/snapshot.js +36 -0
  242. package/src/storage/storage-marker.js +79 -0
  243. package/src/storage/task-guards.js +107 -0
  244. package/src/storage/topology.js +42 -0
  245. package/src/storage/transaction.js +179 -0
  246. package/src/storage/unit-of-work.js +667 -0
  247. package/src/storage/windows-process-incarnation.js +206 -0
  248. package/.forgeloop/forgeloop.gitignore +0 -4
  249. package/LICENSE-DOCS.md +0 -13
  250. package/src/core/transaction-maintenance.js +0 -70
@@ -58,6 +58,104 @@ export const CLI_TASK_OPTION = Object.freeze({
58
58
  export const CLI_BOOTSTRAP_OPTIONS = CLI_COMMON_OPTIONS;
59
59
 
60
60
  export const CLI_COMMAND_DEFINITIONS = Object.freeze({
61
+ "storage-restore-resume": Object.freeze({
62
+ name: "storage-restore-resume", category: "project-maintenance", mutation: "MUTATING",
63
+ options: Object.freeze({
64
+ ...CLI_COMMON_OPTIONS,
65
+ "--operation": Object.freeze({ targetKey: "operationId", parseType: "string", takesValue: true, valueName: "uuid", missingValueMessage: "--operation requires a UUID", description: "exact retained restore journal operation UUID" }),
66
+ "--expected-owner": Object.freeze({ targetKey: "expectedOwnerId", parseType: "string", takesValue: true, valueName: "uuid", missingValueMessage: "--expected-owner requires a UUID", description: "exact retained maintenance owner UUID" }),
67
+ "--replace-active": Object.freeze({ targetKey: "replaceActive", parseType: "boolean", takesValue: false, description: "explicitly select active replacement with retained outgoing authority" }),
68
+ "--writers-quiesced": Object.freeze({ targetKey: "writersQuiesced", parseType: "boolean", takesValue: false, description: "assert that all writers have been externally stopped" }),
69
+ "--json": Object.freeze({ targetKey: "json", parseType: "boolean", takesValue: false, description: "emit restore recovery metadata" }),
70
+ }),
71
+ writes: [".forgeloop/storage-restores", ".forgeloop/state.sqlite", ".forgeloop/attachments", ".forgeloop/storage-version.json", ".forgeloop/.storage-maintenance", ".forgeloop/storage-maintenance-history"], removes: [], mayExecuteExternalProcess: false,
72
+ description: "Adopts an exact dead local maintenance owner and resumes restore. Incomplete snapshots and prior rebuild intents are retained before rebuilding from bound source; completed preparation requires source parity/domain validation. Use --replace-active for preparation or publication replacement recovery. Conflicting intents and retained handoff locks remain refused.",
73
+ }),
74
+ "storage-restore": Object.freeze({
75
+ name: "storage-restore", category: "project-maintenance", mutation: "MUTATING",
76
+ options: Object.freeze({
77
+ ...CLI_COMMON_OPTIONS,
78
+ "--source": Object.freeze({ targetKey: "source", parseType: "string", takesValue: true, valueName: "path", missingValueMessage: "--source requires a path", description: "verified attachment-inclusive backup directory; absolute or relative to the target project" }),
79
+ "--replace-active": Object.freeze({ targetKey: "replaceActive", parseType: "boolean", takesValue: false, description: "explicitly select active replacement with retained outgoing authority" }),
80
+ "--writers-quiesced": Object.freeze({ targetKey: "writersQuiesced", parseType: "boolean", takesValue: false, description: "assert that all writers have been externally stopped" }),
81
+ "--json": Object.freeze({ targetKey: "json", parseType: "boolean", takesValue: false, description: "emit restore activation metadata" }),
82
+ }),
83
+ writes: [".forgeloop/storage-restores", ".forgeloop/state.sqlite", ".forgeloop/attachments", ".forgeloop/storage-version.json", ".forgeloop/.storage-maintenance"], removes: [], mayExecuteExternalProcess: false,
84
+ description: "Verifies and retains a backup before activating it in an operationally fresh project. Existing operational state requires explicit --replace-active, which independently retains and archives outgoing authority before activation; failed restore evidence and maintenance exclusion are retained.",
85
+ }),
86
+ "storage-migration-status": Object.freeze({
87
+ name: "storage-migration-status", category: "project-maintenance", mutation: "READ_ONLY",
88
+ options: Object.freeze({
89
+ ...CLI_COMMON_OPTIONS,
90
+ "--json": Object.freeze({ targetKey: "json", parseType: "boolean", takesValue: false, description: "emit bootstrap storage layout and retained maintenance ownership" }),
91
+ }),
92
+ writes: [], removes: [], mayExecuteExternalProcess: false,
93
+ description: "Inspects storage layout and maintenance exclusion without opening or repairing a database.",
94
+ }),
95
+ "storage-migration-resume": Object.freeze({
96
+ name: "storage-migration-resume", category: "project-maintenance", mutation: "MUTATING",
97
+ options: Object.freeze({
98
+ ...CLI_COMMON_OPTIONS,
99
+ "--destination": Object.freeze({ targetKey: "destination", parseType: "string", takesValue: true, valueName: "path", missingValueMessage: "--destination requires a path", description: "retained migration directory relative to the project" }),
100
+ "--expected-owner": Object.freeze({ targetKey: "expectedOwnerId", parseType: "string", takesValue: true, valueName: "uuid", missingValueMessage: "--expected-owner requires a UUID", description: "exact retained maintenance owner reported by storage-migration-status" }),
101
+ "--writers-quiesced": Object.freeze({ targetKey: "writersQuiesced", parseType: "boolean", takesValue: false, description: "assert that all writers, including older clients, have been externally stopped" }),
102
+ "--reconcile-unbound-handoff": Object.freeze({ targetKey: "acknowledgeUnboundHandoff", parseType: "boolean", takesValue: false, description: "preserve an unbound legacy handoff by atomic archival before resuming the exact dead owner" }),
103
+ "--json": Object.freeze({ targetKey: "json", parseType: "boolean", takesValue: false, description: "emit recovery verification metadata" }),
104
+ }),
105
+ writes: ["<destination>", ".forgeloop/state.sqlite", ".forgeloop/storage-version.json", ".forgeloop/.storage-maintenance", ".forgeloop/storage-maintenance-history"], removes: [], mayExecuteExternalProcess: false,
106
+ description: "Adopts an exact dead local owner and continues verified publication stages. Unrecorded capture and unbound candidate files remain refused; an unbound legacy handoff is archived opaquely only with explicit --reconcile-unbound-handoff acknowledgement.",
107
+ }),
108
+ "storage-rollback": Object.freeze({
109
+ name: "storage-rollback", category: "project-maintenance", mutation: "MUTATING",
110
+ options: Object.freeze({
111
+ ...CLI_COMMON_OPTIONS,
112
+ "--destination": Object.freeze({ targetKey: "destination", parseType: "string", takesValue: true, valueName: "path", missingValueMessage: "--destination requires a path", description: "retained published migration directory relative to the project" }),
113
+ "--legacy-root": Object.freeze({ targetKey: "legacyRoot", parseType: "string", takesValue: true, valueName: "path", missingValueMessage: "--legacy-root requires a path", description: "clean supported pinned legacy checkout used for actual target validation" }),
114
+ "--writers-quiesced": Object.freeze({ targetKey: "writersQuiesced", parseType: "boolean", takesValue: false, description: "assert that all writers, including older clients, have been externally stopped and excluded" }),
115
+ "--native-writes-excluded": Object.freeze({ targetKey: "nativeWritesExcluded", parseType: "boolean", takesValue: false, description: "assert that native writes have been excluded since migration; snapshot equality alone does not prove this" }),
116
+ "--json": Object.freeze({ targetKey: "json", parseType: "boolean", takesValue: false, description: "emit restoration and target-validation metadata" }),
117
+ }),
118
+ writes: ["<destination>", "export-index.json", ".forgeloop/task-state", ".forgeloop/attachments", ".forgeloop/.storage-maintenance"],
119
+ removes: [".forgeloop/state.sqlite", ".forgeloop/storage-version.json"], mayExecuteExternalProcess: true,
120
+ description: "Conditionally restores preserved source before native writes, retaining original native bytes and validating every task with the supported pinned legacy target before release. Failures retain exclusion; post-write restoration is refused.",
121
+ }),
122
+ "storage-rollback-resume": Object.freeze({
123
+ name: "storage-rollback-resume", category: "project-maintenance", mutation: "MUTATING",
124
+ options: Object.freeze({
125
+ ...CLI_COMMON_OPTIONS,
126
+ "--expected-owner": Object.freeze({ targetKey: "expectedOwnerId", parseType: "string", takesValue: true, valueName: "uuid", missingValueMessage: "--expected-owner requires a UUID", description: "exact retained dead local owner reported by storage-migration-status" }),
127
+ "--destination": Object.freeze({ targetKey: "destination", parseType: "string", takesValue: true, valueName: "path", missingValueMessage: "--destination requires a path", description: "retained migration with recorded rollback preparation, staging or publication" }),
128
+ "--legacy-root": Object.freeze({ targetKey: "legacyRoot", parseType: "string", takesValue: true, valueName: "path", missingValueMessage: "--legacy-root requires a path", description: "clean supported pinned legacy checkout used for actual target validation" }),
129
+ "--writers-quiesced": Object.freeze({ targetKey: "writersQuiesced", parseType: "boolean", takesValue: false, description: "assert that all writers, including older clients, have been externally stopped and excluded" }),
130
+ "--native-writes-excluded": Object.freeze({ targetKey: "nativeWritesExcluded", parseType: "boolean", takesValue: false, description: "assert that native writes have been excluded since migration; snapshot equality alone does not prove this" }),
131
+ "--json": Object.freeze({ targetKey: "json", parseType: "boolean", takesValue: false, description: "emit restoration and target-validation metadata" }),
132
+ }),
133
+ writes: ["<destination>", "export-index.json", ".forgeloop/task-state", ".forgeloop/attachments", ".forgeloop/.storage-maintenance"],
134
+ removes: [".forgeloop/state.sqlite", ".forgeloop/storage-version.json"], mayExecuteExternalProcess: true,
135
+ description: "Resumes recorded rollback preparation, staging or publication under exact dead-owner adoption, revalidates native/source locations, and validates every task with the pinned target before release. Unbound attempts remain refused.",
136
+ }),
137
+ "storage-migrate": Object.freeze({
138
+ name: "storage-migrate", category: "project-maintenance", mutation: "MUTATING",
139
+ options: Object.freeze({
140
+ ...CLI_COMMON_OPTIONS,
141
+ "--destination": Object.freeze({ targetKey: "destination", parseType: "string", takesValue: true, valueName: "path", missingValueMessage: "--destination requires a path", description: "new retained migration directory relative to the project; missing parent directories are created" }),
142
+ "--writers-quiesced": Object.freeze({ targetKey: "writersQuiesced", parseType: "boolean", takesValue: false, description: "assert that all writers, including older clients, have been externally stopped" }),
143
+ "--json": Object.freeze({ targetKey: "json", parseType: "boolean", takesValue: false, description: "emit migration publication and verification metadata" }),
144
+ }),
145
+ writes: ["<destination>", ".forgeloop/state.sqlite", ".forgeloop/storage-version.json", ".forgeloop/.storage-maintenance"], removes: [], mayExecuteExternalProcess: false,
146
+ description: "Validates, retains and archives legacy state before activating SQLite. Failed attempts retain maintenance exclusion; resume requires the exact retained owner and a verified candidate.",
147
+ }),
148
+ "storage-backup": Object.freeze({
149
+ name: "storage-backup", category: "project-maintenance", mutation: "MUTATING",
150
+ options: Object.freeze({
151
+ ...CLI_COMMON_OPTIONS,
152
+ "--destination": Object.freeze({ targetKey: "destination", parseType: "string", takesValue: true, valueName: "path", missingValueMessage: "--destination requires a path", description: "new backup file or attachment-inclusive directory relative to the project; parent directory must exist" }),
153
+ "--include-attachments": Object.freeze({ targetKey: "includeAttachments", parseType: "boolean", takesValue: false, description: "create a new backup directory including all canonically referenced attachment bytes" }),
154
+ "--json": Object.freeze({ targetKey: "json", parseType: "boolean", takesValue: false, description: "emit backup metadata" }),
155
+ }),
156
+ writes: ["<destination>"], removes: [], mayExecuteExternalProcess: false,
157
+ description: "Creates an exclusive native SQLite backup, optionally including canonically referenced attachments in a retained directory.",
158
+ }),
61
159
  "protocol-info": Object.freeze({
62
160
  name: "protocol-info",
63
161
  category: "diagnostics",
@@ -1188,7 +1286,7 @@ export const CLI_COMMAND_DEFINITIONS = Object.freeze({
1188
1286
  writes: [".forgeloop/task-state/<taskKey>/executions/exec-<id>.json", ".forgeloop/task-state/<taskKey>/work-state.json", ".forgeloop/task-state/<taskKey>/events.ndjson"],
1189
1287
  removes: [],
1190
1288
  mayExecuteExternalProcess: true,
1191
- description: "Refreshes the work-state checkpoint of an EXECUTING, VERIFYING, or REVIEWING task whose objective is already satisfied in the current repository, after contract-bound executed evidence, so canonical completion can proceed.",
1289
+ description: "Refreshes the work-state checkpoint of an EXECUTING, VERIFYING, CORRECTING, or REVIEWING task whose objective is already satisfied in the current repository, after contract-bound executed evidence, so canonical completion can proceed.",
1192
1290
  }),
1193
1291
  "validate-receipt": Object.freeze({
1194
1292
  name: "validate-receipt",
@@ -1311,13 +1409,15 @@ export const CLI_COMMAND_DEFINITIONS = Object.freeze({
1311
1409
  mutation: "MUTATING",
1312
1410
  options: Object.freeze({
1313
1411
  ...CLI_COMMON_OPTIONS,
1412
+ "--destination": Object.freeze({ targetKey: "destination", parseType: "string", takesValue: true, valueName: "path", description: "retained source and publication evidence destination" }),
1413
+ "--writers-quiesced": Object.freeze({ targetKey: "writersQuiesced", parseType: "boolean", takesValue: false, description: "confirm all legacy writers are stopped and excluded" }),
1314
1414
  "--dry-run": Object.freeze({ targetKey: "dryRun", parseType: "boolean", takesValue: false, description: "show planned migration actions without moving files" }),
1315
1415
  "--json": Object.freeze({ targetKey: "json", parseType: "boolean", takesValue: false, description: "emit structured output as JSON" }),
1316
1416
  }),
1317
- writes: [".forgeloop/task-state/<taskKey>/*"],
1417
+ writes: [".forgeloop/state.sqlite", ".forgeloop/storage-version.json", "<destination>/*"],
1318
1418
  removes: [".forgeloop/current-contract.json", ".forgeloop/routing-result.json", ".forgeloop/work-state.json", ".forgeloop/preflight.json", ".forgeloop/execution-receipt.json", ".forgeloop/events.ndjson", ".forgeloop/continuity.json", ".forgeloop/gates", ".forgeloop/executions"],
1319
1419
  mayExecuteExternalProcess: false,
1320
- description: "Migrates a legacy 1.0 singleton task state layout into a task-namespaced layout.",
1420
+ description: "Migrates legacy singleton task state into SQLite with retained source and verified publication evidence.",
1321
1421
  }),
1322
1422
  "migrate-protocol": Object.freeze({
1323
1423
  name: "migrate-protocol",
@@ -1325,11 +1425,13 @@ export const CLI_COMMAND_DEFINITIONS = Object.freeze({
1325
1425
  mutation: "MUTATING",
1326
1426
  options: Object.freeze({
1327
1427
  ...CLI_COMMON_OPTIONS,
1428
+ "--destination": Object.freeze({ targetKey: "destination", parseType: "string", takesValue: true, valueName: "path", description: "retained source and publication evidence destination" }),
1429
+ "--writers-quiesced": Object.freeze({ targetKey: "writersQuiesced", parseType: "boolean", takesValue: false, description: "confirm all legacy writers are stopped and excluded" }),
1328
1430
  "--to": Object.freeze({ targetKey: "to", parseType: "string", takesValue: true, valueName: "protocolVersion", missingValueMessage: "--to requires a protocol version", description: "target supported protocol version" }),
1329
1431
  "--dry-run": Object.freeze({ targetKey: "dryRun", parseType: "boolean", takesValue: false, description: "show migration actions without writing or deleting artifacts" }),
1330
1432
  "--json": Object.freeze({ targetKey: "json", parseType: "boolean", takesValue: false, description: "emit structured migration result as JSON" }),
1331
1433
  }),
1332
- writes: [".forgeloop/task-state/<taskKey>/*"],
1434
+ writes: [".forgeloop/state.sqlite", ".forgeloop/storage-version.json", "<destination>/*"],
1333
1435
  removes: [".forgeloop/current-contract.json", ".forgeloop/routing-result.json", ".forgeloop/work-state.json", ".forgeloop/preflight.json", ".forgeloop/execution-receipt.json", ".forgeloop/events.ndjson", ".forgeloop/continuity.json", ".forgeloop/gates", ".forgeloop/executions"],
1334
1436
  mayExecuteExternalProcess: false,
1335
1437
  description: "Safely migrates explicitly supported protocol state; unknown target versions fail without rewriting artifacts.",
@@ -1345,10 +1447,10 @@ export const CLI_COMMAND_DEFINITIONS = Object.freeze({
1345
1447
  "--stale-only": Object.freeze({ targetKey: "staleOnly", parseType: "boolean", takesValue: false, description: "release only a lock whose lease is expired" }),
1346
1448
  "--json": Object.freeze({ targetKey: "json", parseType: "boolean", takesValue: false, description: "emit structured output as JSON" }),
1347
1449
  }),
1348
- writes: [],
1349
- removes: [".forgeloop/locks/<taskKey>.lock"],
1450
+ writes: [".forgeloop/state.sqlite"],
1451
+ removes: [],
1350
1452
  mayExecuteExternalProcess: false,
1351
- description: "Removes an orphaned task lock file to recover an interrupted task.",
1453
+ description: "Releases a canonical SQLite operation lease to recover an interrupted task.",
1352
1454
  }),
1353
1455
  "task-recover": Object.freeze({
1354
1456
  name: "task-recover",
@@ -1,3 +1,4 @@
1
+ import { withTaskTransaction } from "./transaction.js";
1
2
  import { createHash } from "node:crypto";
2
3
  import path from "node:path";
3
4
 
@@ -15,6 +16,7 @@ import {
15
16
  taskCodeManifestHistoryPath,
16
17
  } from "./task-paths.js";
17
18
  import { ensureWithin, fileExists } from "./filesystem.js";
19
+ import { operationalArtifactExists } from "../storage/operational-context.js";
18
20
  import { resolveRevisionProvider } from "./revision/provider.js";
19
21
  import { REVISION_PROVIDERS } from "./revision/registry.js";
20
22
 
@@ -217,10 +219,14 @@ export async function readCodeManifest({ target, packageRoot = getPackageRoot(),
217
219
  }
218
220
  }
219
221
 
220
- export async function writeCodeManifest({ target, packageRoot = getPackageRoot(), taskId, manifest } = {}) {
222
+ export async function writeCodeManifest(options = {}) {
223
+ return withTaskTransaction({ target: options.target, taskId: options.taskId, packageRoot: options.packageRoot, operation: "code-manifest-capture" }, () => writeCodeManifestInTransaction(options));
224
+ }
225
+
226
+ async function writeCodeManifestInTransaction({ target, packageRoot = getPackageRoot(), taskId, manifest } = {}) {
221
227
  const value = await validateCodeManifest(manifest, packageRoot);
222
228
  const relativePath = taskCodeManifestPath(taskId);
223
- if (await fileExists(ensureWithin(target, relativePath))) {
229
+ if (operationalArtifactExists(target, relativePath) ?? await fileExists(ensureWithin(target, relativePath))) {
224
230
  let previous;
225
231
  try {
226
232
  previous = await readCodeManifest({ target, packageRoot, taskId });
@@ -232,7 +238,7 @@ export async function writeCodeManifest({ target, packageRoot = getPackageRoot()
232
238
  throw manifestError("E_ATTESTATION_MANIFEST_INVALID", "Code manifest is immutable within a verification cycle", [relativePath]);
233
239
  }
234
240
  const historyPath = taskCodeManifestHistoryPath(taskId, previousCycle);
235
- if (!(await fileExists(ensureWithin(target, historyPath)))) {
241
+ if (!(operationalArtifactExists(target, historyPath) ?? await fileExists(ensureWithin(target, historyPath)))) {
236
242
  await writeJsonArtifact(target, historyPath, previous.value, "code-manifest", packageRoot, { taskId, operation: "code-manifest-history" });
237
243
  }
238
244
  }
@@ -1,113 +1,111 @@
1
- import { runDoctor } from "../commands/doctor.js";
2
- import { runStatus } from "../commands/status.js";
3
- import { runValidateState } from "../commands/validate-state.js";
4
- import { runClearState } from "../commands/clear-state.js";
5
- import { runCheckpointRevalidate } from "../commands/checkpoint-revalidate.js";
6
- import { inspectTarget } from "../commands/inspect.js";
7
- import { runInit } from "../commands/init.js";
8
- import { runRoute } from "../commands/route.js";
9
- import { runValidateReceipt } from "../commands/validate-receipt.js";
10
- import { runValidateProtocol } from "../commands/validate-protocol.js";
11
- import { runUpdate } from "../commands/update.js";
12
- import { runActivate } from "../commands/activate.js";
13
- import { runAdvance } from "../commands/advance.js";
14
- import { runPreflight } from "../commands/preflight.js";
15
- import { runQualityBaseline } from "../commands/quality-baseline.js";
16
- import { runQualityVerify } from "../commands/quality-verify.js";
17
- import { runQualityStatus } from "../commands/quality-status.js";
18
- import { runComplete } from "../commands/complete.js";
19
- import { runAudit } from "../commands/audit.js";
20
- import { runReport } from "../commands/report.js";
21
- import { runPolicy } from "../commands/policy.js";
22
- import { runPolicyDiscover } from "../commands/policy-discover.js";
23
- import { runPolicyStatus } from "../commands/policy-status.js";
24
- import { runPolicyDiff } from "../commands/policy-diff.js";
25
- import { runRuleVerify } from "../commands/rule-verify.js";
26
- import { runBaseline } from "../commands/baseline.js";
27
- import { runProfileInterview } from "../commands/profile-interview.js";
28
- import { runBundle } from "../commands/bundle.js";
29
- import { runPrepareCompletion } from "../commands/prepare-completion.js";
30
- import { runRecordCheck } from "../commands/record-check.js";
31
- import { runCheck } from "../commands/run-check.js";
32
- import { runAction } from "../commands/run-action.js";
33
- import { runActionPropose } from "../commands/action-propose.js";
34
- import { runActionRecord } from "../commands/action-record.js";
35
- import { runActionShow } from "../commands/action-show.js";
36
- import { runActionAuthorize } from "../commands/action-authorize.js";
37
- import { runActionVerify } from "../commands/action-verify.js";
38
- import { runActionReconcile } from "../commands/action-reconcile.js";
39
- import { runMetrics } from "../commands/metrics.js";
40
- import { runUsageRecord } from "../commands/usage-record.js";
41
- import { runEfficiency } from "../commands/efficiency.js";
42
- import { runEval } from "../commands/eval.js";
43
- import { runApprovalRequest } from "../commands/approval-request.js";
44
- import { runApprovalResolve } from "../commands/approval-resolve.js";
45
- import { reconcileClosure } from "../commands/reconcile-closure.js";
46
- import { runRecordTerminalResult } from "../commands/record-terminal-result.js";
47
- import { runRecordDiagnosis } from "../commands/record-diagnosis.js";
48
- import { runRecordIntervention } from "../commands/record-intervention.js";
49
- import { runRecordHypothesisDisposition } from "../commands/record-hypothesis-disposition.js";
50
- import { runHistory } from "../commands/history.js";
51
- import { runTrace } from "../commands/trace.js";
52
- import { runReflect } from "../commands/reflect.js";
53
- import { runProgress } from "../commands/progress.js";
54
- import { runRecordDecisionCriterion } from "../commands/record-decision-criterion.js";
55
- import { runNext } from "../commands/next.js";
56
- import { runContinuity } from "../commands/continuity.js";
57
- import { runRecordContinuity } from "../commands/record-continuity.js";
58
- import { runReconcileContinuity } from "../commands/reconcile-continuity.js";
59
- import { runClearContinuity } from "../commands/clear-continuity.js";
60
- import { runTaskCreate } from "../commands/task-create.js";
61
- import { runDiscover } from "../commands/discover.js";
62
- import { runContractCreate } from "../commands/contract-create.js";
63
- import { runContractRevise } from "../commands/contract-revise.js";
64
- import { runGateRecord } from "../commands/gate-record.js";
65
- import { runGateRevalidate } from "../commands/gate-revalidate.js";
66
- import { runTaskList } from "../commands/task-list.js";
67
- import { runTaskShow } from "../commands/task-show.js";
68
- import { runTaskScope } from "../commands/task-scope.js";
69
- import { runTaskMigrate } from "../commands/task-migrate.js";
70
- import { runMigrateProtocol } from "../commands/migrate-protocol.js";
71
- import { runTaskUnlock } from "../commands/task-unlock.js";
72
- import { runTaskRecover } from "../commands/task-recover.js";
73
- import { runTaskAbandon } from "../commands/task-abandon.js";
74
- import { runTaskResume } from "../commands/task-resume.js";
75
- import { runTaskRepairLegacyRecovery } from "../commands/task-repair-legacy-recovery.js";
76
- import { runTaskRepairContractBootstrap } from "../commands/task-repair-contract-bootstrap.js";
77
- import { runTaskMigrateContractBootstrapRepair } from "../commands/task-migrate-contract-bootstrap-repair.js";
78
- import { runTaskLockStatus } from "../commands/task-lock-status.js";
79
- import { runProtocolInfo } from "../commands/protocol-info.js";
80
- import { runDecisionStatus } from "../commands/decision-status.js";
81
- import { runDecisionShow } from "../commands/decision-show.js";
82
- import { runContextPlan } from "../commands/context-plan.js";
83
- import { runModelRoute } from "../commands/model-route.js";
84
- import { runSemanticPlan } from "../commands/semantic-plan.js";
85
- import { runTestInventory } from "../commands/test-inventory.js";
86
- import { runTestUtility } from "../commands/test-utility.js";
87
- import { runTestPrunePlan } from "../commands/test-prune-plan.js";
88
- import { runTestPruneProbe } from "../commands/test-prune-probe.js";
89
- import { runWorkspaceBind } from "../commands/workspace-bind.js";
90
- import { runWorkspaceStatus } from "../commands/workspace-status.js";
91
- import { runHandoffCreate } from "../commands/handoff-create.js";
92
- import { runHandoffList } from "../commands/handoff-list.js";
93
- import { runHandoffShow } from "../commands/handoff-show.js";
94
- import { runHandoffAccept } from "../commands/handoff-accept.js";
95
- import { runResponsibilitySet } from "../commands/responsibility-set.js";
96
- import { runResponsibilityStatus } from "../commands/responsibility-status.js";
97
- import { runVerifyScope } from "../commands/verify-scope.js";
98
- import { runAttestationCreate } from "../commands/attestation-create.js";
99
- import { runAttestationVerify } from "../commands/attestation-verify.js";
100
- import { runAttestationStatus } from "../commands/attestation-status.js";
101
- import { runAttestationVerifyRange } from "../commands/attestation-verify-range.js";
1
+ const runDoctor = async (...args) => (await import("../commands/doctor.js")).runDoctor(...args);
2
+ const runStatus = async (...args) => (await import("../commands/status.js")).runStatus(...args);
3
+ const runValidateState = async (...args) => (await import("../commands/validate-state.js")).runValidateState(...args);
4
+ const runClearState = async (...args) => (await import("../commands/clear-state.js")).runClearState(...args);
5
+ const runCheckpointRevalidate = async (...args) => (await import("../commands/checkpoint-revalidate.js")).runCheckpointRevalidate(...args);
6
+ const inspectTarget = async (...args) => (await import("../commands/inspect.js")).inspectTarget(...args);
7
+ const runInit = async (...args) => (await import("../commands/init.js")).runInit(...args);
8
+ const runRoute = async (...args) => (await import("../commands/route.js")).runRoute(...args);
9
+ const runValidateReceipt = async (...args) => (await import("../commands/validate-receipt.js")).runValidateReceipt(...args);
10
+ const runValidateProtocol = async (...args) => (await import("../commands/validate-protocol.js")).runValidateProtocol(...args);
11
+ const runUpdate = async (...args) => (await import("../commands/update.js")).runUpdate(...args);
12
+ const runActivate = async (...args) => (await import("../commands/activate.js")).runActivate(...args);
13
+ const runAdvance = async (...args) => (await import("../commands/advance.js")).runAdvance(...args);
14
+ const runPreflight = async (...args) => (await import("../commands/preflight.js")).runPreflight(...args);
15
+ const runQualityBaseline = async (...args) => (await import("../commands/quality-baseline.js")).runQualityBaseline(...args);
16
+ const runQualityVerify = async (...args) => (await import("../commands/quality-verify.js")).runQualityVerify(...args);
17
+ const runQualityStatus = async (...args) => (await import("../commands/quality-status.js")).runQualityStatus(...args);
18
+ const runComplete = async (...args) => (await import("../commands/complete.js")).runComplete(...args);
19
+ const runAudit = async (...args) => (await import("../commands/audit.js")).runAudit(...args);
20
+ const runReport = async (...args) => (await import("../commands/report.js")).runReport(...args);
21
+ const runPolicy = async (...args) => (await import("../commands/policy.js")).runPolicy(...args);
22
+ const runPolicyDiscover = async (...args) => (await import("../commands/policy-discover.js")).runPolicyDiscover(...args);
23
+ const runPolicyStatus = async (...args) => (await import("../commands/policy-status.js")).runPolicyStatus(...args);
24
+ const runPolicyDiff = async (...args) => (await import("../commands/policy-diff.js")).runPolicyDiff(...args);
25
+ const runRuleVerify = async (...args) => (await import("../commands/rule-verify.js")).runRuleVerify(...args);
26
+ const runBaseline = async (...args) => (await import("../commands/baseline.js")).runBaseline(...args);
27
+ const runProfileInterview = async (...args) => (await import("../commands/profile-interview.js")).runProfileInterview(...args);
28
+ const runBundle = async (...args) => (await import("../commands/bundle.js")).runBundle(...args);
29
+ const runPrepareCompletion = async (...args) => (await import("../commands/prepare-completion.js")).runPrepareCompletion(...args);
30
+ const runRecordCheck = async (...args) => (await import("../commands/record-check.js")).runRecordCheck(...args);
31
+ const runCheck = async (...args) => (await import("../commands/run-check.js")).runCheck(...args);
32
+ const runAction = async (...args) => (await import("../commands/run-action.js")).runAction(...args);
33
+ const runActionPropose = async (...args) => (await import("../commands/action-propose.js")).runActionPropose(...args);
34
+ const runActionRecord = async (...args) => (await import("../commands/action-record.js")).runActionRecord(...args);
35
+ const runActionShow = async (...args) => (await import("../commands/action-show.js")).runActionShow(...args);
36
+ const runActionAuthorize = async (...args) => (await import("../commands/action-authorize.js")).runActionAuthorize(...args);
37
+ const runActionVerify = async (...args) => (await import("../commands/action-verify.js")).runActionVerify(...args);
38
+ const runActionReconcile = async (...args) => (await import("../commands/action-reconcile.js")).runActionReconcile(...args);
39
+ const runMetrics = async (...args) => (await import("../commands/metrics.js")).runMetrics(...args);
40
+ const runUsageRecord = async (...args) => (await import("../commands/usage-record.js")).runUsageRecord(...args);
41
+ const runEfficiency = async (...args) => (await import("../commands/efficiency.js")).runEfficiency(...args);
42
+ const runEval = async (...args) => (await import("../commands/eval.js")).runEval(...args);
43
+ const runApprovalRequest = async (...args) => (await import("../commands/approval-request.js")).runApprovalRequest(...args);
44
+ const runApprovalResolve = async (...args) => (await import("../commands/approval-resolve.js")).runApprovalResolve(...args);
45
+ const reconcileClosure = async (...args) => (await import("../commands/reconcile-closure.js")).reconcileClosure(...args);
46
+ const runRecordTerminalResult = async (...args) => (await import("../commands/record-terminal-result.js")).runRecordTerminalResult(...args);
47
+ const runRecordDiagnosis = async (...args) => (await import("../commands/record-diagnosis.js")).runRecordDiagnosis(...args);
48
+ const runRecordIntervention = async (...args) => (await import("../commands/record-intervention.js")).runRecordIntervention(...args);
49
+ const runRecordHypothesisDisposition = async (...args) => (await import("../commands/record-hypothesis-disposition.js")).runRecordHypothesisDisposition(...args);
50
+ const runHistory = async (...args) => (await import("../commands/history.js")).runHistory(...args);
51
+ const runTrace = async (...args) => (await import("../commands/trace.js")).runTrace(...args);
52
+ const runReflect = async (...args) => (await import("../commands/reflect.js")).runReflect(...args);
53
+ const runProgress = async (...args) => (await import("../commands/progress.js")).runProgress(...args);
54
+ const runRecordDecisionCriterion = async (...args) => (await import("../commands/record-decision-criterion.js")).runRecordDecisionCriterion(...args);
55
+ const runNext = async (...args) => (await import("../commands/next.js")).runNext(...args);
56
+ const runContinuity = async (...args) => (await import("../commands/continuity.js")).runContinuity(...args);
57
+ const runRecordContinuity = async (...args) => (await import("../commands/record-continuity.js")).runRecordContinuity(...args);
58
+ const runReconcileContinuity = async (...args) => (await import("../commands/reconcile-continuity.js")).runReconcileContinuity(...args);
59
+ const runClearContinuity = async (...args) => (await import("../commands/clear-continuity.js")).runClearContinuity(...args);
60
+ const runTaskCreate = async (...args) => (await import("../commands/task-create.js")).runTaskCreate(...args);
61
+ const runDiscover = async (...args) => (await import("../commands/discover.js")).runDiscover(...args);
62
+ const runContractCreate = async (...args) => (await import("../commands/contract-create.js")).runContractCreate(...args);
63
+ const runContractRevise = async (...args) => (await import("../commands/contract-revise.js")).runContractRevise(...args);
64
+ const runGateRecord = async (...args) => (await import("../commands/gate-record.js")).runGateRecord(...args);
65
+ const runGateRevalidate = async (...args) => (await import("../commands/gate-revalidate.js")).runGateRevalidate(...args);
66
+ const runTaskList = async (...args) => (await import("../commands/task-list.js")).runTaskList(...args);
67
+ const runTaskShow = async (...args) => (await import("../commands/task-show.js")).runTaskShow(...args);
68
+ const runTaskScope = async (...args) => (await import("../commands/task-scope.js")).runTaskScope(...args);
69
+ const runTaskMigrate = async (...args) => (await import("../commands/task-migrate.js")).runTaskMigrate(...args);
70
+ const runMigrateProtocol = async (...args) => (await import("../commands/migrate-protocol.js")).runMigrateProtocol(...args);
71
+ const runTaskUnlock = async (...args) => (await import("../commands/task-unlock.js")).runTaskUnlock(...args);
72
+ const runTaskRecover = async (...args) => (await import("../commands/task-recover.js")).runTaskRecover(...args);
73
+ const runTaskAbandon = async (...args) => (await import("../commands/task-abandon.js")).runTaskAbandon(...args);
74
+ const runTaskResume = async (...args) => (await import("../commands/task-resume.js")).runTaskResume(...args);
75
+ const runTaskRepairLegacyRecovery = async (...args) => (await import("../commands/task-repair-legacy-recovery.js")).runTaskRepairLegacyRecovery(...args);
76
+ const runTaskRepairContractBootstrap = async (...args) => (await import("../commands/task-repair-contract-bootstrap.js")).runTaskRepairContractBootstrap(...args);
77
+ const runTaskMigrateContractBootstrapRepair = async (...args) => (await import("../commands/task-migrate-contract-bootstrap-repair.js")).runTaskMigrateContractBootstrapRepair(...args);
78
+ const runTaskLockStatus = async (...args) => (await import("../commands/task-lock-status.js")).runTaskLockStatus(...args);
79
+ const runProtocolInfo = async (...args) => (await import("../commands/protocol-info.js")).runProtocolInfo(...args);
80
+ const runDecisionStatus = async (...args) => (await import("../commands/decision-status.js")).runDecisionStatus(...args);
81
+ const runDecisionShow = async (...args) => (await import("../commands/decision-show.js")).runDecisionShow(...args);
82
+ const runContextPlan = async (...args) => (await import("../commands/context-plan.js")).runContextPlan(...args);
83
+ const runModelRoute = async (...args) => (await import("../commands/model-route.js")).runModelRoute(...args);
84
+ const runSemanticPlan = async (...args) => (await import("../commands/semantic-plan.js")).runSemanticPlan(...args);
85
+ const runTestInventory = async (...args) => (await import("../commands/test-inventory.js")).runTestInventory(...args);
86
+ const runTestUtility = async (...args) => (await import("../commands/test-utility.js")).runTestUtility(...args);
87
+ const runTestPrunePlan = async (...args) => (await import("../commands/test-prune-plan.js")).runTestPrunePlan(...args);
88
+ const runTestPruneProbe = async (...args) => (await import("../commands/test-prune-probe.js")).runTestPruneProbe(...args);
89
+ const runWorkspaceBind = async (...args) => (await import("../commands/workspace-bind.js")).runWorkspaceBind(...args);
90
+ const runWorkspaceStatus = async (...args) => (await import("../commands/workspace-status.js")).runWorkspaceStatus(...args);
91
+ const runHandoffCreate = async (...args) => (await import("../commands/handoff-create.js")).runHandoffCreate(...args);
92
+ const runHandoffList = async (...args) => (await import("../commands/handoff-list.js")).runHandoffList(...args);
93
+ const runHandoffShow = async (...args) => (await import("../commands/handoff-show.js")).runHandoffShow(...args);
94
+ const runHandoffAccept = async (...args) => (await import("../commands/handoff-accept.js")).runHandoffAccept(...args);
95
+ const runResponsibilitySet = async (...args) => (await import("../commands/responsibility-set.js")).runResponsibilitySet(...args);
96
+ const runResponsibilityStatus = async (...args) => (await import("../commands/responsibility-status.js")).runResponsibilityStatus(...args);
97
+ const runVerifyScope = async (...args) => (await import("../commands/verify-scope.js")).runVerifyScope(...args);
98
+ const runAttestationCreate = async (...args) => (await import("../commands/attestation-create.js")).runAttestationCreate(...args);
99
+ const runAttestationVerify = async (...args) => (await import("../commands/attestation-verify.js")).runAttestationVerify(...args);
100
+ const runAttestationStatus = async (...args) => (await import("../commands/attestation-status.js")).runAttestationStatus(...args);
101
+ const runAttestationVerifyRange = async (...args) => (await import("../commands/attestation-verify-range.js")).runAttestationVerifyRange(...args);
102
102
  import { exitCodeForAttestationResult } from "./exit-codes.js";
103
- import {
104
- runRepositoryIndexRebuild,
105
- runRepositoryIndexSetup,
106
- runRepositoryIndexStart,
107
- runRepositoryIndexStatus,
108
- runRepositoryIndexStop,
109
- runSearch,
110
- } from "../commands/repository-index.js";
103
+ const runRepositoryIndexRebuild = async (...args) => (await import("../commands/repository-index.js")).runRepositoryIndexRebuild(...args);
104
+ const runRepositoryIndexSetup = async (...args) => (await import("../commands/repository-index.js")).runRepositoryIndexSetup(...args);
105
+ const runRepositoryIndexStart = async (...args) => (await import("../commands/repository-index.js")).runRepositoryIndexStart(...args);
106
+ const runRepositoryIndexStatus = async (...args) => (await import("../commands/repository-index.js")).runRepositoryIndexStatus(...args);
107
+ const runRepositoryIndexStop = async (...args) => (await import("../commands/repository-index.js")).runRepositoryIndexStop(...args);
108
+ const runSearch = async (...args) => (await import("../commands/repository-index.js")).runSearch(...args);
111
109
 
112
110
  /**
113
111
  * Canonical transport-neutral command executors.
@@ -120,7 +118,39 @@ import {
120
118
  * The CLI renders these results; MCP and other integrations consume them
121
119
  * directly. No ownership, recovery, or lifecycle logic may live here.
122
120
  */
123
- export const COMMAND_EXECUTORS = {
121
+ const RAW_COMMAND_EXECUTORS = {
122
+ "storage-restore-resume": async ({ target, packageRoot, options }) => {
123
+ const { runStorageRestoreResume } = await import("../commands/storage-restore-resume.js");
124
+ return { result: await runStorageRestoreResume({ target, packageRoot, operationId: options.operationId, expectedOwnerId: options.expectedOwnerId, writersQuiesced: options.writersQuiesced, replaceActive: options.replaceActive }), exitCode: 0 };
125
+ },
126
+ "storage-restore": async ({ target, packageRoot, options }) => {
127
+ const { runStorageRestore } = await import("../commands/storage-restore.js");
128
+ return { result: await runStorageRestore({ target, packageRoot, source: options.source, writersQuiesced: options.writersQuiesced, replaceActive: options.replaceActive }), exitCode: 0 };
129
+ },
130
+ "storage-migration-status": async ({ target }) => {
131
+ const { runStorageMigrationStatus } = await import("../commands/storage-migration-status.js");
132
+ return { result: await runStorageMigrationStatus({ target }), exitCode: 0 };
133
+ },
134
+ "storage-migration-resume": async ({ target, packageRoot, options }) => {
135
+ const { runStorageMigrationResume } = await import("../commands/storage-migration-resume.js");
136
+ return { result: await runStorageMigrationResume({ target, packageRoot, destination: options.destination, expectedOwnerId: options.expectedOwnerId, writersQuiesced: options.writersQuiesced, acknowledgeUnboundHandoff: options.acknowledgeUnboundHandoff }), exitCode: 0 };
137
+ },
138
+ "storage-rollback-resume": async ({ target, packageRoot, options }) => {
139
+ const { resumeProjectStorageRollback } = await import("../storage/migration-rollback.js");
140
+ return { result: await resumeProjectStorageRollback(target, { packageRoot, destination: options.destination, legacyRoot: options.legacyRoot, expectedOwnerId: options.expectedOwnerId, writersQuiesced: options.writersQuiesced, nativeWritesExcluded: options.nativeWritesExcluded }), exitCode: 0 };
141
+ },
142
+ "storage-rollback": async ({ target, packageRoot, options }) => {
143
+ const { rollbackProjectStorage } = await import("../storage/migration-rollback.js");
144
+ return { result: await rollbackProjectStorage(target, { packageRoot, destination: options.destination, legacyRoot: options.legacyRoot, writersQuiesced: options.writersQuiesced, nativeWritesExcluded: options.nativeWritesExcluded }), exitCode: 0 };
145
+ },
146
+ "storage-migrate": async ({ target, packageRoot, options }) => {
147
+ const { runStorageMigrate } = await import("../commands/storage-migrate.js");
148
+ return { result: await runStorageMigrate({ target, packageRoot, destination: options.destination, writersQuiesced: options.writersQuiesced }), exitCode: 0 };
149
+ },
150
+ "storage-backup": async ({ target, options }) => {
151
+ const { runStorageBackup } = await import("../commands/storage-backup.js");
152
+ return { result: await runStorageBackup({ target, destination: options.destination, includeAttachments: options.includeAttachments }), exitCode: 0 };
153
+ },
124
154
  discover: async ({ target, packageRoot, options }) => ({
125
155
  result: await runDiscover({ target, packageRoot, taskId: options.taskId }),
126
156
  exitCode: 0,
@@ -252,6 +282,7 @@ export const COMMAND_EXECUTORS = {
252
282
  target,
253
283
  packageRoot,
254
284
  to: options.to,
285
+ persistence: runtimeContext?.forgeloopPersistence ?? null,
255
286
  taskId: options.taskId,
256
287
  authorityContext,
257
288
  runtimeContext,
@@ -495,20 +526,24 @@ export const COMMAND_EXECUTORS = {
495
526
  }),
496
527
  exitCode: 0,
497
528
  }),
498
- "record-diagnosis": async ({ target, packageRoot, options }) => ({
499
- result: await runRecordDiagnosis({
500
- target,
501
- packageRoot,
502
- file: options.file ?? null,
503
- hypothesis: options.hypothesis,
504
- failureClass: options.failureClass,
505
- evidenceRefs: options.evidenceRefs,
506
- settledBy: options.settledBy,
507
- nextSafeAction: options.nextSafeAction,
508
- taskId: options.taskId,
509
- }),
510
- exitCode: 0,
511
- }),
529
+ "record-diagnosis": async ({ target, packageRoot, options, runtimeContext }) => {
530
+ const persistence = runtimeContext?.forgeloopPersistence ?? null;
531
+ return {
532
+ result: await runRecordDiagnosis({
533
+ target,
534
+ packageRoot,
535
+ file: options.file ?? null,
536
+ hypothesis: options.hypothesis,
537
+ failureClass: options.failureClass,
538
+ evidenceRefs: options.evidenceRefs,
539
+ settledBy: options.settledBy,
540
+ nextSafeAction: options.nextSafeAction,
541
+ taskId: options.taskId,
542
+ persistence,
543
+ }),
544
+ exitCode: 0,
545
+ };
546
+ },
512
547
  "record-intervention": async ({ target, packageRoot, options }) => ({
513
548
  result: await runRecordIntervention({
514
549
  target,
@@ -720,11 +755,11 @@ export const COMMAND_EXECUTORS = {
720
755
  exitCode: 0,
721
756
  }),
722
757
  "task-migrate": async ({ target, packageRoot, options }) => ({
723
- result: await runTaskMigrate({ target, packageRoot, dryRun: options.dryRun }),
758
+ result: await runTaskMigrate({ target, packageRoot, dryRun: options.dryRun, destination: options.destination, writersQuiesced: options.writersQuiesced }),
724
759
  exitCode: 0,
725
760
  }),
726
761
  "migrate-protocol": async ({ target, packageRoot, options }) => ({
727
- result: await runMigrateProtocol({ target, packageRoot, to: options.to, dryRun: options.dryRun }),
762
+ result: await runMigrateProtocol({ target, packageRoot, to: options.to, dryRun: options.dryRun, destination: options.destination, writersQuiesced: options.writersQuiesced }),
728
763
  exitCode: 0,
729
764
  }),
730
765
  "task-unlock": async ({ target, packageRoot, options }) => ({
@@ -817,3 +852,24 @@ export const EXECUTOR_EXCEPTIONS = Object.freeze([
817
852
  // Bootstrap/presentation-only behaviors intentionally without executors:
818
853
  // none currently. Every canonical command definition must have an executor.
819
854
  ]);
855
+
856
+ export const COMMAND_EXECUTORS = Object.fromEntries(Object.entries(RAW_COMMAND_EXECUTORS).map(([name, executor]) => [name, async context => {
857
+ // Reject unsupported migration targets before fresh-project storage admission
858
+ // can allocate a database or obscure the protocol error with a storage error.
859
+ if (name === "migrate-protocol") {
860
+ const { assertSupportedProtocolMigrationTarget } = await import("./protocol-migration.js");
861
+ assertSupportedProtocolMigrationTarget(context.options?.to);
862
+ }
863
+ if (name === "advance" || name === "record-diagnosis") {
864
+ const { assertCanonicalPersistence } = await import("../storage/operational-context.js");
865
+ assertCanonicalPersistence(context.runtimeContext?.forgeloopPersistence);
866
+ }
867
+ if (!context.target || name === "task-migrate" || name === "migrate-protocol" || name === "storage-migration-status" || name === "storage-rollback-resume" || name === "storage-rollback" || name === "storage-migrate" || name === "storage-migration-resume" || name === "storage-restore" || name === "storage-restore-resume") return executor(context);
868
+ const { withProjectStorage } = await import("../storage/project-boundary.js");
869
+ const { CLI_COMMAND_DEFINITIONS } = await import("./cli-command-definitions.js");
870
+ // Backup writes its destination, not the source store. Doctor repairs only
871
+ // when explicitly requested; inspecting either must not migrate the source.
872
+ const readOnly = CLI_COMMAND_DEFINITIONS[name]?.mutation === "READ_ONLY"
873
+ || context.options?.dryRun === true || name === "storage-backup" || (name === "doctor" && context.options?.fix !== true);
874
+ return withProjectStorage(context.target, () => executor(context), { readOnly, runtimeContext: context.runtimeContext });
875
+ }]));