dsh-logicprobe 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.en-US.md CHANGED
@@ -25,53 +25,9 @@ logicprobe checks a claim against the thing it describes. Facts go against the s
25
25
 
26
26
  The model is always shown as a transition table first, and **confirmed with the user before it runs**. Extraction errors are the dominant failure mode.
27
27
 
28
- ## Installation
29
-
30
- ### Claude Code install (recommended)
31
-
32
- Add the marketplace to **Claude Code**'s `~/.claude/settings.json`:
33
-
34
- ```json
35
- {
36
- "extraKnownMarketplaces": {
37
- "logicprobe": {
38
- "source": { "source": "github", "repo": "AmethystLuna/logicprobe" }
39
- }
40
- }
41
- }
42
- ```
43
-
44
- Then install from the CLI:
45
-
46
- ```bash
47
- claude plugin install logicprobe@logicprobe
48
- ```
49
-
50
- ### Claude Code manual install
51
-
52
- ```bash
53
- git clone https://github.com/AmethystLuna/logicprobe.git ~/.claude/plugins/dev/logicprobe
54
- ```
55
-
56
- Then enable it in `~/.claude/settings.json`:
57
-
58
- ```json
59
- {
60
- "enabledPlugins": {
61
- "logicprobe@dev": true
62
- }
63
- }
64
- ```
65
-
66
- ## DeepSeek Harness (dsh)
67
-
68
- Native dsh support ships as a cordis plugin bundle at the repository root, declared by `dsh.bundle` in the root `package.json`.
28
+ ## Tools and Reports
69
29
 
70
- The bundle does three things:
71
-
72
- 1. **Registers the skills.** They follow the Agent Skills open standard and are discovered as-is by dsh's `skill-filesystem` provider. No extra code.
73
- 2. **Injects the gate text.** The first model step of every session receives the claim-verification gate (1% Rule / Red Flags / proactive suggestion). This is the dsh counterpart of the Claude `SessionStart` hook.
74
- 3. **Registers the native tools and a context.** The tools live on `ctx.tools`. A policy-aware `logicprobe:mode` context lives on `ctx.systemPrompt`. A model-visible catalog entry is available through `cordis_inspect`.
30
+ The two lists below (the native tools, and how to read their reports) do not depend on how you install: dsh uses the native tools, while Claude Code / Codex / Cursor / a terminal / CI use the same skills and the Python CLI engine (see "Usage").
75
31
 
76
32
  The tools:
77
33
 
@@ -102,45 +58,32 @@ Every report separates "the tool ran" from "the review passed":
102
58
  | `hashSpec` | The published specification `modelHash` follows — see [`hash-spec.md`](skills/logicprobe/references/hash-spec.md). |
103
59
  | `hashes` | Every hash the report carries, in one place (model, diagram/matrix, before/after). |
104
60
  | `metadataKeys` | Paths of the `_`-prefixed annotation keys the input carried. |
105
- | `narrativeCoverage` | `{states: "5/5", events: "3/9", scenarios: "0/12"}` — a narrative may cover part of the model, and this is how much is still undocumented. |
61
+ | `narrativeCoverage` | `{states: "5/5", events: "3/9", scenarios: "0/12"}` — a narrative may cover part of the model, and this is how much is still undocumented. The gap is also a `NARRATIVE_PARTIAL` (info) finding, so a gate need not parse `nextSteps` text. |
106
62
  | `nextSteps` | What to do next, derived from the findings; never empty, and identical for two runs over the same input. |
107
63
 
108
64
  Reading `ok` turns a model with a deadlock into a pass; the verdict is the judgement. The non-DSH Python CLI follows the verdict with its exit code: `pass`/`pass_with_findings` → `0`, `fail` or a refusal → `2`.
109
65
 
110
- ### The model carries its own archive record (`_`-prefixed keys)
111
-
112
- Any key starting with `_` — at any level: `_source`, `_verified`, `_extraction_caveats`, `states[0]._note` — is **annotation metadata**: the schema skips it, `modelHash` excludes it, and the report echoes it as `metadataKeys`. Provenance and verification snapshots can therefore live inside the model file instead of a sidecar that drifts away from it, without changing the model's hash identity. Every other key stays closed: a mistyped `sttes` is still an error. `verify model.json --hash-check <hex>` answers whether a recorded hash belongs to any published specification.
113
-
114
- Install (native bundle, recommended):
115
-
116
- ```bash
117
- # from npm (package name: dsh-logicprobe)
118
- dsh plugin --profile web add dsh-logicprobe
119
- # or from GitHub source
120
- dsh plugin --profile web add "github:AmethystLuna/logicprobe"
121
- # when dsh is not installed globally
122
- npx -p @deepseek-ai/dsh dsh plugin --profile web add dsh-logicprobe
123
- ```
124
-
125
- Restart the profile afterwards. `dsh --profile web --dump-config` must show the `id: logicprobe` row with `enabled: true`. More options (plain skill copy, project-level install) are in [`.dsh/INSTALL.md`](.dsh/INSTALL.md).
66
+ **A tool prints the report body, not JSON.** The structured report is unchanged (`schema`/`verdict`/`hashes`/check ids/`code`/`evidence`/`path` all still there); only the text a model reads changed:
126
67
 
