dsh-plugin-dev-kb 1.8.0 → 1.8.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.
Files changed (229) hide show
  1. package/CHANGELOG.md +186 -178
  2. package/README.en.md +172 -172
  3. package/README.md +183 -183
  4. package/kb/INDEX.md +236 -234
  5. package/kb/README.md +88 -88
  6. package/kb/extra/AGENTS.md +77 -77
  7. package/kb/extra/deepseek-llm-api-wire-extensions.md +162 -162
  8. package/kb/extra/deepseek-llm-api-wire-extensions.zh.md +162 -162
  9. package/kb/extra/defensive-patterns/package-surface.md +233 -232
  10. package/kb/extra/defensive-patterns/package-surface.zh.md +233 -232
  11. package/kb/extra/defensive-patterns/remote-and-api.md +117 -117
  12. package/kb/extra/defensive-patterns/remote-and-api.zh.md +117 -117
  13. package/kb/extra/development.md +221 -221
  14. package/kb/extra/development.zh.md +228 -228
  15. package/kb/extra/event-producer-consumer.md +133 -123
  16. package/kb/extra/event-producer-consumer.zh.md +135 -125
  17. package/kb/extra/module-graph.md +1961 -1888
  18. package/kb/extra/module-graph.zh.md +1963 -1890
  19. package/kb/extra/persistence-changes/2026-11-05-timeline-priority-notice.md +60 -0
  20. package/kb/extra/persistence-changes/2026-11-05-timeline-priority-notice.zh.md +60 -0
  21. package/kb/extra/persistence-changes/README.md +92 -92
  22. package/kb/extra/persistence-changes/README.zh.md +92 -92
  23. package/kb/extra/persistence-changes/historical-formats/README.md +75 -75
  24. package/kb/extra/persistence-changes/historical-formats/README.zh.md +75 -75
  25. package/kb/extra/persistence-changes/releases/README.md +103 -103
  26. package/kb/extra/persistence-changes/releases/README.zh.md +103 -103
  27. package/kb/extra/rescope.md +55 -55
  28. package/kb/extra/rescope.zh.md +55 -55
  29. package/kb/extra/subsystems/boot.md +631 -621
  30. package/kb/extra/subsystems/boot.zh.md +631 -621
  31. package/kb/extra/subsystems/computer-use.md +179 -137
  32. package/kb/extra/subsystems/computer-use.zh.md +179 -137
  33. package/kb/extra/subsystems/extensions.md +387 -384
  34. package/kb/extra/subsystems/extensions.zh.md +387 -384
  35. package/kb/extra/subsystems/feedback.md +418 -400
  36. package/kb/extra/subsystems/feedback.zh.md +418 -400
  37. package/kb/extra/subsystems/forge.md +2169 -1226
  38. package/kb/extra/subsystems/forge.zh.md +2171 -1226
  39. package/kb/extra/subsystems/liveshare.md +167 -158
  40. package/kb/extra/subsystems/liveshare.zh.md +167 -158
  41. package/kb/extra/subsystems/mcp.md +237 -234
  42. package/kb/extra/subsystems/mcp.zh.md +237 -234
  43. package/kb/extra/subsystems/office-kit.md +122 -0
  44. package/kb/extra/subsystems/office-kit.zh.md +122 -0
  45. package/kb/extra/subsystems/working-directory.md +95 -64
  46. package/kb/extra/subsystems/working-directory.zh.md +95 -64
  47. package/kb/extra/subsystems/worktrees.md +187 -127
  48. package/kb/extra/subsystems/worktrees.zh.md +187 -127
  49. package/kb/extra/upgrade-guide/v0.2.1-alpha.1/python-ptc-sandbox/guide.md +21 -21
  50. package/kb/extra/upgrade-guide/v0.2.1-alpha.1/python-ptc-sandbox/guide.zh.md +21 -21
  51. package/kb/extra/upgrade-guide/v0.2.1-rc.4/sandbox-unsupported-policy-error/guide.md +18 -0
  52. package/kb/extra/upgrade-guide/v0.2.1-rc.4/sandbox-unsupported-policy-error/guide.zh.md +18 -0
  53. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/llm-error-builtin-codes/guide.md +18 -0
  54. package/kb/extra/upgrade-guide/v0.2.2-alpha.2/llm-error-builtin-codes/guide.zh.md +18 -0
  55. package/kb/extra/upgrade-guide/v0.2.2-alpha.3/office-kit-package/guide.md +34 -0
  56. package/kb/extra/upgrade-guide/v0.2.2-alpha.3/office-kit-package/guide.zh.md +34 -0
  57. package/kb/extra/upgrade-guide/v0.2.2-alpha.3/office-operation-tools/guide.md +49 -0
  58. package/kb/extra/upgrade-guide/v0.2.2-alpha.3/office-operation-tools/guide.zh.md +49 -0
  59. package/kb/extra/upgrade-guide/v0.2.2-alpha.3/office-skill-resources/guide.md +36 -0
  60. package/kb/extra/upgrade-guide/v0.2.2-alpha.3/office-skill-resources/guide.zh.md +36 -0
  61. package/kb/extra/upgrade-guide/v0.2.2-rc.1/account-notification-fields/guide.md +26 -0
  62. package/kb/extra/upgrade-guide/v0.2.2-rc.1/account-notification-fields/guide.zh.md +26 -0
  63. package/kb/extra/upgrade-guide/v0.2.2-rc.1/account-remote-provider/guide.md +22 -0
  64. package/kb/extra/upgrade-guide/v0.2.2-rc.1/account-remote-provider/guide.zh.md +22 -0
  65. package/kb/extra/upgrade-guide/v0.2.2-rc.1/archive-worktrees/guide.md +21 -0
  66. package/kb/extra/upgrade-guide/v0.2.2-rc.1/archive-worktrees/guide.zh.md +21 -0
  67. package/kb/extra/upgrade-guide/v0.2.2-rc.1/attachment-error-codes/guide.md +23 -0
  68. package/kb/extra/upgrade-guide/v0.2.2-rc.1/attachment-error-codes/guide.zh.md +23 -0
  69. package/kb/extra/upgrade-guide/v0.2.2-rc.1/cua-ax-read-limits/guide.md +20 -0
  70. package/kb/extra/upgrade-guide/v0.2.2-rc.1/cua-ax-read-limits/guide.zh.md +20 -0
  71. package/kb/extra/upgrade-guide/v0.2.2-rc.1/cua-hover-ax-only/guide.md +18 -0
  72. package/kb/extra/upgrade-guide/v0.2.2-rc.1/cua-hover-ax-only/guide.zh.md +18 -0
  73. package/kb/extra/upgrade-guide/v0.2.2-rc.1/cua-native-platform/guide.md +23 -0
  74. package/kb/extra/upgrade-guide/v0.2.2-rc.1/cua-native-platform/guide.zh.md +23 -0
  75. package/kb/extra/upgrade-guide/v0.2.2-rc.1/dsh-doc-skill/guide.md +35 -0
  76. package/kb/extra/upgrade-guide/v0.2.2-rc.1/dsh-doc-skill/guide.zh.md +35 -0
  77. package/kb/extra/upgrade-guide/v0.2.2-rc.1/forge-change-request-overview/guide.md +26 -0
  78. package/kb/extra/upgrade-guide/v0.2.2-rc.1/forge-change-request-overview/guide.zh.md +26 -0
  79. package/kb/extra/upgrade-guide/v0.2.2-rc.1/forge-pinned-diff/guide.md +26 -0
  80. package/kb/extra/upgrade-guide/v0.2.2-rc.1/forge-pinned-diff/guide.zh.md +26 -0
  81. package/kb/extra/upgrade-guide/v0.2.2-rc.1/forge-review-reads/guide.md +19 -0
  82. package/kb/extra/upgrade-guide/v0.2.2-rc.1/forge-review-reads/guide.zh.md +19 -0
  83. package/kb/extra/upgrade-guide/v0.2.2-rc.1/package-export-cleanup/guide.md +26 -0
  84. package/kb/extra/upgrade-guide/v0.2.2-rc.1/package-export-cleanup/guide.zh.md +26 -0
  85. package/kb/extra/upgrade-guide/v0.2.2-rc.1/plugin-update-method/guide.md +22 -0
  86. package/kb/extra/upgrade-guide/v0.2.2-rc.1/plugin-update-method/guide.zh.md +22 -0
  87. package/kb/extra/upgrade-guide/v0.2.2-rc.1/ptc-bootstrap-protocol/guide.md +25 -0
  88. package/kb/extra/upgrade-guide/v0.2.2-rc.1/ptc-bootstrap-protocol/guide.zh.md +25 -0
  89. package/kb/extra/upgrade-guide/v0.2.2-rc.1/ptc-inspect-output/guide.md +48 -0
  90. package/kb/extra/upgrade-guide/v0.2.2-rc.1/ptc-inspect-output/guide.zh.md +48 -0
  91. package/kb/extra/upgrade-guide/v0.2.2-rc.1/ptc-scoped-repl-default/guide.md +45 -0
  92. package/kb/extra/upgrade-guide/v0.2.2-rc.1/ptc-scoped-repl-default/guide.zh.md +45 -0
  93. package/kb/extra/upgrade-guide/v0.2.2-rc.1/runtime-context-reminders/guide.md +19 -0
  94. package/kb/extra/upgrade-guide/v0.2.2-rc.1/runtime-context-reminders/guide.zh.md +19 -0
  95. package/kb/extra/upgrade-guide/v0.2.2-rc.1/session-append-overloads/guide.md +17 -0
  96. package/kb/extra/upgrade-guide/v0.2.2-rc.1/session-append-overloads/guide.zh.md +17 -0
  97. package/kb/extra/upgrade-guide/v0.2.2-rc.1/subagent-interrupt-default/guide.md +27 -0
  98. package/kb/extra/upgrade-guide/v0.2.2-rc.1/subagent-interrupt-default/guide.zh.md +27 -0
  99. package/kb/extra/upgrade-guide/v0.2.2-rc.1/terminal-backend-cleanup-error/guide.md +20 -0
  100. package/kb/extra/upgrade-guide/v0.2.2-rc.1/terminal-backend-cleanup-error/guide.zh.md +20 -0
  101. package/kb/extra/upgrade-guide/v0.2.2-rc.1/terminal-bundle-sidebar-backend/guide.md +19 -0
  102. package/kb/extra/upgrade-guide/v0.2.2-rc.1/terminal-bundle-sidebar-backend/guide.zh.md +19 -0
  103. package/kb/extra/upgrade-guide/v0.2.2-rc.1/web-fetch-transport-error-codes/guide.md +18 -0
  104. package/kb/extra/upgrade-guide/v0.2.2-rc.1/web-fetch-transport-error-codes/guide.zh.md +18 -0
  105. package/kb/extra/upgrade-guide/v0.2.2-rc.1/web-search-billing/guide.md +41 -0
  106. package/kb/extra/upgrade-guide/v0.2.2-rc.1/web-search-billing/guide.zh.md +41 -0
  107. package/kb/extra/upgrade-guide/v0.2.2-rc.1/window-drag-regions/guide.md +21 -0
  108. package/kb/extra/upgrade-guide/v0.2.2-rc.1/window-drag-regions/guide.zh.md +21 -0
  109. package/kb/extra/upgrade-guide/v0.2.2-rc.2/client-module-metadata/guide.md +29 -0
  110. package/kb/extra/upgrade-guide/v0.2.2-rc.2/client-module-metadata/guide.zh.md +29 -0
  111. package/kb/extra/upgrade-guide/v0.2.2-rc.2/connection-page-peer/guide.md +25 -0
  112. package/kb/extra/upgrade-guide/v0.2.2-rc.2/connection-page-peer/guide.zh.md +25 -0
  113. package/kb/extra/upgrade-guide/v0.2.2-rc.2/cordis-root-and-intercept-metadata/guide.md +31 -0
  114. package/kb/extra/upgrade-guide/v0.2.2-rc.2/cordis-root-and-intercept-metadata/guide.zh.md +31 -0
  115. package/kb/extra/upgrade-guide/v0.2.2-rc.2/cua-agents-without-preset/guide.md +24 -0
  116. package/kb/extra/upgrade-guide/v0.2.2-rc.2/cua-agents-without-preset/guide.zh.md +24 -0
  117. package/kb/extra/upgrade-guide/v0.2.2-rc.2/cua-macos-provider/guide.md +24 -0
  118. package/kb/extra/upgrade-guide/v0.2.2-rc.2/cua-macos-provider/guide.zh.md +24 -0
  119. package/kb/extra/upgrade-guide/v0.2.2-rc.2/cua-partial-observations/guide.md +19 -0
  120. package/kb/extra/upgrade-guide/v0.2.2-rc.2/cua-partial-observations/guide.zh.md +19 -0
  121. package/kb/extra/upgrade-guide/v0.2.2-rc.2/deepseek-files-timeout/guide.md +15 -0
  122. package/kb/extra/upgrade-guide/v0.2.2-rc.2/deepseek-files-timeout/guide.zh.md +15 -0
  123. package/kb/extra/upgrade-guide/v0.2.2-rc.2/experimental-tool-error-codes/guide.md +28 -0
  124. package/kb/extra/upgrade-guide/v0.2.2-rc.2/experimental-tool-error-codes/guide.zh.md +28 -0
  125. package/kb/extra/upgrade-guide/v0.2.2-rc.2/package-export-cleanup/guide.md +36 -0
  126. package/kb/extra/upgrade-guide/v0.2.2-rc.2/package-export-cleanup/guide.zh.md +36 -0
  127. package/kb/extra/upgrade-guide/v0.2.2-rc.2/python-ptc-removal/guide.md +22 -0
  128. package/kb/extra/upgrade-guide/v0.2.2-rc.2/python-ptc-removal/guide.zh.md +22 -0
  129. package/kb/extra/upgrade-guide/v0.2.2-rc.2/session-status-package/guide.md +31 -0
  130. package/kb/extra/upgrade-guide/v0.2.2-rc.2/session-status-package/guide.zh.md +31 -0
  131. package/kb/extra/upgrade-guide/v0.2.2-rc.2/shared-search-filter/guide.md +18 -0
  132. package/kb/extra/upgrade-guide/v0.2.2-rc.2/shared-search-filter/guide.zh.md +18 -0
  133. package/kb/extra/upgrade-guide/v0.2.2-rc.2/shell-fs-tool-error-codes/guide.md +30 -0
  134. package/kb/extra/upgrade-guide/v0.2.2-rc.2/shell-fs-tool-error-codes/guide.zh.md +30 -0
  135. package/kb/extra/web-styling.md +57 -57
  136. package/kb/extra/web-styling.zh.md +57 -57
  137. package/kb/meta/search-index.json +4508 -3980
  138. package/kb/meta/source.json +18 -18
  139. package/kb/site/develop/practice/llm-adapter.md +192 -192
  140. package/kb/site/en/develop/practice/llm-adapter.md +192 -192
  141. package/kb/site/en/guide/desktop-uninstall-cleanup.md +63 -0
  142. package/kb/site/en/guide/plugin-market.md +153 -151
  143. package/kb/site/en/guide/providers.md +234 -234
  144. package/kb/site/en/guide/quickstart.md +35 -34
  145. package/kb/site/en/reference/capability-seams.md +789 -767
  146. package/kb/site/en/reference/config-catalog.md +5432 -5128
  147. package/kb/site/en/reference/cookbook/adding-a-package.md +175 -175
  148. package/kb/site/en/reference/cookbook/adding-a-tool.md +105 -104
  149. package/kb/site/en/reference/cookbook/extension-cookbook.md +178 -135
  150. package/kb/site/en/reference/cordis-api/context.md +373 -369
  151. package/kb/site/en/reference/cordis-api/fiber.md +457 -433
  152. package/kb/site/en/reference/cordis-api/inherited.md +44 -44
  153. package/kb/site/en/reference/cordis-api/service.md +118 -107
  154. package/kb/site/en/reference/experimental-persistence-catalog.md +36 -23
  155. package/kb/site/en/reference/index.md +174 -174
  156. package/kb/site/en/reference/persistence-catalog.md +9453 -9432
  157. package/kb/site/en/reference/subsystems/compaction.md +288 -288
  158. package/kb/site/en/reference/subsystems/core.md +1172 -1171
  159. package/kb/site/en/reference/subsystems/credentials.md +526 -497
  160. package/kb/site/en/reference/subsystems/filesystem.md +708 -708
  161. package/kb/site/en/reference/subsystems/index.md +82 -82
  162. package/kb/site/en/reference/subsystems/llm-streaming.md +1290 -1288
  163. package/kb/site/en/reference/subsystems/lsp.md +230 -206
  164. package/kb/site/en/reference/subsystems/persistence.md +451 -432
  165. package/kb/site/en/reference/subsystems/plan.md +91 -91
  166. package/kb/site/en/reference/subsystems/ptc-runtime.md +295 -261
  167. package/kb/site/en/reference/subsystems/sandbox.md +250 -232
  168. package/kb/site/en/reference/subsystems/session-query.md +525 -515
  169. package/kb/site/en/reference/subsystems/session-reference.md +231 -229
  170. package/kb/site/en/reference/subsystems/session.md +1478 -1431
  171. package/kb/site/en/reference/subsystems/sidebar-right.md +165 -165
  172. package/kb/site/en/reference/subsystems/skills.md +356 -356
  173. package/kb/site/en/reference/subsystems/slots.md +235 -231
  174. package/kb/site/en/reference/subsystems/terminal.md +188 -188
  175. package/kb/site/en/reference/subsystems/tools.md +902 -891
  176. package/kb/site/en/reference/subsystems/user-questions.md +330 -327
  177. package/kb/site/en/reference/subsystems/web-client.md +161 -104
  178. package/kb/site/en/reference/subsystems/web-server.md +434 -351
  179. package/kb/site/en/reference/subsystems/web.md +268 -268
  180. package/kb/site/en/reference/subsystems/workflow.md +287 -282
  181. package/kb/site/en/reference/subsystems/workspace.md +743 -651
  182. package/kb/site/en/reference/tool-catalog.md +2867 -2704
  183. package/kb/site/guide/desktop-uninstall-cleanup.md +63 -0
  184. package/kb/site/guide/plugin-market.md +153 -151
  185. package/kb/site/guide/providers.md +234 -234
  186. package/kb/site/guide/quickstart.md +35 -34
  187. package/kb/site/reference/capability-seams.md +789 -767
  188. package/kb/site/reference/config-catalog.md +5432 -5128
  189. package/kb/site/reference/cookbook/adding-a-package.md +175 -175
  190. package/kb/site/reference/cookbook/adding-a-tool.md +107 -106
  191. package/kb/site/reference/cookbook/extension-cookbook.md +182 -139
  192. package/kb/site/reference/cordis-api/context.md +373 -369
  193. package/kb/site/reference/cordis-api/fiber.md +459 -435
  194. package/kb/site/reference/cordis-api/inherited.md +44 -44
  195. package/kb/site/reference/cordis-api/service.md +118 -107
  196. package/kb/site/reference/experimental-persistence-catalog.md +36 -23
  197. package/kb/site/reference/index.md +178 -178
  198. package/kb/site/reference/persistence-catalog.md +9453 -9432
  199. package/kb/site/reference/subsystems/compaction.md +288 -288
  200. package/kb/site/reference/subsystems/core.md +1184 -1183
  201. package/kb/site/reference/subsystems/credentials.md +526 -497
  202. package/kb/site/reference/subsystems/filesystem.md +708 -708
  203. package/kb/site/reference/subsystems/index.md +82 -82
  204. package/kb/site/reference/subsystems/llm-streaming.md +1296 -1294
  205. package/kb/site/reference/subsystems/lsp.md +230 -206
  206. package/kb/site/reference/subsystems/persistence.md +451 -432
  207. package/kb/site/reference/subsystems/plan.md +91 -91
  208. package/kb/site/reference/subsystems/ptc-runtime.md +295 -261
  209. package/kb/site/reference/subsystems/sandbox.md +250 -232
  210. package/kb/site/reference/subsystems/session-query.md +525 -515
  211. package/kb/site/reference/subsystems/session-reference.md +231 -229
  212. package/kb/site/reference/subsystems/session.md +1482 -1435
  213. package/kb/site/reference/subsystems/sidebar-right.md +165 -165
  214. package/kb/site/reference/subsystems/skills.md +356 -356
  215. package/kb/site/reference/subsystems/slots.md +239 -235
  216. package/kb/site/reference/subsystems/terminal.md +188 -188
  217. package/kb/site/reference/subsystems/tools.md +902 -891
  218. package/kb/site/reference/subsystems/user-questions.md +330 -327
  219. package/kb/site/reference/subsystems/web-client.md +161 -104
  220. package/kb/site/reference/subsystems/web-server.md +434 -351
  221. package/kb/site/reference/subsystems/web.md +268 -268
  222. package/kb/site/reference/subsystems/workflow.md +287 -282
  223. package/kb/site/reference/subsystems/workspace.md +743 -651
  224. package/kb/site/reference/tool-catalog.md +2872 -2709
  225. package/lib/index.js +359 -359
  226. package/package.json +68 -68
  227. package/skills/dsh-plugin-dev-kb.md +71 -70
  228. package/kb/extra/subsystems/office-to-pdf.md +0 -87
  229. package/kb/extra/subsystems/office-to-pdf.zh.md +0 -87
