@rewind-ai/cli 0.6.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 (244) hide show
  1. package/.env.example +8 -0
  2. package/LICENSE +21 -0
  3. package/README.md +39 -0
  4. package/dist/src/action/capture.d.ts +15 -0
  5. package/dist/src/action/capture.js +215 -0
  6. package/dist/src/action/capture.js.map +1 -0
  7. package/dist/src/action/mediate.d.ts +28 -0
  8. package/dist/src/action/mediate.js +109 -0
  9. package/dist/src/action/mediate.js.map +1 -0
  10. package/dist/src/action/mutate.d.ts +11 -0
  11. package/dist/src/action/mutate.js +189 -0
  12. package/dist/src/action/mutate.js.map +1 -0
  13. package/dist/src/action/objects.d.ts +5 -0
  14. package/dist/src/action/objects.js +50 -0
  15. package/dist/src/action/objects.js.map +1 -0
  16. package/dist/src/action/store.d.ts +24 -0
  17. package/dist/src/action/store.js +149 -0
  18. package/dist/src/action/store.js.map +1 -0
  19. package/dist/src/action/types.d.ts +84 -0
  20. package/dist/src/action/types.js +3 -0
  21. package/dist/src/action/types.js.map +1 -0
  22. package/dist/src/action/undo.d.ts +11 -0
  23. package/dist/src/action/undo.js +42 -0
  24. package/dist/src/action/undo.js.map +1 -0
  25. package/dist/src/adapters/filesystem.d.ts +35 -0
  26. package/dist/src/adapters/filesystem.js +499 -0
  27. package/dist/src/adapters/filesystem.js.map +1 -0
  28. package/dist/src/adapters/index.d.ts +7 -0
  29. package/dist/src/adapters/index.js +19 -0
  30. package/dist/src/adapters/index.js.map +1 -0
  31. package/dist/src/adapters/types.d.ts +54 -0
  32. package/dist/src/adapters/types.js +7 -0
  33. package/dist/src/adapters/types.js.map +1 -0
  34. package/dist/src/api/server.d.ts +25 -0
  35. package/dist/src/api/server.js +786 -0
  36. package/dist/src/api/server.js.map +1 -0
  37. package/dist/src/approval/store.d.ts +35 -0
  38. package/dist/src/approval/store.js +113 -0
  39. package/dist/src/approval/store.js.map +1 -0
  40. package/dist/src/checkpoint.d.ts +9 -0
  41. package/dist/src/checkpoint.js +140 -0
  42. package/dist/src/checkpoint.js.map +1 -0
  43. package/dist/src/cli/v5.d.ts +15 -0
  44. package/dist/src/cli/v5.js +110 -0
  45. package/dist/src/cli/v5.js.map +1 -0
  46. package/dist/src/cli.d.ts +2 -0
  47. package/dist/src/cli.js +823 -0
  48. package/dist/src/cli.js.map +1 -0
  49. package/dist/src/clients/types.d.ts +90 -0
  50. package/dist/src/clients/types.js +239 -0
  51. package/dist/src/clients/types.js.map +1 -0
  52. package/dist/src/commercial/auth/provider.d.ts +61 -0
  53. package/dist/src/commercial/auth/provider.js +227 -0
  54. package/dist/src/commercial/auth/provider.js.map +1 -0
  55. package/dist/src/commercial/entitlement/provider.d.ts +27 -0
  56. package/dist/src/commercial/entitlement/provider.js +192 -0
  57. package/dist/src/commercial/entitlement/provider.js.map +1 -0
  58. package/dist/src/commercial/entitlement/signing.d.ts +61 -0
  59. package/dist/src/commercial/entitlement/signing.js +124 -0
  60. package/dist/src/commercial/entitlement/signing.js.map +1 -0
  61. package/dist/src/commercial/env.d.ts +10 -0
  62. package/dist/src/commercial/env.js +40 -0
  63. package/dist/src/commercial/env.js.map +1 -0
  64. package/dist/src/commercial/product.d.ts +26 -0
  65. package/dist/src/commercial/product.js +39 -0
  66. package/dist/src/commercial/product.js.map +1 -0
  67. package/dist/src/commercial/store.d.ts +46 -0
  68. package/dist/src/commercial/store.js +104 -0
  69. package/dist/src/commercial/store.js.map +1 -0
  70. package/dist/src/commercial/stripe/checkout.d.ts +104 -0
  71. package/dist/src/commercial/stripe/checkout.js +469 -0
  72. package/dist/src/commercial/stripe/checkout.js.map +1 -0
  73. package/dist/src/core/compatibility.d.ts +15 -0
  74. package/dist/src/core/compatibility.js +226 -0
  75. package/dist/src/core/compatibility.js.map +1 -0
  76. package/dist/src/core/engine.d.ts +33 -0
  77. package/dist/src/core/engine.js +432 -0
  78. package/dist/src/core/engine.js.map +1 -0
  79. package/dist/src/core/lifecycle.d.ts +17 -0
  80. package/dist/src/core/lifecycle.js +56 -0
  81. package/dist/src/core/lifecycle.js.map +1 -0
  82. package/dist/src/core/types.d.ts +140 -0
  83. package/dist/src/core/types.js +37 -0
  84. package/dist/src/core/types.js.map +1 -0
  85. package/dist/src/destroy.d.ts +21 -0
  86. package/dist/src/destroy.js +219 -0
  87. package/dist/src/destroy.js.map +1 -0
  88. package/dist/src/diff.d.ts +13 -0
  89. package/dist/src/diff.js +251 -0
  90. package/dist/src/diff.js.map +1 -0
  91. package/dist/src/enforcement/detect.d.ts +13 -0
  92. package/dist/src/enforcement/detect.js +75 -0
  93. package/dist/src/enforcement/detect.js.map +1 -0
  94. package/dist/src/enforcement/hook-policy.d.ts +38 -0
  95. package/dist/src/enforcement/hook-policy.js +111 -0
  96. package/dist/src/enforcement/hook-policy.js.map +1 -0
  97. package/dist/src/enforcement/index.d.ts +8 -0
  98. package/dist/src/enforcement/index.js +8 -0
  99. package/dist/src/enforcement/index.js.map +1 -0
  100. package/dist/src/enforcement/perf.d.ts +6 -0
  101. package/dist/src/enforcement/perf.js +18 -0
  102. package/dist/src/enforcement/perf.js.map +1 -0
  103. package/dist/src/enforcement/policy.d.ts +12 -0
  104. package/dist/src/enforcement/policy.js +84 -0
  105. package/dist/src/enforcement/policy.js.map +1 -0
  106. package/dist/src/enforcement/readonly.d.ts +17 -0
  107. package/dist/src/enforcement/readonly.js +124 -0
  108. package/dist/src/enforcement/readonly.js.map +1 -0
  109. package/dist/src/enforcement/sandbox-clone.d.ts +6 -0
  110. package/dist/src/enforcement/sandbox-clone.js +11 -0
  111. package/dist/src/enforcement/sandbox-clone.js.map +1 -0
  112. package/dist/src/enforcement/setup.d.ts +33 -0
  113. package/dist/src/enforcement/setup.js +168 -0
  114. package/dist/src/enforcement/setup.js.map +1 -0
  115. package/dist/src/enforcement/trust.d.ts +10 -0
  116. package/dist/src/enforcement/trust.js +71 -0
  117. package/dist/src/enforcement/trust.js.map +1 -0
  118. package/dist/src/enforcement/types.d.ts +40 -0
  119. package/dist/src/enforcement/types.js +3 -0
  120. package/dist/src/enforcement/types.js.map +1 -0
  121. package/dist/src/entitlement/provider.d.ts +48 -0
  122. package/dist/src/entitlement/provider.js +95 -0
  123. package/dist/src/entitlement/provider.js.map +1 -0
  124. package/dist/src/hash.d.ts +9 -0
  125. package/dist/src/hash.js +23 -0
  126. package/dist/src/hash.js.map +1 -0
  127. package/dist/src/ledger/query.d.ts +19 -0
  128. package/dist/src/ledger/query.js +158 -0
  129. package/dist/src/ledger/query.js.map +1 -0
  130. package/dist/src/manifest.d.ts +32 -0
  131. package/dist/src/manifest.js +242 -0
  132. package/dist/src/manifest.js.map +1 -0
  133. package/dist/src/mcp/server.d.ts +7 -0
  134. package/dist/src/mcp/server.js +364 -0
  135. package/dist/src/mcp/server.js.map +1 -0
  136. package/dist/src/paths.d.ts +94 -0
  137. package/dist/src/paths.js +354 -0
  138. package/dist/src/paths.js.map +1 -0
  139. package/dist/src/permission/engine.d.ts +15 -0
  140. package/dist/src/permission/engine.js +147 -0
  141. package/dist/src/permission/engine.js.map +1 -0
  142. package/dist/src/permission/types.d.ts +42 -0
  143. package/dist/src/permission/types.js +3 -0
  144. package/dist/src/permission/types.js.map +1 -0
  145. package/dist/src/product/setup.d.ts +35 -0
  146. package/dist/src/product/setup.js +300 -0
  147. package/dist/src/product/setup.js.map +1 -0
  148. package/dist/src/protect/audit.d.ts +5 -0
  149. package/dist/src/protect/audit.js +26 -0
  150. package/dist/src/protect/audit.js.map +1 -0
  151. package/dist/src/protect/capture.d.ts +7 -0
  152. package/dist/src/protect/capture.js +250 -0
  153. package/dist/src/protect/capture.js.map +1 -0
  154. package/dist/src/protect/fingerprint.d.ts +4 -0
  155. package/dist/src/protect/fingerprint.js +49 -0
  156. package/dist/src/protect/fingerprint.js.map +1 -0
  157. package/dist/src/protect/hook-cli.d.ts +2 -0
  158. package/dist/src/protect/hook-cli.js +107 -0
  159. package/dist/src/protect/hook-cli.js.map +1 -0
  160. package/dist/src/protect/index.d.ts +12 -0
  161. package/dist/src/protect/index.js +12 -0
  162. package/dist/src/protect/index.js.map +1 -0
  163. package/dist/src/protect/install.d.ts +34 -0
  164. package/dist/src/protect/install.js +293 -0
  165. package/dist/src/protect/install.js.map +1 -0
  166. package/dist/src/protect/intercept.d.ts +11 -0
  167. package/dist/src/protect/intercept.js +390 -0
  168. package/dist/src/protect/intercept.js.map +1 -0
  169. package/dist/src/protect/protect.d.ts +17 -0
  170. package/dist/src/protect/protect.js +194 -0
  171. package/dist/src/protect/protect.js.map +1 -0
  172. package/dist/src/protect/root-paths.d.ts +13 -0
  173. package/dist/src/protect/root-paths.js +140 -0
  174. package/dist/src/protect/root-paths.js.map +1 -0
  175. package/dist/src/protect/shell-policy.d.ts +17 -0
  176. package/dist/src/protect/shell-policy.js +269 -0
  177. package/dist/src/protect/shell-policy.js.map +1 -0
  178. package/dist/src/protect/status.d.ts +11 -0
  179. package/dist/src/protect/status.js +165 -0
  180. package/dist/src/protect/status.js.map +1 -0
  181. package/dist/src/protect/store.d.ts +20 -0
  182. package/dist/src/protect/store.js +170 -0
  183. package/dist/src/protect/store.js.map +1 -0
  184. package/dist/src/protect/types.d.ts +116 -0
  185. package/dist/src/protect/types.js +3 -0
  186. package/dist/src/protect/types.js.map +1 -0
  187. package/dist/src/protect/undo-session.d.ts +14 -0
  188. package/dist/src/protect/undo-session.js +182 -0
  189. package/dist/src/protect/undo-session.js.map +1 -0
  190. package/dist/src/restore.d.ts +39 -0
  191. package/dist/src/restore.js +141 -0
  192. package/dist/src/restore.js.map +1 -0
  193. package/dist/src/sandbox.d.ts +23 -0
  194. package/dist/src/sandbox.js +198 -0
  195. package/dist/src/sandbox.js.map +1 -0
  196. package/dist/src/session/ambient.d.ts +10 -0
  197. package/dist/src/session/ambient.js +53 -0
  198. package/dist/src/session/ambient.js.map +1 -0
  199. package/dist/src/session/attribution.d.ts +27 -0
  200. package/dist/src/session/attribution.js +201 -0
  201. package/dist/src/session/attribution.js.map +1 -0
  202. package/dist/src/session/index.d.ts +25 -0
  203. package/dist/src/session/index.js +472 -0
  204. package/dist/src/session/index.js.map +1 -0
  205. package/dist/src/session/process.d.ts +34 -0
  206. package/dist/src/session/process.js +234 -0
  207. package/dist/src/session/process.js.map +1 -0
  208. package/dist/src/session/store.d.ts +14 -0
  209. package/dist/src/session/store.js +125 -0
  210. package/dist/src/session/store.js.map +1 -0
  211. package/dist/src/session/types.d.ts +111 -0
  212. package/dist/src/session/types.js +3 -0
  213. package/dist/src/session/types.js.map +1 -0
  214. package/dist/src/session/watcher.d.ts +32 -0
  215. package/dist/src/session/watcher.js +186 -0
  216. package/dist/src/session/watcher.js.map +1 -0
  217. package/dist/src/timing.d.ts +7 -0
  218. package/dist/src/timing.js +19 -0
  219. package/dist/src/timing.js.map +1 -0
  220. package/dist/src/types.d.ts +101 -0
  221. package/dist/src/types.js +3 -0
  222. package/dist/src/types.js.map +1 -0
  223. package/dist/src/verify.d.ts +8 -0
  224. package/dist/src/verify.js +126 -0
  225. package/dist/src/verify.js.map +1 -0
  226. package/docs/ADAPTERS.md +37 -0
  227. package/docs/APPROVALS.md +32 -0
  228. package/docs/ARCHITECTURE.md +57 -0
  229. package/docs/ATTRIBUTION.md +179 -0
  230. package/docs/COMMERCIAL.md +51 -0
  231. package/docs/CURSOR-ENFORCEMENT.md +73 -0
  232. package/docs/ENFORCEMENT.md +134 -0
  233. package/docs/FUTURE.md +91 -0
  234. package/docs/HUMAN-SETUP.md +98 -0
  235. package/docs/IDENTITY-AUTHORITY.md +35 -0
  236. package/docs/MCP.md +107 -0
  237. package/docs/PACKAGING.md +77 -0
  238. package/docs/PERMISSIONS.md +53 -0
  239. package/docs/PRODUCT-V5.md +63 -0
  240. package/docs/PRODUCT-V6.md +69 -0
  241. package/docs/PROTECTED-SESSIONS.md +155 -0
  242. package/docs/THREAT-MODEL.md +84 -0
  243. package/docs/TRANSACTIONS.md +57 -0
  244. package/package.json +85 -0