127
- pnpm 11 has a release-age gate. It holds back versions published less than a day ago (`minimumReleaseAge`, default 1440 minutes), and its default is non-strict, so a bare-name install **silently resolves to the previous version**. The profile then looks like the release never happened. To get the newest version within about 24 hours of a release, pin it:
68
+ - a passing check appears in the `CHECKS` inventory line and does not expand a body — a passing check carries nothing to act on;
69
+ - a fact reported by more than one check (for example `S5` and `A1` reporting the same `(state, event)` pairs) is listed under the check that reported it first, and the later check says it adds nothing instead of reprinting it;
70
+ - findings that render identically inside one check collapse to one line with `(xN)`;
71
+ - only `error` findings inline their `evidence`; warnings do not — evidence is machine data, not reading material.
128
72
 
129
- ```bash
130
- dsh plugin --profile web add dsh-logicprobe@<version>
131
- ```
73
+ Pass `reportView: "full"` when you need the structured report itself (for example to hand it to `logicprobe_report_diff`, which matches on `check + code + evidence`; a body cannot stand in for the object). Hosts without dsh run the CLI, which prints the report JSON: the body is the dsh tools' presentation layer.
132
74
 
133
- pnpm records that version in a `minimumReleaseAgeExclude` entry in the profile's `pnpm-workspace.yaml`. That entry is pnpm's documented escape hatch.
75
+ ### The model carries its own archive record (`_`-prefixed keys)
134
76
 
135
- > Package name note: the npm package is `dsh-logicprobe`, with no scope. In the web profile's `package.json`, both the dependency key and the `dsh.profile.bundles` entry must use that name. On a mismatch the dsh loader cannot find `node_modules/dsh-logicprobe` and the boot fails.
77
+ Any key starting with `_` — at any level: `_source`, `_verified`, `_extraction_caveats`, `states[0]._note` — is **annotation metadata**: the schema skips it, `modelHash` excludes it, and the report echoes it as `metadataKeys`. Provenance and verification snapshots can therefore live inside the model file instead of a sidecar that drifts away from it, without changing the model's hash identity. Every other key stays closed: a mistyped `sttes` is still an error. `verify model.json --hash-check <hex>` answers whether a recorded hash belongs to any published specification.
136
78
 
137
79
  ## UML Modelling and Review
138
80
 
139
- `logicprobe_uml` draws a LogicModelV1 as UML. It also reads a hand-drawn UML diagram back into a model, and it reviews the modelling itself. It has three actions:
81
+ `logicprobe_uml` draws a LogicModelV1 as UML. It also reads a hand-drawn UML diagram back into a model, reviews the modelling itself, and prints the label and comment conventions the parser accepts. It has four actions:
140
82
 
141
83
  - **render**: model to diagram. Mermaid covers state, activity flowchart and sequence views. PlantUML covers state and sequence. Any construct the notation cannot express becomes a warning instead of a silent drop. PlantUML activity is refused, because that syntax cannot carry a graph with merges or cycles faithfully.
142
84
  - **parse**: diagram to model. It reads Mermaid and PlantUML state or activity diagrams, so a hand-drawn diagram can go straight into `logicprobe_verify`. Two inputs are refused because they cannot become a machine: a sequence diagram (a trace cannot reconstruct a machine), and any other Mermaid family (`classDiagram`, `erDiagram`, `gantt`, `mindmap`, …), which comes back as `errorCode: "UML_NOT_A_STATE_DIAGRAM"` naming the family.
143
85
  - **review**: audits the modelling. It reports structural defects and documentation gaps. The structural defects are unreachable states, dead ends, ambiguous branches, self-loops with no exit, and duplicate transitions. The documentation gaps are a missing narrative, unbounded variables, states a reader cannot map back to code, and label drift between diagram and narrative. It also runs the fidelity check: it parses the diagram back into a model and reports every structural difference.
86
+ - **explain-labels**: prints the label spellings and ignored-line rules the parser applies (`directiveLines`, `acceptedLabelForms`, `renderedForm`, `ignoredLines`, `rules`), with no diagram needed. Reach for it when a hand-drawn diagram and a rendered one disagree; the CLI mirror is `uml-review --explain-labels`.
144
87
 
145
88
  **A structure diagram is the dangerous case, because it parses.** A PlantUML component, package, class or deployment diagram declares no diagram kind, so the parser meets its keywords line by line. The arrows look like transitions, so `parse` returns a by-product model — now together with an error finding `UML_NOT_A_STATE_DIAGRAM`, `discardedConstructs` (every declaration it could not represent, with line and text), `discardedEdges` (the arrows misread as transitions) and `verdict: "fail"`. Read that as: **this file has no model and this diagram was not reviewed.** Do not feed the by-product to `logicprobe_verify` and call the result an architecture review. Structural checks over a real dependency graph (allowed-edge matrices, cycles, isolated nodes) do not exist yet; the codes `UML020`+ are reserved for them.
146
89
 
@@ -184,7 +127,7 @@ The dependency matrix is the single source of truth:
184
127
 
185
128
  ## Usage
186
129
 
187
- The plugin injects a capability notification into the first model step. There is **one skill per domain** — four in total. `logicprobe` is the entry point: load it whenever you have any thought of checking whether something about the code is true, and its routing table hands a neighbouring domain on.
130
+ The plugin injects a capability notification into the first model step. There is **one skill per domain**. `logicprobe` is the entry point: load it whenever you have any thought of checking whether something about the code is true, and its routing table hands a neighbouring domain on.
188
131
 
189
132
  | Skill | Domain | Typical trigger |
190
133
  |---|---|---|
@@ -198,20 +141,89 @@ Behavioural questions still follow the suggest-don't-escalate rule: offer an opt
198
141
 
