返回 DeepSeek-Reasonix
SESSION_RECOVERY_AND_PARALLELISM.md
根目录 / docs / SESSION_RECOVERY_AND_PARALLELISM.md
1 # Session Recovery and Parallel Work
2
3 Reasonix keeps transcript persistence and workspace mutation as separate safety
4 boundaries. Read-only work and non-overlapping file claims can run concurrently;
5 opaque writers such as unrestricted shell or unknown MCP mutations retain the
6 workspace write lease. Git worktrees provide an isolated checkout when a task
7 needs an independent workspace.
8
9 ## Session versions
10
11 A format-2 session log holds every version of one conversation as a head of
12 its append-only DAG (see [`SESSION_OWNERSHIP.md`](SESSION_OWNERSHIP.md)).
13 Heads have kinds:
14
15 - `main` is the line the log started with.
16 - `fork` and `rewind` come from user actions: fork-from-here, `/branch`, and
17 conversation rewind.
18 - `concurrent` is created by a save that found another writer on the same
19 chain.
20
21 One head is *selected*; opening the session opens it. Heads are listed,
22 switched, renamed, and retired inside the log. Nothing creates a second
23 session file, and a head that was retired keeps its bytes until a single writer
24 rotates the log.
25
26 Format-1 transcripts (saved before Reasonix 1.39.0 and not yet upgraded) keep
27 their version identity in branch metadata:
28
29 - `normal` is an ordinary conversation transcript.
30 - `recovery` preserves local content after a transcript save conflict, file-lock
31 timeout, or external removal.
32 - `subagent` is reserved for a session-backed child run.
33
34 Older sidecars remain readable. A sidecar with `Recovered=true` is interpreted as
35 a recovery version when the explicit version field is absent. Recovery metadata
36 records the parent conversation/version and the base and disk revisions
37 observed at the conflict; recovery copies stay in the same logical conversation
38 lineage and are not treated as ordinary conversations or subagents.
39
40 ## Recovery lifecycle
41
42 A format-2 save never conflicts. Another writer's appends are followed when
43 this session added nothing; when both added content the save forks a
44 `concurrent` head, and both sides receive a notice. The versions dialog shows
45 both heads and the user picks. There is no `pending` state and no lease
46 handoff to retry: the lease decides only who writes the derived transcript,
47 the indexes, and the turn ledger.
48
49 For a format-1 session an append-compatible snapshot is adopted from disk
50 without creating another version. A divergent snapshot is preserved as a
51 recovery version using the existing CAS and digest checks. A failed lease
52 handoff marks that recovery version as `pending`; the desktop client can retry
53 activation after the writer is released. Recovery lineage reconciliation is
54 idempotent. Covered copies may be moved to recoverable session trash, while
55 divergent content remains available for an explicit version choice.
56
57 The desktop bridge exposes `GetRecoveryLineage` and `GetSessionVersionState`,
58 which list a format-2 log's heads (state `heads`; every member shares the log's
59 path and carries `headId`, `headKind`, `headName`, and `selected`);
60 `ChooseRecoveryBranch` and `SetActiveSessionVersion`, which take `headId` and
61 make a head current (an open tab switches in place, a closed session gets a
62 `select` marker); `CleanRecoveryLineage`, which retires covered heads and
63 reports heads active within the last minute as busy; `RenameSessionHead`;
64 and the format-1 `RetrySessionRecovery` and `ReconcileRecoveryVersions`. A
65 family whose format-1 root was upgraded after recovery copies had been made
66 shows the log's heads and the copies together. Worktree status and merge
67 preparation use the same backend inspection and identity checks as the
68 existing merge flow.
69
70 ## Legacy recovery copies
71
72 `-recovery-` files made before the upgrade are not imported into the log. They
73 remain format-1 sessions of the same lineage: listed under *View versions*,
74 selectable, and covered copies are still moved to recoverable trash by the
75 existing sweep and by `reasonix sessions cleanup`. A format-2 log never forms
76 a recovery group, so cleanup reports zero candidates for it, and
77 `reasonix sessions diagnose` counts session logs, heads, covered heads, and
78 retired heads next to the recovery-copy numbers.
79
80 ## Compatibility
81
82 | Field or format | Old-data behavior | New-reader behavior | Previous-reader behavior | Conclusion |
83 | --- | --- | --- | --- | --- |
84 | `.events.jsonl` format 1 | unchanged | replayed; message ids derived deterministically | unchanged | compatible |
85 | `.events.jsonl` format 2 | n/a | native | refused; file left untouched | explicit boundary (>= 1.39.0) |
86 | `.jsonl` transcript | unchanged format | derived from the selected head | readable, not authoritative | compatible |
87 | `.jsonl.meta` head fields | absent → treated as format 1 | used | ignored | compatible |
88 | `.event-index.json` schema 2 | schema-1 index rejected → replay | native | rejected → slow path | compatible |
89 | `-recovery-<hex>.jsonl` | format-1 lineage | not imported; listed as before | unchanged | compatible |
90 | session catalog `v8.sqlite` | v7 file isolated | native | separate generation files | compatible |
91
92 Format 2 opens in Reasonix 1.39.0 and newer. Mixed installations should
93 upgrade the older side before sharing a session directory; the older binary
94 reports the newer format and does not modify the file.
95
95 lines MARKDOWN