@@ -1,288 +1,288 @@
1
- ---
2
- editSource: "docs/subsystems/compaction.md"
3
- rawMarkdownPath: "en/reference/subsystems/compaction.md"
4
- outline: [2,3]
5
- ---
6
-
7
- # Compaction
8
-
9
- The compaction seam — a [capability seam](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-06-13-capability-seams.md) split like bash: Service Definition ([dsh-compaction](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/compaction/compaction), `ctx.compaction`), Service Provider (a backend such as [dsh-compaction-basic](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/compaction/compaction-basic)), and human Consumer ([dsh-command-compact](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/compaction/command-compact)). Compaction is **one optional capability**, not part of the agent-loop spine — so its vocabulary lives here, not in [core.md](./core.md). A tokenizer- or template-based backend is a sibling package implementing the same interface. Unlike bash, the interface necessarily depends on `dsh-session` and `dsh-llm`: its verbs act on an agent-owned `Session`, and its durable summary event uses the `ContentBlock` vocabulary (see the [compaction capability-seam reference](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction/README.md)).
10
-
11
- Source: [`packages/compaction/compaction/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction/src/types.ts)
12
-
13
- ## The `compaction/*` session events
14
-
15
- Compaction extends [`SessionEventMap`](./session.md) with three event types via declaration merging. All three are **log-only** — they record the lock, summary, selected range, shadowed event seqs, token count, and model call without joining the surface. `SurfaceEventType` is deliberately NOT extended (only message-producing events reach the model), so the summary itself rides on a separate `user/message` with `surfaceOp: { op: 'replace', startSeq, endSeq }` — the only surface mutation performed by summary compaction. The [historical Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/archived/feature/2026-06-18-compaction-capability-seam.md) records the rationale for reusing `user/message`.
16
-
17
- | Event | Payload | Role |
18
- |---|---|---|
19
- | `compaction/start` | `{ turn }` | acquires the log-recorded lock; a number identifies the open automatic turn, while `null` identifies a standalone manual attempt |
20
- | `compaction/summary` | `{ summary, rawOutput?, llmStreamCall?, shadowedRange, shadowedSeqs, shadowedTokenCount, provider, model, maxTokens?, usage? }` | the safe summary projection, optional complete provider output and usage, an `llmStreamCall: true` marker when producing the result consumed exactly one call through this context's `ctx.llm.stream()` (which requires complete `rawOutput`), the shadowed surface-boundary pair (`start`/`end` seqs — a position span, not a numeric interval), the shadowed seqs in surface order, the estimated token count, and the summarize call's envelope (`provider`, `model`, plus its generation cap when one applied) — logged so the one-shot request is reconstructable from log + code (the reconstructability Agent Note); unmarked `rawOutput` does not identify the call path |
21
- | `compaction/end` | `{ turn, error? }` | releases the lock with the same numeric-or-null owner (`error` records an unsuccessful attempt) |
22
-
23
- The lock brackets the **whole** operation: `compaction/start` is appended first, then summarization, the `compaction/summary` record, and the `user/message` replacement all land, and only then `compaction/end`. Releasing the lock last turns a crash mid-operation into a detectable orphaned lock (a `compaction/start` with no matching `compaction/end`) rather than a `compaction/end` that falsely claims compaction finished.
24
-
25
- The markers are lock time points, not an exclusive container. An unrelated idle injection can appear between a standalone manual start and end while summarization is pending. The manual path revalidates only its selected positional span, so that injected context survives after the replacement checkpoint. A live unmatched start blocks every entry point; an unmatched start before a newer `session/end-seed` is stale evidence from a prior lifecycle and is ignored.
26
-
27
- These variants are merged inside a `declare module '@deepseek-ai/dsh-session/types'` block, so — unlike the top-level types on the other subsystem pages — they are not pasted as a drift-checked ` ```ts type-equiv ` block (the `verify-type-equiv` extractor matches only top-level declarations by name). The payload table above is the catalog entry; follow the source link for the authoritative fields.
28
-
29
- <a id="image-offload"></a>
30
- ## Image offload
31
-
32
- `compaction-image-offload` owns the `image/offload` declaration and its pure message projection. Each target identifies a current input node and exact depth-first image occurrences. The event preserves node and message identities and carries no `surfaceOp`. The [package README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction-image-offload/README.md) owns recovery policy, registration, and detached replay.
33
-
34
- ```ts type-equiv
35
- /** Exact input-image occurrences selected by one durable offload decision. */
36
- interface ImageOffloadTarget {
37
- /** Current message-producing event containing these occurrences. */
38
- seq: SessionSeq
39
- /** Zero-based depth-first image indexes within the immutable message. */
40
- imageIndexes: number[]
41
- }
42
- ```
43
-
44
- ## `CompactionResult`
45
-
46
- What a successful compaction returns to its caller: the bookkeeping-event seqs, safe summary projection, shadowed range and seqs, and estimated token count.
47
-
48
- ```ts type-equiv
49
- /** Result of a successful compaction operation. */
50
- interface CompactionResult {
51
- /** Stable identity shared by this compaction's complete durable lifecycle. */
52
- compactionId: CompactionId
53
- /** Human command that initiated this compaction, when it was manual. */
54
- sourceCommandId?: CommandId
55
- /** The seq of the appended `compaction/start` event. */
56
- startSeq: SessionSeq
57
- /** The seq of the appended `compaction/summary` event. */
58
- summarySeq: SessionSeq
59
- /** The seq of the appended `compaction/end` event. */
60
- endSeq: SessionSeq
61
- /** The summary content blocks produced by the backend. */
62
- summary: ContentBlock[]
63
- /**
64
- * The surface-boundary pair that was shadowed: the seqs of the first
65
- * (`start`) and last (`end`) surface nodes of the replaced range. A
66
- * surface-POSITION span, not a numeric seq interval — after a prior replace
67
- * lands a fresh high-seq summary node at an older range's position, `start`
68
- * can be GREATER than `end`. {@link CompactionResult.shadowedSeqs} is the
69
- * authoritative set of shadowed nodes, in surface order.
70
- */
71
- shadowedRange: { start: SessionSeq; end: SessionSeq }
72
- /** The seqs of all shadowed surface nodes, in surface order. */
73
- shadowedSeqs: SessionSeq[]
74
- /** Estimated token count of the shadowed content. */
75
- shadowedTokenCount: number
76
- }
77
- ```
78
-
79
- ## The service
80
-
81
- Automatic callers state why policy is running; implementations may treat confirmed overflow more aggressively than ordinary pressure.
82
-
83
- ```ts type-equiv
84
- /** Why automatic policy is asking a backend to consider compaction. */
85
- type CompactionTrigger = 'pressure' | 'context-overflow'
86
- ```
87
-
88
- `CompactionEngine` exposes `compactIfNeeded(agent, trigger, signal)` for automatic `pressure` or `context-overflow` policy, `compactNow(agent, signal)` for one useful idle-session reduction even below pressure, and `compactRegion(...)` for an explicit inclusive surface range. `compactNow()` runs as agent maintenance between turns, returns `null` without writing when no useful range exists, records a standalone `turn: null` bracket before summarization, and flushes a closed attempt before later queued prompts may derive from the new surface. Every backend creates its replacement `user/message` source with `compactCheckpointSource(compactionId, sourceCommandId?)`; client and wire consumers import that constructor, `CompactionCheckpointSource`, and `isCompactCheckpointSource()` from the cordis-free `@deepseek-ai/dsh-compaction/checkpoint` subpath, while the package root re-exports them for host consumers. The required transaction identity correlates the replacement checkpoint, while the predicate keeps recognition independent of any one backend. Implementations must forward the supplied signal to summarization. The seam owns no pricing API: the singleton [`ctx.tokenMeter`](./token-meter.md) directly owns estimation and replay, while `dsh-compaction-basic` owns retention, event sequencing, routed summarization calls, and their configuration.
89
-
90
- Expected manual failures use `ManualCompactionErrorCode`:
91
-
92
- ```ts type-equiv
93
- /** Expected failure classes for an explicit idle-session compaction request. */
94
- type ManualCompactionErrorCode =
95
- | 'busy'
96
- | 'cancelled'
97
- | 'changed'
98
- | 'summary'
99
- | 'commit'
100
- | 'persistence'
101
- ```
102
-
103
- `changed` and `summary` close and persist the failed attempt without a summary replacement; image omissions recorded during recovery remain effective. `commit` may follow partial mutation; `persistence` means the in-memory bracket closed but its flush failed. Cancellation remains separate and throws the exact abort reason after required cleanup.
104
-
105
- Pressure compaction runs at `agent/pre-step` against the committed request header and at `agent/request` against a changed destination before its header is logged. Model-switch summaries retain the previous route unless an explicit summary target is configured; a failed switch preserves that header and any completed reductions. Once pressure or canonical overflow qualifies, compaction-basic invokes optional [`ctx.toolResultPruner`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction-tool-result-pruner/README.md) before range selection, remeasures through `ctx.tokenMeter`, and can advance the surface without a summary. Failed-request recovery runs through `agent/request-error` after the failed step closes and returns a retry action only when the surface replacement generation advances, even if later summary work throws after pruning; cancellation still wins. Region boundaries preserve tool-call/result pairing but not whole turns, allowing early closed steps of one oversized turn to compact. `dsh-compaction-basic` owns thresholds, retained-tail policy, overflow caps, and failure handling.
106
-
107
- The Service Definition exports `toolPairingBalancedBefore(session, seq)` and `toolPairingBalancedAfter(session, seq)` for the tool-call/result pairing checks before and after a seq. Both validate current surface membership and reject missing seqs and orphan results; the [package contract](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction/README.md#tool-pairing-boundaries) defines their cache behavior.
108
-
109
- ## Tool-result pruning outcomes
110
-
111
- The optional tool-result pruning service reports each durable content replacement and the aggregate Unicode-code-point reduction. Its public result types live in [`compaction-tool-result-pruner/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction-tool-result-pruner/src/types.ts).
112
-
113
- ```ts type-equiv
114
- /** Cited source event and size accounting for one landed surface replacement. */
115
- interface PrunedEntry {
116
- /** Full-fidelity tool-result event shadowed by the replacement. */
117
- readonly originalSeq: SessionSeq
118
- /** Newly appended pruned tool-result event. */
119
- readonly replacementSeq: SessionSeq
120
- /** Tool call shared by the original and replacement. */
121
- readonly callId: ToolCallId
122
- /** Original text size in Unicode code points. */
123
- readonly charsBefore: number
124
- /** Replacement text size in Unicode code points. */
125
- readonly charsAfter: number
126
- }
127
- ```
128
-
129
- ```ts type-equiv
130
- /** Aggregate outcome of one stable-surface pruning pass. */
131
- interface PruneResult {
132
- /** Replacements in the snapshotted surface order. */
133
- readonly pruned: readonly PrunedEntry[]
134
- /** Total Unicode code points removed across replacements. */
135
- readonly charsRemoved: number
136
- }
137
- ```
138
-
139
- <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
140
-
141
- <a id="cordis-surface"></a>
142
-
143
- ## Cordis API
144
-
145
- Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
146
-
147
- <a id="ctxcompaction--compactionengine-abstract-seam"></a>
148
-
149
- ### `ctx.compaction` — `CompactionEngine` (abstract seam)
150
-
151
- Abstract compaction service. Implementations own trigger policy, retention, and summarization, and may consume a separate measurement service. A successful run replaces the selected surface span with one summary node and prevents concurrent compaction of the same session. The replacement user message uses compactCheckpointSource with the transaction identity so consumers recognize and correlate it independently of the backend. Load one implementation per context as `ctx.compaction`.
152
-
153
- ```ts cordis-catalog
154
- /**
155
- * Consider automatic compaction for one explicit trigger. Pressure policy
156
- * uses the latest durable routed request, while context-overflow policy may
157
- * force a useful balanced reduction even below the normal threshold. Return
158
- * `null` when no safe range can be compacted. A single oversized retained
159
- * unit or request envelope cannot be repaired through surface compaction.
160
- *
161
- * @param agent - agent context owning the session surface and routing options.
162
- * @param trigger - normal pressure or provider-confirmed context overflow.
163
- * @param signal - cancellation signal; model-backed implementations must forward it.
164
- * @returns the compaction result, or `null` if no compaction was needed.
165
- */
166
- abstract compactIfNeeded( agent: CompactionAgentContext, trigger: CompactionTrigger, signal: AbortSignal, ): Promise<CompactionResult | null>
167
-
168
- /**
169
- * Explicitly compact useful history even below automatic pressure thresholds.
170
- * Implementations synchronously start an idle task before any asynchronous
171
- * work, select a useful range without writing on a no-op, then
172
- * append a standalone `compaction/start` before summarization. That durable
173
- * marker is the compaction lock until one `compaction/end` attempt. Later waking
174
- * prompts remain accepted in FIFO order and start only after the optional
175
- * durability checkpoint and idle-task settlement. Context injected while the
176
- * summary runs may sit between the marker pair; only the selected span must
177
- * remain stable.
178
- *
179
- * @param agent - idle agent whose durable history should be compacted.
180
- * @param signal - cancellation scoped to this compaction request.
181
- * @param sourceCommandId - initiating command identity for a manual compaction.
182
- * @returns the compaction result, or `null` when no safe useful range exists.
183
- * @throws {@link ManualCompactionError} for expected busy, agent-cancellation,
184
- * changed-span, summarization/shrink, commit-stage, or persistence failures;
185
- * an aborted request preserves its exact abort reason. Failed attempts remain
186
- * visible in the log.
187
- */
188
- abstract compactNow( agent: ManualCompactAgentContext, signal: AbortSignal, sourceCommandId?: CommandId, ): Promise<CompactionResult | null>
189
-
190
- /**
191
- * Forcibly compact a range of surface nodes into a single summary node.
192
- * `start` and `end` name an inclusive span by surface position, not numeric seq
193
- * order; replacements can make visible seqs non-monotonic. Both edges must be
194
- * balanced so assistant tool calls remain paired with their results. A model-
195
- * backed implementation forwards cancellation and rejects active, missing,
196
- * reversed, or unbalanced ranges. The target session is `agent.session`.
197
- * Its replacement user message must use {@link compactCheckpointSource} with
198
- * the transaction's `CompactionId`.
199
- * Use {@link toolPairingBalancedBefore} and {@link toolPairingBalancedAfter}
200
- * for the edge checks.
201
- *
202
- * @param start - first surface seq, inclusive.
203
- * @param end - last surface seq, inclusive.
204
- * @param agent - context whose session is mutated and whose routing options guide summarization.
205
- * @param signal - optional cancellation; model-backed implementations must forward it.
206
- * @throws when compaction is active or the range is missing, reversed, or unbalanced.
207
- * @returns the appended event seqs, summary, replaced range, and token accounting.
208
- */
209
- abstract compactRegion( start: SessionSeq, end: SessionSeq, agent: CompactionAgentContext, signal?: AbortSignal, ): Promise<CompactionResult>
210
- ```
211
-
212
- Types: [CommandId](./commands.md) · [SessionSeq](./session.md)
213
-
214
- Source: [`packages/compaction/compaction/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction/src/index.ts)
215
-
216
- <a id="ctxtoolresultpruner--toolresultpruner"></a>
217
-
218
- ### `ctx.toolResultPruner` — `ToolResultPruner`
219
-
220
- Deterministic head/middle/tail pruning for current tool-result surface nodes.
221
-
222
- ```ts cordis-catalog
223
- /**
224
- * Measure text content in Unicode code points; non-text blocks cost zero.
225
- * @param blocks - tool-result content to measure.
226
- * @returns total Unicode code points across text blocks.
227
- */
228
- measureContent(blocks: readonly ContentBlock[]): number
229
-
230
- /**
231
- * Replace an over-budget text middle while retaining rich-block order.
232
- * Text slicing is by Unicode code point, not UTF-16 code unit, so a retained
233
- * boundary cannot split a surrogate pair. Grapheme clusters may still split.
234
- * @param blocks - original tool-result content.
235
- * @returns pruned content, or `null` when the text is within budget.
236
- */
237
- pruneContent(blocks: readonly ContentBlock[]): ContentBlock[] | null
238
-
239
- /**
240
- * Prune every over-budget tool result from one stable current-surface snapshot.
241
- * Each replacement preserves the complete event data except for `content`,
242
- * cites the shadowed node so replay can recover the replacement input, and is
243
- * immediately preceded by a `compaction/prune` shadow-price event pricing the
244
- * shadowed node through the injected token meter, so pure consumers can
245
- * subtract it without per-node state.
246
- * @param session - session whose current surface is rewritten.
247
- * @returns landed replacements and aggregate Unicode-code-point savings.
248
- * @throws when the session rejects a replacement; replacements committed
249
- * earlier in the pass remain durable.
250
- */
251
- pruneSession(session: Session): PruneResult
252
- ```
253
-
254
- Types: [ContentBlock](./llm-streaming.md) · [Session](./session.md)
255
-
256
- Source: [`packages/compaction/compaction-tool-result-pruner/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction-tool-result-pruner/src/index.ts)
257
-
258
- <a id="compaction-events"></a>
259
-
260
- ### `compaction/*` events
261
-
262
- <a id="compactionsummary-error--waterfall"></a>
263
-
264
- #### `compaction/summary-error` — waterfall
265
-
266
- Recover a failed summary request by synchronously recording a durable change to its selected input. Return true only after making progress; the provider re-derives and re-prices the selection before retrying. Call next() when the failure cannot be recovered. Decisions survive a later summary failure or cancellation.
267
-
268
- ```ts cordis-catalog
269
- /**
270
- * Recover a failed summary request by synchronously recording a durable
271
- * change to its selected input. Return true only after making progress;
272
- * the provider re-derives and re-prices the selection before retrying.
273
- * Call next() when the failure cannot be recovered. Decisions survive a
274
- * later summary failure or cancellation.
275
- * @param payload.session - session containing the selected input.
276
- * @param payload.sourceEventSeqs - selected message events in request order.
277
- * @param payload.error - failure thrown by the summarizer.
278
- * @param payload.signal - optional compaction cancellation signal.
279
- * @param next - delegate to the next recovery listener.
280
- * @mode waterfall
281
- */
282
- 'compaction/summary-error'(payload: { session: Session; sourceEventSeqs: readonly SessionSeq[]; error: unknown; signal?: AbortSignal }, next: () => boolean): boolean
283
- ```
284
-
285
- Types: [Session](./session.md) · [SessionSeq](./session.md)
286
-
287
- Source: [`packages/compaction/compaction/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction/src/index.ts)
288
- <!-- END GENERATED cordis-surface -->
1
+ ---
2
+ editSource: "docs/subsystems/compaction.md"
3
+ rawMarkdownPath: "en/reference/subsystems/compaction.md"
4
+ outline: [2,3]
5
+ ---
6
+
7
+ # Compaction
8
+
9
+ The compaction seam — a [capability seam](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-06-13-capability-seams.md) split like bash: Service Definition ([dsh-compaction](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/compaction/compaction), `ctx.compaction`), Service Provider (a backend such as [dsh-compaction-basic](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/compaction/compaction-basic)), and human Consumer ([dsh-command-compact](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/compaction/command-compact)). Compaction is **one optional capability**, not part of the agent-loop spine — so its vocabulary lives here, not in [core.md](./core.md). A tokenizer- or template-based backend is a sibling package implementing the same interface. Unlike bash, the interface necessarily depends on `dsh-session` and `dsh-llm`: its verbs act on an agent-owned `Session`, and its durable summary event uses the `ContentBlock` vocabulary (see the [compaction capability-seam reference](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction/README.md)).
10
+
11
+ Source: [`packages/compaction/compaction/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction/src/types.ts)
12
+
13
+ ## The `compaction/*` session events
14
+
15
+ Compaction extends [`SessionEventMap`](./session.md) with three event types via declaration merging. All three are **log-only** — they record the lock, summary, selected range, shadowed event seqs, token count, and model call without joining the surface. `SurfaceEventType` is deliberately NOT extended (only message-producing events reach the model), so the summary itself rides on a separate `user/message` with `surfaceOp: { op: 'replace', startSeq, endSeq }` — the only surface mutation performed by summary compaction. The [historical Agent Note](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/archived/feature/2026-06-18-compaction-capability-seam.md) records the rationale for reusing `user/message`.
16
+
17
+ | Event | Payload | Role |
18
+ |---|---|---|
19
+ | `compaction/start` | `{ turn }` | acquires the log-recorded lock; a number identifies the open automatic turn, while `null` identifies a standalone manual attempt |
20
+ | `compaction/summary` | `{ summary, rawOutput?, llmStreamCall?, shadowedRange, shadowedSeqs, shadowedTokenCount, provider, model, maxTokens?, usage? }` | the safe summary projection, optional complete provider output and usage, an `llmStreamCall: true` marker when producing the result consumed exactly one call through this context's `ctx.llm.stream()` (which requires complete `rawOutput`), the shadowed surface-boundary pair (`start`/`end` seqs — a position span, not a numeric interval), the shadowed seqs in surface order, the estimated token count, and the summarize call's envelope (`provider`, `model`, plus its generation cap when one applied) — logged so the one-shot request is reconstructable from log + code (the reconstructability Agent Note); unmarked `rawOutput` does not identify the call path |
21
+ | `compaction/end` | `{ turn, error? }` | releases the lock with the same numeric-or-null owner (`error` records an unsuccessful attempt) |
22
+
23
+ The lock brackets the **whole** operation: `compaction/start` is appended first, then summarization, the `compaction/summary` record, and the `user/message` replacement all land, and only then `compaction/end`. Releasing the lock last turns a crash mid-operation into a detectable orphaned lock (a `compaction/start` with no matching `compaction/end`) rather than a `compaction/end` that falsely claims compaction finished.
24
+
25
+ The markers are lock time points, not an exclusive container. An unrelated idle injection can appear between a standalone manual start and end while summarization is pending. The manual path revalidates only its selected positional span, so that injected context survives after the replacement checkpoint. A live unmatched start blocks every entry point; an unmatched start before a newer `session/end-seed` is stale evidence from a prior lifecycle and is ignored.
26
+
27
+ These variants are merged inside a `declare module '@deepseek-ai/dsh-session/types'` block, so — unlike the top-level types on the other subsystem pages — they are not pasted as a drift-checked ` ```ts type-equiv ` block (the `verify-type-equiv` extractor matches only top-level declarations by name). The payload table above is the catalog entry; follow the source link for the authoritative fields.
28
+
29
+ <a id="image-offload"></a>
30
+ ## Image offload
31
+
32
+ `compaction-image-offload` owns the `image/offload` declaration and its pure message projection. Each target identifies a current input node and exact depth-first image occurrences. The event preserves node and message identities and carries no `surfaceOp`. The [package README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction-image-offload/README.md) owns recovery policy, registration, and detached replay.
33
+
34
+ ```ts type-equiv
35
+ /** Exact input-image occurrences selected by one durable offload decision. */
36
+ interface ImageOffloadTarget {
37
+ /** Current message-producing event containing these occurrences. */
38
+ seq: SessionSeq
39
+ /** Zero-based depth-first image indexes within the immutable message. */
40
+ imageIndexes: number[]
41
+ }
42
+ ```
43
+
44
+ ## `CompactionResult`
45
+
46
+ What a successful compaction returns to its caller: the bookkeeping-event seqs, safe summary projection, shadowed range and seqs, and estimated token count.
47
+
48
+ ```ts type-equiv
49
+ /** Result of a successful compaction operation. */
50
+ interface CompactionResult {
51
+ /** Stable identity shared by this compaction's complete durable lifecycle. */
52
+ compactionId: CompactionId
53
+ /** Human command that initiated this compaction, when it was manual. */
54
+ sourceCommandId?: CommandId
55
+ /** The seq of the appended `compaction/start` event. */
56
+ startSeq: SessionSeq
57
+ /** The seq of the appended `compaction/summary` event. */
58
+ summarySeq: SessionSeq
59
+ /** The seq of the appended `compaction/end` event. */
60
+ endSeq: SessionSeq
61
+ /** The summary content blocks produced by the backend. */
62
+ summary: ContentBlock[]
63
+ /**
64
+ * The surface-boundary pair that was shadowed: the seqs of the first
65
+ * (`start`) and last (`end`) surface nodes of the replaced range. A
66
+ * surface-POSITION span, not a numeric seq interval — after a prior replace
67
+ * lands a fresh high-seq summary node at an older range's position, `start`
68
+ * can be GREATER than `end`. {@link CompactionResult.shadowedSeqs} is the
69
+ * authoritative set of shadowed nodes, in surface order.
70
+ */
71
+ shadowedRange: { start: SessionSeq; end: SessionSeq }
72
+ /** The seqs of all shadowed surface nodes, in surface order. */
73
+ shadowedSeqs: SessionSeq[]
74
+ /** Estimated token count of the shadowed content. */
75
+ shadowedTokenCount: number
76
+ }
77
+ ```
78
+
79
+ ## The service
80
+
81
+ Automatic callers state why policy is running; implementations may treat confirmed overflow more aggressively than ordinary pressure.
82
+
83
+ ```ts type-equiv
84
+ /** Why automatic policy is asking a backend to consider compaction. */
85
+ type CompactionTrigger = 'pressure' | 'context-overflow'
86
+ ```
87
+
88
+ `CompactionEngine` exposes `compactIfNeeded(agent, trigger, signal)` for automatic `pressure` or `context-overflow` policy, `compactNow(agent, signal)` for one useful idle-session reduction even below pressure, and `compactRegion(...)` for an explicit inclusive surface range. `compactNow()` runs as agent maintenance between turns, returns `null` without writing when no useful range exists, records a standalone `turn: null` bracket before summarization, and flushes a closed attempt before later queued prompts may derive from the new surface. Every backend creates its replacement `user/message` source with `compactCheckpointSource(compactionId, sourceCommandId?)`; client and wire consumers import that constructor, `CompactionCheckpointSource`, and `isCompactCheckpointSource()` from the cordis-free `@deepseek-ai/dsh-compaction/checkpoint` subpath, while the package root re-exports them for host consumers. The required transaction identity correlates the replacement checkpoint, while the predicate keeps recognition independent of any one backend. Implementations must forward the supplied signal to summarization. The seam owns no pricing API: the singleton [`ctx.tokenMeter`](./token-meter.md) directly owns estimation and replay, while `dsh-compaction-basic` owns retention, event sequencing, routed summarization calls, and their configuration.
89
+
90
+ Expected manual failures use `ManualCompactionErrorCode`:
91
+
92
+ ```ts type-equiv
93
+ /** Expected failure classes for an explicit idle-session compaction request. */
94
+ type ManualCompactionErrorCode =
95
+ | 'busy'
96
+ | 'cancelled'
97
+ | 'changed'
98
+ | 'summary'
99
+ | 'commit'
100
+ | 'persistence'
101
+ ```
102
+
103
+ `changed` and `summary` close and persist the failed attempt without a summary replacement; image omissions recorded during recovery remain effective. `commit` may follow partial mutation; `persistence` means the in-memory bracket closed but its flush failed. Cancellation remains separate and throws the exact abort reason after required cleanup.
104
+
105
+ Pressure compaction runs at `agent/pre-step` against the committed request header and at `agent/request` against a changed destination before its header is logged. Unless an explicit summary target is configured, every summary in a session that holds an assistant message uses the route that produced the latest one, so a destination whose first request overflowed does not summarize its own overflow; a failed switch preserves that header and any completed reductions. Once pressure or canonical overflow qualifies, compaction-basic invokes optional [`ctx.toolResultPruner`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction-tool-result-pruner/README.md) before range selection, remeasures through `ctx.tokenMeter`, and can advance the surface without a summary. Failed-request recovery runs through `agent/request-error` after the failed step closes and returns a retry action only when the surface replacement generation advances, even if later summary work throws after pruning; cancellation still wins. Region boundaries preserve tool-call/result pairing but not whole turns, allowing early closed steps of one oversized turn to compact. `dsh-compaction-basic` owns thresholds, retained-tail policy, overflow caps, and failure handling.
106
+
107
+ The Service Definition exports `toolPairingBalancedBefore(session, seq)` and `toolPairingBalancedAfter(session, seq)` for the tool-call/result pairing checks before and after a seq. Both validate current surface membership and reject missing seqs and orphan results; the [package contract](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction/README.md#tool-pairing-boundaries) defines their cache behavior.
108
+
109
+ ## Tool-result pruning outcomes
110
+
111
+ The optional tool-result pruning service reports each durable content replacement and the aggregate Unicode-code-point reduction. Its public result types live in [`compaction-tool-result-pruner/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction-tool-result-pruner/src/types.ts).
112
+
113
+ ```ts type-equiv
114
+ /** Cited source event and size accounting for one landed surface replacement. */
115
+ interface PrunedEntry {
116
+ /** Full-fidelity tool-result event shadowed by the replacement. */
117
+ readonly originalSeq: SessionSeq
118
+ /** Newly appended pruned tool-result event. */
119
+ readonly replacementSeq: SessionSeq
120
+ /** Tool call shared by the original and replacement. */
121
+ readonly callId: ToolCallId
122
+ /** Original text size in Unicode code points. */
123
+ readonly charsBefore: number
124
+ /** Replacement text size in Unicode code points. */
125
+ readonly charsAfter: number
126
+ }
127
+ ```
128
+
129
+ ```ts type-equiv
130
+ /** Aggregate outcome of one stable-surface pruning pass. */
131
+ interface PruneResult {
132
+ /** Replacements in the snapshotted surface order. */
133
+ readonly pruned: readonly PrunedEntry[]
134
+ /** Total Unicode code points removed across replacements. */
135
+ readonly charsRemoved: number
136
+ }
137
+ ```
138
+
139
+ <!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
140
+
141
+ <a id="cordis-surface"></a>
142
+
143
+ ## Cordis API
144
+
145
+ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — the language sides differ only in locale-specific paired document paths. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` API lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
146
+
147
+ <a id="ctxcompaction--compactionengine-abstract-seam"></a>
148
+
149
+ ### `ctx.compaction` — `CompactionEngine` (abstract seam)
150
+
151
+ Abstract compaction service. Implementations own trigger policy, retention, and summarization, and may consume a separate measurement service. A successful run replaces the selected surface span with one summary node and prevents concurrent compaction of the same session. The replacement user message uses compactCheckpointSource with the transaction identity so consumers recognize and correlate it independently of the backend. Load one implementation per context as `ctx.compaction`.
152
+
153
+ ```ts cordis-catalog
154
+ /**
155
+ * Consider automatic compaction for one explicit trigger. Pressure policy
156
+ * uses the latest durable routed request, while context-overflow policy may
157
+ * force a useful balanced reduction even below the normal threshold. Return
158
+ * `null` when no safe range can be compacted. A single oversized retained
159
+ * unit or request envelope cannot be repaired through surface compaction.
160
+ *
161
+ * @param agent - agent context owning the session surface and routing options.
162
+ * @param trigger - normal pressure or provider-confirmed context overflow.
163
+ * @param signal - cancellation signal; model-backed implementations must forward it.
164
+ * @returns the compaction result, or `null` if no compaction was needed.
165
+ */
166
+ abstract compactIfNeeded( agent: CompactionAgentContext, trigger: CompactionTrigger, signal: AbortSignal, ): Promise<CompactionResult | null>
167
+
168
+ /**
169
+ * Explicitly compact useful history even below automatic pressure thresholds.
170
+ * Implementations synchronously start an idle task before any asynchronous
171
+ * work, select a useful range without writing on a no-op, then
172
+ * append a standalone `compaction/start` before summarization. That durable
173
+ * marker is the compaction lock until one `compaction/end` attempt. Later waking
174
+ * prompts remain accepted in FIFO order and start only after the optional
175
+ * durability checkpoint and idle-task settlement. Context injected while the
176
+ * summary runs may sit between the marker pair; only the selected span must
177
+ * remain stable.
178
+ *
179
+ * @param agent - idle agent whose durable history should be compacted.
180
+ * @param signal - cancellation scoped to this compaction request.
181
+ * @param sourceCommandId - initiating command identity for a manual compaction.
182
+ * @returns the compaction result, or `null` when no safe useful range exists.
183
+ * @throws {@link ManualCompactionError} for expected busy, agent-cancellation,
184
+ * changed-span, summarization/shrink, commit-stage, or persistence failures;
185
+ * an aborted request preserves its exact abort reason. Failed attempts remain
186
+ * visible in the log.
187
+ */
188
+ abstract compactNow( agent: ManualCompactAgentContext, signal: AbortSignal, sourceCommandId?: CommandId, ): Promise<CompactionResult | null>
189
+
190
+ /**
191
+ * Forcibly compact a range of surface nodes into a single summary node.
192
+ * `start` and `end` name an inclusive span by surface position, not numeric seq
193
+ * order; replacements can make visible seqs non-monotonic. Both edges must be
194
+ * balanced so assistant tool calls remain paired with their results. A model-
195
+ * backed implementation forwards cancellation and rejects active, missing,
196
+ * reversed, or unbalanced ranges. The target session is `agent.session`.
197
+ * Its replacement user message must use {@link compactCheckpointSource} with
198
+ * the transaction's `CompactionId`.
199
+ * Use {@link toolPairingBalancedBefore} and {@link toolPairingBalancedAfter}
200
+ * for the edge checks.
201
+ *
202
+ * @param start - first surface seq, inclusive.
203
+ * @param end - last surface seq, inclusive.
204
+ * @param agent - context whose session is mutated and whose routing options guide summarization.
205
+ * @param signal - optional cancellation; model-backed implementations must forward it.
206
+ * @throws when compaction is active or the range is missing, reversed, or unbalanced.
207
+ * @returns the appended event seqs, summary, replaced range, and token accounting.
208
+ */
209
+ abstract compactRegion( start: SessionSeq, end: SessionSeq, agent: CompactionAgentContext, signal?: AbortSignal, ): Promise<CompactionResult>
210
+ ```
211
+
212
+ Types: [CommandId](./commands.md) · [SessionSeq](./session.md)
213
+
214
+ Source: [`packages/compaction/compaction/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction/src/index.ts)
215
+
216
+ <a id="ctxtoolresultpruner--toolresultpruner"></a>
217
+
218
+ ### `ctx.toolResultPruner` — `ToolResultPruner`
219
+
220
+ Deterministic head/middle/tail pruning for current tool-result surface nodes.
221
+
222
+ ```ts cordis-catalog
223
+ /**
224
+ * Measure text content in Unicode code points; non-text blocks cost zero.
225
+ * @param blocks - tool-result content to measure.
226
+ * @returns total Unicode code points across text blocks.
227
+ */
228
+ measureContent(blocks: readonly ContentBlock[]): number
229
+
230
+ /**
231
+ * Replace an over-budget text middle while retaining rich-block order.
232
+ * Text slicing is by Unicode code point, not UTF-16 code unit, so a retained
233
+ * boundary cannot split a surrogate pair. Grapheme clusters may still split.
234
+ * @param blocks - original tool-result content.
235
+ * @returns pruned content, or `null` when the text is within budget.
236
+ */
237
+ pruneContent(blocks: readonly ContentBlock[]): ContentBlock[] | null
238
+
239
+ /**
240
+ * Prune every over-budget tool result from one stable current-surface snapshot.
241
+ * Each replacement preserves the complete event data except for `content`,
242
+ * cites the shadowed node so replay can recover the replacement input, and is
243
+ * immediately preceded by a `compaction/prune` shadow-price event pricing the
244
+ * shadowed node through the injected token meter, so pure consumers can
245
+ * subtract it without per-node state.
246
+ * @param session - session whose current surface is rewritten.
247
+ * @returns landed replacements and aggregate Unicode-code-point savings.
248
+ * @throws when the session rejects a replacement; replacements committed
249
+ * earlier in the pass remain durable.
250
+ */
251
+ pruneSession(session: Session): PruneResult
252
+ ```
253
+
254
+ Types: [ContentBlock](./llm-streaming.md) · [Session](./session.md)
255
+
256
+ Source: [`packages/compaction/compaction-tool-result-pruner/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction-tool-result-pruner/src/index.ts)
257
+
258
+ <a id="compaction-events"></a>
259
+
260
+ ### `compaction/*` events
261
+
262
+ <a id="compactionsummary-error--waterfall"></a>
263
+
264
+ #### `compaction/summary-error` — waterfall
265
+
266
+ Recover a failed summary request by synchronously recording a durable change to its selected input. Return true only after making progress; the provider re-derives and re-prices the selection before retrying. Call next() when the failure cannot be recovered. Decisions survive a later summary failure or cancellation.
267
+
268
+ ```ts cordis-catalog
269
+ /**
270
+ * Recover a failed summary request by synchronously recording a durable
271
+ * change to its selected input. Return true only after making progress;
272
+ * the provider re-derives and re-prices the selection before retrying.
273
+ * Call next() when the failure cannot be recovered. Decisions survive a
274
+ * later summary failure or cancellation.
275
+ * @param payload.session - session containing the selected input.
276
+ * @param payload.sourceEventSeqs - selected message events in request order.
277
+ * @param payload.error - failure thrown by the summarizer.
278
+ * @param payload.signal - optional compaction cancellation signal.
279
+ * @param next - delegate to the next recovery listener.
280
+ * @mode waterfall
281
+ */
282
+ 'compaction/summary-error'(payload: { session: Session; sourceEventSeqs: readonly SessionSeq[]; error: unknown; signal?: AbortSignal }, next: () => boolean): boolean
283
+ ```
284
+
285
+ Types: [Session](./session.md) · [SessionSeq](./session.md)
286
+
287
+ Source: [`packages/compaction/compaction/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/compaction/compaction/src/index.ts)
288
+ <!-- END GENERATED cordis-surface -->