199
142
  Outside dsh (Claude Code, Cursor, Codex, a terminal, CI) the install is the **repository** (marketplace or git), which carries `tools/python/logicprobe-engine.py`. Python 3.8+ standard library only. The dsh bundle (npm or profile install) does not include it. With a LogicModelV1 JSON at hand, run it directly:
200
143
 
201
- - `verify` runs S1-S8 / A1-A14 / D1-D4
144
+ - `verify` runs S1-S8 / A1-A14 / D1-D4 (`--before-model`, `--baseline`, `--hash-spec`, `--hash-check`)
202
145
  - `compose` runs the C1 / C2 composition
203
146
  - `export` emits UPPAAL, TLA+, PRISM and SPIN input
204
- - `uml-render`, `uml-parse` and `uml-review` cover the UML front end
147
+ - `uml-render`, `uml-parse` and `uml-review` cover the UML front end (`uml-review --explain-labels` prints the label and comment conventions the parser accepts)
148
+ - `structure` and `granularity` audit dependency graphs and multi-level refinement (UML020-UML031)
149
+ - `--help` is the authoritative subcommand list; this page does not copy it
205
150
 
206
- Its output is byte-identical to the dsh tools, cross-checked by `tests/python/run.mjs`. When the model exists only as extracted tables, fill in `tools/python/verification-harness.py`. Data-model checks use `tools/python/data-model-harness.py`. When Python is unavailable, for example on an air-gapped machine, the matching guide describes a manual verification mode.
151
+ Every subcommand the engine implements produces a report byte-identical to the dsh tool, cross-checked by `tests/python/run.mjs`. When the model exists only as extracted tables, fill in `tools/python/verification-harness.py`. **Data-model verification has no mirror subcommand**: hosts without dsh use `tools/python/data-model-harness.py` or the manual mode in the matching guide, and the concurrency claim scan is the same story (it only routes). When Python is unavailable, for example on an air-gapped machine, the matching guide describes a manual verification mode.
207
152
 
208
153
  Sample models live under [`examples/`](examples/README.md): an order state machine before/after, an e-commerce data model, and a User field migration.
209
154
 
210
- ## Codex CLI
155
+ ## Installation
211
156
 
212
- This plugin also supports OpenAI Codex CLI. Skills follow the Agent Skills standard and work identically on both platforms.
157
+ ### Claude Code (recommended)
213
158
 
214
- ### Codex install
159
+ Add the marketplace to **Claude Code**'s `~/.claude/settings.json`:
160
+
161
+ ```json
162
+ {
163
+ "extraKnownMarketplaces": {
164
+ "logicprobe": {
165
+ "source": { "source": "github", "repo": "AmethystLuna/logicprobe" }
166
+ }
167
+ }
168
+ }
169
+ ```
170
+
171
+ Then install from the CLI:
172
+
173
+ ```bash
174
+ claude plugin install logicprobe@logicprobe
175
+ ```
176
+
177
+ ### Claude Code manual install
178
+
179
+ ```bash
180
+ git clone https://github.com/AmethystLuna/logicprobe.git ~/.claude/plugins/dev/logicprobe
181
+ ```
182
+
183
+ Then enable it in `~/.claude/settings.json`:
184
+
185
+ ```json
186
+ {
187
+ "enabledPlugins": {
188
+ "logicprobe@dev": true
189
+ }
190
+ }
191
+ ```
192
+
193
+ ### DeepSeek Harness (dsh)
194
+
195
+ Native dsh support ships as a cordis plugin bundle at the repository root, declared by `dsh.bundle` in the root `package.json`.
196
+
197
+ The bundle does three things:
198
+
199
+ 1. **Registers the skills.** They follow the Agent Skills open standard and are discovered as-is by dsh's `skill-filesystem` provider. No extra code.
200
+ 2. **Injects the gate text.** The first model step of every session receives the claim-verification gate (proactive suggestion). This is the dsh counterpart of the Claude `SessionStart` hook.
201
+ 3. **Registers the native tools and a context.** The tools live on `ctx.tools`. A policy-aware `logicprobe:mode` context lives on `ctx.systemPrompt`. A model-visible catalog entry is available through `cordis_inspect`.
202
+
203
+ ```bash
204
+ # from npm (package name: dsh-logicprobe)
205
+ dsh plugin --profile web add dsh-logicprobe
206
+ # or from GitHub source
207
+ dsh plugin --profile web add "github:AmethystLuna/logicprobe"
208
+ # when dsh is not installed globally
209
+ npx -p @deepseek-ai/dsh dsh plugin --profile web add dsh-logicprobe
210
+ ```
211
+
212
+ Restart the profile afterwards. `dsh --profile web --dump-config` must show the `id: logicprobe` row with `enabled: true`. More options (plain skill copy, project-level install) are in [`.dsh/INSTALL.md`](.dsh/INSTALL.md).
213
+
214
+ pnpm 11 has a release-age gate. It holds back versions published less than a day ago (`minimumReleaseAge`, default 1440 minutes), and its default is non-strict, so a bare-name install **silently resolves to the previous version**. The profile then looks like the release never happened. To get the newest version within about 24 hours of a release, pin it:
215
+
216
+ ```bash
217
+ dsh plugin --profile web add dsh-logicprobe@<version>
218
+ ```
219
+
220
+ pnpm records that version in a `minimumReleaseAgeExclude` entry in the profile's `pnpm-workspace.yaml`. That entry is pnpm's documented escape hatch.
221
+
222
+ > Package name note: the npm package is `dsh-logicprobe`, with no scope. In the web profile's `package.json`, both the dependency key and the `dsh.profile.bundles` entry must use that name. On a mismatch the dsh loader cannot find `node_modules/dsh-logicprobe` and the boot fails.
223
+
224
+ ### Codex CLI
225
+
226
+ This plugin also supports OpenAI Codex CLI. Skills follow the Agent Skills standard and work identically on both platforms.
215
227
 
