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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-logicprobe",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Verifies claims about designs and code. Facts go against the source. Behaviour goes through an executable model: state machines, protocols, composition, data models, migrations. Structure diagrams are read as dependency graphs, at one level or several. Two reports can be compared for regression. Exports UPPAAL, TLA+, PRISM and SPIN input. Ships a native DeepSeek Harness bundle that injects the verification gate into the first model step.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"build": "tsc -p tsconfig.json && node scripts/build-client.mjs",
|
|
80
80
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
81
81
|
"bump": "node scripts/bump-version.mjs",
|
|
82
|
-
"test:engine": "npm run build && node tests/engine/run.mjs && node tests/data-engine/run.mjs && node tests/concurrency/run.mjs && node tests/uml/run.mjs && node tests/apply-smoke.mjs && node tests/dsh-client-half.test.mjs && node tests/dsh-volatile-fallback.test.mjs && node tests/claude-session-start-hook.test.mjs && node tests/skills/run.mjs && node tests/structure/run.mjs && node tests/baseline/run.mjs && node tests/granularity/run.mjs && node tests/exporters/run.mjs && node tests/external/run.mjs && node tests/python/run.mjs",
|
|
82
|
+
"test:engine": "npm run build && node tests/engine/run.mjs && node tests/data-engine/run.mjs && node tests/concurrency/run.mjs && node tests/uml/run.mjs && node tests/apply-smoke.mjs && node tests/dsh-client-half.test.mjs && node tests/dsh-volatile-fallback.test.mjs && node tests/claude-session-start-hook.test.mjs && node tests/skills/run.mjs && node tests/structure/run.mjs && node tests/baseline/run.mjs && node tests/granularity/run.mjs && node tests/exporters/run.mjs && node tests/report-view/run.mjs && node tests/external/run.mjs && node tests/python/run.mjs",
|
|
83
83
|
"test:full": "npm run build && node tests/full-suite.mjs",
|
|
84
84
|
"test:python": "npm run build && node tests/python/run.mjs"
|
|
85
85
|
},
|
|
@@ -60,7 +60,7 @@ This step is NOT skippable — it creates an explicit, auditable record of what
|
|
|
60
60
|
|-------|----------|
|
|
61
61
|
| LIGHTWEIGHT | All 5 checklist items (file paths, API/type names, line numbers, behavioral claims, mechanism feasibility) answered in context with explicit results per item |
|
|
62
62
|
| STANDARD | Phase 1-2: enumerate every verifiable claim → verify each against codebase with evidence |
|
|
63
|
-
| ESCALATED | Full pipeline: Phase 1-5 including Logic Primitive Verification (Phase 2a
|
|
63
|
+
| ESCALATED | Full pipeline: Phase 1-5 including Logic Primitive Verification (Phase 2a structural, Phase 2b adversarial) |
|
|
64
64
|
|
|
65
65
|
### Plan Verification Block
|
|
66
66
|
|
|
@@ -151,7 +151,7 @@ Document claims → Extract model → Runtime check:
|
|
|
151
151
|
|
|
152
152
|
Refactoring variant:
|
|
153
153
|
Old code + Refactoring plan → Extract BEFORE model + AFTER model
|
|
154
|
-
→ Run pipeline on AFTER model (
|
|
154
|
+
→ Run the pipeline on the AFTER model (the same checks)
|
|
155
155
|
→ Compare BEFORE vs AFTER: behavioral preservation, regression, complexity delta
|
|
156
156
|
→ Flag any invariant that held in BEFORE but fails in AFTER
|
|
157
157
|
|
|
@@ -171,8 +171,10 @@ UML modelling variant (the task is to draw a flow, not to check a claim):
|
|
|
171
171
|
| `logicprobe_concurrency_scan` | Mines concurrency claims (thread-safe, lock-free, race condition, mutex, ISR-safe) and routes them to dedicated verification. It does not prove concurrency safety. |
|
|
172
172
|
| `logicprobe_export` | Emits external-checker input from a verified model: UPPAAL, TLA+, PRISM, SPIN. |
|
|
173
173
|
| `logicprobe_uml` | render / parse / review / explain-labels for UML modelling — the diagram domain belongs to the `logicprobe-uml` skill. |
|
|
174
|
+
| `logicprobe_structure_verify` | Reviews a structure diagram as a dependency graph. It reports isolated nodes, dangling endpoints, cycles, disallowed edges, layer violations and missing required edges, and it checks refinement across declared levels. The diagram domain belongs to the `logicprobe-structure` skill. |
|
|
175
|
+
| `logicprobe_report_diff` | Compares two reports of the same family. A finding's identity is its check, its code and its machine-readable locator, so reworded prose reads as changed rather than new. This is slice acceptance computed instead of eyeballed. Without the tool, `verify --baseline REPORT` prints the same diff. |
|
|
174
176
|
|
|
175
|
-
The repository engine mirrors the same checks
|
|
177
|
+
The repository engine mirrors the same checks for hosts without the native tools, and its `--help` lists the subcommands. Two capabilities have no mirror. Data-model verification takes the data harness or the manual mode there. The concurrency claim scan is the same story: `logicprobe-concurrency` routes the claims instead. That engine prints the report JSON, not the body — the body is the dsh tools' rendering.
|
|
176
178
|
|
|
177
179
|
### Reading a Report: `ok` Is Not a Verdict
|
|
178
180
|
|
|
@@ -191,6 +193,8 @@ Every tool report carries the same outcome contract. **`ok` says a report was pr
|
|
|
191
193
|
| `metadataKeys[]` | Paths of the `_`-prefixed annotation keys the schema ignored, e.g. `["_source", "_verified", "states[0]._note"]` (present only when the input carried any). |
|
|
192
194
|
| `narrativeCoverage` | `{states: "5/5", events: "3/9", scenarios: "0/12"}` when the model carries a narrative — a partial narrative is valid, and this is how much is still undocumented. The gap is also a `NARRATIVE_PARTIAL` (info) finding, so a gate can read it without parsing `nextSteps` text. |
|
|
193
195
|
|
|
196
|
+
A tool prints a body, not JSON. Passing checks stay in the `CHECKS` inventory line, and a fact that several checks report is listed once. Only error findings inline their evidence. Pass `reportView: "full"` when you need the structured report itself, for example to hand it to `logicprobe_report_diff`.
|
|
197
|
+
|
|
194
198
|
Turn the verdict into an answer, never into a summary of `ok`:
|
|
195
199
|
|
|
196
200
|
- `verdict: "pass"` — no error and no warning finding. Safe to report as verified, still with the scope the model covered.
|
|
@@ -231,7 +235,7 @@ When the document under review is a refactoring plan (modifying existing state m
|
|
|
231
235
|
1. **Extract the BEFORE model** from the existing codebase (not the plan — verify what the code actually does, not what the plan claims it does)
|
|
232
236
|
2. **Extract the AFTER model** from the refactoring plan
|
|
233
237
|
3. **Show both tables AND their model narratives** to the user side by side and confirm the delta is intentional
|
|
234
|
-
4. **Run Phase 2a + 2b on the AFTER model** — same
|
|
238
|
+
4. **Run Phase 2a + 2b on the AFTER model** — the same checks a new design gets
|
|
235
239
|
5. **Compare BEFORE vs AFTER**:
|
|
236
240
|
|
|
237
241
|
| Check | Method | Severity if Violated |
|
|
@@ -248,7 +252,7 @@ When the document under review is a refactoring plan (modifying existing state m
|
|
|
248
252
|
|
|
249
253
|
Run the checks with the native `logicprobe_verify` tool (model JSON, structured guard DSL, path-aware invariants) — see `references/dsh-model-schema.md`. A host without the tools can run the repository engine against the same JSON. For probe patterns, extraction methodology and manual procedures, load `references/logic-verification-guide.md`.
|
|
250
254
|
|
|
251
|
-
### Phase 2a: Structural Primitives
|
|
255
|
+
### Phase 2a: Structural Primitives
|
|
252
256
|
|
|
253
257
|
Run these FIRST. They establish basic well-formedness before adversarial probing.
|
|
254
258
|
|
|
@@ -263,7 +267,7 @@ Run these FIRST. They establish basic well-formedness before adversarial probing
|
|
|
263
267
|
| S7 | **Invariant validity** | Does every reachable state satisfy the plan's stated "always/never/guaranteed" assertions? | Error — plan claim is false |
|
|
264
268
|
| S8 | **Monotonic variables** | If a variable is declared `monotonic: inc/dec`, do all updates respect that direction? | Error — counter can move backwards |
|
|
265
269
|
|
|
266
|
-
### Phase 2b: Adversarial Probes
|
|
270
|
+
### Phase 2b: Adversarial Probes
|
|
267
271
|
|
|
268
272
|
Run these SECOND. Each probe actively tries to BREAK the model. If any probe succeeds (finds a violation), the plan has a behavior gap.
|
|
269
273
|
|
|
@@ -402,6 +406,19 @@ This skill owns behavioural claims. Three neighbouring domains have their own sk
|
|
|
402
406
|
|
|
403
407
|
---
|
|
404
408
|
|
|
409
|
+
## Red Flags
|
|
410
|
+
|
|
411
|
+
If you catch yourself thinking any of these, stop:
|
|
412
|
+
|
|
413
|
+
| You think | Reality |
|
|
414
|
+
|-----------|---------|
|
|
415
|
+
| "Too simple to check" | The check is cheap. The silent skip is not. |
|
|
416
|
+
| "I read the code, so I know" | Knowing is not evidence. Cite `file:line`, or run the model, or call the claim unverified. |
|
|
417
|
+
| "The spec or the diagram says so" | Both are claims about the code. Reconcile them with a source-side scan. |
|
|
418
|
+
| "I'll check while implementing" | Check before the decision, not after. |
|
|
419
|
+
| "Reasoning is enough" | Reasoning is not a run. One counter-example kills a universal claim. |
|
|
420
|
+
| "The report passed, so the code is fine" | The report covers the model you gave it. Reconcile it, and say what you did not check. |
|
|
421
|
+
|
|
405
422
|
## Rules
|
|
406
423
|
|
|
407
424
|
1. Never trust a document's claim without codebase verification.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# DSH Model Schema v1 — logicprobe_verify
|
|
2
2
|
|
|
3
|
-
The dsh-native `logicprobe_verify` tool accepts a structured JSON model. The engine runs
|
|
3
|
+
The dsh-native `logicprobe_verify` tool accepts a structured JSON model. The engine runs the structural and adversarial checks (S1-S8, A1-A14) and returns a JSON report. When `beforeModel` is supplied, it also runs D1-D4 before/after regression checks. Guards and updates are structured data — no code strings, no arbitrary execution.
|
|
4
4
|
|
|
5
5
|
## Top-level model
|
|
6
6
|
|
|
@@ -10,14 +10,15 @@ as outside this engine and points at tooling that can handle it.
|
|
|
10
10
|
|
|
11
11
|
| Dimension | What logicprobe covers today | Claim examples | Dedicated tooling | Why not here |
|
|
12
12
|
|---|---|---|---|---|
|
|
13
|
-
| Hard real time (timing) | Order, counts, path budgets (A12)
|
|
13
|
+
| Hard real time (timing) | Order, counts, path budgets (A12), and deadlines over discrete ticks (A14). Time otherwise appears as counters and events | "500 ms to SAFE", "no deadline miss", "period ≤ 1 ms" | UPPAAL, IMITATOR (timed automata); binary-level timing analysis for WCET | No continuous clocks. A deadline that is not a tick count cannot be expressed |
|
|
14
14
|
| Preemptive concurrency | Event-order interleavings (A2/A3), resource pairing (A4), idempotent replay (A8) | "thread-safe", "interrupt-safe", "no priority inversion" | TSan/Helgrind (runtime), CBMC (proof), TLA+ (interleaving model), RTOS-aware analysis | Single-threaded event model; no preemption, IRQ nesting, or atomics at instruction level |
|
|
15
15
|
| Hybrid control (continuous plant) | Discrete transitions and modes only | "switching is stable", "no chattering", "settling within T" | SpaceEx, Flow* (hybrid reachability), Simulink/Stateflow verification | No continuous dynamics; stability is not expressible |
|
|
16
16
|
| Probabilistic / reliability | Qualitative reachability and invariants | "MTBF ≥ X", "failure rate ≤ p", "availability ≥ 99.9%" | PRISM, Storm (stochastic model checking), fault-tree / FMEA | No probability semantics |
|
|
17
17
|
| Execution cost / performance | A12 budget checks over declared transition `cost` (absent = 1) | "worst-case dispatch ≤ 100 cycles" | aiT, RapiTime (real WCET at binary level) | `cost` is a modeler label, not measured execution time |
|
|
18
|
-
| Multi-machine composition |
|
|
19
|
-
|
|
|
20
|
-
|
|
|
18
|
+
| Multi-machine composition | `logicprobe_compose_verify` (dsh) and the engine's `compose` subcommand (non-dsh) check machines together: C1 composition deadlock, C2 a rendezvous that never fires. They stop at one handshake event per rendezvous | "A sends E, B always handles E", "these two never deadlock" | CSP (FDR), mCRL2, TLA+ (compositional models) | No payloads, no rate ratio and no fairness bound; each machine's own step order is free |
|
|
19
|
+
| Protocol semantics (message contents, channels, per-message ordering) | Events and handshakes between machines | "QoS 1 delivers exactly once", "the broker never reorders", "the queue never overflows" | TLA+, mCRL2, SPIN (Promela channels) | The model has states and events, not messages, queues or payloads |
|
|
20
|
+
| Nested/hierarchical statecharts | Flat models only; flatten before verification | parent/child states, orthogonal regions | SCXML / Stateflow (native hierarchy) | A flat state list only. `logicprobe_compose_verify` places machines side by side; it does not nest states. Flatten manually and re-confirm |
|
|
21
|
+
| Write-site / single-owner analysis | **Not covered, and not planned.** logicprobe reviews the diagram and the model; it does not read the source to see *who writes* a variable, a register or a field | "only the ISR writes this", "one owner per flag", "no double write to the CAN mailbox" | A source-side AST/rule check (e.g. the project's own include/arch checker), a static analyzer (clang-tidy, PC-lint, Coverity), or a model checker over the real code (CBMC) | It needs the source and a rule table about statements — a different input than a model or a diagram. `logicprobe_concurrency_scan` will flag the *claim* as unverified and route it here, which is the honest part of this plugin's answer (it is a dsh-only capability; without it, route the claim by hand) |
|
|
21
22
|
|
|
22
23
|
## Where the routing surfaces
|
|
23
24
|
|
|
@@ -30,8 +31,8 @@ as outside this engine and points at tooling that can handle it.
|
|
|
30
31
|
interrupt-safe, ...) carry `suggestions` naming dedicated tools.
|
|
31
32
|
- Manual review: when reading a plan, match its claims against the table above and
|
|
32
33
|
require dedicated evidence before accepting "always"/"never"/"guaranteed" language
|
|
33
|
-
- Generators: `
|
|
34
|
-
TLA+ (TLC spec + safety), PRISM (.pm + .pctl),
|
|
35
|
-
LogicModelV1
|
|
36
|
-
integers) and
|
|
37
|
-
|
|
34
|
+
- Generators: `logicprobe_export` (dsh) and the engine's `export` subcommand (non-dsh) emit
|
|
35
|
+
native inputs for UPPAAL (.xta + queries), TLA+ (TLC spec + safety), PRISM (.pm + .pctl),
|
|
36
|
+
and SPIN (Promela + ltl) from a LogicModelV1. Both translate the core machine (guards,
|
|
37
|
+
updates, weights; booleans as integers) and return unrepresentable invariants as explicit
|
|
38
|
+
warnings.
|
|
@@ -202,7 +202,7 @@ When a probe finds a counter-example, classify it:
|
|
|
202
202
|
|
|
203
203
|
### Model Fidelity Warning
|
|
204
204
|
|
|
205
|
-
The model is an APPROXIMATION. It models state transitions, not execution semantics. A model that passes
|
|
205
|
+
The model is an APPROXIMATION. It models state transitions, not execution semantics. A model that passes every check (S1-S8 structural, A1-A14) means the plan's LOGIC is consistent — NOT that the implementation will work. Always follow logic verification with code-level review.
|
|
206
206
|
|
|
207
207
|
## Refactoring Verification
|
|
208
208
|
|
|
@@ -41,3 +41,4 @@ The full routing table, including hard-real-time, hybrid-control and execution-c
|
|
|
41
41
|
2. **No absolute language in the answer.** "This is thread-safe" is exactly the claim being mined, not a result this skill can produce.
|
|
42
42
|
3. **One counterexample is enough to refute.** If a race is suspected, the deliverable is the interleaving that breaks it plus the harness that demonstrates it (TSan/Helgrind output), not an argument.
|
|
43
43
|
4. **Sequential targets are out of scope.** If nothing runs concurrently, say so and stop.
|
|
44
|
+
5. **The scanner is dsh-only.** `logicprobe_concurrency_scan` has no mirror subcommand. Without it, mine the text by hand against the keyword table above and route each claim the same way.
|
package/src/compose-tool.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
2
2
|
import type { JsonValue } from './json-value.js'
|
|
3
3
|
import { runCompositionVerification } from './engine.js'
|
|
4
|
+
import { renderReportText } from './report-view.js'
|
|
4
5
|
|
|
5
6
|
export const LOGICPROBE_COMPOSE_TOOL_NAME = 'logicprobe_compose_verify'
|
|
6
7
|
|
|
@@ -26,14 +27,19 @@ export const logicProbeComposeTool = defineTool({
|
|
|
26
27
|
type: 'integer',
|
|
27
28
|
description: 'Maximum composite states to explore. Default 10000.',
|
|
28
29
|
},
|
|
30
|
+
reportView: {
|
|
31
|
+
type: 'string',
|
|
32
|
+
enum: ['digest', 'full'],
|
|
33
|
+
description: 'digest (default) prints the readable body; full prints the structured report, which logicprobe_report_diff needs.',
|
|
34
|
+
},
|
|
29
35
|
},
|
|
30
36
|
output: {
|
|
31
37
|
schema: {
|
|
32
38
|
type: 'json',
|
|
33
39
|
description: 'Composition verification report with C1/C2 findings.',
|
|
34
40
|
},
|
|
35
|
-
render(
|
|
36
|
-
return [{ type: 'text' as const, text:
|
|
41
|
+
render(args, value) {
|
|
42
|
+
return [{ type: 'text' as const, text: renderReportText(value, { full: args.reportView === 'full' }) }]
|
|
37
43
|
},
|
|
38
44
|
},
|
|
39
45
|
timeoutMs: 10_000,
|
package/src/concurrency-tool.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
2
2
|
import type { JsonValue } from './json-value.js'
|
|
3
3
|
import { runConcurrencyScan } from './concurrency.js'
|
|
4
|
+
import { renderReportText } from './report-view.js'
|
|
4
5
|
|
|
5
6
|
export const LOGICPROBE_CONCURRENCY_SCAN_TOOL_NAME = 'logicprobe_concurrency_scan'
|
|
6
7
|
|
|
@@ -20,14 +21,19 @@ export const logicProbeConcurrencyScanTool = defineTool({
|
|
|
20
21
|
required: true,
|
|
21
22
|
description: 'Document or plan text to scan for concurrency-related claims.',
|
|
22
23
|
},
|
|
24
|
+
reportView: {
|
|
25
|
+
type: 'string',
|
|
26
|
+
enum: ['digest', 'full'],
|
|
27
|
+
description: 'digest (default) prints the readable body; full prints the structured report, which logicprobe_report_diff needs.',
|
|
28
|
+
},
|
|
23
29
|
},
|
|
24
30
|
output: {
|
|
25
31
|
schema: {
|
|
26
32
|
type: 'json',
|
|
27
33
|
description: 'Concurrency scan report with findings and summary.',
|
|
28
34
|
},
|
|
29
|
-
render(
|
|
30
|
-
return [{ type: 'text' as const, text:
|
|
35
|
+
render(args, value) {
|
|
36
|
+
return [{ type: 'text' as const, text: renderReportText(value, { full: args.reportView === 'full' }) }]
|
|
31
37
|
},
|
|
32
38
|
},
|
|
33
39
|
timeoutMs: 10_000,
|
package/src/data-tool.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
1
|
+
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
2
2
|
import type { JsonValue } from './json-value.js'
|
|
3
3
|
import { runDataVerification, DATA_ENGINE_SCHEMA_VERSION } from './data-engine.js'
|
|
4
|
+
import { renderReportText } from './report-view.js'
|
|
4
5
|
|
|
5
6
|
export const LOGICPROBE_DATAMODEL_VERIFY_TOOL_NAME = 'logicprobe_datamodel_verify'
|
|
6
7
|
|
|
@@ -40,14 +41,19 @@ export const logicProbeDataModelVerifyTool = defineTool({
|
|
|
40
41
|
type: 'json',
|
|
41
42
|
description: 'Optional backup/restore pairs for DA7 rollback symmetry.',
|
|
42
43
|
},
|
|
44
|
+
reportView: {
|
|
45
|
+
type: 'string',
|
|
46
|
+
enum: ['digest', 'full'],
|
|
47
|
+
description: 'digest (default) prints the readable body; full prints the structured report, which logicprobe_report_diff needs.',
|
|
48
|
+
},
|
|
43
49
|
},
|
|
44
50
|
output: {
|
|
45
51
|
schema: {
|
|
46
52
|
type: 'json',
|
|
47
53
|
description: 'logicprobe-datamodel verification report with summary and per-check findings.',
|
|
48
54
|
},
|
|
49
|
-
render(
|
|
50
|
-
return [{ type: 'text' as const, text:
|
|
55
|
+
render(args, value) {
|
|
56
|
+
return [{ type: 'text' as const, text: renderReportText(value, { full: args.reportView === 'full' }) }]
|
|
51
57
|
},
|
|
52
58
|
},
|
|
53
59
|
timeoutMs: 10_000,
|
package/src/export-tool.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
|
2
2
|
import type { JsonValue } from './json-value.js'
|
|
3
3
|
import { REPORT_SCHEMAS, DEFAULT_HASH_SPEC, modelHash, refusalVerdict, validateModel, verdictOf } from './engine.js'
|
|
4
4
|
import { exportModel, type ExportFormat } from './exporters.js'
|
|
5
|
+
import { renderReportText } from './report-view.js'
|
|
5
6
|
|
|
6
7
|
/** The model hash of an export's input, when the input validates (the success path always does). */
|
|
7
8
|
function exportHashes(model: unknown): { hashSpec: typeof DEFAULT_HASH_SPEC; modelHash?: string } {
|
|
@@ -34,14 +35,19 @@ export const logicProbeExportTool = defineTool({
|
|
|
34
35
|
enum: ['uppaal', 'tla', 'prism', 'spin'],
|
|
35
36
|
description: 'Target tool format.',
|
|
36
37
|
},
|
|
38
|
+
reportView: {
|
|
39
|
+
type: 'string',
|
|
40
|
+
enum: ['digest', 'full'],
|
|
41
|
+
description: 'digest (default) prints the generated file verbatim; full prints the structured result as JSON.',
|
|
42
|
+
},
|
|
37
43
|
},
|
|
38
44
|
output: {
|
|
39
45
|
schema: {
|
|
40
46
|
type: 'json',
|
|
41
47
|
description: 'Export result with generated file content.',
|
|
42
48
|
},
|
|
43
|
-
render(
|
|
44
|
-
return [{ type: 'text' as const, text:
|
|
49
|
+
render(args, value) {
|
|
50
|
+
return [{ type: 'text' as const, text: renderReportText(value, { full: args.reportView === 'full' }) }]
|
|
45
51
|
},
|
|
46
52
|
},
|
|
47
53
|
timeoutMs: 10_000,
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* logicprobe — DeepSeek Harness native plugin for the Logic Probe toolbox.
|
|
3
|
-
* Injects the session-start gate text (what this plugin checks, the
|
|
4
|
-
* the
|
|
3
|
+
* Injects the session-start gate text (what this plugin checks, the routing to
|
|
4
|
+
* the skills, the tool list, how to read a report)
|
|
5
5
|
* into the first model step of every agent session, mirroring the SessionStart
|
|
6
6
|
* hook the Claude Code plugin installs.
|
|
7
7
|
* The skill ships in this package's `skills/` directory and is registered at
|
|
@@ -18,8 +18,9 @@
|
|
|
18
18
|
* to the first step after their promotion, and the history guard re-injects it
|
|
19
19
|
* there. The default gate text is the dsh-native adaptation of
|
|
20
20
|
* `hooks/session-start-content.md`. Both are a guide to calling the tools: what
|
|
21
|
-
* this plugin checks, the
|
|
22
|
-
*
|
|
21
|
+
* this plugin checks, the routing to the sibling skills, the tool list, and how to
|
|
22
|
+
* read a report. The Red Flags table is enforcement scaffolding and lives in the
|
|
23
|
+
* skill body instead, where a session that needs it can load it.
|
|
23
24
|
* They stay in sync. Method, doctrine and per-domain detail live in the skills
|
|
24
25
|
* and their references, not here. Deployments override via Config.
|
|
25
26
|
*
|
|
@@ -75,41 +76,28 @@ const GATE_SOURCE_KIND: 'plugin:logicprobe' = 'plugin:logicprobe'
|
|
|
75
76
|
|
|
76
77
|
export type InteractionMode = 'ask' | 'auto' | 'follow-approval'
|
|
77
78
|
|
|
78
|
-
const DEFAULT_GATE_CONTENT = `
|
|
79
|
-
<EXTREMELY_IMPORTANT>
|
|
80
|
-
Plugin logicprobe is active. It checks claims about designs and code: facts against the source, behaviour as an executable model.
|
|
81
|
-
|
|
82
|
-
**
|
|
83
|
-
|
|
84
|
-
**
|
|
85
|
-
|
|
86
|
-
**
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
- \`
|
|
91
|
-
- \`
|
|
92
|
-
- \`
|
|
93
|
-
- \`
|
|
94
|
-
- \`
|
|
95
|
-
- \`
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
**Red Flags** — if you think any of these, stop:
|
|
102
|
-
|
|
103
|
-
| You think | Reality |
|
|
104
|
-
|-----------|---------|
|
|
105
|
-
| "Too simple to check" | The check is cheap. The silent skip is not. |
|
|
106
|
-
| "I read the code, so I know" | Knowing is not evidence. Cite \`file:line\`, or run the model, or call the claim unverified. |
|
|
107
|
-
| "The spec or the diagram says so" | Both are claims about the code. Reconcile them with a source-side scan. |
|
|
108
|
-
| "I'll check while implementing" | Check before the decision, not after. |
|
|
109
|
-
| "Reasoning is enough" | Reasoning is not a run. One counter-example kills a universal claim. |
|
|
110
|
-
| "The report passed, so the code is fine" | The report covers the model you gave it. Reconcile it, and say what you did not check. |
|
|
111
|
-
|
|
112
|
-
</EXTREMELY_IMPORTANT>
|
|
79
|
+
const DEFAULT_GATE_CONTENT = `
|
|
80
|
+
<EXTREMELY_IMPORTANT>
|
|
81
|
+
Plugin logicprobe is active. It checks claims about designs and code: facts against the source, behaviour as an executable model.
|
|
82
|
+
|
|
83
|
+
**Unsure whether a check applies?** Load \`logicprobe\` first. It is the entry point: it owns the doctrine, the model schema, the depth rules and the routing to its siblings.
|
|
84
|
+
|
|
85
|
+
**Load the skill that matches the claim**: \`logicprobe\` (entry point; claim and behaviour checks), \`logicprobe-uml\` (diagrams), \`logicprobe-structure\` (architecture, dependencies), \`logicprobe-concurrency\` (concurrency claims), \`logicprobe-datamodel\` (data models, migrations).
|
|
86
|
+
|
|
87
|
+
**Tools** (dsh):
|
|
88
|
+
|
|
89
|
+
- \`logicprobe_verify\` — state machines: structural checks, adversarial probes, budgets, deadlines, before/after regression.
|
|
90
|
+
- \`logicprobe_datamodel_verify\` — data models and migrations: structure, migration coverage, copy consistency, rollback, before/after data.
|
|
91
|
+
- \`logicprobe_compose_verify\` — two or more machines: deadlock, and a rendezvous that never fires.
|
|
92
|
+
- \`logicprobe_concurrency_scan\` — finds concurrency claims and routes them. It proves nothing about concurrency.
|
|
93
|
+
- \`logicprobe_export\` — UPPAAL, TLA+, PRISM and SPIN input from a verified model.
|
|
94
|
+
- \`logicprobe_uml\` — render, parse or review a UML diagram.
|
|
95
|
+
- \`logicprobe_structure_verify\` — dependency review of a structure diagram, at one level or several.
|
|
96
|
+
- \`logicprobe_report_diff\` — baseline against current: what a change added, removed or changed.
|
|
97
|
+
|
|
98
|
+
**Read a report**: gate on \`verdict\` (\`pass\`, \`pass_with_findings\`, \`fail\`), never on \`ok\`. Reports carry \`verdictReason\`, \`hashes\` and \`nextSteps\`. Keys starting with \`_\` are notes: ignored, and left out of the model hash. A tool prints the report body: passing checks stay in the inventory line, repeated facts are grouped, and warning evidence is omitted — pass \`reportView: "full"\` only when you need the structured report itself, which \`logicprobe_report_diff\` consumes.
|
|
99
|
+
|
|
100
|
+
</EXTREMELY_IMPORTANT>
|
|
113
101
|
`
|
|
114
102
|
|
|
115
103
|
/** A schemastery field that may or may not carry `.volatile()`. */
|
|
@@ -261,7 +249,7 @@ function inspectProvider(config: Config, isToolRegistered: () => boolean, isData
|
|
|
261
249
|
return {
|
|
262
250
|
manifest: {
|
|
263
251
|
id: 'logicprobe',
|
|
264
|
-
description: 'Session-start gate injection and native verification tooling for the Logic Probe toolbox. The gate is a guide to calling the tools: what the plugin checks, the
|
|
252
|
+
description: 'Session-start gate injection and native verification tooling for the Logic Probe toolbox. The gate is a guide to calling the tools: what the plugin checks, the routing to the sibling skills, the tool list, and how to read a report. Doctrine and per-domain detail live in the skills.',
|
|
265
253
|
methods: [
|
|
266
254
|
{
|
|
267
255
|
name: 'status',
|
package/src/report-diff-tool.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
2
2
|
import type { JsonValue } from './json-value.js'
|
|
3
3
|
import { diffReports } from './baseline.js'
|
|
4
|
+
import { renderReportText } from './report-view.js'
|
|
4
5
|
|
|
5
6
|
export const LOGICPROBE_REPORT_DIFF_TOOL_NAME = 'logicprobe_report_diff'
|
|
6
7
|
|
|
@@ -25,14 +26,19 @@ export const logicProbeReportDiffTool = defineTool({
|
|
|
25
26
|
required: true,
|
|
26
27
|
description: 'The current report to compare against the baseline.',
|
|
27
28
|
},
|
|
29
|
+
reportView: {
|
|
30
|
+
type: 'string',
|
|
31
|
+
enum: ['digest', 'full'],
|
|
32
|
+
description: 'digest (default) prints the readable body; full prints the structured diff report.',
|
|
33
|
+
},
|
|
28
34
|
},
|
|
29
35
|
output: {
|
|
30
36
|
schema: {
|
|
31
37
|
type: 'json',
|
|
32
38
|
description: 'Baseline diff report: added/removed/changed findings, delta verdict, current verdict, summary and next steps.',
|
|
33
39
|
},
|
|
34
|
-
render(
|
|
35
|
-
return [{ type: 'text' as const, text:
|
|
40
|
+
render(args, value) {
|
|
41
|
+
return [{ type: 'text' as const, text: renderReportText(value, { full: args.reportView === 'full' }) }]
|
|
36
42
|
},
|
|
37
43
|
},
|
|
38
44
|
timeoutMs: 10_000,
|