@deepseek-ai/dsh-session-projection-cache 0.1.5-rc.1 → 0.1.6-alpha.1

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/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/session/session-projection-cache/README.md
5
- README.md: dcbe57af1f9c13f1f43572ff188dfdaaf9287160
6
- README.zh.md: 367d893c56a23e0965eb1e10f42fb6705284af6b
5
+ README.md: 3125f50b07f222feb0ef2af5e28abcfae19631a7
6
+ README.zh.md: c98cda187dd898a0b30a9721c0bc7412a91964c5
package/README.md CHANGED
@@ -64,7 +64,7 @@ Three mandatory points always write: session creation persists the seed-derived
64
64
 
65
65
  The log leads and the cache follows: a live checkpoint flushes the session's buffered events durably before the cache row lands, so a crash can leave the cache behind the log but never ahead of it. Reads and writes share the storage domain's coherent in-memory state; the per-unit write chain mutates memory only after durability. Each version-stamped record must match the live unit schema and complete lifecycle identity (`formatVersion`, `createdAt`, `cwd`, `isSeeded`, and `inheritedEventCount`), so a row folded from another Session format generation or fork cut cannot seed the caller. The JSON backend stores each record at `<root>/session_projcache/sessions/<id>.json` in an owner-only directory tree.
66
66
 
67
- Upgrades never cost the boot or expose an unproven fold. Records stamped with a version in the spec's `compatibleVersions` remain structurally readable for a current checkpoint rewrite, but a missing or older `formatVersion` never matches a current Session and therefore cannot seed hydration. A lifecycle-matching predecessor title remains available only through the listing hint above because title text is invariant across the adjacent Session-format edges and its row still passes the current projection `stateVersion` and schema. Once the format matches, absent lineage fields decode as the unseeded lineage — exact for unseeded sessions, while a seeded caller fails the identity match and refolds cold. A stored record that still fails schema validation is moved aside as `<id>.json.bak.<stamp>` under the domain's `invalidRecords: 'backup-and-skip'` policy, logged with its cause, and rebuilt by the next checkpoint.
67
+ Upgrades never block startup or expose an unproven fold. Records stamped with a version in the spec's `compatibleVersions` remain structurally readable for a current checkpoint rewrite, but a missing or older `formatVersion` never matches a current Session and therefore cannot seed hydration. A lifecycle-matching predecessor title remains available only through the listing hint above because title text is invariant across the adjacent Session-format edges and its row still passes the current projection `stateVersion` and schema. Once the format matches, absent lineage fields decode as the unseeded lineage — exact for unseeded sessions, while a seeded caller fails the identity match and refolds cold. A stored record that still fails schema validation is moved aside as `<id>.json.bak.<stamp>` under the domain's `invalidRecords: 'backup-and-skip'` policy, logged with its cause, and rebuilt by the next checkpoint.
68
68
 
69
69
  -----
70
70
 
@@ -128,7 +128,7 @@ These limits define where the cache needs operational care. They are current pac
128
128
  - **No eviction or retention surface** — records accumulate per session; pruning stored checkpoints is out-of-band maintenance, same stance as session persistence itself.
129
129
  - **Interval throttle is per-session coarse** — the timer arms at the first dirty event after a clean write; a steady sub-threshold trickle writes once per interval, not a sliding window.
130
130
  - **No cache-side cold refold** — the cache serves and refreshes its rows but never reads the session log (it does not depend on the persistence layer); a consumer that needs a guaranteed cold snapshot refolds from the log itself.
131
- - **Every schema or domain-version change must prove its upgrade story** — a change to the stored record schema or the domain version lands in the same PR with an archived fixture of the previously shipped on-disk format under `tests/fixtures/` and test cases in `tests/fixtures.spec.ts` proving the chosen disposition: read-compat recovery (`compatibleVersions`), current-version rewrite, or backup-and-skip salvage. A bump whose old records are simply discarded still proves that the discard neither fails the boot nor poisons the tree.
131
+ - **Every schema or domain-version change must prove its upgrade story** — a change to the stored record schema or the domain version lands in the same PR with an archived fixture of the previously shipped on-disk format under `tests/fixtures/` and test cases in `tests/fixtures.spec.ts` proving the chosen disposition: read-compat recovery (`compatibleVersions`), current-version rewrite, or backup-and-skip salvage. A bump whose old records are simply discarded still proves that the discard neither causes startup to fail nor poisons the tree.
132
132
 
