dsh-log-contract 0.3.5 → 0.3.7

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.md CHANGED
@@ -1,64 +1,143 @@
1
- # dsh-log-contract · 日志契约守护
1
+ <div align="center">
2
2
 
3
- > DSH(DeepSeek Harness)会话日志的**结构契约保险丝**:离线体检 + 写前校验。
4
- > 原名 `log-contract-validator`(候选二号),按 Offer快 三件套规划定名 **`dsh-log-contract`**。
3
+ # 🔒 dsh-log-contract
5
4
 
6
- DSH 会话日志(`*.jsonl` / `*.jsonl.zstd`)装一条保险丝:人眼看不出、程序解析会崩的日志格式漂移,在它这里被拦下并告警。它不判断日志**内容**对不对,只守护日志**结构**是否破坏了下游消费者(Harness 读路径、客户端引擎、插件 marker 语义)的预期。
5
+ **Log Contract Guard** the structural fuse for DeepSeek Harness session logs:
6
+ offline health check + pre-write validation. The business layer's **doctor**.
7
7
 
8
- - **`check <session-log>`** —— 离线体检:官方解码器全量解码 + 契约逐条校验 + foldSurface 终验,产出违规报告。
9
- - **`prewrite <edit-file> --log <session-log>`** —— ★ 写前校验:任何写入(追加 / 帧级手术)在落盘之前先过三层契约,违约即拦。
10
- - **`contracts`** —— 列出内置契约规则目录(每条附官方源码出处)。
8
+ [![npm version](https://img.shields.io/npm/v/dsh-log-contract)](https://www.npmjs.com/package/dsh-log-contract)
9
+ [![npm downloads](https://img.shields.io/npm/dm/dsh-log-contract)](https://www.npmjs.com/package/dsh-log-contract)
10
+ [![License: MIT](https://img.shields.io/npm/l/dsh-log-contract)](https://github.com/yamingmou/dsh-log-contract/blob/main/LICENSE)
11
+ [![DSH plugin](https://img.shields.io/badge/DSH-plugin-4A90D9)](https://github.com/topics/dsh-plugin)
12
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen)](https://github.com/yamingmou/dsh-log-contract/pulls)
13
+
14
+ **English** · [简体中文](./README.zh.md)
15
+
16
+ </div>
17
+
18
+ Formerly `log-contract-validator` (candidate #2); named **`dsh-log-contract`**
19
+ per the OfferKuai three-piece plan.
20
+
21
+ A fuse for DSH session logs (`*.jsonl` / `*.jsonl.zstd`): format drift that humans
22
+ cannot see but parsers crash on is caught and reported here. It does **not** judge
23
+ whether log *content* is right — only whether log *structure* breaks the
24
+ expectations of downstream consumers (the Harness read path, the client engine,
25
+ plugin marker semantics).
26
+
27
+ - **`check <session-log>`** — offline health check: official decoder full decode +
28
+ per-rule contract validation + foldSurface final verification, with a violation
29
+ report.
30
+ - **`prewrite <edit-file> --log <session-log>`** — ★ pre-write validation: any
31
+ write (append / frame-level surgery) passes the three-layer contract before it
32
+ lands; violations are blocked.
33
+ - **`contracts`** — list the built-in contract rule catalog (each with its
34
+ official source reference).
35
+
36
+ ---
37
+
38
+ ## Where it sits in the business layer
39
+
40
+ > **dsh-log-contract is the core capability component of
41
+ > [dsh-retrace](https://github.com/yamingmou/dsh-retrace)** — the "doctor" module
42
+ > of the business layer: session-log **check & repair**, so every recall/edit/rewind
43
+ > lands on a legal log and `/compact` never breaks.
44
+
45
+ | Layer | What it is | Components |
46
+ |---|---|---|
47
+ | **Agent business layer (production-grade)** | Framework-agnostic core: session hygiene / retraceability / auditability / recoverability | Four modules: governance / retrospect / archaeology / **doctor** |
48
+ | **dsh-retrace** | The business layer's DeepSeek Harness implementation | recall/edit/version/rollback/watchdog |
49
+ | **dsh-log-contract** | dsh-retrace's core component = the business layer's **doctor** (check & repair) | check / prewrite / fix / extract / audit |
50
+
51
+ **Meaning**: dsh-log-contract is published standalone (for direct use or
52
+ re-implementation), but it is first the "check & repair" capability of dsh-retrace —
53
+ together they form the **Agent business layer (production-grade guarantees)** on
54
+ DSH (see the [dsh-retrace roadmap](https://github.com/yamingmou/dsh-retrace/blob/main/docs/ROADMAP.md)).
11
55
 
12
56
  ---
13
57
 
14
- ## 为什么需要它
58
+ ## Why it exists
15
59
 
16
- **#3632one log, two consumers, two verdicts」**:一条日志同时被人类与自动化程序消费,人眼容忍格式微调,程序解析依赖严格契约;格式一旦漂移,人看不出问题,程序直接崩溃或误报。
60
+ **#3632 "one log, two consumers, two verdicts"**: one log is consumed by both
61
+ humans and automated programs. Humans tolerate format drift; programs depend on
62
+ strict contracts. Once the format drifts, humans see nothing wrong while programs
63
+ crash or misreport.
17
64
 
18
- **2026-08-25 会话修复事故(真实回归用例)**:一次"恢复被隐藏内容"的修复,第 1 轮清空 marker `sourceEventSeqs` 直接写盘 会话加载抛 `SessionPersistenceCorruptionError`;第 2 轮把 marker 改成 `append` → 客户端引擎崩溃。两次都是**违约写入没被拦**。如果有写前校验,会话根本不会被改坏。本工具把这次事故沉淀为两条核心规则(S5、M1)与回归测试。
65
+ **Real incidents shaped every rule here** see the [Incident log](#-incident-log)
66
+ below. Each incident is a regression fixture: a corrupted session that this tool
67
+ must flag, and a fixed session that it must pass.
19
68
 
20
69
  ---
21
70
 
22
- ## 三层契约(判定模型)
71
+ ## Three-layer contract (the model)
23
72
 
24
- | | 契约 | 本工具 |
73
+ > 30+ rules across the layers below (`contracts` lists them all, each with its
74
+ > official source reference).
75
+
76
+ | Layer | Rules | What it guards |
25
77
  |---|---|---|
26
- | **持久化层** | seq 严格连续;type 在已知词汇表内;surface 事件携带合法 `surfaceOp`;replace `sourceEventSeqs` 必须**完整覆盖被替换节点**;官方 `foldSurface` 不抛 = 通过 | 规则 H/R/E/S(含 S5 核心) |
27
- | **客户端引擎层** | `data.turn/step` null `assistant/message` 只能以 **replace** 承载(插件 marker 定义),append 会触发引擎崩溃 | 规则 M1 |
28
- | **插件语义层** | marker id 前缀必须可识别(改名登记遗留前缀);marker 自身 seq 不得进入自身 shadowed | 规则 P1/P2 |
78
+ | **Persistence** | H/R/E/S (incl. **S5**) + **S9** | seq contiguous, known types, legal `surfaceOp`, `sourceEventSeqs` fully covers shadowed nodes, file-physical seq monotonic, `foldSurface` not throwing |
79
+ | **Client engine** | **M1** + **T1 / T2 / I1** | turn-null markers only as replace; token-meter pairing; cross-step source refs; inbox seed-relative replay |
80
+ | **Wire message flow** | **W1 / W2** | tool messages follow an assistant with tool_calls; no user text between tool_calls and results |
81
+ | **Plugin semantics** | P1/P2 | marker id prefixes recognizable; a marker's seq not in its own shadowed set |
29
82
 
30
- > 校验哲学:先用与官方同语义的增量重放做**逐事件归因**(定位到 seq/行号),再跑官方 `foldSurface` 做**终验**(不抛才算过)——两套都绿才过。
83
+ > Philosophy: first an incremental replay with official-equivalent semantics for
84
+ > **per-event attribution** (pinpoint seq/line), then the official `foldSurface` as
85
+ > the **final verdict** (not throwing = pass) — both green to pass.
31
86
 
32
87
  ---
33
88
 
34
- ## 安装
89
+ ## ⚡ Incident log — why "production-grade" is not a slogan
90
+
91
+ Every rule below was born from a **real incident** in our workspace. These are the
92
+ sessions that made us build this tool. Dates and shapes are real; session ids are
93
+ omitted for privacy.
94
+
95
+ | # | Date | What happened | The rule / fix it produced |
96
+ |---|---|---|---|
97
+ | 1 | 2026-08-25 | A "restore hidden content" repair wrote a replace marker with **emptied `sourceEventSeqs`** → the session refused to load (`SessionPersistenceCorruptionError`); a second attempt changed the marker to **append** → the client engine crashed. Both were **violating writes that nothing caught**. | **S5** (sourceEventSeqs must cover shadowed nodes), **M1** (turn-null assistant/message can only be replace), pre-write validation |
98
+ | 2 | 2026-08-27~28 | Interrupted/restarted turns replayed with a **stale in-memory cursor**, re-appending old seqs to the file tail (tail regression, duplicate batches); two writers interleaved → **file-physical order non-monotonic** (`734056 → 733539 → 735470`). Sessions failed to load with `seq gap`. | **S9** (physical-order monotonic), fix `--tail-renumber` |
99
+ | 3 | 2026-08-27~28 | **Fork-boundary orphan splice**: the fork's "remove parent's pending prompt" splice assumed the parent's inbox; the child's seed-relative replay has an empty inbox → `resume failed: invalid persisted inbox splice`. | **I1** (inbox seed-relative replay), fix `--neutralize-orphan` |
100
+ | 4 | 2026-08-28 | An oversized session (**1,052,557 tokens** vs the 1M window) could neither continue nor `/compact`; the trim budget estimator underpriced CJK by ~3.7×. | T1 (token-meter pairing) for compactability, `fix --trim` budget guidance |
101
+ | 5 | 2026-08-29 | **W1/W2 wire violations**: markers shadowed an assistant with tool_calls but left the tool results dangling → strict endpoints (`INVALID_REQUEST`) reject the session's request stream. | **W1 / W2** (wire message flow) |
102
+ | 6 | 2026-08-30 | A single **turn-null marker** made the token-meter listener throw on **every** appended event (`consumedEvents` never advanced → full-prefix re-fold per event) → **30s / 10,008 log lines**, host event loop crushed, all sessions locked. Same session also had a **cross-step sourceEventSeqs** (steps 7/8/9 mixed in one assistant message) — offline checks were green, the live meter crashed. | **T1** (turn/step pairing), **T2** (cross-step source refs), `fix --neutralize`, `fix --clip-crossstep` |
103
+
104
+ > **Takeaway**: every rule in this tool is a scar from a real session — validated
105
+ > against the actual corrupted-session fixtures, not synthetic theory. That is what
106
+ > "production-grade" means here.
107
+
108
+ ---
109
+
110
+ ## Installation
35
111
 
36
112
  ```bash
37
- pnpm add -D dsh-log-contract # npm install
113
+ pnpm add -D dsh-log-contract # or npm install
38
114
  pnpm dlx dsh-log-contract --help
39
115
  ```
40
116
 
41
- > **你是 dsh-retrace 用户?** 无需单独安装——`dsh-retrace` 已把 `dsh-log-contract`
42
- > 声明为依赖,装 retrace 时自动带好契约守护(体检/写前校验/修复原语全部随插件生效)。
43
- > 本包独立发布,供愿意单独使用或二次开发的用户直接引入。
117
+ > **Using dsh-retrace?** No separate install needed — `dsh-retrace` declares
118
+ > `dsh-log-contract` as a dependency, so the contract guard (check / pre-write /
119
+ > repair primitives) comes with the plugin automatically. This package is published
120
+ > standalone for direct use or re-implementation.
44
121
  >
45
- > **从 GitHub 下载了 ZIP?** 解压后 `cd dsh-log-contract && npm install && npm run build`,
46
- > 然后 `node bin/dsh-log-contract.mjs check <session-log>` 即可使用(无需全局安装)。
122
+ > **Downloaded the repo as a ZIP?** `cd dsh-log-contract && npm install && npm run build`,
123
+ > then `node bin/dsh-log-contract.mjs check <session-log>` — no global install needed.
47
124
 
48
- 依赖:Node ≥ 22(`node:zlib` 内置 zstd)、`@deepseek-ai/dsh-session`(peer,校验/解码复用官方实现,保证与 Harness 读路径同源)。
125
+ Dependencies: Node ≥ 22 (`node:zlib` has built-in zstd), `@deepseek-ai/dsh-session`
126
+ (peer; validation/decode reuse the official implementation, so it stays in sync
127
+ with the Harness read path).
49
128
 
50
129
  ---
51
130
 
52
- ## CLI 用法
131
+ ## CLI
53
132
 
54
- ### 1. 离线体检
133
+ ### 1. Offline health check
55
134
 
56
135
  ```bash
57
136
  dsh-log-contract check ~/.dsh/sessions/<id>.jsonl.zstd
58
- dsh-log-contract check ~/.dsh/sessions/<id>.jsonl.zstd --json # 机器可读
137
+ dsh-log-contract check ~/.dsh/sessions/<id>.jsonl.zstd --json # machine-readable
59
138
  ```
60
139
 
61
- 输出示例:
140
+ Sample output (the CLI reports in Chinese — it is the tool's UI language):
62
141
 
63
142
  ```
64
143
  📋 dsh-log-contract check —— backup-session-xxxx.jsonl.zstd
@@ -71,139 +150,153 @@ dsh-log-contract check ~/.dsh/sessions/<id>.jsonl.zstd --json # 机器可读
71
150
  ❌ 未通过:见上方违规明细(error 级 = 会话不可读/不可写)
72
151
  ```
73
152
 
74
- 退出码:0 = 通过(无 error 级违规);1 = 存在 error 级违规。
153
+ Exit code: 0 = pass (no error-level violations); 1 = error-level violations exist.
75
154
 
76
- `check` 0.2.0 起新增 **W1/W2 wire 级检查**:按 surface 顺序展开模型请求消息流,
77
- 捕获"悬空 tool 消息"tool 结果没有前置 assistant tool_calls)与"user 文本插在
78
- tool_calls 与其结果之间"——这类问题 DeepSeek 曾容忍,但 MiMo 等严格端点会直接
79
- `INVALID_REQUEST`(2026-08-27 实锤)。
155
+ `check` adds **W1/W2 wire-level checks** since 0.2.0: expand the model request
156
+ stream in surface order and catch "dangling tool messages" (a tool result with no
157
+ preceding assistant tool_calls) and "user text between tool_calls and their
158
+ results" — tolerated by some endpoints, `INVALID_REQUEST` on strict ones
159
+ (MiMo, verified 2026-08-27).
80
160
 
81
- ### 1.5. 修复(2026-08 事故固化方案)
161
+ ### 2. Repair (`fix`)
82
162
 
83
163
  ```bash
84
- # 干跑(只报告):严格 seq 连续扫描 + 全契约体检(含 W1/W2)+ 可移除 marker
164
+ # Dry run (report only): strict seq scan + full contract check + removable-marker count
85
165
  dsh-log-contract fix ~/.dsh/sessions/<id>.jsonl.zstd --remove-markers
86
166
 
87
- # 应用:备份后落盘(.zstd 走官方帧格式重建:帧1=header、帧2=其余、checksum、单个结尾换行)
167
+ # Apply: backup first, then write (.zstd rebuilt in official frame format: frame1=header,
168
+ # frame2=rest, checksum, single trailing newline)
88
169
  dsh-log-contract fix ~/.dsh/sessions/<id>.jsonl.zstd --remove-markers --apply
89
170
  ```
90
171
 
91
- - `--remove-markers`:移除 retrace/message-editor marker 并全量重编号
92
- seq/seq0/sourceEventSeqs/surfaceOp 同步)——用于大范围 marker 遮蔽历史、
93
- marker 漏盖 tool/result 导致的悬空 tool。
94
- - 手术安全协议:改前备份、改后全量复检(strictScan + check + foldSurface)、
95
- marker 只能遮蔽其之前的节点、marker 绝不能改成 append(M1 客户端崩溃)。
96
- - ⚠️ 若会话已被运行中的应用驻留内存,修复文件后需**重启应用**(强杀避免脏状态刷回)。
172
+ - `--remove-markers`: remove retrace/message-editor markers and renumber everything
173
+ (seq/seq0/sourceEventSeqs/surfaceOp in sync) — for large marker-shadowed history
174
+ or markers that left dangling tools.
175
+ - `--neutralize`: in-place neutralization of turn-null markers (incident #6) —
176
+ type → `retrace/marker` + `ignorable:true`, drops surfaceOp/sourceEventSeqs,
177
+ seq/line count unchanged (safe while the session is resident).
178
+ - `--clip-crossstep`: trim cross-step sourceEventSeqs (incident #6) — keep only
179
+ same-turn/step chunk references.
180
+ - Surgery safety protocol: back up first, re-verify after (strictScan + check +
181
+ foldSurface); markers may only shadow earlier nodes; a marker must never become
182
+ append (M1 crashes the client engine).
183
+ - ⚠️ If the session is resident in a running app, **restart the app** after fixing
184
+ the file (hard-kill to avoid dirty state flushing back).
97
185
 
98
- ### 2. 写前校验(本次事故的直接解药)
186
+ ### 3. Pre-write validation (`prewrite`)
99
187
 
100
- `edit-file` JSON,两种形状:
188
+ `edit-file` is JSON with two shapes:
101
189
 
102
190
  ```jsonc
103
- // 拟追加一个事件到日志尾部(seq 缺省 = 自动按 nextSeq 赋值)
191
+ // Append one event to the log tail (seq omitted = auto-assigned as nextSeq)
104
192
  { "append": { "type": "assistant/message", "surfaceOp": { "op": "replace", "start": 121774, "end": 156421 }, "sourceEventSeqs": [121774, 121779, "…"], "data": { "turn": null, "step": null, "message": { "…": "…" }, "editor": { "targetSeq": 156430, "text": "…" } } } }
105
193
 
106
- // 帧级手术后的完整事件列表(改后确认,与改前基线双绿才允许落盘)
107
- { "edit": [ "…完整事件列表…" ] }
194
+ // Frame-level surgery: the complete event list after the edit (both baseline and
195
+ // result must be green before it may land)
196
+ { "edit": [ "…full event list…" ] }
108
197
  ```
109
198
 
110
199
  ```bash
111
200
  dsh-log-contract prewrite marker-write.json --log ~/.dsh/sessions/<id>.jsonl.zstd
112
201
  ```
113
202
 
114
- - 基线本身有 error 级违规时直接拒绝校验(安全修复协议第 2 步:**改前基线必须绿**)。
115
- - 判定通过才允许落盘——**validate first, commit later**(与官方 `SurfaceManager.validateNext` 同思路)。
203
+ - A baseline with error-level violations is rejected outright (safety protocol
204
+ step 2: **the pre-surgery baseline must be green**).
205
+ - Only a pass may land — **validate first, commit later** (same idea as the
206
+ official `SurfaceManager.validateNext`).
116
207
 
117
- ### 3. 契约目录
208
+ ### 4. Contract catalog
118
209
 
119
210
  ```bash
120
211
  dsh-log-contract contracts
121
212
  ```
122
213
 
123
- 完整契约清单见 [docs/CONTRACTS.md](docs/CONTRACTS.md)
214
+ Full catalog in [docs/CONTRACTS.md](docs/CONTRACTS.md).
215
+
216
+ ### 5. Session archaeology (`extract` / `audit-report`)
217
+
218
+ Every tool call's full input/output is persisted in the session log — a data and
219
+ audit asset. Read-only archaeology:
220
+
221
+ ```sh
222
+ # Export tool outputs matching a command regex (original text preserved)
223
+ dsh-log-contract extract <session-log> --pattern "seed-scale" --min-size 50 --out ./found
224
+
225
+ # Archaeology audit report: call count / pairing rate / orphans / command distribution
226
+ dsh-log-contract audit-report <session-log>
227
+ ```
228
+
229
+ Contract rules P3 (tool/call↔tool/result pairing integrity) and P4 (output
230
+ structure parseable) keep the dig working: orphan calls and abnormal `text` fields
231
+ are flagged in `check`.
124
232
 
125
233
  ---
126
234
 
127
- ## Node API(写前校验嵌入你的脚本)
235
+ ## Node API (embed pre-write validation in your script)
128
236
 
129
237
  ```js
130
238
  import { loadSessionLog, validateSessionLog, createPreWriter } from 'dsh-log-contract';
131
239
 
132
- // ① 基线体检(改前基线必须绿)
240
+ // ① Baseline check (the pre-surgery baseline must be green)
133
241
  const log = loadSessionLog('session.jsonl.zstd');
134
242
  const baseline = validateSessionLog(log);
135
- if (!baseline.ok) throw new Error('基线已坏,先修基线');
243
+ if (!baseline.ok) throw new Error('baseline is broken; repair it first');
136
244
 
137
- // ② 写前校验:拟写入一个 marker replace
245
+ // ② Pre-write validation: about to write a marker replace
138
246
  const prewriter = createPreWriter({ events: log.events.map((e) => e.event) });
139
247
  const verdict = prewriter.validateAppend({
140
248
  type: 'assistant/message',
141
249
  surfaceOp: { op: 'replace', start: 121774, end: 156421 },
142
- sourceEventSeqs: [121774, 121779 /* …必须完整覆盖被替换节点… */],
250
+ sourceEventSeqs: [121774, 121779 /* …must fully cover shadowed nodes… */],
143
251
  data: { turn: null, step: null, message: { /* … */ } },
144
252
  });
145
253
  if (!verdict.ok) {
146
254
  for (const v of verdict.violations) console.error(v.id, v.message);
147
- process.exit(1); // 不落盘
255
+ process.exit(1); // do not land
148
256
  }
149
- // ③ 通过后才写
257
+ // ③ Only a pass writes
150
258
  ```
151
259
 
152
260
  ---
153
261
 
154
- ## 测试
262
+ ## Tests
155
263
 
156
264
  ```bash
157
- pnpm check && pnpm test # 语法检查 + 40 个单测(含事故回归用例)
265
+ pnpm check && pnpm test # syntax check + 79 unit tests (incl. incident regressions)
158
266
  ```
159
267
 
160
- - **合成夹具**(入库):合法会话 / seq 缺口 / 空 sourceEventSeqs / turn=null append / 未知 type / 坏 chunk 行 / 撕裂尾帧 / 未知 marker 前缀 / 自指 shadowed 等。
161
- - **真实化石**(不入库,含用户隐私):本地跑
268
+ - **Synthetic fixtures** (in-repo): legal session / seq gap / empty sourceEventSeqs
269
+ / turn-null append / unknown type / bad chunk row / torn tail frame / unknown
270
+ marker prefix / self-shadowing etc.
271
+ - **Real fossils** (not in-repo, contain user data): run locally
162
272
 
163
273
  ```bash
164
- node scripts/check-local-fossils.mjs # 扫描 ../ backup-session-*.jsonl.zstd
274
+ node scripts/check-local-fossils.mjs # scans ../ for backup-session-*.jsonl.zstd
165
275
  ```
166
276
 
167
- 已知真值表:事故修复后会话 PASS;`seqgap`/`corrupt`/`rewritten-230542` FAIL;`spliced-orphan` PASS(持久化层合法——#3632 的"消费路径判不可读"属于另一类契约,本工具只守护持久化契约层,见 [docs/CONTRACTS.md](docs/CONTRACTS.md) 边界说明)。
168
-
169
- ---
170
-
171
- ## 与三件套的关系
172
-
173
- | 工具 | 象限 | 状态 |
174
- |---|---|---|
175
- | [workbuddy-session-fork](https://github.com/yamingmou/workbuddy-session-fork) | 会话分叉 · 状态管理 | ✅ 已发布 v1.2.0 |
176
- | **dsh-log-contract**(本仓库) | 日志契约 · 接口稳定性 | ✅ Phase 1(check/prewrite)+ Phase 1.5(fix)0.2.0 |
177
- | dsh-turn-guard(规划中) | 中断回合 · 异常韧性 | 待立项 |
178
-
179
- 三者共享同一份 DSH 日志事件契约认知(59 条审计发现 = spec,aborted/corrupt/seqgap 化石 = 测试集)。dsh-retrace(回溯时间线)可把本工具的违规标记渲染到时间线上;本工具是 retrace 投影源健康度的**前置保险**。
277
+ Known truth table: incident-repaired sessions PASS; `seqgap`/`corrupt`/
278
+ `rewritten-230542` FAIL; `spliced-orphan` PASS (legal for the persistence layer —
279
+ #3632's "consumer path deems it unreadable" is a different contract; this tool only
280
+ guards the persistence contract layer, see the boundary note in
281
+ [docs/CONTRACTS.md](docs/CONTRACTS.md)).
180
282
 
181
283
  ---
182
284
 
183
285
  ## Roadmap
184
286
 
185
- - [x] **Phase 10.1.0)**:CLI 离线体检 + 写前校验 + 契约目录
186
- - [x] **Phase 1.50.2.0)**:`fix` 子命令(严格 seq 扫描 + W1/W2 wire 检查 + 移除 marker 重编号 + 官方帧格式重建);CI 集成(`dsh-log-contract check` 作为 Harness 会话目录的定时守护)
187
- - [ ] Phase 2:运行时守护(订阅 session append 事件流实时校验,断裂即标记 `dsh/contract-violation` 事件,策略可配 告警/拦截)——DSH 插件形态
188
- - [ ] Phase 3:与 dsh-turn-guard / dsh-retrace 时间线联动
189
-
190
- ## 许可
287
+ - [x] **Phase 1 (0.1.0)**: CLI offline check + pre-write validation + contract catalog
288
+ - [x] **Phase 1.5 (0.2.0)**: `fix` subcommand (strict seq scan + W1/W2 wire checks +
289
+ marker removal with renumbering + official frame rebuild); CI integration
290
+ (`dsh-log-contract check` as a scheduled guard over the Harness session dir)
291
+ - [x] **0.3.x (2026-08-30 incident hardening)**: T1 token-meter pairing → 0.3.1 W1/W2
292
+ fold-position fix → 0.3.2 `tailSeq` → 0.3.3 `fix --neutralize` (in-place
293
+ turn-null neutralization) → 0.3.4 `fix --clip-crossstep` (cross-step clipping) →
294
+ 0.3.5 **T2/S9/I1 rules** (cross-step source refs / physical order / inbox replay)
295
+ - [ ] Phase 2: runtime guard (subscribe to the session append stream, validate live,
296
+ mark violations as `dsh/contract-violation`, policy configurable alert/block) —
297
+ DSH plugin form
298
+ - [ ] Phase 3: link with dsh-turn-guard / dsh-retrace timeline
299
+
300
+ ## License
191
301
 
192
302
  MIT © OfferKuai Team
193
-
194
-
195
- ## 🧭 会话考古(extract / audit-report)
196
-
197
- DSH 会话日志持久化了每次工具调用的完整输入输出——数据资产与审计资产。
198
- 本工具提供只读考古能力:
199
-
200
- ```sh
201
- # 按命令正则导出工具输出(保留原始文本)
202
- dsh-log-contract extract <session-log> --pattern "seed-scale" --min-size 50 --out ./found
203
-
204
- # 考古审计报告:调用数 / 配对率 / 孤儿数 / 命令分布
205
- dsh-log-contract audit-report <session-log>
206
- ```
207
-
208
- 契约规则 P3(tool/call↔tool/result 配对完整性)与 P4(输出结构可解析)
209
- 守护"挖得动":孤儿调用、text 字段异常在 check 中告警。