返回 DeepSeek-Reasonix
HISTORICAL_SESSION_MIGRATION_ON_DEMAND.md
根目录 / docs / HISTORICAL_SESSION_MIGRATION_ON_DEMAND.md
1 # On-demand historical session migration
2
3 ## Scope
4
5 Desktop startup no longer converts every legacy transcript or canonical v4
6 directory. Startup only repairs small, non-historical lifecycle reservations.
7 The historical catalog reads directory entries, published head indexes, and
8 durable registry metadata. Legacy and canonical v4 rows participate in the normal sidebar and
9 history search; opening one starts preparation in the conversation navigation
10 flow and switches to the canonical target only after preparation commits.
11
12 Restored, unprepared tabs retain their title and a non-error **Import and open**
13 action. Merely restarting does not prepare content or start a controller. The
14 action uses the same navigation owner as sidebar/history selection. Empty
15 canonical probe directories are not historical sessions; damaged session
16 artifacts remain discoverable for an explicit retry.
17
18 The management surface is **Settings → Storage → Historical sessions**. Trash
19 contains archived/deleted canonical sessions only.
20
21 ## Ownership and lifecycle
22
23 - A source import takes a per-source cross-process lock and, for canonical
24 stores, a shared directory ownership lock for the complete copy and commit.
25 - A source already owned by another CLI or runtime returns a blocked source
26 status immediately. It never waits behind the desktop runtime rebuild lock.
27 - Duplicate requests for one source join the same revisioned preparation task.
28 Interactive navigation and a bulk batch hold separate demands, so cancelling
29 a batch cannot cancel a session that the user is currently opening.
30 - Batch import is sequential, cancellable, and resumable. Its selected source
31 snapshot is stored in `historical-import-queue.v1.json` with an atomic,
32 cross-process-locked update. After restart it is paused until the user
33 explicitly continues. Cancellation leaves
34 `prepared` and `content_ready` reservations for the next explicit attempt.
35 - Existing `content_ready` operations are replayed against their durable target;
36 they are not converted into a second session. Recovery validates the target
37 and lifecycle fences without requiring the old source or its ownership lock.
38 - Archive and purge state remains authoritative. Deleted or archived sessions
39 are not resurrected by a later catalog scan.
40 - Once adopted, the source and its canonical target share one conversation
41 identity. The sidebar displays only the canonical row; archive hides both
42 aliases and creates one trash entry, while restore returns only that row.
43 - Permanent deletion keeps adoption and topic-removal evidence. An explicit
44 purge records source-cleanup intent before removing content and may also
45 remove an unchanged canonical source directory once no active, archived,
46 pending-import, or unresolved recovery owner references it. Shared sources,
47 changed content, legacy multi-file DAG originals, and shared content pools
48 remain intact. A missing historical root does not block canonical deletion.
49 - `PrepareSession`, `GetSessionPreparation`, and
50 `CancelSessionPreparation` expose `queued`, `preparing`, `ready`, `blocked`,
51 `failed`, and `cancelled` scheduling states without adding lifecycle phases.
52 - Source content checks compare durable bytes rather than timestamps or title
53 metadata. A confirmed version can be explicitly imported with
54 `PrepareHistoricalSourceVersion`; its `:review:<fingerprint>` mapping is a
55 separate branch while the original mapping remains stable.
56
57 Discovery publishes a metadata snapshot in the background; ordinary lists only
58 read that snapshot. Renames and pins are applied before search and sorting, and
59 transferred on adoption. A pending sidebar source follows the same navigation
60 preparation owner as history. Cancellation responses are fenced by navigation
61 intent, operation identity, and revision; branch preparation cannot take focus
62 back after the user navigates elsewhere.
63
64 Shutdown drains the batch worker before releasing queue ownership, preserving
65 the current and remaining selections for manual continuation. One process owns
66 a batch worker lease. Sidecar mutations read the latest disk value under the
67 write lock, modify only their owned fields, and atomically replace it; stale
68 queue revisions are rejected rather than overwriting another process's work.
69
70 ## Compatibility
71
72 Discovery, import, archive, and restore leave source files unchanged. Explicit
73 permanent deletion follows the guarded cleanup rules above. Source mappings,
74 recovery entries, and unknown fields remain durable; deleted sessions retain
75 minimal adoption evidence after live presentation and membership are removed.
76 Path normalization aliases resolve older source hashes without rewriting their
77 receipts or pending operation identities. Independent head and reviewed-version
78 identities remain separate; ambiguous normalized ownership is rejected. The
79 path-only legacy route remains an alias for the selected DAG head; valid head
80 indexes expose alternate heads as separate on-demand sources. A missing or
81 stale index degrades to one source row and never causes event-log replay in a
82 listing RPC.
83
84 The queue sidecar is scheduling intent only. The workspace lifecycle registry
85 remains authoritative for target Session IDs and commit state. Older builds
86 ignore the sidecar and optional RPC fields; surviving committed sessions and
87 retained sources remain readable after rollback. Explicitly purged content is
88 not restored by rollback. Older purge journals without source-cleanup intent
89 never gain authority to remove originals on upgrade. Preparation metadata is never added to
90 model prompts or transcript messages.
91
92 | Data | Compatibility behavior |
93 | --- | --- |
94 | Lifecycle registry | No new operation types or phases; existing target IDs and mappings remain authoritative. Optional versioned cleanup intent uses the purge request payload. Older readers may leave originals behind but cannot restore the deleted canonical identity. |
95 | Version 1 queue sidecar | Optional `queueRevision` defaults to zero; existing files load paused. Unknown root and presentation fields survive writes. |
96 | Rollback to pre-sidecar builds | Scheduling is unavailable; retained source files and surviving canonical sessions remain readable. Purged content remains deleted. |
97 | Concurrent older sidecar writers | Older code does not honor the new worker lease/revision contract; do not run mixed-version batch writers. Upgrade all Desktop instances first. |
98
99 ## Verification
100
101 The implementation has deterministic coverage for startup non-migration,
102 cross-process cold-export contention, duplicate and cancelled imports,
103 prepared/content-ready resume, revisioned duplicate preparation, paused queue
104 restart, archive/purge fencing, and browser interactions for listing, retry,
105 open-after-commit, and batch controls. Regression tests additionally cover normal
106 global/project discovery while a source is occupied, title/pin search and adoption,
107 shutdown during commit followed by restart, independent sidecar writers, unknown
108 field preservation, source-independent recovery, and late navigation responses.
109 Lifecycle regressions cover older source hashes across restart, one trash entry,
110 independent heads, shared-source protection, source-writer contention, missing
111 historical roots, and process exit before and after source cleanup.
112
112 lines MARKDOWN