133
133
  <a id="dev-note"></a>
134
134
  ### Dev Note
package/README.zh.md CHANGED
@@ -9,7 +9,7 @@ kind: "package-reference"
9
9
 
10
10
  ## 概述
11
11
 
12
- 本包保存持久的逐会话投影检查点,让历史列表、统计信息与 goal 快照无需加载每个会话日志即可读取缓存值。冷投影折叠可从已检查点化的前缀之后继续,从而减少重启后的工作量。会话日志始终是权威:崩溃可能使检查点陈旧,但不会使其领先于已提交事件;不兼容记录会被忽略或备份。当重启的会话需要频繁读取投影时选择本包;当投影只服务实时会话,或额外存储写入与无限增长的检查点保留成本超过节省的工作量时跳过本包。
12
+ 本包保存持久的逐会话投影检查点,让历史列表、统计信息与 goal 快照无需加载每个会话日志即可读取缓存值。冷投影折叠可从已检查点化的前缀之后继续,从而减少重启后的工作量。会话日志始终是权威:崩溃可能使检查点陈旧,但不会使其领先于已提交事件;不兼容记录会被忽略或备份。当重启的会话需要频繁读取投影时选择本包;当投影只服务活会话,或额外存储写入与无限增长的检查点保留成本超过节省的工作量时跳过本包。
13
13
 
14
14
  ## 目录
15
15
 
@@ -29,7 +29,7 @@ kind: "package-reference"
29
29
 
30
30
  ### 何时选择
31
31
 
32
- 当部署会重启会话,并需要为历史列表、统计信息或 goal 快照提供持久投影值时,选择本包。当投影只服务实时会话,或额外存储写入的成本高于所节省的投影工作时,跳过本包。
32
+ 当部署会重启会话,并需要为历史列表、统计信息或 goal 快照提供持久投影值时,选择本包。当投影只服务活会话,或额外存储写入的成本高于所节省的投影工作时,跳过本包。
33
33
 
34
34
  ### 最小配置
35
35
 
@@ -54,7 +54,7 @@ kind: "package-reference"
54
54
 
55
55
  ### 检查点如何写入
56
56
 
57
- 三个必写点总是写入:会话创建保存由种子派生的切面,`turn/end` 保存列表读取所需的轮次终值,会话释放保存最终实时切面。其间,配置的条数与间隔节流随事件累积写入。每次写入通过领域写入链以原子方式替换该会话的完整记录;失败会记录警告并让缓存保持陈旧,后续写入会自行修复。
57
+ 三个必写点总是写入:会话创建保存由种子派生的切面,`turn/end` 保存列表读取所需的轮次终值,会话释放保存活会话的最终切面。其间,配置的条数与间隔节流随事件累积写入。每次写入通过领域写入链以原子方式替换该会话的完整记录;失败会记录警告并让缓存保持陈旧,后续写入会自行修复。
58
58
 
59
59
  ### 读取缓存值
60
60
 
@@ -62,7 +62,7 @@ kind: "package-reference"
62
62
 
63
63
  ### 缓存保证什么
64
64
 