216
228
  ```bash
217
229
  # Add as a marketplace
@@ -229,12 +241,10 @@ git clone https://github.com/AmethystLuna/logicprobe.git ~/.codex/plugins/logicp
229
241
 
230
242
  Skills are invoked with `$logicprobe`, or selected automatically by Codex from the task context.
231
243
 
232
- ## Cursor
244
+ ### Cursor
233
245
 
234
246
  Cursor 2.5+ has built-in plugin support.
235
247
 
236
- ### Cursor install
237
-
238
248
  ```bash
239
249
  # Clone to Cursor plugins directory
240
250
  git clone https://github.com/AmethystLuna/logicprobe.git ~/.cursor/plugins/logicprobe
@@ -242,12 +252,10 @@ git clone https://github.com/AmethystLuna/logicprobe.git ~/.cursor/plugins/logic
242
252
 
243
253
  Or install from the Cursor plugin marketplace UI: `/add-plugin AmethystLuna/logicprobe`
244
254
 
245
- ## Kimi CLI
255
+ ### Kimi CLI
246
256
 
247
257
  Kimi CLI discovers skills from `.claude/skills/` paths automatically. The `.kimi-plugin/plugin.json` manifest registers the plugin for Kimi's plugin manager.
248
258
 
249
- ### Kimi install
250
-
251
259
  ```bash
252
260
  # Via Kimi plugin manager
253
261
  /plugins install https://github.com/AmethystLuna/logicprobe.git
@@ -258,7 +266,7 @@ git clone https://github.com/AmethystLuna/logicprobe.git ~/.kimi/plugins/logicpr
258
266
 
259
267
  Skills are invoked with `/skill:logicprobe`.
260
268
 
261
- ## OpenCode
269
+ ### OpenCode
262
270
 
263
271
  Skills are auto-discovered from `.claude/skills/` and `.codex/skills/` paths. Add this to your `opencode.json`:
264
272
 
@@ -270,7 +278,7 @@ Skills are auto-discovered from `.claude/skills/` and `.codex/skills/` paths. Ad
270
278
 
271
279
  Or install through `skop`, which consumes the Claude marketplace manifest. See `.opencode/INSTALL.md`.
272
280
 
273
- ## ZCode (Z.AI)
281
+ ### ZCode (Z.AI)
274
282
 
275
283
  ZCode 3.0+ follows the Agent Skills standard. It has no plugin marketplace, so copy the skills yourself:
276
284
 
package/README.md CHANGED
@@ -23,53 +23,9 @@ logicprobe 核验声称与实物是否一致。事实类对着源码查。行为
23
23
 
24
24
  模型永远先以转换表形式展示,**经用户确认后才运行**。模型提取错误是验证的头号失败模式。
25
25
 
26
- ## 安装
27
-
28
- ### Claude Code 安装(推荐)
29
-
30
- 在 **Claude Code** 的 `~/.claude/settings.json` 中添加 marketplace:
31
-
32
- ```json
33
- {
34
- "extraKnownMarketplaces": {
35
- "logicprobe": {
36
- "source": { "source": "github", "repo": "AmethystLuna/logicprobe" }
37
- }
38
- }
39
- }
40
- ```
41
-
42
- 然后通过 CLI 安装:
43
-
44
- ```bash
45
- claude plugin install logicprobe@logicprobe
46
- ```
47
-
48
- ### Claude Code 手动安装
49
-
50
- ```bash
51
- git clone https://github.com/AmethystLuna/logicprobe.git ~/.claude/plugins/dev/logicprobe
52
- ```
53
-
54
- 然后在 `~/.claude/settings.json` 中启用:
55
-
56
- ```json
57
- {
58
- "enabledPlugins": {
59
- "logicprobe@dev": true
60
- }
61
- }
62
- ```
63
-
64
- ## DeepSeek Harness (dsh)
65
-
66
- 原生 dsh 支持以 cordis 插件 bundle 的形式提供,位于**仓库根**,由根 `package.json` 的 `dsh.bundle` 声明。
26
+ ## 工具与报告
67
27
 
68
- 这个 bundle 做三件事:
69
-
70
- 1. **注册技能。** 技能遵循 Agent Skills 开放标准,由 dsh 的 `skill-filesystem` provider 原样发现,不需要额外代码。
71
- 2. **注入门禁文本。** 每个会话的第一个模型步骤会收到 claim 验证门禁(1% Rule / Red Flags / 主动建议)。这是 Claude `SessionStart` hook 在 dsh 上的对应物。
72
- 3. **注册原生工具与上下文。** 工具挂在 `ctx.tools` 上,另有一条策略感知上下文 `logicprobe:mode`(`ctx.systemPrompt`),以及模型可见目录条目(`cordis_inspect`)。
28
+ 下面两份清单(原生工具清单,以及怎么读它们的报告)与**安装方式无关**:dsh 走原生工具,Claude Code / Codex / Cursor / 终端 / CI 走同一套技能与 Python CLI 引擎(见「使用」)。
73
29
 
74
30
  工具清单:
75
31
 
@@ -100,45 +56,32 @@ git clone https://github.com/AmethystLuna/logicprobe.git ~/.claude/plugins/dev/l
100
56
  | `hashSpec` | `modelHash` 依据的已发布规范(见 [`hash-spec.md`](skills/logicprobe/references/hash-spec.md))。 |
101
57
  | `hashes` | 本次报告涉及的全部哈希集中一处(模型哈希、图/矩阵哈希、前后模型哈希)。 |
102
58
  | `metadataKeys` | 输入里带 `_` 前缀的注记键路径(仅当存在时出现)。 |
103
- | `narrativeCoverage` | `{states: "5/5", events: "3/9", scenarios: "0/12"}`:narrative **允许部分覆盖**,这里报告还差多少。 |
59
+ | `narrativeCoverage` | `{states: "5/5", events: "3/9", scenarios: "0/12"}`:narrative **允许部分覆盖**,这里报告还差多少;缺口同时是一条 `NARRATIVE_PARTIAL`(info)发现,门禁不必去解析 `nextSteps` 文本。 |
104
60
  | `nextSteps` | 由发现推导的下一步,永不为空,同一输入两次运行逐字一致。 |
105
61
 
106
62
  只看 `ok` 会把「有死锁」的模型读成通过——判据是 `verdict`。非 DSH 的 Python CLI 退出码跟随 verdict:`pass`/`pass_with_findings` → `0`,`fail` 或拒绝 → `2`。
107
63
 
108
- ### 模型自带的归档记录(`_` 前缀键)
109
-
110
- 任何以 `_` 开头的键(任意层级,如 `_source`、`_verified`、`_extraction_caveats`、`states[0]._note`)都是**注记元数据**:schema 跳过、`modelHash` 排除、报告以 `metadataKeys` 回显。这样来源与验证快照可以跟模型放在同一个文件里,不必再维护一个会漂移的 sidecar,而模型的哈希身份不变。其余键仍然闭合——拼错的 `sttes` 依旧报错。用 `verify model.json --hash-check <hex>` 可回答某个历史哈希是否属于任何已发布规范。
111
-
112
- 安装(原生 bundle,推荐):
113
-
114
- ```bash
115
- # 从 npm 安装(包名 dsh-logicprobe)
116
- dsh plugin --profile web add dsh-logicprobe
117
- # 或从 GitHub 源码安装
118
- dsh plugin --profile web add "github:AmethystLuna/logicprobe"
119
- # 未全局安装 dsh 时可用 npx
120
- npx -p @deepseek-ai/dsh dsh plugin --profile web add dsh-logicprobe
121
- ```
122
-
123
- 装完重启 profile。运行 `dsh --profile web --dump-config` 应看到 `id: logicprobe` 且 `enabled: true`。更多方式(纯技能拷贝、项目级等)见 [`.dsh/INSTALL.md`](.dsh/INSTALL.md)。
64
+ **工具打印的是报告正文,不是 JSON。** 结构化报告本身没有变(`schema`/`verdict`/`hashes`/检查项 id/`code`/`evidence`/`path` 都在),变的只是给模型看的那份文本:
124
65
 
125
- pnpm 11 有一个发布年龄闸门。它挡住发布不满一天的新版本(`minimumReleaseAge`,默认 1440 分钟),而且默认是非严格模式,所以裸名安装会**静默装到上一个版本**,profile 看起来像这次发版没发生。发版后约 24 小时内要装最新版,请带上版本号:
66
+ - 通过的检查只出现在 `CHECKS` 清单行里,不再展开正文(通过的检查没有可行动内容);
67
+ - 同一个事实被多个检查各报一遍时(例如 `S5` 与 `A1` 报同一批 `(state, event)` 对),只在先出现的检查里列出,后出现的检查写明「与上面重复」,不再重印;
68
+ - 同一检查内逐字相同的发现折叠成一行并标注 `(xN)`;
69
+ - 只有 `error` 级发现内联 `evidence`,`warning` 级不内联——那是机器字段,不是阅读材料。
126
70
 
127
- ```bash
128
- dsh plugin --profile web add dsh-logicprobe@<version>
129
- ```
71
+ 需要结构化报告本体时传 `reportView: "full"`(例如要把它交给 `logicprobe_report_diff`,它按 `check + code + evidence` 匹配身份,正文替代不了对象)。非 dsh 宿主走 CLI,它直接打印报告 JSON:那份正文是 dsh 工具的呈现层。
130
72
 
131
- pnpm 会把该版本写进 profile 的 `pnpm-workspace.yaml` 的 `minimumReleaseAgeExclude` 条目。那是它官方的豁免方式。
73
+ ### 模型自带的归档记录(`_` 前缀键)
132
74
 
133
- > 注意包名。npm 包名是 `dsh-logicprobe`,没有 scope。在 web profile 的 `package.json` 中,依赖键与 `dsh.profile.bundles` 必须都写 `dsh-logicprobe`。写错时 dsh 加载器找不到 `node_modules/dsh-logicprobe`,启动会失败。
75
+ 任何以 `_` 开头的键(任意层级,如 `_source`、`_verified`、`_extraction_caveats`、`states[0]._note`)都是**注记元数据**:schema 跳过、`modelHash` 排除、报告以 `metadataKeys` 回显。这样来源与验证快照可以跟模型放在同一个文件里,不必再维护一个会漂移的 sidecar,而模型的哈希身份不变。其余键仍然闭合——拼错的 `sttes` 依旧报错。用 `verify model.json --hash-check <hex>` 可回答某个历史哈希是否属于任何已发布规范。
134
76
 
135
77
  ## UML 建模与审查
136
78
 
137
- `logicprobe_uml` 把一份 LogicModelV1 画成 UML,也可以把手绘的 UML 读回模型,还可以审查建模本身。它有 3 个动作:
79
+ `logicprobe_uml` 把一份 LogicModelV1 画成 UML,也可以把手绘的 UML 读回模型,还可以审查建模本身,或打印解析器接受的标签与注释口径。它有 4 个动作:
138
80
 
139
81
  - **render**:模型 → 图。Mermaid 支持状态图、活动流程图、时序图;PlantUML 支持状态图与时序图。notation 表达不了的构造会变成 warning,不会被悄悄丢掉。PlantUML 活动图直接拒绝,因为它的语法无法忠实承载带合流或环的图。
140
82
  - **parse**:图 → 模型。支持 Mermaid 与 PlantUML 的状态图、活动图,因此手绘的图也能送进 `logicprobe_verify` 验证。两类输入会被拒绝,因为它们无法变成状态机:时序图(迹无法重建机),以及**其它 Mermaid 图族**(`classDiagram`、`erDiagram`、`gantt`、`mindmap`…),返回 `errorCode: "UML_NOT_A_STATE_DIAGRAM"` 并点名该图族。
141
83
  - **review**:审查建模。它报告两类问题。结构缺陷包括不可达状态、死端、歧义分支、无出口自环、重复迁移。文档缺口包括缺 narrative、变量无界、状态无可读标注、图与 narrative 标签漂移。它还会做保真度检查:把图重新解析回模型,任何结构性差异都报出来。
84
+ - **explain-labels**:打印解析器接受的标签写法与忽略行口径(`directiveLines`、`acceptedLabelForms`、`renderedForm`、`ignoredLines`、`rules`),不需要给图。手绘图与渲染图对不齐时先看它;命令行对应 `uml-review --explain-labels`。
142
85
 
143
86
  **结构图是最危险的一类,因为它「能解析」。** PlantUML 的组件图 / 包图 / 类图 / 部署图不声明图类型,解析器会逐行碰上它的关键字。箭头看起来就是迁移,于是 `parse` 会返回一个副产品模型——但现在同时给出 error 级发现 `UML_NOT_A_STATE_DIAGRAM`、`discardedConstructs`(每条无法表达的声明及其行号与原文)、`discardedEdges`(被误读成迁移的箭头数),以及 `verdict: "fail"`。意思是:**这份文件没有被建模,这张图没有被审查。** 不要把那个副产品喂给 `logicprobe_verify` 当作架构审查结论。针对真正依赖图的结构检查(允许依赖矩阵、环、孤立节点)尚未实现,编号 `UML020`+ 已为其保留。
144
87
 
@@ -182,7 +125,7 @@ pnpm 会把该版本写进 profile 的 `pnpm-workspace.yaml` 的 `minimumRelease
182
125
 
