@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.
- package/.env.example +8 -0
- package/LICENSE +21 -0
- package/README.md +39 -0
- package/dist/src/action/capture.d.ts +15 -0
- package/dist/src/action/capture.js +215 -0
- package/dist/src/action/capture.js.map +1 -0
- package/dist/src/action/mediate.d.ts +28 -0
- package/dist/src/action/mediate.js +109 -0
- package/dist/src/action/mediate.js.map +1 -0
- package/dist/src/action/mutate.d.ts +11 -0
- package/dist/src/action/mutate.js +189 -0
- package/dist/src/action/mutate.js.map +1 -0
- package/dist/src/action/objects.d.ts +5 -0
- package/dist/src/action/objects.js +50 -0
- package/dist/src/action/objects.js.map +1 -0
- package/dist/src/action/store.d.ts +24 -0
- package/dist/src/action/store.js +149 -0
- package/dist/src/action/store.js.map +1 -0
- package/dist/src/action/types.d.ts +84 -0
- package/dist/src/action/types.js +3 -0
- package/dist/src/action/types.js.map +1 -0
- package/dist/src/action/undo.d.ts +11 -0
- package/dist/src/action/undo.js +42 -0
- package/dist/src/action/undo.js.map +1 -0
- package/dist/src/adapters/filesystem.d.ts +35 -0
- package/dist/src/adapters/filesystem.js +499 -0
- package/dist/src/adapters/filesystem.js.map +1 -0
- package/dist/src/adapters/index.d.ts +7 -0
- package/dist/src/adapters/index.js +19 -0
- package/dist/src/adapters/index.js.map +1 -0
- package/dist/src/adapters/types.d.ts +54 -0
- package/dist/src/adapters/types.js +7 -0
- package/dist/src/adapters/types.js.map +1 -0
- package/dist/src/api/server.d.ts +25 -0
- package/dist/src/api/server.js +786 -0
- package/dist/src/api/server.js.map +1 -0
- package/dist/src/approval/store.d.ts +35 -0
- package/dist/src/approval/store.js +113 -0
- package/dist/src/approval/store.js.map +1 -0
- package/dist/src/checkpoint.d.ts +9 -0
- package/dist/src/checkpoint.js +140 -0
- package/dist/src/checkpoint.js.map +1 -0
- package/dist/src/cli/v5.d.ts +15 -0
- package/dist/src/cli/v5.js +110 -0
- package/dist/src/cli/v5.js.map +1 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +823 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/clients/types.d.ts +90 -0
- package/dist/src/clients/types.js +239 -0
- package/dist/src/clients/types.js.map +1 -0
- package/dist/src/commercial/auth/provider.d.ts +61 -0
- package/dist/src/commercial/auth/provider.js +227 -0
- package/dist/src/commercial/auth/provider.js.map +1 -0
- package/dist/src/commercial/entitlement/provider.d.ts +27 -0
- package/dist/src/commercial/entitlement/provider.js +192 -0
- package/dist/src/commercial/entitlement/provider.js.map +1 -0
- package/dist/src/commercial/entitlement/signing.d.ts +61 -0
- package/dist/src/commercial/entitlement/signing.js +124 -0
- package/dist/src/commercial/entitlement/signing.js.map +1 -0
- package/dist/src/commercial/env.d.ts +10 -0
- package/dist/src/commercial/env.js +40 -0
- package/dist/src/commercial/env.js.map +1 -0
- package/dist/src/commercial/product.d.ts +26 -0
- package/dist/src/commercial/product.js +39 -0
- package/dist/src/commercial/product.js.map +1 -0
- package/dist/src/commercial/store.d.ts +46 -0
- package/dist/src/commercial/store.js +104 -0
- package/dist/src/commercial/store.js.map +1 -0
- package/dist/src/commercial/stripe/checkout.d.ts +104 -0
- package/dist/src/commercial/stripe/checkout.js +469 -0
- package/dist/src/commercial/stripe/checkout.js.map +1 -0
- package/dist/src/core/compatibility.d.ts +15 -0
- package/dist/src/core/compatibility.js +226 -0
- package/dist/src/core/compatibility.js.map +1 -0
- package/dist/src/core/engine.d.ts +33 -0
- package/dist/src/core/engine.js +432 -0
- package/dist/src/core/engine.js.map +1 -0
- package/dist/src/core/lifecycle.d.ts +17 -0
- package/dist/src/core/lifecycle.js +56 -0
- package/dist/src/core/lifecycle.js.map +1 -0
- package/dist/src/core/types.d.ts +140 -0
- package/dist/src/core/types.js +37 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/destroy.d.ts +21 -0
- package/dist/src/destroy.js +219 -0
- package/dist/src/destroy.js.map +1 -0
- package/dist/src/diff.d.ts +13 -0
- package/dist/src/diff.js +251 -0
- package/dist/src/diff.js.map +1 -0
- package/dist/src/enforcement/detect.d.ts +13 -0
- package/dist/src/enforcement/detect.js +75 -0
- package/dist/src/enforcement/detect.js.map +1 -0
- package/dist/src/enforcement/hook-policy.d.ts +38 -0
- package/dist/src/enforcement/hook-policy.js +111 -0
- package/dist/src/enforcement/hook-policy.js.map +1 -0
- package/dist/src/enforcement/index.d.ts +8 -0
- package/dist/src/enforcement/index.js +8 -0
- package/dist/src/enforcement/index.js.map +1 -0
- package/dist/src/enforcement/perf.d.ts +6 -0
- package/dist/src/enforcement/perf.js +18 -0
- package/dist/src/enforcement/perf.js.map +1 -0
- package/dist/src/enforcement/policy.d.ts +12 -0
- package/dist/src/enforcement/policy.js +84 -0
- package/dist/src/enforcement/policy.js.map +1 -0
- package/dist/src/enforcement/readonly.d.ts +17 -0
- package/dist/src/enforcement/readonly.js +124 -0
- package/dist/src/enforcement/readonly.js.map +1 -0
- package/dist/src/enforcement/sandbox-clone.d.ts +6 -0
- package/dist/src/enforcement/sandbox-clone.js +11 -0
- package/dist/src/enforcement/sandbox-clone.js.map +1 -0
- package/dist/src/enforcement/setup.d.ts +33 -0
- package/dist/src/enforcement/setup.js +168 -0
- package/dist/src/enforcement/setup.js.map +1 -0
- package/dist/src/enforcement/trust.d.ts +10 -0
- package/dist/src/enforcement/trust.js +71 -0
- package/dist/src/enforcement/trust.js.map +1 -0
- package/dist/src/enforcement/types.d.ts +40 -0
- package/dist/src/enforcement/types.js +3 -0
- package/dist/src/enforcement/types.js.map +1 -0
- package/dist/src/entitlement/provider.d.ts +48 -0
- package/dist/src/entitlement/provider.js +95 -0
- package/dist/src/entitlement/provider.js.map +1 -0
- package/dist/src/hash.d.ts +9 -0
- package/dist/src/hash.js +23 -0
- package/dist/src/hash.js.map +1 -0
- package/dist/src/ledger/query.d.ts +19 -0
- package/dist/src/ledger/query.js +158 -0
- package/dist/src/ledger/query.js.map +1 -0
- package/dist/src/manifest.d.ts +32 -0
- package/dist/src/manifest.js +242 -0
- package/dist/src/manifest.js.map +1 -0
- package/dist/src/mcp/server.d.ts +7 -0
- package/dist/src/mcp/server.js +364 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/paths.d.ts +94 -0
- package/dist/src/paths.js +354 -0
- package/dist/src/paths.js.map +1 -0
- package/dist/src/permission/engine.d.ts +15 -0
- package/dist/src/permission/engine.js +147 -0
- package/dist/src/permission/engine.js.map +1 -0
- package/dist/src/permission/types.d.ts +42 -0
- package/dist/src/permission/types.js +3 -0
- package/dist/src/permission/types.js.map +1 -0
- package/dist/src/product/setup.d.ts +35 -0
- package/dist/src/product/setup.js +300 -0
- package/dist/src/product/setup.js.map +1 -0
- package/dist/src/protect/audit.d.ts +5 -0
- package/dist/src/protect/audit.js +26 -0
- package/dist/src/protect/audit.js.map +1 -0
- package/dist/src/protect/capture.d.ts +7 -0
- package/dist/src/protect/capture.js +250 -0
- package/dist/src/protect/capture.js.map +1 -0
- package/dist/src/protect/fingerprint.d.ts +4 -0
- package/dist/src/protect/fingerprint.js +49 -0
- package/dist/src/protect/fingerprint.js.map +1 -0
- package/dist/src/protect/hook-cli.d.ts +2 -0
- package/dist/src/protect/hook-cli.js +107 -0
- package/dist/src/protect/hook-cli.js.map +1 -0
- package/dist/src/protect/index.d.ts +12 -0
- package/dist/src/protect/index.js +12 -0
- package/dist/src/protect/index.js.map +1 -0
- package/dist/src/protect/install.d.ts +34 -0
- package/dist/src/protect/install.js +293 -0
- package/dist/src/protect/install.js.map +1 -0
- package/dist/src/protect/intercept.d.ts +11 -0
- package/dist/src/protect/intercept.js +390 -0
- package/dist/src/protect/intercept.js.map +1 -0
- package/dist/src/protect/protect.d.ts +17 -0
- package/dist/src/protect/protect.js +194 -0
- package/dist/src/protect/protect.js.map +1 -0
- package/dist/src/protect/root-paths.d.ts +13 -0
- package/dist/src/protect/root-paths.js +140 -0
- package/dist/src/protect/root-paths.js.map +1 -0
- package/dist/src/protect/shell-policy.d.ts +17 -0
- package/dist/src/protect/shell-policy.js +269 -0
- package/dist/src/protect/shell-policy.js.map +1 -0
- package/dist/src/protect/status.d.ts +11 -0
- package/dist/src/protect/status.js +165 -0
- package/dist/src/protect/status.js.map +1 -0
- package/dist/src/protect/store.d.ts +20 -0
- package/dist/src/protect/store.js +170 -0
- package/dist/src/protect/store.js.map +1 -0
- package/dist/src/protect/types.d.ts +116 -0
- package/dist/src/protect/types.js +3 -0
- package/dist/src/protect/types.js.map +1 -0
- package/dist/src/protect/undo-session.d.ts +14 -0
- package/dist/src/protect/undo-session.js +182 -0
- package/dist/src/protect/undo-session.js.map +1 -0
- package/dist/src/restore.d.ts +39 -0
- package/dist/src/restore.js +141 -0
- package/dist/src/restore.js.map +1 -0
- package/dist/src/sandbox.d.ts +23 -0
- package/dist/src/sandbox.js +198 -0
- package/dist/src/sandbox.js.map +1 -0
- package/dist/src/session/ambient.d.ts +10 -0
- package/dist/src/session/ambient.js +53 -0
- package/dist/src/session/ambient.js.map +1 -0
- package/dist/src/session/attribution.d.ts +27 -0
- package/dist/src/session/attribution.js +201 -0
- package/dist/src/session/attribution.js.map +1 -0
- package/dist/src/session/index.d.ts +25 -0
- package/dist/src/session/index.js +472 -0
- package/dist/src/session/index.js.map +1 -0
- package/dist/src/session/process.d.ts +34 -0
- package/dist/src/session/process.js +234 -0
- package/dist/src/session/process.js.map +1 -0
- package/dist/src/session/store.d.ts +14 -0
- package/dist/src/session/store.js +125 -0
- package/dist/src/session/store.js.map +1 -0
- package/dist/src/session/types.d.ts +111 -0
- package/dist/src/session/types.js +3 -0
- package/dist/src/session/types.js.map +1 -0
- package/dist/src/session/watcher.d.ts +32 -0
- package/dist/src/session/watcher.js +186 -0
- package/dist/src/session/watcher.js.map +1 -0
- package/dist/src/timing.d.ts +7 -0
- package/dist/src/timing.js +19 -0
- package/dist/src/timing.js.map +1 -0
- package/dist/src/types.d.ts +101 -0
- package/dist/src/types.js +3 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/verify.d.ts +8 -0
- package/dist/src/verify.js +126 -0
- package/dist/src/verify.js.map +1 -0
- package/docs/ADAPTERS.md +37 -0
- package/docs/APPROVALS.md +32 -0
- package/docs/ARCHITECTURE.md +57 -0
- package/docs/ATTRIBUTION.md +179 -0
- package/docs/COMMERCIAL.md +51 -0
- package/docs/CURSOR-ENFORCEMENT.md +73 -0
- package/docs/ENFORCEMENT.md +134 -0
- package/docs/FUTURE.md +91 -0
- package/docs/HUMAN-SETUP.md +98 -0
- package/docs/IDENTITY-AUTHORITY.md +35 -0
- package/docs/MCP.md +107 -0
- package/docs/PACKAGING.md +77 -0
- package/docs/PERMISSIONS.md +53 -0
- package/docs/PRODUCT-V5.md +63 -0
- package/docs/PRODUCT-V6.md +69 -0
- package/docs/PROTECTED-SESSIONS.md +155 -0
- package/docs/THREAT-MODEL.md +84 -0
- package/docs/TRANSACTIONS.md +57 -0
- package/package.json +85 -0
package/docs/MCP.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# REWIND MCP (V2 tools → V5 engine)
|
|
2
|
+
|
|
3
|
+
## Architecture
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
Cursor Agent
|
|
7
|
+
│ MCP tools/call
|
|
8
|
+
▼
|
|
9
|
+
REWIND MCP server (stdio, local)
|
|
10
|
+
│ identify actor (MCP client)
|
|
11
|
+
│ Transaction Engine (V5)
|
|
12
|
+
│ → permission → FilesystemAdapter
|
|
13
|
+
│ → BEFORE → mutate → AFTER
|
|
14
|
+
│ append action ledger (+ v5 overlay)
|
|
15
|
+
▼
|
|
16
|
+
sandbox-test-project/ (or sandbox-enforced-project)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Provenance comes from **mediation**, not from watching the OS.
|
|
20
|
+
MCP is a mediation route, not REWIND itself.
|
|
21
|
+
|
|
22
|
+
## Tools
|
|
23
|
+
|
|
24
|
+
| Tool | Mutating | Notes |
|
|
25
|
+
|------|----------|-------|
|
|
26
|
+
| `rewind_read_file` | no | Audit only |
|
|
27
|
+
| `rewind_list_directory` | no | Audit only |
|
|
28
|
+
| `rewind_write_file` | yes | Create or overwrite |
|
|
29
|
+
| `rewind_create_file` | yes | Fails if exists |
|
|
30
|
+
| `rewind_delete_file` | yes | Stores blob before delete |
|
|
31
|
+
| `rewind_move_file` | yes | Fails if destination exists |
|
|
32
|
+
| `rewind_create_directory` | yes | |
|
|
33
|
+
| `rewind_delete_directory` | yes | Captures full subtree |
|
|
34
|
+
| `rewind_get_status` | no | |
|
|
35
|
+
| `rewind_action_history` | no | |
|
|
36
|
+
| `rewind_undo_action` | undo | Conflict-aware |
|
|
37
|
+
|
|
38
|
+
No shell/exec tools.
|
|
39
|
+
|
|
40
|
+
## Configuration (Cursor)
|
|
41
|
+
|
|
42
|
+
Project file: `.cursor/mcp.json`
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"mcpServers": {
|
|
47
|
+
"rewind": {
|
|
48
|
+
"command": "npx",
|
|
49
|
+
"args": ["tsx", "${workspaceFolder}/src/cli.ts", "mcp"],
|
|
50
|
+
"env": {
|
|
51
|
+
"REWIND_PROJECT_ROOT": "${workspaceFolder}"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Also works via **Cursor Settings → Tools & MCP → Add new MCP server** (stdio).
|
|
59
|
+
|
|
60
|
+
Restart Cursor or toggle the server after changing config. Check **Output → MCP Logs** if tools do not appear.
|
|
61
|
+
|
|
62
|
+
Manual start for debugging:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
cd /Users/jack/Desktop/REWIND
|
|
66
|
+
npm run mcp
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
(stdio — normally Cursor launches this.)
|
|
70
|
+
|
|
71
|
+
## Provenance guarantees
|
|
72
|
+
|
|
73
|
+
**What we claim**
|
|
74
|
+
|
|
75
|
+
- An MCP client requested tool `T` with args `…`
|
|
76
|
+
- REWIND itself performed the filesystem mutation
|
|
77
|
+
- `source = MCP` on the ledger entry
|
|
78
|
+
- Client `name`/`version` recorded when MCP initialize provides them; otherwise `UNKNOWN_MCP_CLIENT`
|
|
79
|
+
|
|
80
|
+
**What we do not claim**
|
|
81
|
+
|
|
82
|
+
- “Cursor process PID authored these bytes”
|
|
83
|
+
- “All Cursor activity is mediated”
|
|
84
|
+
- That native Cursor edits are impossible while MCP is connected
|
|
85
|
+
|
|
86
|
+
## Bypass limitation (critical)
|
|
87
|
+
|
|
88
|
+
Cursor retains native filesystem tools. An agent can edit `sandbox-test-project` **without** calling REWIND MCP.
|
|
89
|
+
|
|
90
|
+
| Path | Provenance |
|
|
91
|
+
|------|------------|
|
|
92
|
+
| `rewind_write_file` | MCP / HIGH mediation certainty |
|
|
93
|
+
| Native Cursor edit | UNKNOWN (V1 watcher may observe WHAT only) |
|
|
94
|
+
|
|
95
|
+
REWIND never claims it controls all Cursor activity merely because MCP is connected.
|
|
96
|
+
|
|
97
|
+
Closing the bypass eventually requires vendor tool policies, sandboxing, or agent integration — out of scope for V2.
|
|
98
|
+
|
|
99
|
+
## V3 note
|
|
100
|
+
|
|
101
|
+
Mutating tools accept `sandbox: "test" | "enforced"` (default `test`).
|
|
102
|
+
Use `sandbox=enforced` against `sandbox-enforced-project/` under V3 fs-readonly + hooks + optional seatbelt.
|
|
103
|
+
See docs/ENFORCEMENT.md — enforcement is **scoped**, not universal.
|
|
104
|
+
|
|
105
|
+
## Safety
|
|
106
|
+
|
|
107
|
+
All tools use V0/V1 path validation. Escapes (`../`, absolute outsides, `.rewind`, symlink escapes) fail closed.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Packaging & updates
|
|
2
|
+
|
|
3
|
+
## Current distribution (V6.2)
|
|
4
|
+
|
|
5
|
+
| Channel | Status |
|
|
6
|
+
|---------|--------|
|
|
7
|
+
| `npm pack` + global install from tarball | Proven locally |
|
|
8
|
+
| npm registry `@rewind-ai/cli` | Ready to publish (not published yet) |
|
|
9
|
+
| Homebrew | Not created |
|
|
10
|
+
| Signed macOS app | Not created |
|
|
11
|
+
|
|
12
|
+
### User install (after publish)
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install -g @rewind-ai/cli
|
|
16
|
+
cd /path/to/your/project
|
|
17
|
+
rewind setup
|
|
18
|
+
rewind doctor
|
|
19
|
+
rewind open
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Package name: **`@rewind-ai/cli`**. Binary command: **`rewind`**.
|
|
23
|
+
|
|
24
|
+
### Local pack proof (before publish)
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm run build
|
|
28
|
+
npm pack # creates rewind-ai-cli-0.6.2.tgz
|
|
29
|
+
npm install -g ./rewind-ai-cli-0.6.2.tgz
|
|
30
|
+
rewind version
|
|
31
|
+
cd /tmp/some-project && rewind setup
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Do not claim the package is on npm until it is published.
|
|
35
|
+
|
|
36
|
+
## Runtime paths
|
|
37
|
+
|
|
38
|
+
| Kind | Location |
|
|
39
|
+
|------|----------|
|
|
40
|
+
| Package (read-only) | npm global prefix / node_modules/@rewind-ai/cli |
|
|
41
|
+
| Project state | `<project>/.rewind/` |
|
|
42
|
+
| User state | `~/.rewind/` (credentials, commercial, keys, optional `.env`) |
|
|
43
|
+
|
|
44
|
+
Never write runtime state into `dist/` or the package install directory.
|
|
45
|
+
|
|
46
|
+
## Env / Stripe TEST config (installed users)
|
|
47
|
+
|
|
48
|
+
Prefer **user-level** env — not a `.env` inside the npm package:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
mkdir -p ~/.rewind
|
|
52
|
+
# Create ~/.rewind/.env with sk_test_… / price_… / whsec_…
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Also accepted: project-cwd `.env` (gitignored). See [HUMAN-SETUP.md](./HUMAN-SETUP.md).
|
|
56
|
+
|
|
57
|
+
## Updates
|
|
58
|
+
|
|
59
|
+
`rewind update` prints channel instructions.
|
|
60
|
+
Updates **must not** delete `.rewind/` history, CAS, or policies.
|
|
61
|
+
|
|
62
|
+
## Uninstall
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
rewind uninstall # removes MCP config; keeps recovery data
|
|
66
|
+
rewind uninstall --delete-recovery-data --yes
|
|
67
|
+
npm uninstall -g @rewind-ai/cli
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Publish (manual — do not run until ready)
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm login
|
|
74
|
+
npm publish --access public
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`package.json` includes `"publishConfig": { "access": "public" }` for the scoped package.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Permissions (V5)
|
|
2
|
+
|
|
3
|
+
## EXISTS
|
|
4
|
+
|
|
5
|
+
Local policy file: `.rewind/policy/permissions.json`
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"version": 1,
|
|
10
|
+
"defaultEffect": "ALLOW",
|
|
11
|
+
"rules": [
|
|
12
|
+
{
|
|
13
|
+
"id": "ask-delete",
|
|
14
|
+
"priority": 10,
|
|
15
|
+
"effect": "ASK",
|
|
16
|
+
"adapter": "filesystem",
|
|
17
|
+
"operation": "delete",
|
|
18
|
+
"resourcePattern": "**",
|
|
19
|
+
"enabled": true,
|
|
20
|
+
"reason": "Deletes require approval"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Decisions (before mutation)
|
|
27
|
+
|
|
28
|
+
| Decision | Behaviour |
|
|
29
|
+
|----------|-----------|
|
|
30
|
+
| ALLOW | Continue mediated execute |
|
|
31
|
+
| ASK | No mutation; transaction → AWAITING_APPROVAL + pending approval record |
|
|
32
|
+
| DENY | No mutation; transaction → DENIED |
|
|
33
|
+
|
|
34
|
+
### Match dimensions (generic)
|
|
35
|
+
|
|
36
|
+
actor client · adapter · operation · resource glob · reversibility · risk
|
|
37
|
+
|
|
38
|
+
Default document uses `defaultEffect: ALLOW` so existing FS tests remain usable.
|
|
39
|
+
|
|
40
|
+
CLI:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
rewind policy
|
|
44
|
+
rewind policy init
|
|
45
|
+
rewind policy set ask-delete ASK --op delete --enable
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## PLANNED
|
|
49
|
+
|
|
50
|
+
- Risk scoring
|
|
51
|
+
- Per-actor quotas
|
|
52
|
+
- UI policy editor
|
|
53
|
+
- Outside-project DENY that is not already covered by path safety
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# REWIND V5 — Product Core
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
**EXISTS (shipped in this tree):** general transaction model, adapter interface, FilesystemAdapter wrapping V2 mediation, permission engine (ALLOW/ASK/DENY), approval backend + CLI, actor/authority foundation, ledger query layer, V5 CLI surface, MCP routed through V5 engine, loopback local API + minimal control UI, development entitlement provider, threat model docs.
|
|
6
|
+
|
|
7
|
+
**PLANNED (not shipped):** shell/DB/HTTP/browser adapters, real compensation strategies, delegated human authority, Stripe/billing, polished desktop app, universal enforcement of native Cursor writes.
|
|
8
|
+
|
|
9
|
+
## Product truth
|
|
10
|
+
|
|
11
|
+
REWIND is undo for AI agents — a local **control and transaction layer**:
|
|
12
|
+
|
|
13
|
+
CONTROL → RECORD → REVERSE → PROVE
|
|
14
|
+
|
|
15
|
+
Mediated path: `AGENT → REWIND → TARGET`
|
|
16
|
+
|
|
17
|
+
Filesystem is the first production adapter, not the definition of REWIND.
|
|
18
|
+
|
|
19
|
+
## Non-negotiable lessons preserved
|
|
20
|
+
|
|
21
|
+
1. Observation ≠ attribution
|
|
22
|
+
2. Native/bypassed writes are never authoritative mediated actions
|
|
23
|
+
3. Mediation provides trustworthy provenance
|
|
24
|
+
4. Reversible actions need before/after state
|
|
25
|
+
5. Undo is conflict-aware
|
|
26
|
+
6. If current ≠ expected after → refuse undo
|
|
27
|
+
7. Human/newer work wins
|
|
28
|
+
8. Enforcement ≠ mediation
|
|
29
|
+
9. MCP is a mediation route, not REWIND itself
|
|
30
|
+
10. Filesystem is the first adapter
|
|
31
|
+
|
|
32
|
+
## Commands
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm run rewind -- status
|
|
36
|
+
npm run rewind -- transactions
|
|
37
|
+
npm run rewind -- transaction <act_…>
|
|
38
|
+
npm run rewind -- undo <act_…>
|
|
39
|
+
npm run rewind -- approvals
|
|
40
|
+
npm run rewind -- approve <appr_…>
|
|
41
|
+
npm run rewind -- deny <appr_…>
|
|
42
|
+
npm run rewind -- policy
|
|
43
|
+
npm run rewind -- policy init
|
|
44
|
+
npm run rewind -- policy set ask-delete ASK --op delete --enable
|
|
45
|
+
npm run rewind -- api # loopback 127.0.0.1:7429 + token
|
|
46
|
+
npm run mcp
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## What V5 proves
|
|
50
|
+
|
|
51
|
+
- Core no longer assumes every transaction is a filesystem op (adapter boundary exists).
|
|
52
|
+
- One mediated execution path for FS MCP tools (via transaction engine).
|
|
53
|
+
- Permissions can DENY/ASK before mutation; DENY leaves target unchanged.
|
|
54
|
+
- Approvals revalidate state (TOCTOU refusal).
|
|
55
|
+
- Conflict-aware undo still protects newer work.
|
|
56
|
+
- Local API is loopback + token, not a public service.
|
|
57
|
+
|
|
58
|
+
## What V5 does not prove
|
|
59
|
+
|
|
60
|
+
- Agents cannot bypass REWIND (same-UID / native tools still can).
|
|
61
|
+
- Non-filesystem adapters work.
|
|
62
|
+
- Commercial licensing / entitlement enforcement.
|
|
63
|
+
- A production desktop product UX.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# REWIND V6 — First sellable product
|
|
2
|
+
|
|
3
|
+
## EXISTS
|
|
4
|
+
|
|
5
|
+
Installable product surface for **REWIND Personal** (£2.99/month list):
|
|
6
|
+
|
|
7
|
+
| Area | Status |
|
|
8
|
+
|------|--------|
|
|
9
|
+
| `rewind setup` / `doctor` / `open` / `uninstall` / `version` / `update` | Shipped |
|
|
10
|
+
| Cursor MCP client integration | Shipped (only tested client) |
|
|
11
|
+
| Control app (Activity/Approvals/Agents/Policy/Settings) | Shipped via local API |
|
|
12
|
+
| Browser login (`rewind login`) local-dev + OIDC-ready | Shipped (local-dev works without IdP) |
|
|
13
|
+
| Commercial file store (users/installs/subs) | Shipped (not Postgres) |
|
|
14
|
+
| Stripe TEST Checkout Session + signed webhook → Personal | Shipped (V6.1) |
|
|
15
|
+
| Installable npm package (`npm pack` / global tarball) | Shipped (V6.2) |
|
|
16
|
+
| Simulated subscribe without Stripe keys | Kept for offline/dev |
|
|
17
|
+
| Ed25519 signed entitlements + cache/grace | Shipped |
|
|
18
|
+
| **Undo never paywalled** | Invariant + tested |
|
|
19
|
+
|
|
20
|
+
## Product boundary
|
|
21
|
+
|
|
22
|
+
- **CORE** — transaction engine, adapters, undo, CAS, permissions (no billing)
|
|
23
|
+
- **SERVICE** — local API, MCP, project setup
|
|
24
|
+
- **CLIENT** — control UI
|
|
25
|
+
- **COMMERCIAL** — auth, Stripe, signed entitlement (separate from Core)
|
|
26
|
+
|
|
27
|
+
## Honest language
|
|
28
|
+
|
|
29
|
+
**REWIND CONNECTED** — mediated actions will be recorded.
|
|
30
|
+
Native Cursor writes outside MCP are **not** authoritative transactions.
|
|
31
|
+
|
|
32
|
+
## User journey (test mode)
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install && npm run build
|
|
36
|
+
npm pack && npm install -g ./rewind-ai-cli-*.tgz
|
|
37
|
+
rewind setup
|
|
38
|
+
rewind login --email you@example.com
|
|
39
|
+
rewind subscribe # SIMULATED without keys; STRIPE TEST MODE with sk_test_ + price_
|
|
40
|
+
rewind open # control UI on 127.0.0.1
|
|
41
|
+
# Ask Cursor to create a file via REWIND MCP
|
|
42
|
+
rewind transactions
|
|
43
|
+
rewind undo <id>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## REAL STRIPE SANDBOX PROOF
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# .env (gitignored) with sk_test_…, price_…, whsec_… from stripe listen
|
|
50
|
+
rewind api
|
|
51
|
+
stripe listen --forward-to http://127.0.0.1:7429/v1/commercial/stripe/webhook
|
|
52
|
+
rewind login --email you@example.com
|
|
53
|
+
rewind subscribe # opens real Checkout — does NOT activate locally
|
|
54
|
+
# Complete TEST payment → signed webhook → Personal entitlement
|
|
55
|
+
rewind status # Entitlement: REWIND Personal
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Webhook path: `POST /v1/commercial/stripe/webhook` on the local loopback API (default port **7429**).
|
|
59
|
+
|
|
60
|
+
## PLANNED / NOT DONE
|
|
61
|
+
|
|
62
|
+
- Published npm package / Homebrew tap / notarised macOS app
|
|
63
|
+
- Production Auth0/Clerk OIDC credentials
|
|
64
|
+
- Production entitlement signing service (private key offline)
|
|
65
|
+
- Customer Portal wiring
|
|
66
|
+
- Website checkout wiring
|
|
67
|
+
- Hosted commercial HTTP (non-loopback)
|
|
68
|
+
|
|
69
|
+
See [HUMAN-SETUP.md](./HUMAN-SETUP.md) and [PACKAGING.md](./PACKAGING.md).
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# REWIND V4 — Protected Cursor Sessions
|
|
2
|
+
|
|
3
|
+
## Verdict
|
|
4
|
+
|
|
5
|
+
**Model A (intercept + transactionalise) is proven** for supported Cursor Agent tool paths in a project configured with REWIND hooks.
|
|
6
|
+
|
|
7
|
+
Workflow:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm run rewind -- protect ./sandbox-v4-project
|
|
11
|
+
# open sandbox-v4-project in Cursor — use the agent normally
|
|
12
|
+
npm run rewind -- status
|
|
13
|
+
npm run rewind -- undo-session rw_…
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The user does **not** need to say “use rewind_write_file.”
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Architecture (Model A)
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
Cursor Agent Write / StrReplace / Delete
|
|
24
|
+
│
|
|
25
|
+
▼
|
|
26
|
+
preToolUse (failClosed)
|
|
27
|
+
│ capture BEFORE → CAS
|
|
28
|
+
│ create PREPARED/EXECUTING action
|
|
29
|
+
│ permission: allow
|
|
30
|
+
▼
|
|
31
|
+
Cursor performs native mutation
|
|
32
|
+
│
|
|
33
|
+
▼
|
|
34
|
+
postToolUse / afterFileEdit
|
|
35
|
+
│ capture AFTER → CAS
|
|
36
|
+
│ mark COMPLETED
|
|
37
|
+
▼
|
|
38
|
+
.rewind/actions + audit ledger
|
|
39
|
+
|
|
40
|
+
Shell (beforeShellExecution, failClosed)
|
|
41
|
+
read-only allowlist → allow
|
|
42
|
+
mutation / opaque interpreters → deny
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Provenance claim (precise):**
|
|
46
|
+
|
|
47
|
+
> Cursor Agent requested this tool operation during protected session X.
|
|
48
|
+
|
|
49
|
+
**Not claimed:** OS-level authorship (PID wrote these bytes).
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Lifecycle
|
|
54
|
+
|
|
55
|
+
1. `protect <path>` — validate root, init `.rewind`, baseline fingerprint, create `ProtectedSession`, merge hooks/MCP, self-test, print summary.
|
|
56
|
+
2. Developer opens the project in Cursor and works normally.
|
|
57
|
+
3. Hooks ledger native mutations; shell policy blocks dangerous commands.
|
|
58
|
+
4. `status` / `sessions` / `actions` — inspect.
|
|
59
|
+
5. `undo-session <id>` — reverse COMPLETED actions newest→oldest with conflict protection.
|
|
60
|
+
6. `unprotect` — remove only REWIND-managed hook/MCP entries; keep history.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Trust model
|
|
65
|
+
|
|
66
|
+
| State | Meaning |
|
|
67
|
+
|-------|---------|
|
|
68
|
+
| AUTHORITATIVE | Session mutations explained by COMPLETED CURSOR_HOOK actions (or clean baseline) |
|
|
69
|
+
| UNTRUSTED | Unexplained mutation / incomplete actions / drift — **not** attributed to Cursor without hook evidence |
|
|
70
|
+
|
|
71
|
+
Human keyboard edits are **not** claimed as Cursor actions. If drift detection sees them → `UNKNOWN_MUTATION` / UNTRUSTED.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Cursor hooks installed
|
|
76
|
+
|
|
77
|
+
| Event | failClosed | Role |
|
|
78
|
+
|-------|------------|------|
|
|
79
|
+
| `sessionStart` | false | Crash recovery + context note |
|
|
80
|
+
| `sessionEnd` | false | Bind cursor session ids |
|
|
81
|
+
| `preToolUse` (Write\|Delete\|StrReplace\|EditNotebook\|Shell) | **true** | BEFORE capture / shell redirect to beforeShell path |
|
|
82
|
+
| `postToolUse` | false | AFTER capture |
|
|
83
|
+
| `postToolUseFailure` | false | Mark FAILED |
|
|
84
|
+
| `afterFileEdit` | false | Secondary AFTER capture |
|
|
85
|
+
| `beforeShellExecution` | **true** | Conservative shell policy |
|
|
86
|
+
| `beforeMCPExecution` | false | Allow (MCP optional for Model A) |
|
|
87
|
+
|
|
88
|
+
Security-critical gates use `failClosed: true`: hook crash, timeout, or invalid JSON **blocks** the action (Cursor behaviour).
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Shell policy
|
|
93
|
+
|
|
94
|
+
Prefer false-positive blocks over silent mutation.
|
|
95
|
+
|
|
96
|
+
- **Allow:** `pwd`, `ls`, `cat`, `grep`/`rg`, `find` (no `-delete`/`-exec`), `git status|diff|log|…`, `echo`/`printf` without redirects.
|
|
97
|
+
- **Deny:** redirects (`>`, `>>`), `rm`/`mv`/`cp`/`mkdir`/`touch`/`sed -i`, **and** opaque interpreters (`node`, `python`, `bash`, `npm`, …) even without obvious redirects.
|
|
98
|
+
|
|
99
|
+
Indirect writes via `node -e '…writeFile…'` are **blocked**.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Session undo
|
|
104
|
+
|
|
105
|
+
1. Load COMPLETED actions for session.
|
|
106
|
+
2. Sort newest → oldest.
|
|
107
|
+
3. For each: if current == recorded AFTER → restore BEFORE; else CONFLICT (preserve bytes) and continue.
|
|
108
|
+
4. Status: `UNDONE` | `PARTIALLY_UNDONE` | `CONFLICTED`.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Crash recovery
|
|
113
|
+
|
|
114
|
+
Incomplete `PREPARED`/`EXECUTING` actions (pre fired, post missing) are marked `FAILED` on next `protect` / `sessionStart` recovery. No fabricated AFTER state.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Human vs agent
|
|
119
|
+
|
|
120
|
+
Hooks bound the **Cursor agent tool loop only**. The human can edit in the editor freely. This is not OS filesystem lockdown (see V3).
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Limitations
|
|
125
|
+
|
|
126
|
+
- Only projects with REWIND hooks loaded (open the protected folder as the workspace).
|
|
127
|
+
- Tab / non-agent edit paths may not hit the same hooks.
|
|
128
|
+
- Opaque shell is denied rather than checkpointed.
|
|
129
|
+
- Observation is of Cursor’s declared tool use — not kernel provenance.
|
|
130
|
+
- MCP is optional for Model A; ledgering is hook-based.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Manual testing
|
|
135
|
+
|
|
136
|
+
See the final V4 report in-chat, or:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
npm run rewind -- protect ./sandbox-v4-project
|
|
140
|
+
# Open sandbox-v4-project in Cursor; refactor auth without mentioning REWIND
|
|
141
|
+
npm run rewind -- status
|
|
142
|
+
npm run rewind -- undo-session <id>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Fail-closed demo helpers (tests / harness):
|
|
146
|
+
|
|
147
|
+
- `breakProtectHook(projectRoot)` / `restoreProtectHook(projectRoot)`
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Allowed security claim
|
|
152
|
+
|
|
153
|
+
> REWIND can protect filesystem changes made through supported Cursor Agent tool paths in a project configured with REWIND hooks.
|
|
154
|
+
|
|
155
|
+
Not allowed: “prevents all AI writes”, “OS-level protection”, “every Cursor filesystem change is guaranteed mediated.”
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Threat Model (V5) — brutally accurate
|
|
2
|
+
|
|
3
|
+
## Trust boundaries
|
|
4
|
+
|
|
5
|
+
| Zone | Trust |
|
|
6
|
+
|------|--------|
|
|
7
|
+
| Mediated path (MCP/CLI/API → engine → adapter) | **Authoritative provenance** for what REWIND executed |
|
|
8
|
+
| Native Cursor edits / shell / other processes | **Untrusted observation only** — not mediated actions |
|
|
9
|
+
| `.rewind/` ledger + CAS | Local integrity assumed; not cryptographically sealed against the same user |
|
|
10
|
+
|
|
11
|
+
## Mediated vs bypassed
|
|
12
|
+
|
|
13
|
+
- **Mediated:** action entered via REWIND tools/engine → before/after recorded → undo may be safe.
|
|
14
|
+
- **Bypassed:** same-UID write outside REWIND → may appear in watchers → **must never** be labelled authoritative mediated provenance.
|
|
15
|
+
|
|
16
|
+
Observation is not attribution. V1 proved this; V5 does not reverse that finding.
|
|
17
|
+
|
|
18
|
+
## MCP is not universal enforcement
|
|
19
|
+
|
|
20
|
+
MCP is a **mediation route**. Agents (and Cursor native tools) can still mutate the filesystem without calling REWIND. Enforcement (V3 hooks/seatbelt/fs-readonly) is a separate, partial experiment on `sandbox-enforced-project`.
|
|
21
|
+
|
|
22
|
+
## Same-UID problems
|
|
23
|
+
|
|
24
|
+
REWIND runs as the user. Anything the user can write, another process under the same UID can write — including:
|
|
25
|
+
|
|
26
|
+
- Cursor built-in apply/write tools
|
|
27
|
+
- Shell `>` / `tee` / editors
|
|
28
|
+
- Malicious or confused agents skipping MCP
|
|
29
|
+
|
|
30
|
+
Mandatory mediation is **not** achieved for the general Cursor workspace.
|
|
31
|
+
|
|
32
|
+
## Hooks limitations
|
|
33
|
+
|
|
34
|
+
Cursor hooks can deny some tool calls when the hook runner works. Fail-closed hooks that **crash** (e.g. runner init failure) can brick the agent or, if failClosed is disabled, fail open. Hooks are not a kernel boundary.
|
|
35
|
+
|
|
36
|
+
## Sandbox limitations
|
|
37
|
+
|
|
38
|
+
Approved sandboxes (`sandbox-test-project`, `sandbox-enforced-project`) constrain MCP path safety. They do not stop native edits to those trees unless additional enforcement is enabled — and even then, same-UID bypasses remain.
|
|
39
|
+
|
|
40
|
+
## Local API attack surface
|
|
41
|
+
|
|
42
|
+
- Binds **127.0.0.1 only** (not `0.0.0.0`).
|
|
43
|
+
- Bearer token written to `.rewind/api-token` (mode 0600) and required for mutating routes.
|
|
44
|
+
- Any local process that can read the token can approve/undo. Treat workstation compromise as full compromise.
|
|
45
|
+
- No TLS; loopback only.
|
|
46
|
+
|
|
47
|
+
## Approval TOCTOU
|
|
48
|
+
|
|
49
|
+
Mitigated for **target state fingerprint** change between ASK and APPROVE. Remaining risks:
|
|
50
|
+
|
|
51
|
+
- Intent fields are not re-hashed beyond adapter revalidation
|
|
52
|
+
- Approver confusion / social engineering
|
|
53
|
+
- Clock / ordering races across multiple pending approvals on related paths
|
|
54
|
+
|
|
55
|
+
## Ledger & CAS tampering
|
|
56
|
+
|
|
57
|
+
A local attacker (or the agent itself) can edit `.rewind/actions`, `.rewind/transactions`, or `.rewind/objects`. V5 does **not** provide tamper-evident sealing or remote attestation. Provenance is trustworthy only relative to an untampered local REWIND home.
|
|
58
|
+
|
|
59
|
+
Malicious agents may attempt to alter `.rewind` to fake undo safety. Path safety blocks MCP from targeting `.rewind/**`, but shell/native writes can still reach it.
|
|
60
|
+
|
|
61
|
+
## Process crash
|
|
62
|
+
|
|
63
|
+
Incomplete `PREPARED` / `EXECUTING` / `UNDOING` → marked `FAILED` on recovery.
|
|
64
|
+
`AWAITING_APPROVAL` is preserved (not treated as crash debris).
|
|
65
|
+
Partial mutations mid-execute can leave filesystem dirty with FAILED ledger entries — operator must inspect.
|
|
66
|
+
|
|
67
|
+
## Entitlement
|
|
68
|
+
|
|
69
|
+
Development provider always allows mediation. A future paid provider can deny mediation, but cannot stop bypass writes.
|
|
70
|
+
|
|
71
|
+
## Authentication & commercial (V6)
|
|
72
|
+
|
|
73
|
+
- Browser login preferred; LocalDevAuth for test; OIDC when configured
|
|
74
|
+
- Credentials in `~/.rewind/credentials.json` (0600); optional macOS Keychain mirror
|
|
75
|
+
- Signed entitlements (ed25519); private key never in the distributed app
|
|
76
|
+
- Stripe webhooks must be signature-verified; idempotent event ids
|
|
77
|
+
- Licence theft: cached entitlement is bound to installation id in claims (soft); full device attestation is PLANNED
|
|
78
|
+
- Entitlement replay/tamper: signature verification required; tampered payloads fall back to free mediation — **undo still works**
|
|
79
|
+
- Local API remains loopback + bearer token
|
|
80
|
+
- Uninstall never deletes recovery data unless `--delete-recovery-data --yes`
|
|
81
|
+
- Update channel must not wipe `.rewind/`
|
|
82
|
+
|
|
83
|
+
Until then: **REWIND proves control for actions that choose to go through it**, not total containment of all agent I/O.
|
|
84
|
+
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Transactions (V5)
|
|
2
|
+
|
|
3
|
+
## EXISTS
|
|
4
|
+
|
|
5
|
+
### Model
|
|
6
|
+
|
|
7
|
+
`Transaction` (version 5) is the in-memory / overlay / query model:
|
|
8
|
+
|
|
9
|
+
- identity: `id`, `sequence`, `sessionId`, `createdAt`
|
|
10
|
+
- `actor` / `authority` / `source`
|
|
11
|
+
- `adapter` + `operation` + `target`
|
|
12
|
+
- `before` / `after` (adapter-typed payloads)
|
|
13
|
+
- `reversibility`, `permission`, `status`, `undo`
|
|
14
|
+
- filesystem keeps `legacyTool` for MCP/CLI compatibility
|
|
15
|
+
|
|
16
|
+
On disk for filesystem actions:
|
|
17
|
+
|
|
18
|
+
1. **v2 ActionRecord** — `.rewind/actions/act_….json` (backwards compatible)
|
|
19
|
+
2. **v5 overlay** — `.rewind/transactions/act_….json` (full Transaction)
|
|
20
|
+
|
|
21
|
+
Existing V2/V3 action files remain readable via compatibility mapping.
|
|
22
|
+
|
|
23
|
+
### Status lifecycle
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
PREPARED → AWAITING_APPROVAL → DENIED
|
|
27
|
+
→ EXECUTING → COMPLETED → UNDOING → UNDONE
|
|
28
|
+
→ FAILED
|
|
29
|
+
→ DENIED
|
|
30
|
+
COMPLETED → CONFLICTED (undo refused)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Invalid transitions throw `InvalidTransitionError`.
|
|
34
|
+
|
|
35
|
+
### Reversibility classes
|
|
36
|
+
|
|
37
|
+
| Class | Meaning in V5 |
|
|
38
|
+
|-------|----------------|
|
|
39
|
+
| REVERSIBLE | Exact restore when current == after (FS ops) |
|
|
40
|
+
| COMPENSATABLE | Domain concept only — **no compensation implemented** |
|
|
41
|
+
| APPROVAL_REQUIRED | Policy/intent classification; not auto-executed |
|
|
42
|
+
| IRREVERSIBLE | No safe inverse |
|
|
43
|
+
|
|
44
|
+
### Undo
|
|
45
|
+
|
|
46
|
+
1. Load transaction
|
|
47
|
+
2. Adapter `compareExpectedCurrent`
|
|
48
|
+
3. If mismatch → CONFLICTED, refuse
|
|
49
|
+
4. Else adapter `reverse` + verify
|
|
50
|
+
|
|
51
|
+
Human/newer work wins.
|
|
52
|
+
|
|
53
|
+
## PLANNED
|
|
54
|
+
|
|
55
|
+
- Event-sourced append-only status log (today: overlay + action file updates for status fields)
|
|
56
|
+
- Cross-adapter dependency graphs
|
|
57
|
+
- Compensating transactions for non-FS adapters
|