65
- 日志领先,缓存跟随:实时检查点先把会话的缓冲事件持久化,然后才保存缓存记录。因此崩溃可能让缓存落后于日志,但绝不会让缓存领先。读取和写入共享存储域内一致的内存状态;逐单元写入链只在持久化成功后修改内存。每个带版本戳的记录必须匹配实时单元 schema 与完整生命周期身份(`formatVersion`、`createdAt`、`cwd`、`isSeeded` 和 `inheritedEventCount`),因此从另一会话格式代或 fork 切点折叠出的行不能播种调用方。JSON 后端把每条记录存于仅所有者可访问的 `<root>/session_projcache/sessions/<id>.json` 目录树中。
65
+ 日志领先,缓存跟随:活会话检查点先把会话的缓冲事件持久化,然后才保存缓存记录。因此崩溃可能让缓存落后于日志,但绝不会让缓存领先。读取和写入共享存储域内一致的内存状态;逐单元写入链只在持久化成功后修改内存。每个带版本戳的记录必须匹配当前运行单元的 schema 与完整生命周期身份(`formatVersion`、`createdAt`、`cwd`、`isSeeded` 和 `inheritedEventCount`),因此从另一会话格式代或 fork 切点折叠出的行不能播种调用方。JSON 后端把每条记录存于仅所有者可访问的 `<root>/session_projcache/sessions/<id>.json` 目录树中。
66
66
 
67
67
  升级绝不拖垮启动,也不会暴露未经证明的折叠结果。版本戳落在 spec `compatibleVersions` 集合内的记录仍可被结构化读取并等待当前检查点重写,但缺失或更旧的 `formatVersion` 绝不匹配当前 Session,因此不能作为 hydrate seed。生命周期匹配的 predecessor title 只能通过上述列表 hint 读取,因为 title 文本在相邻 Session format edge 之间保持不变,并且该 row 仍须通过当前 projection `stateVersion` 与 schema。格式匹配后,缺失的 lineage 字段解码为 unseeded lineage——对非 fork 会话精确无误,seeded 调用方则通不过身份比对、回落冷折叠。仍然通不过 schema 校验的存量记录会按域的 `invalidRecords: 'backup-and-skip'` 策略移出为 `<id>.json.bak.<时间戳>`、连同原因写入日志,并由下一次检查点重建。
68
68
 
@@ -78,7 +78,7 @@ kind: "package-reference"
78
78
 
79
79
  ### 设计理念
80
80
 
81
- 缓存是投影注册表检查点接口上的折叠捷径,存于 `per-record` 领域数据表中。它带来六项后果:读取绝不绕过领域写入链;每次后台写入都 fail-soft;`ver` 不匹配时丢弃而不迁移记录;记录必须通过实时单元的 `stateSchema`;写入通过无损 JSON 边界替换一份完整会话记录;日志领先,缓存跟随。
81
+ 缓存是投影注册表检查点接口上的折叠捷径,存于 `per-record` 领域数据表中。它带来六项后果:读取绝不绕过领域写入链;每次后台写入都 fail-soft;`ver` 不匹配时丢弃而不迁移记录;记录必须通过当前运行单元的 `stateSchema`;写入通过无损 JSON 边界替换一份完整会话记录;日志领先,缓存跟随。
82
82
 
83
83
  ### 读写所有权
84
84
 
@@ -88,9 +88,9 @@ kind: "package-reference"
88
88
 
89
89
  | 文件 | 职责 |
90
90
  |---|---|
91
- | [`src/index.ts`](src/index.ts) | 插件入口:`SessionProjectionCache` 服务、写后监听器、缓存读取 |
91
+ | [`src/index.ts`](src/index.ts) | 插件入口:`SessionProjectionCache` 服务、后台写入监听器、缓存读取 |
92
92
  | [`src/spec.ts`](src/spec.ts) | `session_projcache` 域 spec 与记录身份类型 |
93
- | — | 不发布运行时不变式伴生入口;正确性在写入与读取路径强制。 |
93
+ | — | 不发布运行时不变式伴生入口;完整正确性关系只能通过对持久化日志重新执行折叠来检查;持久化边界通过 schema 校验,读路径的版本与水位防护由包规范证明,相关局部约束在写入与读取路径强制执行。 |
94
94
 
95
95
  </details>
96
96
 
@@ -128,7 +128,7 @@ kind: "package-reference"
128
128
  - **无淘汰或保留接口**——记录按会话持续累积;清理已存储检查点属于带外维护,与会话持久化采用相同策略。