183
126
  ## 使用
184
127
 
185
- 插件在会话首个模型步骤自动注入能力通知。技能按**领域**拆分,一共四个;`logicprobe` 是总入口,只要有一点「想验证代码/某个说法是否成立」的念头就加载它,它自己的路由表再把相邻领域交出去:
128
+ 插件在会话首个模型步骤自动注入能力通知。技能按**领域**拆分;`logicprobe` 是总入口,只要有一点「想验证代码/某个说法是否成立」的念头就加载它,它自己的路由表再把相邻领域交出去:
186
129
 
187
130
  | 技能 | 领域 | 典型触发 |
188
131
  |---|---|---|
@@ -196,20 +139,89 @@ pnpm 会把该版本写进 profile 的 `pnpm-workspace.yaml` 的 `minimumRelease
196
139
 
197
140
  在 dsh 之外(Claude Code、Cursor、Codex、终端、CI),装的是**仓库**(marketplace / git),随仓库带 `tools/python/logicprobe-engine.py`:只需 Python 3.8+ 标准库。dsh 安装包(npm / bundle)不含它。已有 LogicModelV1 JSON 时直接运行:
198
141
 
199
- - `verify` 跑 S1-S8 / A1-A14 / D1-D4
142
+ - `verify` 跑 S1-S8 / A1-A14 / D1-D4(`--before-model`、`--baseline`、`--hash-spec`、`--hash-check`)
200
143
  - `compose` 跑 C1 / C2 组合
201
144
  - `export` 生成 UPPAAL、TLA+、PRISM、SPIN 输入
202
- - `uml-render`、`uml-parse`、`uml-review` 覆盖 UML 前端
145
+ - `uml-render`、`uml-parse`、`uml-review` 覆盖 UML 前端(`uml-review --explain-labels` 打印解析器接受的标签与注释口径)
146
+ - `structure`、`granularity` 审查依赖图与多粒度细化(UML020-UML031)
147
+ - 子命令的权威清单是 `--help`,本文不复制一份
203
148
 
204
- 它与 dsh 工具逐字节一致,对照见 `tests/python/run.mjs`。模型只有抽取出的状态表时,填充模板 `tools/python/verification-harness.py`。数据模型验证使用 `tools/python/data-model-harness.py`。Python 不可用(例如离线开发机)时,对应 guide 提供手动验证模式。
149
+ 凡引擎实现的子命令,其报告与 dsh 工具逐字节一致,对照见 `tests/python/run.mjs`。模型只有抽取出的状态表时,填充模板 `tools/python/verification-harness.py`。**数据模型验证没有镜像子命令**:非 dsh 宿主用 `tools/python/data-model-harness.py`,或对应 guide 的手动验证模式;并发声称扫描同理(它只做分流)。Python 不可用(例如离线开发机)时,对应 guide 提供手动验证模式。
205
150
 
206
151
  示例模型见 [`examples/`](examples/README.md):订单状态机 before/after、电商数据模型、User 字段迁移。
207
152
 
208
- ## Codex CLI
153
+ ## 安装
209
154
 
210
- 本插件同样支持 OpenAI Codex CLI。技能遵循 Agent Skills 标准,两个平台行为一致。
155
+ ### Claude Code(推荐)
211
156
 
212
- ### Codex 安装
157
+ 在 **Claude Code** 的 `~/.claude/settings.json` 中添加 marketplace:
158
+
159
+ ```json
160
+ {
161
+ "extraKnownMarketplaces": {
162
+ "logicprobe": {
163
+ "source": { "source": "github", "repo": "AmethystLuna/logicprobe" }
164
+ }
165
+ }
166
+ }
167
+ ```
168
+
169
+ 然后通过 CLI 安装:
170
+
171
+ ```bash
172
+ claude plugin install logicprobe@logicprobe
173
+ ```
174
+
175
+ ### Claude Code 手动安装
176
+
177
+ ```bash
178
+ git clone https://github.com/AmethystLuna/logicprobe.git ~/.claude/plugins/dev/logicprobe
179
+ ```
180
+
181
+ 然后在 `~/.claude/settings.json` 中启用:
182
+
183
+ ```json
184
+ {
185
+ "enabledPlugins": {
186
+ "logicprobe@dev": true
187
+ }
188
+ }
189
+ ```
190
+
191
+ ### DeepSeek Harness (dsh)
192
+
193
+ 原生 dsh 支持以 cordis 插件 bundle 的形式提供,位于**仓库根**,由根 `package.json` 的 `dsh.bundle` 声明。
194
+
195
+ 这个 bundle 做三件事:
196
+
197
+ 1. **注册技能。** 技能遵循 Agent Skills 开放标准,由 dsh 的 `skill-filesystem` provider 原样发现,不需要额外代码。
198
+ 2. **注入门禁文本。** 每个会话的第一个模型步骤会收到 claim 验证门禁(主动建议)。这是 Claude `SessionStart` hook 在 dsh 上的对应物。
199
+ 3. **注册原生工具与上下文。** 工具挂在 `ctx.tools` 上,另有一条策略感知上下文 `logicprobe:mode`(`ctx.systemPrompt`),以及模型可见目录条目(`cordis_inspect`)。
200
+
201
+ ```bash
202
+ # 从 npm 安装(包名 dsh-logicprobe)
203
+ dsh plugin --profile web add dsh-logicprobe
204
+ # 或从 GitHub 源码安装
205
+ dsh plugin --profile web add "github:AmethystLuna/logicprobe"
206
+ # 未全局安装 dsh 时可用 npx
207
+ npx -p @deepseek-ai/dsh dsh plugin --profile web add dsh-logicprobe
208
+ ```
209
+
210
+ 装完重启 profile。运行 `dsh --profile web --dump-config` 应看到 `id: logicprobe` 且 `enabled: true`。更多方式(纯技能拷贝、项目级等)见 [`.dsh/INSTALL.md`](.dsh/INSTALL.md)。
211
+
212
+ pnpm 11 有一个发布年龄闸门。它挡住发布不满一天的新版本(`minimumReleaseAge`,默认 1440 分钟),而且默认是非严格模式,所以裸名安装会**静默装到上一个版本**,profile 看起来像这次发版没发生。发版后约 24 小时内要装最新版,请带上版本号:
213
+
214
+ ```bash
215
+ dsh plugin --profile web add dsh-logicprobe@<version>
216
+ ```
217
+
218
+ pnpm 会把该版本写进 profile 的 `pnpm-workspace.yaml` 的 `minimumReleaseAgeExclude` 条目。那是它官方的豁免方式。
219
+
220
+ > 注意包名。npm 包名是 `dsh-logicprobe`,没有 scope。在 web profile 的 `package.json` 中,依赖键与 `dsh.profile.bundles` 必须都写 `dsh-logicprobe`。写错时 dsh 加载器找不到 `node_modules/dsh-logicprobe`,启动会失败。
221
+
222
+ ### Codex CLI
223
+
224
+ 本插件同样支持 OpenAI Codex CLI。技能遵循 Agent Skills 标准,两个平台行为一致。
213
225
 
214
226
  ```bash