@@ -0,0 +1,432 @@
1
+ /**
2
+ * V5 transaction engine — single authoritative mediated execution path.
3
+ *
4
+ * MCP / CLI / API → prepare → permission → adapter → before → mutate → after
5
+ */
6
+ import path from "node:path";
7
+ import { randomBytes } from "node:crypto";
8
+ import { mkdir, writeFile, rename, readFile } from "node:fs/promises";
9
+ import { getProjectRoot, getRewindHome, PathSafetyError, } from "../paths.js";
10
+ import { getAdapter } from "../adapters/index.js";
11
+ import { nextSequence, saveAction, loadAction, newActionId, listActions, } from "../action/store.js";
12
+ import { markAuthoritative } from "../enforcement/trust.js";
13
+ import { actionRecordToTransaction, transactionToActionRecord, } from "./compatibility.js";
14
+ import { assertTransition, isCrashRecoverableIncomplete } from "./lifecycle.js";
15
+ import { emptyUndoInfo, unknownAuthority, TRANSACTION_MODEL_VERSION, } from "./types.js";
16
+ import { decidePermission } from "../permission/engine.js";
17
+ import { deletePendingApproval, fingerprintState, loadPendingApproval, savePendingApproval, } from "../approval/store.js";
18
+ import { requireMediationEntitlement } from "../entitlement/provider.js";
19
+ export class TransactionEngineError extends Error {
20
+ code;
21
+ transaction;
22
+ name = "TransactionEngineError";
23
+ constructor(message, code, transaction) {
24
+ super(message);
25
+ this.code = code;
26
+ this.transaction = transaction;
27
+ }
28
+ }
29
+ function newApprovalId() {
30
+ return `appr_${randomBytes(8).toString("hex")}`;
31
+ }
32
+ function ensureProjectRoot(intent, projectRoot) {
33
+ return {
34
+ ...intent,
35
+ metadata: {
36
+ ...(intent.metadata ?? {}),
37
+ projectRoot,
38
+ },
39
+ };
40
+ }
41
+ async function writeJsonAtomic(file, data) {
42
+ await mkdir(path.dirname(file), { recursive: true });
43
+ const tmp = `${file}.tmp-${process.pid}`;
44
+ await writeFile(tmp, JSON.stringify(data, null, 2) + "\n", "utf8");
45
+ await rename(tmp, file);
46
+ }
47
+ function overlayPath(id, projectRoot) {
48
+ return path.join(getRewindHome(projectRoot), "transactions", `${id}.json`);
49
+ }
50
+ async function saveTransactionOverlay(txn, projectRoot) {
51
+ await writeJsonAtomic(overlayPath(txn.id, projectRoot), txn);
52
+ }
53
+ async function persistFsTransaction(txn, projectRoot) {
54
+ await saveTransactionOverlay(txn, projectRoot);
55
+ if (txn.adapter !== "filesystem")
56
+ return;
57
+ const action = transactionToActionRecord(txn);
58
+ if (txn.status === "AWAITING_APPROVAL") {
59
+ action.status = "PREPARED";
60
+ action.error = "AWAITING_APPROVAL";
61
+ }
62
+ else if (txn.status === "DENIED") {
63
+ action.status = "FAILED";
64
+ action.error = txn.error ?? "DENIED by policy";
65
+ }
66
+ else if (txn.status === "UNDOING") {
67
+ action.status = "EXECUTING";
68
+ }
69
+ await saveAction(action, projectRoot);
70
+ }
71
+ export async function loadTransaction(id, projectRoot = getProjectRoot()) {
72
+ try {
73
+ const raw = await readFile(overlayPath(id, projectRoot), "utf8");
74
+ const txn = JSON.parse(raw);
75
+ if (txn.version === TRANSACTION_MODEL_VERSION) {
76
+ txn.metadata = { ...txn.metadata, projectRoot };
77
+ return txn;
78
+ }
79
+ }
80
+ catch {
81
+ /* fall through to v2 action ledger */
82
+ }
83
+ const action = await loadAction(id, projectRoot);
84
+ const txn = actionRecordToTransaction(action);
85
+ txn.metadata = { ...txn.metadata, projectRoot };
86
+ return txn;
87
+ }
88
+ function transition(txn, to) {
89
+ assertTransition(txn.status, to);
90
+ txn.status = to;
91
+ }
92
+ /**
93
+ * Execute a mediated transaction through the V5 core.
94
+ */
95
+ export async function executeTransaction(rawIntent, projectRoot = getProjectRoot(), options = {}) {
96
+ const throwOnDeny = options.throwOnDeny !== false;
97
+ await requireMediationEntitlement();
98
+ const intent = ensureProjectRoot(rawIntent, projectRoot);
99
+ const adapter = getAdapter(intent.adapter);
100
+ const validation = await adapter.validateOperation(intent);
101
+ if (!validation.ok) {
102
+ throw new PathSafetyError(validation.error ?? "Validation failed");
103
+ }
104
+ const target = validation.target;
105
+ intent.target = target;
106
+ const prepare = await adapter.captureBefore(intent);
107
+ let txn;
108
+ if (options.existingId) {
109
+ txn = await loadTransaction(options.existingId, projectRoot);
110
+ txn.before = prepare.before;
111
+ txn.target = target;
112
+ txn.operation = intent.operation;
113
+ txn.reversibility = {
114
+ class: prepare.reversibility,
115
+ strategy: prepare.strategy,
116
+ expectedState: null,
117
+ };
118
+ if (prepare.legacyTool)
119
+ txn.legacyTool = prepare.legacyTool;
120
+ txn.metadata = { ...txn.metadata, projectRoot };
121
+ if (txn.status === "AWAITING_APPROVAL") {
122
+ transition(txn, "PREPARED");
123
+ }
124
+ }
125
+ else {
126
+ const client = {
127
+ name: intent.actor.client,
128
+ version: intent.actor.clientVersion ?? "unknown",
129
+ };
130
+ const { session, sequence } = await nextSequence(projectRoot, client);
131
+ txn = {
132
+ id: newActionId(),
133
+ version: TRANSACTION_MODEL_VERSION,
134
+ sequence,
135
+ sessionId: intent.sessionId ?? session.id,
136
+ createdAt: new Date().toISOString(),
137
+ completedAt: null,
138
+ actor: intent.actor,
139
+ authority: intent.authority ?? unknownAuthority(),
140
+ source: intent.source,
141
+ adapter: intent.adapter,
142
+ operation: intent.operation,
143
+ target,
144
+ before: prepare.before,
145
+ after: null,
146
+ reversibility: {
147
+ class: prepare.reversibility,
148
+ strategy: prepare.strategy,
149
+ expectedState: null,
150
+ },
151
+ permission: null,
152
+ status: "PREPARED",
153
+ dependencies: [],
154
+ undo: emptyUndoInfo(),
155
+ error: null,
156
+ sandbox: intent.sandbox ?? null,
157
+ legacyTool: prepare.legacyTool ?? null,
158
+ metadata: { ...(intent.metadata ?? {}), projectRoot },
159
+ };
160
+ }
161
+ await persistFsTransaction(txn, projectRoot);
162
+ if (!options.fromApproval && !intent.bypassPermission) {
163
+ const perm = await decidePermission({
164
+ intent,
165
+ projectRoot,
166
+ resource: target.resource,
167
+ reversibility: prepare.reversibility,
168
+ });
169
+ txn.permission = {
170
+ decision: perm.decision,
171
+ reason: perm.reason,
172
+ policyId: perm.policyId,
173
+ evaluatedAt: perm.evaluatedAt,
174
+ };
175
+ if (perm.decision === "DENY") {
176
+ transition(txn, "DENIED");
177
+ txn.completedAt = new Date().toISOString();
178
+ txn.error = perm.reason;
179
+ await persistFsTransaction(txn, projectRoot);
180
+ if (throwOnDeny) {
181
+ throw new TransactionEngineError(`DENIED: ${perm.reason}`, "DENIED", txn);
182
+ }
183
+ return txn;
184
+ }
185
+ if (perm.decision === "ASK") {
186
+ transition(txn, "AWAITING_APPROVAL");
187
+ const inspected = await adapter.inspectCurrent(intent);
188
+ const pending = {
189
+ id: newApprovalId(),
190
+ createdAt: new Date().toISOString(),
191
+ transactionId: txn.id,
192
+ intent,
193
+ stateFingerprint: fingerprintState(inspected),
194
+ capturedBefore: prepare.before,
195
+ reason: perm.reason,
196
+ policyId: perm.policyId,
197
+ reversibilityClass: prepare.reversibility,
198
+ risk: null,
199
+ };
200
+ await savePendingApproval(pending, projectRoot);
201
+ txn.metadata = {
202
+ ...txn.metadata,
203
+ pendingApprovalId: pending.id,
204
+ };
205
+ await persistFsTransaction(txn, projectRoot);
206
+ return txn;
207
+ }
208
+ }
209
+ else if (!txn.permission || options.fromApproval) {
210
+ txn.permission = {
211
+ decision: "ALLOW",
212
+ reason: options.fromApproval ? "human_approved" : "bypass_permission",
213
+ policyId: txn.permission?.policyId ?? null,
214
+ evaluatedAt: new Date().toISOString(),
215
+ };
216
+ }
217
+ transition(txn, "EXECUTING");
218
+ await persistFsTransaction(txn, projectRoot);
219
+ try {
220
+ const result = await adapter.execute(intent, txn);
221
+ txn.after = result.after;
222
+ if (txn.after.kind === "filesystem") {
223
+ txn.reversibility.expectedState = txn.after.primary.hash;
224
+ }
225
+ transition(txn, "COMPLETED");
226
+ txn.completedAt = new Date().toISOString();
227
+ txn.error = null;
228
+ txn.undo = {
229
+ status: txn.reversibility.class === "REVERSIBLE" ? "READY" : "NONE",
230
+ attemptedAt: null,
231
+ result: null,
232
+ conflict: null,
233
+ };
234
+ await persistFsTransaction(txn, projectRoot);
235
+ if (txn.adapter === "filesystem") {
236
+ await markAuthoritative(txn.target.resource, txn.id, projectRoot).catch(() => undefined);
237
+ if (txn.target.secondary) {
238
+ await markAuthoritative(txn.target.secondary, txn.id, projectRoot).catch(() => undefined);
239
+ }
240
+ }
241
+ return txn;
242
+ }
243
+ catch (err) {
244
+ transition(txn, "FAILED");
245
+ txn.error = err instanceof Error ? err.message : String(err);
246
+ txn.completedAt = new Date().toISOString();
247
+ await persistFsTransaction(txn, projectRoot);
248
+ throw err instanceof Error ? err : new Error(String(err));
249
+ }
250
+ }
251
+ export async function approvePending(approvalId, projectRoot = getProjectRoot()) {
252
+ const pending = await loadPendingApproval(approvalId, projectRoot);
253
+ const adapter = getAdapter(pending.intent.adapter);
254
+ const intent = ensureProjectRoot(pending.intent, projectRoot);
255
+ const current = await adapter.inspectCurrent(intent);
256
+ const fp = fingerprintState(current);
257
+ if (fp !== pending.stateFingerprint) {
258
+ const txn = await loadTransaction(pending.transactionId, projectRoot);
259
+ if (txn.status === "AWAITING_APPROVAL") {
260
+ transition(txn, "FAILED");
261
+ }
262
+ else {
263
+ txn.status = "FAILED";
264
+ }
265
+ txn.error =
266
+ "Approval refused: target state changed while waiting (TOCTOU revalidation)";
267
+ txn.completedAt = new Date().toISOString();
268
+ await persistFsTransaction(txn, projectRoot);
269
+ await deletePendingApproval(approvalId, projectRoot);
270
+ throw new TransactionEngineError(txn.error, "CONFLICT", txn);
271
+ }
272
+ const validation = await adapter.validateOperation(intent);
273
+ if (!validation.ok) {
274
+ await deletePendingApproval(approvalId, projectRoot);
275
+ throw new TransactionEngineError(validation.error ?? "Revalidation failed", "VALIDATION");
276
+ }
277
+ await deletePendingApproval(approvalId, projectRoot);
278
+ return executeTransaction(intent, projectRoot, {
279
+ existingId: pending.transactionId,
280
+ fromApproval: true,
281
+ });
282
+ }
283
+ export async function denyPending(approvalId, projectRoot = getProjectRoot()) {
284
+ const pending = await loadPendingApproval(approvalId, projectRoot);
285
+ const txn = await loadTransaction(pending.transactionId, projectRoot);
286
+ if (txn.status !== "AWAITING_APPROVAL") {
287
+ throw new TransactionEngineError(`Transaction ${txn.id} is ${txn.status}, not AWAITING_APPROVAL`, "INVALID_STATE", txn);
288
+ }
289
+ transition(txn, "DENIED");
290
+ txn.completedAt = new Date().toISOString();
291
+ txn.error = "Denied by human approval";
292
+ txn.permission = {
293
+ decision: "DENY",
294
+ reason: "human_denied",
295
+ policyId: pending.policyId,
296
+ evaluatedAt: new Date().toISOString(),
297
+ };
298
+ await persistFsTransaction(txn, projectRoot);
299
+ await deletePendingApproval(approvalId, projectRoot);
300
+ return txn;
301
+ }
302
+ export async function undoTransaction(id, projectRoot = getProjectRoot()) {
303
+ // INVARIANT: never paywall undo of already-recorded work.
304
+ const { requireUndoEntitlement } = await import("../entitlement/provider.js");
305
+ await requireUndoEntitlement();
306
+ const txn = await loadTransaction(id, projectRoot);
307
+ txn.metadata = { ...txn.metadata, projectRoot };
308
+ if (txn.status === "UNDONE") {
309
+ return {
310
+ ok: false,
311
+ conflict: false,
312
+ transaction: txn,
313
+ message: `Transaction ${id} is already UNDONE.`,
314
+ };
315
+ }
316
+ if (txn.status !== "COMPLETED") {
317
+ return {
318
+ ok: false,
319
+ conflict: false,
320
+ transaction: txn,
321
+ message: `Transaction ${id} status is ${txn.status}; only COMPLETED can be undone.`,
322
+ };
323
+ }
324
+ if (txn.reversibility.class !== "REVERSIBLE") {
325
+ return {
326
+ ok: false,
327
+ conflict: false,
328
+ transaction: txn,
329
+ message: `Transaction ${id} is ${txn.reversibility.class}; cannot undo.`,
330
+ };
331
+ }
332
+ const adapter = getAdapter(txn.adapter);
333
+ const match = await adapter.compareExpectedCurrent(txn);
334
+ if (!match.matches) {
335
+ transition(txn, "CONFLICTED");
336
+ txn.undo = {
337
+ status: "CONFLICTED",
338
+ attemptedAt: new Date().toISOString(),
339
+ result: "conflict",
340
+ conflict: {
341
+ expected: match.expected,
342
+ actual: match.actual,
343
+ message: `UNDO CONFLICT\n\n` +
344
+ `Transaction: ${txn.id}\n` +
345
+ `Target: ${txn.target.resource}${txn.target.secondary ? ` → ${txn.target.secondary}` : ""}\n\n` +
346
+ `Expected current hash:\n${match.expected}\n\n` +
347
+ `Actual current hash:\n${match.actual}\n\n` +
348
+ `The target changed after this action.\n` +
349
+ `Automatic undo has been blocked to protect newer work.\n` +
350
+ `Do NOT overwrite.`,
351
+ },
352
+ };
353
+ await persistFsTransaction(txn, projectRoot);
354
+ return {
355
+ ok: false,
356
+ conflict: true,
357
+ transaction: txn,
358
+ message: txn.undo.conflict.message,
359
+ };
360
+ }
361
+ transition(txn, "UNDOING");
362
+ txn.undo.status = "UNDOING";
363
+ txn.undo.attemptedAt = new Date().toISOString();
364
+ await persistFsTransaction(txn, projectRoot);
365
+ const reversed = await adapter.reverse(txn);
366
+ if (!reversed.ok) {
367
+ transition(txn, "FAILED");
368
+ txn.error = reversed.error ?? "Undo failed";
369
+ txn.undo.status = "REFUSED";
370
+ txn.undo.result = "failed";
371
+ await persistFsTransaction(txn, projectRoot);
372
+ return {
373
+ ok: false,
374
+ conflict: false,
375
+ transaction: txn,
376
+ message: txn.error,
377
+ };
378
+ }
379
+ transition(txn, "UNDONE");
380
+ txn.undo.status = "UNDONE";
381
+ txn.undo.result = "ok";
382
+ await persistFsTransaction(txn, projectRoot);
383
+ return {
384
+ ok: true,
385
+ conflict: false,
386
+ transaction: txn,
387
+ message: `Undone ${txn.id}: ${txn.target.resource} restored to before-state.`,
388
+ };
389
+ }
390
+ export async function recoverIncompleteTransactions(projectRoot = getProjectRoot()) {
391
+ const actions = await listActions(projectRoot);
392
+ let n = 0;
393
+ for (const a of actions) {
394
+ let overlayStatus = null;
395
+ try {
396
+ const raw = await readFile(overlayPath(a.id, projectRoot), "utf8");
397
+ const overlay = JSON.parse(raw);
398
+ if (overlay.version === TRANSACTION_MODEL_VERSION) {
399
+ overlayStatus = overlay.status;
400
+ }
401
+ }
402
+ catch {
403
+ /* no overlay */
404
+ }
405
+ // Pending approvals are intentional — never crash-recover them away.
406
+ if (overlayStatus === "AWAITING_APPROVAL" ||
407
+ a.error === "AWAITING_APPROVAL") {
408
+ continue;
409
+ }
410
+ const actionIncomplete = isCrashRecoverableIncomplete(a.status);
411
+ const overlayIncomplete = overlayStatus !== null && isCrashRecoverableIncomplete(overlayStatus);
412
+ // Trust either ledger: tests may mutate act_*.json after a completed
413
+ // overlay write; real crashes leave both incomplete.
414
+ if (!actionIncomplete && !overlayIncomplete)
415
+ continue;
416
+ a.status = "FAILED";
417
+ a.error =
418
+ a.error ?? "Incomplete action recovered on startup (crash safety)";
419
+ a.completedAt = new Date().toISOString();
420
+ await saveAction(a, projectRoot);
421
+ const txn = actionRecordToTransaction(a);
422
+ txn.status = "FAILED";
423
+ txn.metadata = { projectRoot };
424
+ await saveTransactionOverlay(txn, projectRoot);
425
+ n++;
426
+ }
427
+ return n;
428
+ }
429
+ export function transactionToLegacyAction(txn) {
430
+ return transactionToActionRecord(txn);
431
+ }
432
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/core/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Validated transaction status transitions.
3
+ * Impossible transitions throw — fail loudly.
4
+ */
5
+ import type { TransactionStatus } from "./types.js";
6
+ export declare class InvalidTransitionError extends Error {
7
+ readonly from: TransactionStatus;
8
+ readonly to: TransactionStatus;
9
+ readonly name = "InvalidTransitionError";
10
+ constructor(from: TransactionStatus, to: TransactionStatus);
11
+ }
12
+ export declare function canTransition(from: TransactionStatus, to: TransactionStatus): boolean;
13
+ export declare function assertTransition(from: TransactionStatus, to: TransactionStatus): void;
14
+ /** Statuses that crash recovery may mark FAILED. */
15
+ export declare function isIncompleteStatus(status: TransactionStatus): boolean;
16
+ /** AWAITING_APPROVAL is intentional pending work — not crash debris. */
17
+ export declare function isCrashRecoverableIncomplete(status: TransactionStatus): boolean;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Validated transaction status transitions.
3
+ * Impossible transitions throw — fail loudly.
4
+ */
5
+ export class InvalidTransitionError extends Error {
6
+ from;
7
+ to;
8
+ name = "InvalidTransitionError";
9
+ constructor(from, to) {
10
+ super(`Invalid transaction transition: ${from} → ${to}`);
11
+ this.from = from;
12
+ this.to = to;
13
+ }
14
+ }
15
+ const ALLOWED = {
16
+ PREPARED: new Set([
17
+ "AWAITING_APPROVAL",
18
+ "DENIED",
19
+ "EXECUTING",
20
+ "FAILED",
21
+ ]),
22
+ AWAITING_APPROVAL: new Set([
23
+ "PREPARED", // revalidation reset before execute
24
+ "DENIED",
25
+ "EXECUTING",
26
+ "FAILED",
27
+ ]),
28
+ DENIED: new Set(), // terminal
29
+ EXECUTING: new Set(["COMPLETED", "FAILED"]),
30
+ COMPLETED: new Set(["UNDOING", "CONFLICTED"]),
31
+ FAILED: new Set(), // terminal (crash recovery marks incomplete → FAILED)
32
+ UNDOING: new Set(["UNDONE", "FAILED", "CONFLICTED"]),
33
+ UNDONE: new Set(), // terminal
34
+ CONFLICTED: new Set(), // terminal — newer work wins; no silent overwrite
35
+ };
36
+ export function canTransition(from, to) {
37
+ if (from === to)
38
+ return true;
39
+ return ALLOWED[from]?.has(to) ?? false;
40
+ }
41
+ export function assertTransition(from, to) {
42
+ if (!canTransition(from, to)) {
43
+ throw new InvalidTransitionError(from, to);
44
+ }
45
+ }
46
+ /** Statuses that crash recovery may mark FAILED. */
47
+ export function isIncompleteStatus(status) {
48
+ return (status === "PREPARED" ||
49
+ status === "EXECUTING" ||
50
+ status === "UNDOING");
51
+ }
52
+ /** AWAITING_APPROVAL is intentional pending work — not crash debris. */
53
+ export function isCrashRecoverableIncomplete(status) {
54
+ return status === "PREPARED" || status === "EXECUTING" || status === "UNDOING";
55
+ }
56
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../../src/core/lifecycle.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAG7B;IACA;IAHA,IAAI,GAAG,wBAAwB,CAAC;IAClD,YACkB,IAAuB,EACvB,EAAqB;QAErC,KAAK,CAAC,mCAAmC,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;QAHzC,SAAI,GAAJ,IAAI,CAAmB;QACvB,OAAE,GAAF,EAAE,CAAmB;IAGvC,CAAC;CACF;AAED,MAAM,OAAO,GAA8D;IACzE,QAAQ,EAAE,IAAI,GAAG,CAAC;QAChB,mBAAmB;QACnB,QAAQ;QACR,WAAW;QACX,QAAQ;KACT,CAAC;IACF,iBAAiB,EAAE,IAAI,GAAG,CAAC;QACzB,UAAU,EAAE,oCAAoC;QAChD,QAAQ;QACR,WAAW;QACX,QAAQ;KACT,CAAC;IACF,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,WAAW;IAC9B,SAAS,EAAE,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAC3C,SAAS,EAAE,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAC7C,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,sDAAsD;IACzE,OAAO,EAAE,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IACpD,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,WAAW;IAC9B,UAAU,EAAE,IAAI,GAAG,EAAE,EAAE,kDAAkD;CAC1E,CAAC;AAEF,MAAM,UAAU,aAAa,CAC3B,IAAuB,EACvB,EAAqB;IAErB,IAAI,IAAI,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAC7B,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,IAAuB,EACvB,EAAqB;IAErB,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,sBAAsB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,kBAAkB,CAAC,MAAyB;IAC1D,OAAO,CACL,MAAM,KAAK,UAAU;QACrB,MAAM,KAAK,WAAW;QACtB,MAAM,KAAK,SAAS,CACrB,CAAC;AACJ,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,4BAA4B,CAC1C,MAAyB;IAEzB,OAAO,MAAM,KAAK,UAAU,IAAI,MAAM,KAAK,WAAW,IAAI,MAAM,KAAK,SAAS,CAAC;AACjF,CAAC"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * REWIND V5 — general transaction domain model.
3
+ *
4
+ * Filesystem ActionRecord (v2) remains the on-disk ledger shape for mediated
5
+ * FS actions. Transaction (v5) is the in-memory / query / adapter-facing model.
6
+ * See compatibility.ts for mapping. Do not treat planned adapters as shipped.
7
+ */
8
+ import type { EntrySnapshot } from "../action/types.js";
9
+ import type { SandboxName } from "../paths.js";
10
+ export declare const TRANSACTION_MODEL_VERSION: 5;
11
+ /** Lifecycle states for a mediated transaction. */
12
+ export type TransactionStatus = "PREPARED" | "AWAITING_APPROVAL" | "DENIED" | "EXECUTING" | "COMPLETED" | "FAILED" | "UNDOING" | "UNDONE" | "CONFLICTED";
13
+ /**
14
+ * Reversibility semantics.
15
+ * COMPENSATABLE is reserved for future adapters that implement compensation.
16
+ * Do not claim compensation unless an adapter actually provides a strategy.
17
+ */
18
+ export type ReversibilityClass = "REVERSIBLE" | "COMPENSATABLE" | "APPROVAL_REQUIRED" | "IRREVERSIBLE";
19
+ export type PermissionDecision = "ALLOW" | "ASK" | "DENY";
20
+ export type ActorType = "mcp_client" | "cli" | "api" | "protect" | "unknown";
21
+ export type TransactionSource = "MCP" | "CLI" | "API" | "PROTECT" | "UNKNOWN";
22
+ export type AdapterId = "filesystem" | (string & {});
23
+ export type TargetType = "file" | "directory" | "path" | "resource" | (string & {});
24
+ /** Which client/agent requested the action — not human identity. */
25
+ export interface Actor {
26
+ type: ActorType;
27
+ client: string;
28
+ clientVersion: string | null;
29
+ /** Opaque identity string when a host supplies one. Never invent a human. */
30
+ identity: string | null;
31
+ }
32
+ /**
33
+ * Delegated authority foundation.
34
+ * V5: typically UNKNOWN — do not fabricate a human principal.
35
+ */
36
+ export interface Authority {
37
+ status: "UNKNOWN" | "UNSPECIFIED" | "DELEGATED";
38
+ principal: string | null;
39
+ scope: string | null;
40
+ constraints: string[];
41
+ expiresAt: string | null;
42
+ /** Reserved for future spend/action limits — unused in V5. */
43
+ limits: Record<string, number> | null;
44
+ /** Reserved for future delegation chain — unused in V5. */
45
+ delegationChain: string[] | null;
46
+ }
47
+ export interface TransactionTarget {
48
+ type: TargetType;
49
+ /** Adapter-specific resource locator (e.g. sandbox-relative path). */
50
+ resource: string;
51
+ displayName: string | null;
52
+ /** Secondary resource (e.g. move destination). */
53
+ secondary: string | null;
54
+ }
55
+ export interface PermissionRecord {
56
+ decision: PermissionDecision;
57
+ reason: string | null;
58
+ policyId: string | null;
59
+ evaluatedAt: string;
60
+ }
61
+ export interface ReversibilityInfo {
62
+ class: ReversibilityClass;
63
+ /** Named strategy when adapter-specific (e.g. "restore_snapshot"). */
64
+ strategy: string | null;
65
+ /** Adapter-opaque expected post-state fingerprint for conflict checks. */
66
+ expectedState: string | null;
67
+ }
68
+ export interface UndoInfo {
69
+ status: "NONE" | "READY" | "UNDOING" | "UNDONE" | "CONFLICTED" | "REFUSED";
70
+ attemptedAt: string | null;
71
+ result: string | null;
72
+ conflict: {
73
+ expected: string | null;
74
+ actual: string | null;
75
+ message: string;
76
+ } | null;
77
+ }
78
+ /**
79
+ * Adapter-specific before/after payloads.
80
+ * Filesystem uses EntrySnapshot; other adapters will use their own shapes.
81
+ */
82
+ export type AdapterStatePayload = {
83
+ kind: "filesystem";
84
+ primary: EntrySnapshot;
85
+ secondary: EntrySnapshot | null;
86
+ } | {
87
+ kind: "opaque";
88
+ data: unknown;
89
+ };
90
+ export interface Transaction {
91
+ id: string;
92
+ version: typeof TRANSACTION_MODEL_VERSION;
93
+ sequence: number;
94
+ sessionId: string;
95
+ createdAt: string;
96
+ completedAt: string | null;
97
+ actor: Actor;
98
+ authority: Authority;
99
+ source: TransactionSource;
100
+ adapter: AdapterId;
101
+ operation: string;
102
+ target: TransactionTarget;
103
+ before: AdapterStatePayload | null;
104
+ after: AdapterStatePayload | null;
105
+ reversibility: ReversibilityInfo;
106
+ permission: PermissionRecord | null;
107
+ status: TransactionStatus;
108
+ dependencies: string[];
109
+ undo: UndoInfo;
110
+ error: string | null;
111
+ /** Filesystem sandbox when adapter === filesystem. */
112
+ sandbox: SandboxName | null;
113
+ /**
114
+ * Legacy v2 tool name when this transaction was produced via FS mediation.
115
+ * Preserves MCP/CLI compatibility.
116
+ */
117
+ legacyTool: string | null;
118
+ metadata: Record<string, unknown>;
119
+ }
120
+ export interface TransactionIntent {
121
+ adapter: AdapterId;
122
+ operation: string;
123
+ target: TransactionTarget;
124
+ /** Adapter-specific input (content, modes, etc.). */
125
+ input: unknown;
126
+ actor: Actor;
127
+ authority?: Authority;
128
+ source: TransactionSource;
129
+ sessionId?: string | undefined;
130
+ sandbox?: SandboxName | undefined;
131
+ metadata?: Record<string, unknown> | undefined;
132
+ /** Skip permission engine (internal/tests only — default false). */
133
+ bypassPermission?: boolean | undefined;
134
+ }
135
+ export declare function unknownAuthority(): Authority;
136
+ export declare function actorFromMcpClient(client: {
137
+ name: string;
138
+ version: string;
139
+ }): Actor;
140
+ export declare function emptyUndoInfo(): UndoInfo;