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 +192 -99
- package/README.zh.md +253 -0
- package/bin/dsh-log-contract.mjs +61 -6
- package/lib/checks.js +5 -1
- package/lib/index.js +2 -2
- package/lib/repair.js +509 -5
- package/lib/validate.js +69 -0
- package/package.json +10 -7
package/README.md
CHANGED
|
@@ -1,64 +1,143 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
> 原名 `log-contract-validator`(候选二号),按 Offer快 三件套规划定名 **`dsh-log-contract`**。
|
|
3
|
+
# 🔒 dsh-log-contract
|
|
5
4
|
|
|
6
|
-
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
-
|
|
8
|
+
[](https://www.npmjs.com/package/dsh-log-contract)
|
|
9
|
+
[](https://www.npmjs.com/package/dsh-log-contract)
|
|
10
|
+
[](https://github.com/yamingmou/dsh-log-contract/blob/main/LICENSE)
|
|
11
|
+
[](https://github.com/topics/dsh-plugin)
|
|
12
|
+
[](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
|
-
**#3632
|
|
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
|
-
**
|
|
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
|
-
|
|
|
27
|
-
|
|
|
28
|
-
|
|
|
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
|
-
>
|
|
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 #
|
|
113
|
+
pnpm add -D dsh-log-contract # or npm install
|
|
38
114
|
pnpm dlx dsh-log-contract --help
|
|
39
115
|
```
|
|
40
116
|
|
|
41
|
-
>
|
|
42
|
-
>
|
|
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
|
-
>
|
|
46
|
-
>
|
|
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
|
-
|
|
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
|
-
|
|
153
|
+
Exit code: 0 = pass (no error-level violations); 1 = error-level violations exist.
|
|
75
154
|
|
|
76
|
-
`check`
|
|
77
|
-
|
|
78
|
-
tool_calls
|
|
79
|
-
`INVALID_REQUEST
|
|
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
|
-
###
|
|
161
|
+
### 2. Repair (`fix`)
|
|
82
162
|
|
|
83
163
|
```bash
|
|
84
|
-
#
|
|
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
|
-
#
|
|
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
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
-
|
|
95
|
-
|
|
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
|
-
###
|
|
186
|
+
### 3. Pre-write validation (`prewrite`)
|
|
99
187
|
|
|
100
|
-
`edit-file`
|
|
188
|
+
`edit-file` is JSON with two shapes:
|
|
101
189
|
|
|
102
190
|
```jsonc
|
|
103
|
-
//
|
|
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
|
-
|
|
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
|
-
-
|
|
115
|
-
-
|
|
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
|
-
###
|
|
208
|
+
### 4. Contract catalog
|
|
118
209
|
|
|
119
210
|
```bash
|
|
120
211
|
dsh-log-contract contracts
|
|
121
212
|
```
|
|
122
213
|
|
|
123
|
-
|
|
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
|
-
// ②
|
|
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 #
|
|
265
|
+
pnpm check && pnpm test # syntax check + 79 unit tests (incl. incident regressions)
|
|
158
266
|
```
|
|
159
267
|
|
|
160
|
-
-
|
|
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 #
|
|
274
|
+
node scripts/check-local-fossils.mjs # scans ../ for backup-session-*.jsonl.zstd
|
|
165
275
|
```
|
|
166
276
|
|
|
167
|
-
|
|
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 1
|
|
186
|
-
- [x] **Phase 1.5
|
|
187
|
-
|
|
188
|
-
-
|
|
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 中告警。
|