215
227
  # 添加 marketplace
@@ -227,12 +239,10 @@ git clone https://github.com/AmethystLuna/logicprobe.git ~/.codex/plugins/logicp
227
239
 
228
240
  技能通过 `$logicprobe` 调用,或由 Codex 根据任务上下文自动选择。
229
241
 
230
- ## Cursor
242
+ ### Cursor
231
243
 
232
244
  Cursor 2.5+ 内置插件支持。
233
245
 
234
- ### Cursor 安装
235
-
236
246
  ```bash
237
247
  # 克隆到 Cursor 插件目录
238
248
  git clone https://github.com/AmethystLuna/logicprobe.git ~/.cursor/plugins/logicprobe
@@ -240,12 +250,10 @@ git clone https://github.com/AmethystLuna/logicprobe.git ~/.cursor/plugins/logic
240
250
 
241
251
  或通过 Cursor 插件市场 UI 安装:`/add-plugin AmethystLuna/logicprobe`
242
252
 
243
- ## Kimi CLI
253
+ ### Kimi CLI
244
254
 
245
255
  Kimi CLI 自动从 `.claude/skills/` 路径发现技能。`.kimi-plugin/plugin.json` 清单向 Kimi 插件管理器注册本插件。
246
256
 
247
- ### Kimi 安装
248
-
249
257
  ```bash
