dsh-logicprobe 1.1.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 +15 -4
- package/README.md +15 -4
- package/lib/compose-tool.js +8 -2
- package/lib/concurrency-tool.js +8 -2
- package/lib/data-tool.js +8 -2
- package/lib/engine.js +3151 -3151
- package/lib/export-tool.js +8 -2
- package/lib/index.js +28 -40
- package/lib/report-diff-tool.js +8 -2
- package/lib/report-view.js +295 -0
- package/lib/structure-tool.js +8 -2
- package/lib/tool.js +8 -2
- package/lib/types/engine.d.ts +419 -419
- package/lib/types/index.d.ts +5 -4
- package/lib/types/report-view.d.ts +43 -0
- package/lib/uml-tool.js +145 -146
- package/lib/uml.js +1748 -1748
- package/package.json +2 -2
- package/skills/logicprobe/SKILL.md +23 -6
- package/skills/logicprobe/references/dsh-model-schema.md +1 -1
- package/skills/logicprobe/references/gap-routing-guide.md +10 -9
- package/skills/logicprobe/references/logic-verification-guide.md +1 -1
- package/skills/logicprobe-concurrency/SKILL.md +1 -0
- package/src/compose-tool.ts +8 -2
- package/src/concurrency-tool.ts +8 -2
- package/src/data-tool.ts +9 -3
- package/src/export-tool.ts +8 -2
- package/src/index.ts +28 -40
- package/src/report-diff-tool.ts +8 -2
- package/src/report-view.ts +343 -0
- package/src/structure-tool.ts +8 -2
- package/src/tool.ts +8 -2
- package/src/uml-tool.ts +10 -11
package/README.en-US.md
CHANGED
|
@@ -63,6 +63,15 @@ Every report separates "the tool ran" from "the review passed":
|
|
|
63
63
|
|
|
64
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`.
|
|
65
65
|
|
|
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:
|
|
67
|
+
|
|
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.
|
|
72
|
+
|
|
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.
|
|
74
|
+
|
|
66
75
|
### The model carries its own archive record (`_`-prefixed keys)
|
|
67
76
|
|
|
68
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.
|
|
@@ -118,7 +127,7 @@ The dependency matrix is the single source of truth:
|
|
|
118
127
|
|
|
119
128
|
## Usage
|
|
120
129
|
|
|
121
|
-
The plugin injects a capability notification into the first model step. There is **one skill per domain
|
|
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.
|
|
122
131
|
|
|
123
132
|
| Skill | Domain | Typical trigger |
|
|
124
133
|
|---|---|---|
|
|
@@ -132,12 +141,14 @@ Behavioural questions still follow the suggest-don't-escalate rule: offer an opt
|
|
|
132
141
|
|
|
133
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:
|
|
134
143
|
|
|
135
|
-
- `verify` runs S1-S8 / A1-A14 / D1-D4
|
|
144
|
+
- `verify` runs S1-S8 / A1-A14 / D1-D4 (`--before-model`, `--baseline`, `--hash-spec`, `--hash-check`)
|
|
136
145
|
- `compose` runs the C1 / C2 composition
|
|
137
146
|
- `export` emits UPPAAL, TLA+, PRISM and SPIN input
|
|
138
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
|
|
139
150
|
|
|
140
|
-
|
|
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.
|
|
141
152
|
|
|
142
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.
|
|
143
154
|
|
|
@@ -186,7 +197,7 @@ Native dsh support ships as a cordis plugin bundle at the repository root, decla
|
|
|
186
197
|
The bundle does three things:
|
|
187
198
|
|
|
188
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.
|
|
189
|
-
2. **Injects the gate text.** The first model step of every session receives the claim-verification gate (
|
|
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.
|
|
190
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`.
|
|
191
202
|
|
|
192
203
|
```bash
|
package/README.md
CHANGED
|
@@ -61,6 +61,15 @@ logicprobe 核验声称与实物是否一致。事实类对着源码查。行为
|
|
|
61
61
|
|
|
62
62
|
只看 `ok` 会把「有死锁」的模型读成通过——判据是 `verdict`。非 DSH 的 Python CLI 退出码跟随 verdict:`pass`/`pass_with_findings` → `0`,`fail` 或拒绝 → `2`。
|
|
63
63
|
|
|
64
|
+
**工具打印的是报告正文,不是 JSON。** 结构化报告本身没有变(`schema`/`verdict`/`hashes`/检查项 id/`code`/`evidence`/`path` 都在),变的只是给模型看的那份文本:
|
|
65
|
+
|
|
66
|
+
- 通过的检查只出现在 `CHECKS` 清单行里,不再展开正文(通过的检查没有可行动内容);
|
|
67
|
+
- 同一个事实被多个检查各报一遍时(例如 `S5` 与 `A1` 报同一批 `(state, event)` 对),只在先出现的检查里列出,后出现的检查写明「与上面重复」,不再重印;
|
|
68
|
+
- 同一检查内逐字相同的发现折叠成一行并标注 `(xN)`;
|
|
69
|
+
- 只有 `error` 级发现内联 `evidence`,`warning` 级不内联——那是机器字段,不是阅读材料。
|
|
70
|
+
|
|
71
|
+
需要结构化报告本体时传 `reportView: "full"`(例如要把它交给 `logicprobe_report_diff`,它按 `check + code + evidence` 匹配身份,正文替代不了对象)。非 dsh 宿主走 CLI,它直接打印报告 JSON:那份正文是 dsh 工具的呈现层。
|
|
72
|
+
|
|
64
73
|
### 模型自带的归档记录(`_` 前缀键)
|
|
65
74
|
|
|
66
75
|
任何以 `_` 开头的键(任意层级,如 `_source`、`_verified`、`_extraction_caveats`、`states[0]._note`)都是**注记元数据**:schema 跳过、`modelHash` 排除、报告以 `metadataKeys` 回显。这样来源与验证快照可以跟模型放在同一个文件里,不必再维护一个会漂移的 sidecar,而模型的哈希身份不变。其余键仍然闭合——拼错的 `sttes` 依旧报错。用 `verify model.json --hash-check <hex>` 可回答某个历史哈希是否属于任何已发布规范。
|
|
@@ -116,7 +125,7 @@ logicprobe 核验声称与实物是否一致。事实类对着源码查。行为
|
|
|
116
125
|
|
|
117
126
|
## 使用
|
|
118
127
|
|
|
119
|
-
|
|
128
|
+
插件在会话首个模型步骤自动注入能力通知。技能按**领域**拆分;`logicprobe` 是总入口,只要有一点「想验证代码/某个说法是否成立」的念头就加载它,它自己的路由表再把相邻领域交出去:
|
|
120
129
|
|
|
121
130
|
| 技能 | 领域 | 典型触发 |
|
|
122
131
|
|---|---|---|
|
|
@@ -130,12 +139,14 @@ logicprobe 核验声称与实物是否一致。事实类对着源码查。行为
|
|
|
130
139
|
|
|
131
140
|
在 dsh 之外(Claude Code、Cursor、Codex、终端、CI),装的是**仓库**(marketplace / git),随仓库带 `tools/python/logicprobe-engine.py`:只需 Python 3.8+ 标准库。dsh 安装包(npm / bundle)不含它。已有 LogicModelV1 JSON 时直接运行:
|
|
132
141
|
|
|
133
|
-
- `verify` 跑 S1-S8 / A1-A14 / D1-D4
|
|
142
|
+
- `verify` 跑 S1-S8 / A1-A14 / D1-D4(`--before-model`、`--baseline`、`--hash-spec`、`--hash-check`)
|
|
134
143
|
- `compose` 跑 C1 / C2 组合
|
|
135
144
|
- `export` 生成 UPPAAL、TLA+、PRISM、SPIN 输入
|
|
136
145
|
- `uml-render`、`uml-parse`、`uml-review` 覆盖 UML 前端(`uml-review --explain-labels` 打印解析器接受的标签与注释口径)
|
|
146
|
+
- `structure`、`granularity` 审查依赖图与多粒度细化(UML020-UML031)
|
|
147
|
+
- 子命令的权威清单是 `--help`,本文不复制一份
|
|
137
148
|
|
|
138
|
-
|
|
149
|
+
凡引擎实现的子命令,其报告与 dsh 工具逐字节一致,对照见 `tests/python/run.mjs`。模型只有抽取出的状态表时,填充模板 `tools/python/verification-harness.py`。**数据模型验证没有镜像子命令**:非 dsh 宿主用 `tools/python/data-model-harness.py`,或对应 guide 的手动验证模式;并发声称扫描同理(它只做分流)。Python 不可用(例如离线开发机)时,对应 guide 提供手动验证模式。
|
|
139
150
|
|
|
140
151
|
示例模型见 [`examples/`](examples/README.md):订单状态机 before/after、电商数据模型、User 字段迁移。
|
|
141
152
|
|
|
@@ -184,7 +195,7 @@ git clone https://github.com/AmethystLuna/logicprobe.git ~/.claude/plugins/dev/l
|
|
|
184
195
|
这个 bundle 做三件事:
|
|
185
196
|
|
|
186
197
|
1. **注册技能。** 技能遵循 Agent Skills 开放标准,由 dsh 的 `skill-filesystem` provider 原样发现,不需要额外代码。
|
|
187
|
-
2. **注入门禁文本。** 每个会话的第一个模型步骤会收到 claim
|
|
198
|
+
2. **注入门禁文本。** 每个会话的第一个模型步骤会收到 claim 验证门禁(主动建议)。这是 Claude `SessionStart` hook 在 dsh 上的对应物。
|
|
188
199
|
3. **注册原生工具与上下文。** 工具挂在 `ctx.tools` 上,另有一条策略感知上下文 `logicprobe:mode`(`ctx.systemPrompt`),以及模型可见目录条目(`cordis_inspect`)。
|
|
189
200
|
|
|
190
201
|
```bash
|
package/lib/compose-tool.js
CHANGED
|
@@ -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(
|
|
32
|
-
return [{ type: 'text', text:
|
|
37
|
+
render(args, value) {
|
|
38
|
+
return [{ type: 'text', text: renderReportText(value, { full: args.reportView === 'full' }) }];
|
|
33
39
|
},
|
|
34
40
|
},
|
|
35
41
|
timeoutMs: 10_000,
|
package/lib/concurrency-tool.js
CHANGED
|
@@ -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(
|
|
26
|
-
return [{ type: 'text', text:
|
|
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(
|
|
46
|
-
return [{ type: 'text', text:
|
|
51
|
+
render(args, value) {
|
|
52
|
+
return [{ type: 'text', text: renderReportText(value, { full: args.reportView === 'full' }) }];
|
|
47
53
|
},
|
|
48
54
|
},
|
|
49
55
|
timeoutMs: 10_000,
|