129
129
  - **间隔节流采用按会话的粗粒度控制**——一次无脏数据的写入完成后,计时器在首个脏事件到达时启动;持续但低于条数阈值的事件流每间隔写入一次,而非滑动窗口。
130
130
  - **缓存侧不做冷重折叠**——缓存只服务并刷新自己的记录,从不读取会话日志,因为它不依赖持久化层;需要保证冷快照的消费方自行从日志重新折叠。
131
- - **每次 schema 或域版本变更都必须论证升级路径**——改动存储记录 schema 或域版本时,同一 PR 必须在 `tests/fixtures/` 下归档此前已发布的磁盘格式样本,并在 `tests/fixtures.spec.ts` 中用测试论证所选的处置方式:读兼容恢复(`compatibleVersions`)、当前版本重写,或 backup-and-skip 抢救。即便选择直接丢弃旧记录的 bump,也要证明丢弃既不炸启动、也不污染缓存树。
131
+ - **每次 schema 或域版本变更都必须论证升级路径**——改动存储记录 schema 或域版本时,同一 PR 必须在 `tests/fixtures/` 下归档此前已发布磁盘格式的 fixture(测试前置数据),并在 `tests/fixtures.spec.ts` 中用测试论证所选的处置方式:读兼容恢复(`compatibleVersions`)、当前版本重写,或 backup-and-skip 抢救。即便选择直接丢弃旧记录的 bump,也要证明丢弃既不会导致启动失败,也不会污染缓存树。
132
132
 
133
133
  <a id="dev-note"></a>
134
134
  ### 开发备注
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-session-projection-cache",
3
3
  "description": "Persisted projection cache (ctx.sessionProjectionCache): durable per-session checkpoint records on the session_projcache storage domain (per-record layout), throttled write-behind, and the cached listing read",
4
- "version": "0.1.5-rc.1",
4
+ "version": "0.1.6-alpha.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -28,21 +28,21 @@
28
28
  "license": "MIT",
29
29
  "dependencies": {
30
30
  "zod": "^4.4.3",
31
- "@deepseek-ai/dsh-util-values": "^0.1.5-rc.1",
31
+ "@deepseek-ai/dsh-util-values": "^0.1.6-alpha.1",
32
32
  "@deepseek-ai/schemastery": "^3.18.2"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "@deepseek-ai/cordis": "^4.0.2",
36
- "@deepseek-ai/dsh-session": "^0.1.5-rc.1",
37
- "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.1",
38
- "@deepseek-ai/dsh-storage-domain": "^0.1.5-rc.1"
36
+ "@deepseek-ai/dsh-session": "^0.1.6-alpha.1",
37
+ "@deepseek-ai/dsh-session-projection": "^0.1.6-alpha.1",
38
+ "@deepseek-ai/dsh-storage-domain": "^0.1.6-alpha.1"
39
39
  },
40
40
  "devDependencies": {
41
+ "@deepseek-ai/dsh-session": "^0.1.6-alpha.1",
42
+ "@deepseek-ai/dsh-session-projection": "^0.1.6-alpha.1",
41
43
  "@deepseek-ai/cordis": "^4.0.2",
42
- "@deepseek-ai/dsh-session": "^0.1.5-rc.1",
43
- "@deepseek-ai/dsh-session-projection": "^0.1.5-rc.1",
44
- "@deepseek-ai/dsh-storage": "^0.1.5-rc.1",
45
- "@deepseek-ai/dsh-storage-domain": "^0.1.5-rc.1",
46
- "@deepseek-ai/dsh-storage-json": "^0.1.5-rc.1"
44
+ "@deepseek-ai/dsh-storage": "^0.1.6-alpha.1",
45
+ "@deepseek-ai/dsh-storage-domain": "^0.1.6-alpha.1",
46
+ "@deepseek-ai/dsh-storage-json": "^0.1.6-alpha.1"
47
47
  }
48
48
  }