250
258
  # 通过 Kimi 插件管理器
251
259
  /plugins install https://github.com/AmethystLuna/logicprobe.git
@@ -256,7 +264,7 @@ git clone https://github.com/AmethystLuna/logicprobe.git ~/.kimi/plugins/logicpr
256
264
 
257
265
  技能通过 `/skill:logicprobe` 调用。
258
266
 
259
- ## OpenCode
267
+ ### OpenCode
260
268
 
261
269
  技能自动从 `.claude/skills/` 和 `.codex/skills/` 路径发现。在 `opencode.json` 中添加:
262
270
 
@@ -268,7 +276,7 @@ git clone https://github.com/AmethystLuna/logicprobe.git ~/.kimi/plugins/logicpr
268
276
 
269
277
  或通过 `skop` 安装(消费 Claude marketplace 清单)。详见 `.opencode/INSTALL.md`。
270
278
 
271
- ## ZCode (Z.AI)
279
+ ### ZCode (Z.AI)
272
280
 
273
281
  ZCode 3.0+ 遵循 Agent Skills 标准。它没有插件市场,手动把技能复制过去:
274
282
 
@@ -1,5 +1,6 @@
1
1
  import { defineTool } from '@deepseek-ai/dsh-tools';
2
2
  import { runCompositionVerification } from './engine.js';
