@sema-agent/server 7.138.0 → 7.139.0
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/MIGRATION.md +276 -7
- package/README.md +7 -4
- package/README.zh-CN.md +6 -4
- package/USAGE.md +73 -29
- package/deploy/sema-up/README.md +1 -1
- package/deploy/sema-up/lib/lanes.json +3 -2
- package/dist/adoption/wire.d.ts +3 -3
- package/dist/approval-card.d.ts +20 -20
- package/dist/bench/s1/arms.d.ts +1 -1
- package/dist/bench/s1/arms.js +1 -3
- package/dist/bench/s1/run-firm.js +2 -2
- package/dist/boot/device-lane.d.ts +8 -3
- package/dist/boot/device-lane.js +7 -2
- package/dist/boot/execution-env.d.ts +4 -2
- package/dist/boot/execution-env.js +16 -24
- package/dist/boot/execution-lane.d.ts +1 -1
- package/dist/boot/governance-seams.d.ts +3 -2
- package/dist/boot/governance-seams.js +9 -11
- package/dist/boot/memory-consolidation.js +2 -2
- package/dist/boot/resolve-spec.d.ts +1 -1
- package/dist/boot/resolve-spec.js +8 -9
- package/dist/boot/retention-lane.d.ts +5 -5
- package/dist/boot/retention-lane.js +0 -6
- package/dist/boot/runner-deps.d.ts +3 -1
- package/dist/boot/runner-deps.js +2 -1
- package/dist/boot/session-faces.d.ts +0 -3
- package/dist/boot/session-faces.js +15 -8
- package/dist/boot/stage-02-web-admin-pull.js +2 -2
- package/dist/boot/stage-05-execution-env.js +2 -2
- package/dist/boot/stage-06-runners.js +0 -1
- package/dist/boot/stage-09-leader.js +1 -2
- package/dist/boot/stage-10-http-server.js +2 -2
- package/dist/boot/stores.js +4 -4
- package/dist/boot/web-admin.js +2 -2
- package/dist/capabilities/mcp-probe.js +1 -1
- package/dist/capabilities/scenarios.d.ts +1 -1
- package/dist/capability-facts.d.ts +15 -7
- package/dist/capability-facts.js +8 -3
- package/dist/config-catalog.js +7 -7
- package/dist/config-invariants.d.ts +23 -3
- package/dist/config-invariants.js +42 -0
- package/dist/config-provider.d.ts +19 -24
- package/dist/config-provider.js +27 -12
- package/dist/config-types.d.ts +10 -5
- package/dist/config.d.ts +33 -0
- package/dist/config.js +44 -15
- package/dist/delegated-session-owner.d.ts +2 -2
- package/dist/deployment-shape.d.ts +1 -1
- package/dist/device-enrollment.d.ts +41 -2
- package/dist/device-enrollment.js +27 -12
- package/dist/device-store.d.ts +58 -85
- package/dist/device-store.js +19 -49
- package/dist/device-ws-hub.js +2 -1
- package/dist/env-name-allowlist-knobs.d.ts +5 -4
- package/dist/exec-cut.d.ts +60 -0
- package/dist/exec-cut.js +36 -0
- package/dist/execution-lane-caps.d.ts +19 -0
- package/dist/execution-lane-caps.js +10 -0
- package/dist/execution-placement.d.ts +259 -0
- package/dist/execution-placement.js +199 -0
- package/dist/field-conflict.d.ts +3 -2
- package/dist/field-conflict.js +1 -0
- package/dist/hosted-posture.d.ts +2 -2
- package/dist/http/admission.js +8 -19
- package/dist/http/checkpoint-ctx.d.ts +21 -12
- package/dist/http/checkpoint-ctx.js +4 -2
- package/dist/http/claimed-run.d.ts +1 -1
- package/dist/http/durable-run-leg.js +9 -5
- package/dist/http/execution-context.d.ts +218 -0
- package/dist/http/execution-context.js +330 -0
- package/dist/http/resume-legs.js +50 -20
- package/dist/http/route-ctx.d.ts +14 -8
- package/dist/http/routes/background.d.ts +29 -1
- package/dist/http/routes/background.js +29 -2
- package/dist/http/routes/devices.d.ts +13 -19
- package/dist/http/routes/devices.js +21 -26
- package/dist/http/routes/session-sync.js +110 -15
- package/dist/http/routes/sessions.d.ts +6 -0
- package/dist/http/routes/sessions.js +115 -11
- package/dist/http/routes/side-query.d.ts +12 -4
- package/dist/http/routes/side-query.js +4 -5
- package/dist/http/routes/tasks.js +37 -31
- package/dist/http/server.d.ts +35 -19
- package/dist/http/server.js +11 -0
- package/dist/http/session-inherit-env.d.ts +3 -4
- package/dist/http/session-inherit-env.js +1 -1
- package/dist/http/wire-types.d.ts +8 -12
- package/dist/index.d.ts +1 -0
- package/dist/memory-sync-client.d.ts +53 -14
- package/dist/memory-sync-client.js +196 -116
- package/dist/memory-sync.d.ts +1 -1
- package/dist/memory-sync.js +3 -2
- package/dist/observability/cost-taxonomy.d.ts +2 -2
- package/dist/observability/fail-open.d.ts +12 -0
- package/dist/observability/fail-open.js +12 -0
- package/dist/observability/run-terminal.js +0 -1
- package/dist/orchestration/workflow-notify-journal.js +4 -4
- package/dist/org-memory-admission.d.ts +4 -3
- package/dist/org-memory-admission.js +6 -6
- package/dist/parked-decide.d.ts +34 -9
- package/dist/parked-decide.js +12 -19
- package/dist/parked-revive-surface.d.ts +12 -15
- package/dist/parked-revive-surface.js +3 -6
- package/dist/peer-seat.d.ts +13 -7
- package/dist/peer-seat.js +37 -3
- package/dist/plugins/approval-ask-store-file.d.ts +7 -0
- package/dist/plugins/approval-ask-store-file.js +11 -0
- package/dist/plugins/approval-ask-store-memory.d.ts +6 -0
- package/dist/plugins/approval-ask-store-memory.js +12 -0
- package/dist/plugins/approval-ask-store-sql.d.ts +22 -5
- package/dist/plugins/approval-ask-store-sql.js +30 -12
- package/dist/plugins/caching-session-store.d.ts +6 -2
- package/dist/plugins/caching-session-store.js +9 -3
- package/dist/plugins/checkpoint-store-sql.d.ts +6 -5
- package/dist/plugins/checkpoint-store-sql.js +5 -7
- package/dist/plugins/device-store-sql.d.ts +25 -51
- package/dist/plugins/device-store-sql.js +49 -103
- package/dist/plugins/execution-placement-sql.d.ts +151 -0
- package/dist/plugins/execution-placement-sql.js +223 -0
- package/dist/plugins/file-history-store-sql.d.ts +7 -6
- package/dist/plugins/file-history-store-sql.js +5 -5
- package/dist/plugins/file-run-store.d.ts +6 -1
- package/dist/plugins/file-run-store.js +4 -0
- package/dist/plugins/fork-routing-session-store.d.ts +6 -0
- package/dist/plugins/fork-routing-session-store.js +16 -0
- package/dist/plugins/local-session-store.d.ts +149 -50
- package/dist/plugins/local-session-store.js +382 -107
- package/dist/plugins/memory-key-guards.d.ts +4 -0
- package/dist/plugins/memory-key-guards.js +1 -0
- package/dist/plugins/memory-run-store.d.ts +1 -1
- package/dist/plugins/one-time-migrations.d.ts +111 -3
- package/dist/plugins/one-time-migrations.js +380 -10
- package/dist/plugins/outcome-ledger-sql.d.ts +2 -2
- package/dist/plugins/permission-rule-store-sql.d.ts +13 -15
- package/dist/plugins/permission-rule-store-sql.js +13 -16
- package/dist/plugins/pg-pool.d.ts +7 -3
- package/dist/plugins/pg-session-storage.d.ts +31 -20
- package/dist/plugins/pg-session-storage.js +120 -52
- package/dist/plugins/remote-env-adb.d.ts +20 -4
- package/dist/plugins/remote-env-adb.js +70 -62
- package/dist/plugins/remote-env-device.d.ts +30 -12
- package/dist/plugins/remote-env-device.js +18 -17
- package/dist/plugins/remote-env-e2b.d.ts +18 -4
- package/dist/plugins/remote-env-e2b.js +41 -42
- package/dist/plugins/remote-env-file-error.d.ts +2 -0
- package/dist/plugins/remote-env-file-error.js +1 -1
- package/dist/plugins/remote-env-host.d.ts +21 -8
- package/dist/plugins/remote-env-host.js +66 -70
- package/dist/plugins/remote-env-k8s.d.ts +11 -16
- package/dist/plugins/remote-env-k8s.js +61 -54
- package/dist/plugins/remote-env-local-docker.d.ts +29 -6
- package/dist/plugins/remote-env-local-docker.js +46 -59
- package/dist/plugins/remote-env-ssh.d.ts +16 -4
- package/dist/plugins/remote-env-ssh.js +72 -56
- package/dist/plugins/remote-shell.d.ts +100 -3
- package/dist/plugins/remote-shell.js +166 -2
- package/dist/plugins/retention-store-sql.d.ts +9 -6
- package/dist/plugins/retention-store-sql.js +7 -1
- package/dist/plugins/run-store-sql.d.ts +13 -3
- package/dist/plugins/run-store-sql.js +5 -0
- package/dist/plugins/schema-consistency.d.ts +15 -5
- package/dist/plugins/schema-consistency.js +14 -8
- package/dist/plugins/schema-drift-sentence.d.ts +27 -0
- package/dist/plugins/schema-drift-sentence.js +38 -0
- package/dist/plugins/session-fork.d.ts +54 -0
- package/dist/plugins/session-fork.js +38 -1
- package/dist/plugins/session-row-sql.d.ts +22 -0
- package/dist/plugins/session-row-sql.js +81 -0
- package/dist/plugins/session-store.d.ts +1 -1
- package/dist/plugins/store-backend.d.ts +1 -1
- package/dist/plugins/store-backend.js +19 -7
- package/dist/plugins/store-contracts.d.ts +25 -5
- package/dist/plugins/tidb-pool.d.ts +12 -7
- package/dist/plugins/tidb-pool.js +9 -3
- package/dist/plugins/tidb-session-store.d.ts +57 -26
- package/dist/plugins/tidb-session-store.js +118 -50
- package/dist/plugins/tool-result-store-sql.d.ts +3 -2
- package/dist/plugins/tool-result-store-sql.js +18 -10
- package/dist/project-memory.d.ts +9 -15
- package/dist/project-memory.js +5 -4
- package/dist/request-key-closure.js +1 -1
- package/dist/request-value-closure.d.ts +6 -7
- package/dist/request-value-closure.js +1 -3
- package/dist/run-local.d.ts +6 -0
- package/dist/run-local.js +24 -20
- package/dist/runs.d.ts +2 -1
- package/dist/runs.js +3 -1
- package/dist/security.d.ts +38 -12
- package/dist/security.js +8 -2
- package/dist/server-secret-env.d.ts +9 -5
- package/dist/session-children-retire.d.ts +27 -9
- package/dist/session-children-retire.js +9 -5
- package/dist/session-incarnation.d.ts +19 -9
- package/dist/session-incarnation.js +4 -2
- package/dist/session-row.d.ts +114 -5
- package/dist/session-row.js +55 -5
- package/dist/session-titler.d.ts +2 -2
- package/dist/task-a2a.d.ts +1 -1
- package/dist/task-cwd.d.ts +6 -1
- package/dist/task-mcp.d.ts +3 -3
- package/dist/tool-approval.d.ts +6 -0
- package/dist/tool-approval.js +8 -1
- package/dist/trace/project.d.ts +1 -0
- package/dist/trace/project.js +1 -0
- package/dist/trace/self-minted-wire.d.ts +111 -2
- package/dist/trace/self-minted-wire.js +38 -1
- package/dist/url-refusal.d.ts +1 -1
- package/dist/web-admin-client/apply-effective.d.ts +17 -3
- package/dist/web-admin-client/apply-effective.js +20 -10
- package/dist/web-admin-client/skills-mcp.js +3 -2
- package/dist/web-admin-client/types.d.ts +6 -0
- package/package.json +3 -3
- package/wire-changes/server@7.139.0.json +348 -0
- package/dist/http/device-placement.d.ts +0 -175
- package/dist/http/device-placement.js +0 -145
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { FileSessionRepo, type AcquiredSession, type SessionHead, type SessionStore, type SessionRepo, type SessionTreeEntry } from "@sema-agent/core";
|
|
2
|
-
import type { SessionRunRollupSource, SessionSummary } from "./store-contracts.js";
|
|
3
|
-
import type
|
|
2
|
+
import type { SessionRunClaimSource, SessionRunRollupSource, SessionSummary } from "./store-contracts.js";
|
|
3
|
+
import { type ClientSessionRowWrite, type ReplaySessionRowWrite, type ReplaySessionRowWriteOutcome, type SessionRowPatch, type SessionRowWriteOutcome } from "../session-row.js";
|
|
4
4
|
import { type Logger } from "../observability/logger.js";
|
|
5
5
|
import { type SessionFace } from "../session-incarnation.js";
|
|
6
|
+
import { type ExecutionPlacementSeat, type LocalPlacementBackfillSeat } from "../execution-placement.js";
|
|
7
|
+
import { type ForkTarget, type ForkToOutcome } from "./session-fork.js";
|
|
6
8
|
import { type InstructionSourceBaseline } from "../instruction-source-notice.js";
|
|
7
9
|
import type { SessionWorkspace } from "../session-workspace.js";
|
|
8
10
|
import { type StagedCommitOptions, type StagingHandle, type SyncRelation } from "../session-sync-kernel.js";
|
|
@@ -54,8 +56,8 @@ export declare class LocalSessionStore implements SessionStore {
|
|
|
54
56
|
/** Absolute path to the lastActivity JSON sidecar, or undefined when not persisting (in-memory-only deployment). */
|
|
55
57
|
private readonly sidecarPath?;
|
|
56
58
|
/** Title map (`session-titles.json`) — the local twin of the SQL `session_meta.title` column: one cell, two writers
|
|
57
|
-
* (the user's {@link
|
|
58
|
-
* only — writer order: `src/session-row.ts
|
|
59
|
+
* (the user's {@link writeSessionRowCells}; the auto-titler's {@link setTitleIfNull}, fills an absent cell
|
|
60
|
+
* only — writer order: `src/session-row.ts`; both under the session write lock). Separate file from the lastActivity sidecar ON PURPOSE (that format is a
|
|
59
61
|
* #10 clobber area); ultra-low-rate. Cross-instance sharing: see {@link SidecarMap}. */
|
|
60
62
|
private readonly titles;
|
|
61
63
|
/** Pin map (`session-pinned.json`, {@link readPinnedSidecar}) — the local twin of `session_meta.pinned`. Its own file for
|
|
@@ -82,13 +84,27 @@ export declare class LocalSessionStore implements SessionStore {
|
|
|
82
84
|
/** 认领行(`session_owner_claimed`)的出口 —— 一次性迁移 M10 的认领臂专用(窗口见 `plugins/one-time-migrations.ts` 登记表)。 */
|
|
83
85
|
private readonly log;
|
|
84
86
|
/**
|
|
85
|
-
* 按会话的写锁(表见 {@link SESSION_WRITE_LOCKS_BY_ROOT})—— 会话行两位的**每一笔**写(
|
|
87
|
+
* 按会话的写锁(表见 {@link SESSION_WRITE_LOCKS_BY_ROOT})—— 会话行两位的**每一笔**写(用户的行格写原语:判 → 边档草稿 → 落盘 → 发布;自动标题器的
|
|
88
|
+
* `setTitleIfNull`:见格在就不写)与同一 id 上住客的**每一次**换人
|
|
86
89
|
* (删除:存档 + 三只行边档 + 元数据格;按 id 建会话:打开即建、登记;导入:铸新住客;换装:删后插回;staged 导入的提交)排在同一条链上:判过的住客
|
|
87
90
|
* 在那一笔发布完之前不会被换掉,删除不会落在「判过、未发布」之间,同 id 的新住客也不会在删除做到一半时生出来、再被它的收尾抹掉。只有这一把;
|
|
88
91
|
* SQL 孪生是一条带化身条件的 UPDATE、一条事务里的删除,没有这个窗,不需要它。按 id 的 acquire(打开 / 首建)也在这条链上:交出的会话挂的住客与打开
|
|
89
92
|
* 同一节读到(见 `load`)。新 id 的建会话(不带 id 的 acquire、fork)不与任何人争同一 id,不上锁。
|
|
90
93
|
*/
|
|
91
94
|
private readonly sessionWriteLocks;
|
|
95
|
+
/**
|
|
96
|
+
* 执行席(规则在 `src/execution-placement.ts`):读 = 那一格的 `execution` 位(fork 创建的格而存档不在 ⇒ `forking`);place / markMirror 在这只会话的写锁里判住客
|
|
97
|
+
* (化身 + 头读投影的属主 `owner ?? null`)再只改 `execution` 那一位 —— 住客换了(删后重建、M10 窗内认领)⇒ `gone`,不写。
|
|
98
|
+
* 认领(run 店的单活槽,{@link SessionRunClaimSource}):`markMirror` 在同一把写锁里读它、只拦「absent → mirror」这一笔(判序与 SQL 孪生同,见 {@link markMirrorExecution});`place` 是认领持有者自己的初始放置写,不读认领。
|
|
99
|
+
* local 的导入三写口不读认领 —— 它们的认领判在路由(第一阶段写前判 + 提交前复判),没有 SQL 孪生那样的写事务内读。
|
|
100
|
+
*/
|
|
101
|
+
readonly executionPlacement: ExecutionPlacementSeat;
|
|
102
|
+
/**
|
|
103
|
+
* 一次性迁移 M32 的 local 腿用的席(随 M32 · 窗口见 `one-time-migrations.ts` 登记表):`read` 与 {@link executionPlacement} 的 `read` 是**同一读**({@link placementRead}),只差「这只会话的存档读不出」这一形
|
|
104
|
+
* (格缺而探针读不出;fork 创建的格而探针说不出在不在)—— 席的读照旧抛那只故障,本席答 {@link UnusableArchive}(开机回填不动存档、只补一格放置:读不出的会话由回填点名跳过,不拒启)。
|
|
105
|
+
* `place` 就是席的 `place`。
|
|
106
|
+
*/
|
|
107
|
+
readonly executionPlacementBackfill: LocalPlacementBackfillSeat;
|
|
92
108
|
/** @param repo the core SessionRepo this store projects into the §0.5 SessionStore shape.
|
|
93
109
|
* @param runs the run store whose per-session projection is the ONLY source of a row's `runCount` / `lastStatus` / `lastRunId` /
|
|
94
110
|
* `lastTaskRunId` (LocalBackend passes its `FileRunStore`). Required — a run-less local session store does not exist.
|
|
@@ -97,9 +113,41 @@ export declare class LocalSessionStore implements SessionStore {
|
|
|
97
113
|
* restart (the file-backed deployment); omit it for the in-memory deployment (nothing survives).
|
|
98
114
|
* @param opts.log the `session_owner_claimed` line's sink (LocalBackend passes a logger at the deployment's LOG_LEVEL;
|
|
99
115
|
* absent ⇒ an info-level JSON-line logger — a claim is never silent). */
|
|
100
|
-
constructor(repo: HeadReadingSessionRepo, runs: SessionRunRollupSource, dataDir?: string, opts?: {
|
|
116
|
+
constructor(repo: HeadReadingSessionRepo, runs: SessionRunRollupSource & SessionRunClaimSource, dataDir?: string, opts?: {
|
|
101
117
|
log?: Pick<Logger, "info">;
|
|
102
118
|
});
|
|
119
|
+
/**
|
|
120
|
+
* 这一格此刻是不是 `forking`(fork 创建的格 {@link isForkCreatedCell} ∧ 存档不在)。存档在不在只问 repo 的唯一探针 {@link probeArchive} 的「不在」—— **只问有没有**:存档在而用不了(会话头读不出 / 截断)
|
|
121
|
+
* 是「在」,内容读不读得出归真正读内容的那一读(门之后、体之前读一次叶子,读不出 ⇒ `corrupt_session`)。所以带键的会话与不带键的会话在执行席上同形,坏档照样能被换装修好
|
|
122
|
+
* (换装是修坏档的唯一路径)。**唯一的例外是探针说不出在不在**(`storage` 词:读的时候抛了别的故障)⇒ 不替它答 forking 与否:{@link forkingOf} 把那只故障上抛(要对这只会话动手的读者 ——
|
|
123
|
+
* 写口的判、登记、缺档新建臂 —— 看到它就抛),{@link forkingRead} 交出 {@link UnusableArchive}(执行席的读上抛它,回填席点名它)。持这只会话的写锁时读数稳定(改存档在不在的写者都持这把锁);锁外是一次观察。
|
|
124
|
+
*/
|
|
125
|
+
private forkingRead;
|
|
126
|
+
/** {@link forkingRead} 的上抛一形(与 {@link metaOf} 之于 {@link metaRead} 同一条规矩):探针说不出在不在 ⇒ 抛那只故障、原样。 */
|
|
127
|
+
private forkingOf;
|
|
128
|
+
/**
|
|
129
|
+
* 执行放置的读**本体**(一次:那一格 + 必要时的存档探针;两只席的读共用这一只)。行不在 ⇒ `undefined`;盘上有会话而格缺 ⇒ 补铸(与 {@link headOf} 同一只 {@link metaRead});
|
|
130
|
+
* 存档读不出({@link UnusableArchive}:格缺而探针读不出 ⇒ 不补铸;fork 创建的格而探针说不出在不在 ⇒ {@link forkingRead} 交出)⇒ 交出这只 {@link UnusableArchive}。
|
|
131
|
+
* 上抛还是点名,归两只席各自的读者({@link readExecutionPlacement} 上抛那只故障;{@link executionPlacementBackfill} 原样交出)。
|
|
132
|
+
*/
|
|
133
|
+
private placementRead;
|
|
134
|
+
/** 执行席的读(core 席的合同:读故障抛,不吞成 absent):{@link placementRead} 的本体,存档读不出 ⇒ 上抛那只故障、原样(与 {@link metaOf} 同一条规矩:要动存档的读者看到读不出就抛)。 */
|
|
135
|
+
private readExecutionPlacement;
|
|
136
|
+
/** place(锁内):判官 {@link settledPlaceOutcome} 在写链的草稿上判(与登记的防 clobber 同一处),可写 ⇒ 只改 `execution` 位。 */
|
|
137
|
+
private placeExecution;
|
|
138
|
+
/**
|
|
139
|
+
* identical 臂补 mirror(锁内):先在这只会话的写锁里读 run 认领(行在才读;SQL 孪生:写事务内锁根行后读 `task_active`,根行不在 ⇒ 不读),再交判官 {@link settledMirrorOutcome};
|
|
140
|
+
* 判官的答案先于认领 —— 行不在 / 住客不同 ⇒ `gone`、writer ⇒ `writer`、已是 mirror ⇒ `mirrored`(幂等零写)都不被认领改写;只有「absent → mirror」这一笔写
|
|
141
|
+
* 遇上认领 ⇒ `active`(带那只认领的 task id,格不写)。可写且无认领 ⇒ 只改 `execution` 位为 mirror。
|
|
142
|
+
*/
|
|
143
|
+
private markMirrorExecution;
|
|
144
|
+
/**
|
|
145
|
+
* 执行位两只写口的锁内一形(调用方持这只会话的写锁):在写链的草稿上读出这一格(`forking` 在锁内先判 —— 改存档在不在的写者都持这把锁)、交判官,
|
|
146
|
+
* 判官给 `execution` ⇒ 只改那一位。判官 / 解码抛的错**不在写链里抛**(写链一节抛了会把共享链留成拒态):收下、写链这一节不写、出链后原样上抛。
|
|
147
|
+
*/
|
|
148
|
+
private settleExecutionHeld;
|
|
149
|
+
/** 已发布的那一格(同步读;调用方先 `meta.ensureLoaded()`)。 */
|
|
150
|
+
private metaCellOf;
|
|
103
151
|
/**
|
|
104
152
|
* 把 `sessionId` 那一格写成 `next(before)` 的结果并**落盘**(写链里在草稿上判、写、落盘后才发布给读者 —— 与 instruction-source 同一只 `commit`;
|
|
105
153
|
* 判据建立在每一节之前的盘上状态上,所以防 clobber 的「已记下就不动」写在 `next` 里,不写在链外)。`next` 返回 `undefined` = 不改。
|
|
@@ -114,7 +162,15 @@ export declare class LocalSessionStore implements SessionStore {
|
|
|
114
162
|
* 不可重入 —— 锁里的调用方只调 `…Held` 那一形(它们假定锁已在手),不再回到上锁的公开口。
|
|
115
163
|
*/
|
|
116
164
|
private withSessionWriteLock;
|
|
117
|
-
/**
|
|
165
|
+
/**
|
|
166
|
+
* 盘上这只会话的存档此刻是什么状态(repo 的**唯一探针**;`open` 读整只存档,所以只在边档里没有那一格、或要判 `forking` 时才走到这里)。三种答案:
|
|
167
|
+
* 不在(`not_found`)· 在而读得出 · 读不出({@link UnusableArchive}:`corrupt_session` / `invalid_session` = 在而内容用不了;`storage` = 读的时候抛了别的故障,I/O 级,
|
|
168
|
+
* 说不出在不在 —— 词的读法见 {@link archiveFaultWord})。探针**不吞也不改**那只故障:{@link UnusableArchive.fault} 就是抛出来的那一只,每个读者各自决定上抛还是点名 ——
|
|
169
|
+
* 要对这份存档动手的({@link existsInRepo};{@link metaOf};{@link readExecutionPlacement})一律上抛它;一次性迁移 M32 的回填({@link executionPlacementBackfill})经
|
|
170
|
+
* {@link metaRead} / {@link forkingRead} 收下它、点名跳过,不上抛。只问有没有的 {@link forkingRead} 把 `corrupt_session` / `invalid_session` 读作「在」(存档找到了),`storage` 不替它答。
|
|
171
|
+
*/
|
|
172
|
+
private probeArchive;
|
|
173
|
+
/** 盘上有没有一份**读得出**的这只会话的存档(补铸 / 登记 / 导入的落点判 / fork 目标这些要对存档动手的读者用):用不了的存档照旧上抛它的故障。 */
|
|
118
174
|
private existsInRepo;
|
|
119
175
|
/**
|
|
120
176
|
* 一只会话的元数据 —— 属主与化身的**唯一读口**(按 id 读 {@link headOf} / 删除与换装的属主门都经它)。`undefined` = 无此会话。
|
|
@@ -122,6 +178,12 @@ export declare class LocalSessionStore implements SessionStore {
|
|
|
122
178
|
* ⇒ 补铸一格只有化身的(属主没有事实可写,不伪造)并落盘后再答 —— 之后的读都命中那一格,不再回 repo。
|
|
123
179
|
*/
|
|
124
180
|
private metaOf;
|
|
181
|
+
/**
|
|
182
|
+
* {@link metaOf} 的本体(三态,不抛「用不了」):边档里有那一格 ⇒ 读它;没有 ⇒ 问**唯一探针** {@link probeArchive} 一次 —— 不在 ⇒ 无此会话;在而读得出 ⇒ 补铸({@link cellOfPresent});
|
|
183
|
+
* 读不出 ⇒ {@link UnusableArchive}(**不补铸**:不替一份读不出的存档铸化身)。要动存档的读者({@link metaOf})把它上抛;不动存档、只要「有没有」的读者
|
|
184
|
+
* ({@link executionPlacementBackfill})原样收下。
|
|
185
|
+
*/
|
|
186
|
+
private metaRead;
|
|
125
187
|
/**
|
|
126
188
|
* 一只**已证明在盘上**的会话的那一格:有 ⇒ 读它;没有(7.104.0 之前写下、此后没被读过)⇒ 补铸一格只有化身的(属主没有事实可写,不伪造)
|
|
127
189
|
* 并落盘后再答。证明由调用方给:{@link metaOf} 探过 repo;acquire 的打开腿在这只会话的写锁里刚打开它({@link openForItselfHeld})。
|
|
@@ -150,21 +212,35 @@ export declare class LocalSessionStore implements SessionStore {
|
|
|
150
212
|
probeTitle(sessionId: string): Promise<"none" | "untitled" | "titled">;
|
|
151
213
|
/** The auto-titler's write (the local twin of the SQL setTitleIfNull): lands only on an absent cell — a title already
|
|
152
214
|
* there (the user's included) wins. Persists the whole (small) map via a SERIALIZED tmp+rename snapshot; a write
|
|
153
|
-
* failure keeps the in-memory title (degrades to re-title after restart).
|
|
215
|
+
* failure keeps the in-memory title (degrades to re-title after restart). Runs under this session's write lock — the
|
|
216
|
+
* user's conditional write ({@link writeSessionRowCells}) judges its row tag and writes under the same lock, so the two
|
|
217
|
+
* writers of the title cell never interleave between a judgement and its write (the SQL twins get this from the row lock). */
|
|
154
218
|
setTitleIfNull(sessionId: string, title: string): Promise<boolean>;
|
|
155
219
|
/**
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
* `
|
|
159
|
-
*
|
|
160
|
-
* `title` 串 ⇒
|
|
220
|
+
* 会话行格写原语 —— 用户标题 / 置顶的**唯一**写口(SQL 孪生 `writeSessionRowCells` 的 local 对位;规则与判序:`src/session-row.ts` 头注「写原语」)。
|
|
221
|
+
* **整段在这只会话的写锁里**({@link withSessionWriteLock}):读出锁住的那一行(会话元数据那一格的属主 + 化身 + 执行位、列表面上有它、两只边档的格)→
|
|
222
|
+
* 同一只判官 `judgeSessionRowWrite`(行期望 → 写者身份 → 标签)→ 写 → 应答行(同锁内另读,经 `settleSessionRowWrite` 复核住客)。删除 / 导入 /
|
|
223
|
+
* 换装 / 登记 / 自动标题器同锁,判过的那一行在这一笔发布完之前换不掉。行期望带 `log` 时读这只会话存档的 mark(存档的追加不走这把锁 —— 那一维在 local 上是一次观察)。
|
|
224
|
+
* `title` 串 ⇒ 写进那一格(自动标题器的 {@link setTitleIfNull} 见格在就不写 ⇒ 用户那笔恒留下);`title: null` ⇒ 删那一格(清回自动标题);
|
|
161
225
|
* `pinned:true` 写 `true`、`false` 删键。
|
|
162
|
-
*
|
|
163
|
-
* (SQL 孪生是一条 UPDATE)
|
|
226
|
+
* local 的保证是「互斥 + 先判后写」,**不是多文件原子提交**:落不了盘 ⇒ 抛、那一只边档的内存不动;两键同一体时是两只文件、两次落盘,第二只落不了时第一只
|
|
227
|
+
* 已在盘上、标签已变(SQL 孪生是一条 UPDATE)—— 恢复 = 读当前行(或下一次带旧标签得 `changed` 的应答行)按它重发,收敛。`lastActivity` 不动(改名不是活动)。
|
|
228
|
+
* 重载按入口分:`replay` 的结局只有 `written` / `absent`。
|
|
229
|
+
*/
|
|
230
|
+
writeSessionRowCells(sessionId: string, cells: SessionRowPatch, how: ClientSessionRowWrite): Promise<SessionRowWriteOutcome<SessionSummary>>;
|
|
231
|
+
writeSessionRowCells(sessionId: string, cells: SessionRowPatch, how: ReplaySessionRowWrite): Promise<ReplaySessionRowWriteOutcome<SessionSummary>>;
|
|
232
|
+
/**
|
|
233
|
+
* 写原语锁住的那一行(调用方持这只会话的写锁并已 {@link loadRowSidecars}):会话元数据那一格(属主 `owner ?? null` —— 与头读、列表行同读;化身经
|
|
234
|
+
* `incarnationFromCell` 的 `absent` 读法;执行位 `mirror`)+ 列表面上有它(会话仓里有;`forking` 中间态的存档不在 ⇒ 不在列表上)+ 两只边档的格。
|
|
235
|
+
* 没有那一格或不在列表面上 ⇒ `undefined`(没有行)。local 没有委派分区行。
|
|
164
236
|
*/
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
private
|
|
237
|
+
private lockedRowOf;
|
|
238
|
+
/** 两只边档上这只会话的可写格(已发布的值;缺键 = 缺省)。调用方先 {@link loadRowSidecars}。 */
|
|
239
|
+
private rowCellsOf;
|
|
240
|
+
/** 写原语的格写(锁内一形,调用方持这只会话的写锁):两只边档各经自己的写链(草稿 → 落盘 → 发布);落不了盘 ⇒ 抛、那一只的内存不动。 */
|
|
241
|
+
private writeRowCellsHeld;
|
|
242
|
+
/** 应答行(锁内另读):列表行同一只合成 + 读到它时那一格上的住客。不在列表面上 / 没有那一格 ⇒ `undefined`。 */
|
|
243
|
+
private listRowOf;
|
|
168
244
|
/** ONE session's list row — {@link listSessions}' projection ({@link summaryOf}, the same synthesis) for one id;
|
|
169
245
|
* `undefined` = not a row of the list face (not in the session repo). */
|
|
170
246
|
sessionSummaryOf(sessionId: string): Promise<SessionSummary | undefined>;
|
|
@@ -287,6 +363,8 @@ export declare class LocalSessionStore implements SessionStore {
|
|
|
287
363
|
private ownerCellOf;
|
|
288
364
|
/** 一只会话的列表行 —— {@link listSessions} 与 {@link sessionSummaryOf} 的**同一只**合成(字段来源逐位见 listSessions 的头注)。调用方先 {@link loadRowSidecars}。 */
|
|
289
365
|
private summaryOf;
|
|
366
|
+
/** 列表行的 `rowTag` 键(规则 `session-row.ts`):化身出自会话元数据那一格(与写原语锁住的那一行同读),属主与两格由调用方交 —— 就是这一行交出去的那两位(同一刻读);没有那一格 ⇒ 键缺席。 */
|
|
367
|
+
private rowTagKeyOf;
|
|
290
368
|
/** [ref]:run 店里每个会话的 run 投影(按 sessionId 索引)。
|
|
291
369
|
* **一次读**:run 店的 `listSessions` 本来就按会话聚合全账(无会话过滤口),这里取全量再按会话仓的 id 查表 —— 比逐会话 N 次读便宜,
|
|
292
370
|
* 也不在会话店里另存一份 run 账。读失败 ⇒ 抛(不吞成 `0 / ""`:那会把「读不到」说成「没跑过」)。 */
|
|
@@ -308,6 +386,19 @@ export declare class LocalSessionStore implements SessionStore {
|
|
|
308
386
|
* 把它的答案原样交给引擎自己的 `repo.fork`(与 core 内存店 `TtlSessionStore.fork` 同一条调用链);两只 SQL 孪生同读它(`session-fork.ts`)。钉:
|
|
309
387
|
* core 店契约盒的 `[fork]` 格(`test/session-store-contract-kit.test.ts`)。 */
|
|
310
388
|
fork(sourceId: string, owner?: string | null): Promise<string | null>;
|
|
389
|
+
/**
|
|
390
|
+
* **fork 续写的店契约**(local 一形;规则与结果闭集在 `session-fork.ts`,SQL 孪生同义):
|
|
391
|
+
* · **两把写锁**:按 id 字典序依次取源与目标的写锁(锁不可重入;同 id 只取一把)—— 同 id 的每个写者(删除 / 登记 / 导入 / 按 id 首建 / 别的 fork)都在目标那把锁里,
|
|
392
|
+
* core `repo.fork` 的改名覆盖写只在锁内被调;
|
|
393
|
+
* · **源先判**:源存档不在 ⇒ `null`(源被删之后的同键重试答「源不在」);属主读在拷贝之前(源锁持到拷贝落定)—— 唯一读法 `forkOwnerOf`;
|
|
394
|
+
* · **唯一创建点 = 格先、存档后**:锁内「目标格不在 ∧ 目标存档不在」才写目标格(带 fork 键;新住客,执行位 absent),再交 core `repo.fork` 写存档。
|
|
395
|
+
* 崩在两步之间 = fork 创建的格而存档不在 = `forking`:普通取用一律 {@link SessionForkInProgressError};同键重试在两把锁内补拷存档、答 `replayed`。
|
|
396
|
+
* 拷贝抛错(不是崩溃)⇒ 撤掉刚写的目标格再上抛(撤不掉 ⇒ 留下的就是 `forking`,与崩在中间同形);
|
|
397
|
+
* · **撞已在** ⇒ 按目标格的属主与 fork 键分类({@link classifyForkTarget})。
|
|
398
|
+
*/
|
|
399
|
+
forkTo(sourceId: string, owner: string | null, target: ForkTarget): Promise<ForkToOutcome | null>;
|
|
400
|
+
/** {@link forkTo} 的锁内一形(调用方持源与目标两把写锁)。 */
|
|
401
|
+
private forkToHeld;
|
|
311
402
|
/** 2c session-sync — EXPORT a session's full durable entry log (core `SessionRepo.exportEntries`; the
|
|
312
403
|
* in-memory/file repo holds the whole log so there is no floor to bypass). null if the source is unknown / the
|
|
313
404
|
* underlying repo lacks the optional seam. The owner is NOT exported — import re-stamps it. */
|
|
@@ -329,58 +420,65 @@ export declare class LocalSessionStore implements SessionStore {
|
|
|
329
420
|
batchSize?: number;
|
|
330
421
|
}): Promise<AsyncIterable<SessionTreeEntry> | null>;
|
|
331
422
|
/**
|
|
332
|
-
* 2c session-sync — IMPORT a verbatim entry log into `sessionId`(
|
|
333
|
-
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
423
|
+
* 2c session-sync — IMPORT a verbatim entry log into a **new** session `sessionId`(`owner` = 鉴权过的导入者)。按接口句(`importEntries` 只建新会话;改写既有会话走
|
|
424
|
+
* {@link replaceEntries} / 暂存提交),SQL 孪生同判(占行不成 ⇒ 拒):id 上已有行(或格缺而存档在)⇒ `conflict`,一个字节不写;新行的属主 = 导入者、铸一只化身、
|
|
425
|
+
* 执行位 mirror。属主在本店的属主格上判(会话元数据那一格是本店唯一的属主真源;本店建的存档在引擎仓里不带属主戳 —— `register` 只 `repo.create({ id })` ——
|
|
426
|
+
* 引擎仓的属主比较替这一格答不了)。整段在这只会话的写锁里,写序见 {@link importHeld}。
|
|
336
427
|
*/
|
|
337
428
|
importEntries(sessionId: string, owner: string | null, entries: SessionTreeEntry[]): Promise<void>;
|
|
338
429
|
/**
|
|
339
430
|
* 2c session-sync (§7/§8) — IDEMPOTENT REPLACE,按接口句(`SessionStorage.replaceEntries`:先清这只会话既有的对话日志,再导入 `entries`)。
|
|
340
|
-
* 与 {@link importEntries}
|
|
341
|
-
* 所以一只会话头读不出的存档也换得掉;存档是重建的那一只,建档时刻 = 换装时刻(SQL 孪生 replace 重插行、`created_at` 重记,同义)
|
|
431
|
+
* 与 {@link importEntries} 同一个入口、同一只写序,只差落点(行不在,或行上的属主就是导入者)与内容那一半(先清内容存档再导入,见 {@link importHeld} ③)——
|
|
432
|
+
* 所以一只会话头读不出的存档也换得掉;存档是重建的那一只,建档时刻 = 换装时刻(SQL 孪生 replace 重插行、`created_at` 重记,同义)。行的四只边档原样。
|
|
342
433
|
*/
|
|
343
434
|
replaceEntries(sessionId: string, owner: string | null, entries: SessionTreeEntry[]): Promise<void>;
|
|
344
435
|
/**
|
|
345
436
|
* 换装三条写腿(公开 {@link importEntries} / {@link replaceEntries} 与暂存提交 {@link commitStagedImport})的**同一个入口**:调用方给的属主先过
|
|
346
437
|
* {@link importerOwnerOf}(主体名或 `null`;否则 `TypeError`,什么都没读、一个字节没写),再进这只会话的写锁 —— 锁里的写体只见判过的那一个值,
|
|
347
|
-
* 写进行的属主就是它。引擎导入口的属主判管不到这一格:换装交给引擎的是存档自己的戳(见 {@link
|
|
438
|
+
* 写进行的属主就是它。引擎导入口的属主判管不到这一格:换装交给引擎的是存档自己的戳(见 {@link importHeld} ③),不是调用方的属主。
|
|
348
439
|
*/
|
|
349
440
|
private withImportLock;
|
|
350
441
|
/**
|
|
351
|
-
*
|
|
352
|
-
*
|
|
442
|
+
* 三个导入写口(`importEntries` / `replaceEntries` / 暂存提交的换装臂)的共用写序(调用方持这只会话的写锁,属主的形已在入口判过):
|
|
443
|
+
* ① 只读、零写:引擎闸 `validateEntriesForImport`(坏包 ⇒ `invalid_session`)· 本处写者 ⇒ {@link SessionWriterPresentError} · `forking` ⇒
|
|
444
|
+
* {@link SessionForkInProgressError} · 不是这个写口的门判过的行 ⇒ {@link importRowRefused}(判据 {@link importMayLand},按写口带来的 {@link ImportLanding};
|
|
445
|
+
* 这条路径上唯一一次判属主);
|
|
446
|
+
* ② 行先:{@link landImportCell}(属主重戳为导入者、化身与 fork 键沿用或新铸、执行位 mirror);
|
|
447
|
+
* ③ 内容,按写口的动词(唯一读法在下面这一只 switch;这里不读那一格、不判属主,只换**内容**):
|
|
448
|
+
* · `create` / `judged`(导入):原地换锁里读到的那一份存档的日志(没有存档 ⇒ 导入新建一只),存档的元数据整只留着(其中的建档时刻是列表行的
|
|
449
|
+
* firstActivityAt,与 SQL 孪生留在行上的 `created_at` 同义)。存档上的属主戳不是本店的事实(本店建的存档一律不带戳,存量存档可能带着此前导入者的戳),
|
|
450
|
+
* 只是引擎仓原地换的条件:按那一份存档自己的戳导入,并以它为 `expect`(戳 + 存档的令牌)—— 读与写之间它换了一代 ⇒ 引擎仓拒 `conflict`。
|
|
451
|
+
* 读存档、校验、存档判与写在引擎仓里是一步,抛在哪一处内容都一个字节没动 ⇒ 撤回 ②({@link withdrawImportCell}:行原样,SQL 孪生的事务回滚同义)再原样上抛;
|
|
452
|
+
* · `replace`(接口句「先清既有对话日志,再导入」):先清掉内容存档(不带 `expect` —— 带了就得先读它的头,读不出的存档就清不掉),再导入一只新存档。
|
|
453
|
+
* 清不可撤:清过之后导入再抛(I/O 故障),内容就没了,行留 ② 落下的 mirror(只读方向,下次推送补齐)—— 已发版本的 replace 同形(删后导入)。
|
|
454
|
+
* 带 fork 键的行(fork 建出的目标)留下的是「mirror、键仍在、存档不在」:不读作 `forking`({@link isForkCreatedCell}:fork 创建点写下的格执行位恒缺,② 落下 mirror 之后它就不再是那一形),
|
|
455
|
+
* 下一次 replace / 暂存提交照常落定,同键 fork 重试仍 replayed(SQL 孪生一个事务里删重插、整段回滚,没有这个窗);
|
|
456
|
+
* 收尾:新近 = 此刻(推送即活动)。标题 / 置顶 / 指令来源 / 工作区四只行边档一个字节不碰。
|
|
457
|
+
* 崩在 ②③ 之间 = 格已是 mirror、内容旧或空 = 只读方向,下次推送补齐(SQL 孪生在一个事务里写行与内容,没有这个中间态)。
|
|
353
458
|
*/
|
|
354
459
|
private importHeld;
|
|
355
460
|
/**
|
|
356
|
-
*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
360
|
-
* 校验(`validateEntriesForImport`)、存档判与写在它里面是一步,抛在哪一处都一个字节没写。
|
|
361
|
-
* 存档上的属主戳不是本店的事实(属主只在那一格;本店建的存档一律不带戳,存量存档可能带着此前导入者的戳),只是引擎仓原地换的条件:
|
|
362
|
-
* 按那一份存档自己的戳导入,并以它为 `expect`(戳 + 存档的令牌;没有存档 ⇒ `row: null`,导入新建一只不带戳的存档)——
|
|
363
|
-
* 换的就是这一份;读与写之间它换了一代 ⇒ 引擎仓拒 `conflict`,一个字节不写。
|
|
461
|
+
* ① 的属主 / 住客条件:这一行此刻是不是这个写口的门判过的行({@link ImportLanding};一次读、零写 —— 格缺时「行在不在」只问存档的唯一探针
|
|
462
|
+
* {@link existsInRepo},不补铸那一格)。属主比的是头读的读法 `owner ?? null`(从没被记下 = 无主;格缺而存档在 = 从没被记下),比较器是删除门的那一只
|
|
463
|
+
* {@link ownerEq}。M10 的认领只归登记({@link register}),导入不认领:遗留的「属主未记」格对带 principal 的 `replace` 读作别人的行,拒了之后那一格
|
|
464
|
+
* 原样仍是「未记」,窗内登记照样认领。
|
|
364
465
|
*/
|
|
365
|
-
private
|
|
466
|
+
private importMayLand;
|
|
366
467
|
/**
|
|
367
|
-
*
|
|
368
|
-
*
|
|
369
|
-
*
|
|
370
|
-
* (`
|
|
468
|
+
* ② 推送落下的那一格 —— 三个导入写口与暂存提交「内容相同、日志不动」那一支都经这**一处**(调用方持写锁、① 已判过):属主重戳为导入者;
|
|
469
|
+
* 化身与 fork 键经 {@link carriedRowCells}(三只店同一句)读那一格自己 —— 行在 ⇒ 沿用(同一行 = 同一位住客,属主重戳与否不改这一判),刚建 ⇒ 新铸、不带键;
|
|
470
|
+
* 执行位 = mirror(导入落下的是「写者在别处」;SQL 孪生的提交点同一句写)。只写这一格:四只行边档与新近不在这里。
|
|
471
|
+
* 交回写之前的那一格(`undefined` = 原本没有),③ 撤回用。
|
|
371
472
|
*/
|
|
372
|
-
private
|
|
473
|
+
private landImportCell;
|
|
373
474
|
/**
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
* 会话元数据那一格属主重戳为导入者;化身经 {@link carriedIncarnation}(三只店同一句)读那一格自己 —— 行在 ⇒ 沿用(同一行 = 同一位住客),
|
|
377
|
-
* 刚建的行 ⇒ 铸一只;然后记新近 = 此刻:推送即活动,不因内容相同分叉。标题 / 置顶 / 指令来源 / 工作区四只行边档不碰。
|
|
378
|
-
* SQL 孪生暂存提交那一句 `UPDATE session_meta SET owner = ?, updated_at = now, leaf_id, leaf_seq` 的 local 对位(那一句两支同写)。
|
|
475
|
+
* 撤回 ② —— ③ 的原地换抛了(内容一个字节没动):那一格回到 ② 之前(原本没有 ⇒ 删掉),行原样。撤不掉 ⇒ 响亮:两只故障都点名
|
|
476
|
+
* (留下的格是 mirror —— 只读方向,与崩在 ②③ 之间同形,下次推送补齐)。
|
|
379
477
|
*/
|
|
380
|
-
private
|
|
478
|
+
private withdrawImportCell;
|
|
381
479
|
/** 2c session-sync P1d-β (PUSH streaming) — begin a STAGED import. The LOCAL backend is single-writer with no
|
|
382
480
|
* cross-instance / cross-replica concurrency story (the durable twins carry that), so the staging handle simply
|
|
383
|
-
* ACCUMULATES the streamed batches in memory then, on commit, runs the SAME in-place log swap ({@link
|
|
481
|
+
* ACCUMULATES the streamed batches in memory then, on commit, runs the SAME in-place log swap ({@link importHeld} ③: one
|
|
384
482
|
* engine-repo import onto the archive as it stands — validate, judge and write in one step) the whole-bundle local import uses. Keep it
|
|
385
483
|
* simple per §1: the durable twins are where the SHADOW-id swap + bounded-memory + concurrency matter. */
|
|
386
484
|
beginImportStaging(realSessionId: string, token: string): StagingHandle;
|
|
@@ -393,7 +491,8 @@ export declare class LocalSessionStore implements SessionStore {
|
|
|
393
491
|
/**
|
|
394
492
|
* {@link LocalStagingHandle.commit} 的整段 —— **一次持锁**(这只会话的写锁,{@link withSessionWriteLock}):属主 CAS(此刻的属主格 = 这次导入的门判过的那一格,
|
|
395
493
|
* 否则抛 {@link StagedCommitOwnerChangedError},一个字节不写;在判目的端日志之前判,SQL 孪生同序)→ 提交时重新分类(目的端此刻的日志 vs staged)
|
|
396
|
-
* → 拒未经同意的 fork / stale / 载荷分叉 →
|
|
494
|
+
* → 拒未经同意的 fork / stale / 载荷分叉 → 本处写者拒 → 换装(导入写序 ①②③,落点 `judged` = 上面这一判;化身与 fork 键按换装律沿用)或 identical 且内容相同时日志不动、
|
|
495
|
+
* 行照样落(② 那一格:重戳属主 + mirror)→ 两支同记新近(推送即活动)→ **在同一次持锁里**
|
|
397
496
|
* 读出落定的会话面交回。锁放下之前谁也换不掉这一位住客,所以交回的面就是这次提交落下的那一位(SQL 孪生在提交事务里读同一行,同义);
|
|
398
497
|
* 提交之后按住客条件写的重放(会话行两位)只认这只面,不再重读。改属主的每一条写腿(登记 / 删除 / 导入 / 换装)都在同一把锁里,所以锁内这一读到锁放下都成立。
|
|
399
498
|
*/
|
|
@@ -406,7 +505,7 @@ export declare class LocalSessionStore implements SessionStore {
|
|
|
406
505
|
* tool-result rows are purged separately by the route's purgeSession coordinator. 整段在这只会话的写锁里(换人)。 */
|
|
407
506
|
deleteSession(sessionId: string, owner: string | null): Promise<boolean>;
|
|
408
507
|
/**
|
|
409
|
-
* {@link deleteSession} 的锁内一形(调用方持这只会话的写锁;换装不走它 —— 换装只换内容存档,行原样,见 {@link
|
|
508
|
+
* {@link deleteSession} 的锁内一形(调用方持这只会话的写锁;换装不走它 —— 换装只换内容存档,行原样,见 {@link importHeld})。
|
|
410
509
|
* 删的是 SQL 孪生 `session_meta` 那一行在本店的全部对位:会话存档、四只行边档(标题 / 置顶 / 指令来源基线 / 工作区)、新近标记、属主 + 化身那一格。
|
|
411
510
|
* 四只边档的那一键**都经各自的写链删**(`commit`:草稿上删、落盘、再发布 —— 与写它们的那一笔同一条链、同一把会话锁),落不了盘 ⇒ 抛:
|
|
412
511
|
* 留在盘上的值会挂到同 id 的下一位住客身上(E21 的删除权残留)。元数据格**最后**删:四只边档任一只落不了而抛时,那一格还在 ⇒ 会话对属主门仍
|