3
+ import { renderReportText } from './report-view.js';
3
4
  export const LOGICPROBE_COMPOSE_TOOL_NAME = 'logicprobe_compose_verify';
4
5
  /**
5
6
  * DSH tool wrapping multi-machine composition verification:
@@ -22,14 +23,19 @@ export const logicProbeComposeTool = defineTool({
22
23
  type: 'integer',
23
24
  description: 'Maximum composite states to explore. Default 10000.',
24
25
  },
26
+ reportView: {
27
+ type: 'string',
28
+ enum: ['digest', 'full'],
29
+ description: 'digest (default) prints the readable body; full prints the structured report, which logicprobe_report_diff needs.',
30
+ },
25
31
  },
26
32
  output: {
27
33
  schema: {
28
34
  type: 'json',
29
35
  description: 'Composition verification report with C1/C2 findings.',
30
36
  },
31
- render(_args, value) {
32
- return [{ type: 'text', text: JSON.stringify(value, null, 2) }];
37
+ render(args, value) {
38
+ return [{ type: 'text', text: renderReportText(value, { full: args.reportView === 'full' }) }];
33
39
  },
34
40
  },
35
41
  timeoutMs: 10_000,
@@ -1,5 +1,6 @@
1
1
  import { defineTool } from '@deepseek-ai/dsh-tools';
2
2
  import { runConcurrencyScan } from './concurrency.js';
3
+ import { renderReportText } from './report-view.js';
3
4
  export const LOGICPROBE_CONCURRENCY_SCAN_TOOL_NAME = 'logicprobe_concurrency_scan';
4
5
  /**
5
6
  * Model-visible DSH tool that mines design documents/plans for concurrency-related
@@ -16,14 +17,19 @@ export const logicProbeConcurrencyScanTool = defineTool({
16
17
  required: true,
17
18
  description: 'Document or plan text to scan for concurrency-related claims.',
18
19
  },
20
+ reportView: {
21
+ type: 'string',
22
+ enum: ['digest', 'full'],
23
+ description: 'digest (default) prints the readable body; full prints the structured report, which logicprobe_report_diff needs.',
24
+ },
19
25
  },
20
26
  output: {
21
27
  schema: {
22
28
  type: 'json',
23
29
  description: 'Concurrency scan report with findings and summary.',
24
30
  },
25
- render(_args, value) {
26
- return [{ type: 'text', text: JSON.stringify(value, null, 2) }];
31
+ render(args, value) {
32
+ return [{ type: 'text', text: renderReportText(value, { full: args.reportView === 'full' }) }];
27
33
  },
28
34
  },
29
35
  timeoutMs: 10_000,
package/lib/data-tool.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { defineTool } from '@deepseek-ai/dsh-tools';
2
2
  import { runDataVerification, DATA_ENGINE_SCHEMA_VERSION } from './data-engine.js';
3
+ import { renderReportText } from './report-view.js';
3
4
  export const LOGICPROBE_DATAMODEL_VERIFY_TOOL_NAME = 'logicprobe_datamodel_verify';
4
5
  /**
5
6
  * Model-visible DSH tool wrapping the bundled data-model verification engine.
@@ -36,14 +37,19 @@ export const logicProbeDataModelVerifyTool = defineTool({
36
37
  type: 'json',
37
38
  description: 'Optional backup/restore pairs for DA7 rollback symmetry.',
38
39
  },
40
+ reportView: {
41
+ type: 'string',
42
+ enum: ['digest', 'full'],
43
+ description: 'digest (default) prints the readable body; full prints the structured report, which logicprobe_report_diff needs.',
44
+ },
39
45
  },
40
46
  output: {
41
47
  schema: {
42
48
  type: 'json',
43
49
  description: 'logicprobe-datamodel verification report with summary and per-check findings.',
44
50
  },
45
- render(_args, value) {
46
- return [{ type: 'text', text: JSON.stringify(value, null, 2) }];
51
+ render(args, value) {
52
+ return [{ type: 'text', text: renderReportText(value, { full: args.reportView === 'full' }) }];
47
53
  },
48
54
  },
49
55
  timeoutMs: 10_000,