dsh-logicprobe 0.9.0 → 1.1.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 +128 -66
- package/README.md +128 -66
- package/lib/baseline.js +142 -0
- package/lib/client.js +56 -1
- package/lib/compose-tool.js +1 -1
- package/lib/concurrency.js +14 -0
- package/lib/data-engine.js +42 -8
- package/lib/engine.js +3151 -2801
- package/lib/export-tool.js +27 -2
- package/lib/granularity.js +237 -0
- package/lib/index.js +63 -41
- package/lib/report-diff-tool.js +39 -0
- package/lib/structure-tool.js +64 -0
- package/lib/structure.js +648 -0
- package/lib/tool.js +3 -3
- package/lib/types/baseline.d.ts +69 -0
- package/lib/types/concurrency.d.ts +10 -0
- package/lib/types/data-engine.d.ts +13 -1
- package/lib/types/engine.d.ts +419 -277
- package/lib/types/granularity.d.ts +106 -0
- package/lib/types/index.d.ts +9 -8
- package/lib/types/report-diff-tool.d.ts +8 -0
- package/lib/types/structure-tool.d.ts +10 -0
- package/lib/types/structure.d.ts +156 -0
- package/lib/types/tool.d.ts +2 -2
- package/lib/types/uml.d.ts +89 -0
- package/lib/uml-tool.js +146 -104
- package/lib/uml.js +1748 -1544
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +16 -14
- package/skills/logicprobe/SKILL.md +84 -58
- package/skills/logicprobe/references/dsh-model-schema.md +102 -10
- package/skills/logicprobe/references/gap-routing-guide.md +37 -36
- package/skills/logicprobe/references/hash-spec.md +153 -0
- package/skills/logicprobe/references/logic-verification-guide.md +27 -250
- package/skills/logicprobe-concurrency/SKILL.md +43 -0
- package/skills/{logicprobe → logicprobe-concurrency}/references/concurrency-risk-guide.md +1 -1
- package/skills/logicprobe-datamodel/SKILL.md +5 -4
- package/skills/logicprobe-datamodel/references/data-model-guide.md +1 -1
- package/skills/logicprobe-datamodel/references/data-model-schema.md +1 -1
- package/skills/logicprobe-structure/SKILL.md +95 -0
- package/skills/logicprobe-structure/references/structure-review-guide.md +177 -0
- package/skills/logicprobe-uml/SKILL.md +57 -0
- package/skills/{logicprobe → logicprobe-uml}/references/uml-modeling-guide.md +121 -8
- package/src/baseline.ts +180 -0
- package/src/client.js +56 -1
- package/src/compose-tool.ts +47 -47
- package/src/concurrency.ts +23 -0
- package/src/data-engine.ts +51 -9
- package/src/engine.ts +503 -72
- package/src/export-tool.ts +73 -48
- package/src/granularity.ts +312 -0
- package/src/index.ts +63 -41
- package/src/report-diff-tool.ts +43 -0
- package/src/structure-tool.ts +68 -0
- package/src/structure.ts +724 -0
- package/src/tool.ts +3 -3
- package/src/uml-tool.ts +53 -10
- package/src/uml.ts +288 -24
- package/skills/logicprobe/references/logicprobe-engine.py +0 -4943
- package/skills/logicprobe/references/verification-harness.py +0 -959
- package/skills/logicprobe-datamodel/references/data-model-harness.py +0 -528
package/src/tool.ts
CHANGED
|
@@ -10,13 +10,13 @@ export const LOGICPROBE_VERIFY_TOOL_NAME = 'logicprobe_verify'
|
|
|
10
10
|
* the 22-check report (S1-S8 structural, A1-A14), or a 26-check
|
|
11
11
|
* report when beforeModel is supplied (D1 behavioral preservation, D2
|
|
12
12
|
* invariant continuity, D3 regression delta, D4 deadlock/liveness regression).
|
|
13
|
-
* This is the dsh-native
|
|
14
|
-
*
|
|
13
|
+
* This is the dsh-native path: the model is built and run here, with no
|
|
14
|
+
* template to fill in by hand.
|
|
15
15
|
*/
|
|
16
16
|
export const logicProbeVerifyTool = defineTool({
|
|
17
17
|
name: LOGICPROBE_VERIFY_TOOL_NAME,
|
|
18
18
|
description:
|
|
19
|
-
'Run
|
|
19
|
+
'Run state-machine verification on a LogicModelV1 object. Model shape: schemaVersion 1, init, states ({id, terminal?}), transitions ({from, event, to, guard?, updates?, cost?}), plus optional variables, invariants, concurrentPairs, boundaryChecks, resourcePairs, idempotentEvents and narrative. Guards are structured: {variable, op, value}, {all}, {any} or {not}. Invariants cover never-states, var-in-range, event-before-state, leads-to, sequence, atomicity, budget, probability and deadline. `cost` defaults to 1 and drives the A12 budget check. `weight` defaults to 1 and makes the model a DTMC for A13. A state with `maxTicks` needs top-level `tickEvents`; A14 reports over-residency. The schema is closed: an undeclared key is a validation error. Keys starting with `_` are metadata: ignored, kept out of `modelHash`, and echoed as `metadataKeys`. Variables support monotonic inc and dec. Pass `beforeModel` and `stateMapping` to add the D1-D4 regression. Read `verdict`, never `ok`. The full schema is in the `logicprobe` skill: references/dsh-model-schema.md.',
|
|
20
20
|
parameters: {
|
|
21
21
|
model: {
|
|
22
22
|
type: 'json',
|
package/src/uml-tool.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
1
|
+
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
2
|
+
import { createHash } from 'node:crypto'
|
|
2
3
|
import type { JsonValue } from './json-value.js'
|
|
3
|
-
import {
|
|
4
|
+
import { REPORT_SCHEMAS, DEFAULT_HASH_SPEC, modelHash, refusalVerdict, verdictOf, verdictOfFindings, type VerdictSummary } from './engine.js'
|
|
5
|
+
import { renderUml, parseUml, parseFindings, reviewUml, explainLabels, UmlError, type UmlDiagram, type UmlFinding, type UmlNotation, type UmlParseResult } from './uml.js'
|
|
4
6
|
|
|
5
7
|
export const LOGICPROBE_UML_TOOL_NAME = 'logicprobe_uml'
|
|
6
8
|
|
|
@@ -19,13 +21,13 @@ export const LOGICPROBE_UML_TOOL_NAME = 'logicprobe_uml'
|
|
|
19
21
|
export const logicProbeUmlTool = defineTool({
|
|
20
22
|
name: LOGICPROBE_UML_TOOL_NAME,
|
|
21
23
|
description:
|
|
22
|
-
'Model a code flow as UML, and
|
|
24
|
+
'Model a code flow as UML, and audit the modelling. action="render" turns a LogicModelV1 into diagram source: mermaid (state, activity, sequence) or plantuml (state, sequence). action="parse" reads Mermaid or PlantUML state or activity text back into a LogicModelV1, so a hand-drawn diagram can be verified. A sequence diagram is refused: a trace cannot reconstruct a machine. So is any other diagram family (class, ER, gantt, mindmap). That refusal carries errorCode "UML_NOT_A_STATE_DIAGRAM". A PlantUML component, package or deployment diagram declares no kind, so the parser detects those constructs itself. It returns a by-product model and reports the error UML_NOT_A_STATE_DIAGRAM, with `discardedConstructs` and `discardedEdges`. Never treat that model as a model of the file. action="review" audits the modelling: structural defects (UML002-UML009), documentation gaps (UML010-UML015), and a fidelity check that re-parses the rendered diagram (UML017). Give it a model, a diagram, or both. action="explain-labels" prints the label and comment conventions the parser accepts, without needing a diagram. Rendering never invents structure. A construct the notation cannot express becomes a warning. For dependency questions on a component or class diagram, use `logicprobe_structure_verify` instead. Read `verdict`, not `ok`: error findings mean a failed review.',
|
|
23
25
|
parameters: {
|
|
24
26
|
action: {
|
|
25
27
|
type: 'string',
|
|
26
28
|
required: true,
|
|
27
|
-
enum: ['render', 'parse', 'review'],
|
|
28
|
-
description: 'render = model → UML source; parse = UML source → model; review = audit the modelling (and its fidelity to the model).',
|
|
29
|
+
enum: ['render', 'parse', 'review', 'explain-labels'],
|
|
30
|
+
description: 'render = model → UML source; parse = UML source → model; review = audit the modelling (and its fidelity to the model); explain-labels = print the label and comment conventions this parser accepts.',
|
|
29
31
|
},
|
|
30
32
|
model: {
|
|
31
33
|
type: 'json',
|
|
@@ -79,12 +81,44 @@ export const logicProbeUmlTool = defineTool({
|
|
|
79
81
|
if (args.action === 'render') {
|
|
80
82
|
if (args.model === undefined) return errorResult('action=render needs `model` (a LogicModelV1 object)')
|
|
81
83
|
const result = renderUml(args.model, (args.notation === undefined || args.notation === 'auto' ? 'mermaid' : args.notation) as UmlNotation, (args.kind ?? 'state') as UmlDiagram, args.maxSteps)
|
|
82
|
-
return { ok: true, action: 'render', notation: result.notation, kind: result.diagram, diagram: result.primary, warnings: result.warnings } as unknown as JsonValue
|
|
84
|
+
return { ok: true, ran: true, ...verdictOf(0, result.warnings.length), schema: REPORT_SCHEMAS.umlRender, action: 'render', notation: result.notation, kind: result.diagram, diagram: result.primary, hashes: { diagram: createHash('sha256').update(result.primary).digest('hex') }, warnings: result.warnings } as unknown as JsonValue
|
|
83
85
|
}
|
|
84
86
|
if (args.action === 'parse') {
|
|
85
87
|
if (args.diagram === undefined) return errorResult('action=parse needs `diagram` (Mermaid or PlantUML text)')
|
|
86
88
|
const result = parseUml(args.diagram, args.notation ?? 'auto')
|
|
87
|
-
|
|
89
|
+
// A diagram from another family still parses into *something*. `parseFindings`
|
|
90
|
+
// says so, and the verdict is what stops that something from being trusted:
|
|
91
|
+
// `ok: true` only means the parser ran.
|
|
92
|
+
const findings = parseFindings(result)
|
|
93
|
+
return {
|
|
94
|
+
ok: true,
|
|
95
|
+
ran: true,
|
|
96
|
+
...parseVerdict(result, findings),
|
|
97
|
+
schema: REPORT_SCHEMAS.umlParse,
|
|
98
|
+
action: 'parse',
|
|
99
|
+
notation: result.notation,
|
|
100
|
+
kind: result.diagram,
|
|
101
|
+
model: result.model,
|
|
102
|
+
labels: result.labels,
|
|
103
|
+
findings,
|
|
104
|
+
discardedConstructs: result.discardedConstructs,
|
|
105
|
+
discardedEdges: result.discardedEdges,
|
|
106
|
+
hashes: { hashSpec: DEFAULT_HASH_SPEC, modelHash: modelHash(result.model), diagram: createHash('sha256').update(args.diagram).digest('hex') },
|
|
107
|
+
warnings: result.warnings,
|
|
108
|
+
} as unknown as JsonValue
|
|
109
|
+
}
|
|
110
|
+
// R9: the label contract was documented in the library and in `explainLabels()`, but no
|
|
111
|
+
// tool exposed it, so it was reachable only by reading the source or the docs.
|
|
112
|
+
if (args.action === 'explain-labels') {
|
|
113
|
+
const notation = (args.notation === undefined || args.notation === 'auto' ? 'mermaid' : args.notation) as UmlNotation
|
|
114
|
+
return {
|
|
115
|
+
ok: true,
|
|
116
|
+
ran: true,
|
|
117
|
+
...verdictOf(0, 0),
|
|
118
|
+
schema: REPORT_SCHEMAS.umlExplainLabels,
|
|
119
|
+
action: 'explain-labels',
|
|
120
|
+
...explainLabels(notation),
|
|
121
|
+
} as unknown as JsonValue
|
|
88
122
|
}
|
|
89
123
|
const report = reviewUml({
|
|
90
124
|
model: args.model,
|
|
@@ -96,11 +130,20 @@ export const logicProbeUmlTool = defineTool({
|
|
|
96
130
|
})
|
|
97
131
|
return report as unknown as JsonValue
|
|
98
132
|
} catch (error) {
|
|
99
|
-
|
|
133
|
+
const message = error instanceof Error ? error.message : String(error)
|
|
134
|
+
return errorResult(message, error instanceof UmlError ? error.code : undefined) as unknown as JsonValue
|
|
100
135
|
}
|
|
101
136
|
},
|
|
102
137
|
})
|
|
103
138
|
|
|
104
|
-
|
|
105
|
-
|
|
139
|
+
/** The parse verdict counts parser notes as findings: an ignored line is information the model does not carry. */
|
|
140
|
+
function parseVerdict(result: UmlParseResult, findings: UmlFinding[]): VerdictSummary {
|
|
141
|
+
const errors = findings.filter((finding) => finding.severity === 'error').length
|
|
142
|
+
const warnings = findings.filter((finding) => finding.severity === 'warning').length + result.warnings.length
|
|
143
|
+
const firstCode = findings.find((finding) => finding.severity === 'error')?.code ?? findings.find((finding) => finding.severity === 'warning')?.code
|
|
144
|
+
return verdictOf(errors, warnings, firstCode)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function errorResult(message: string, errorCode = 'UML_INPUT'): JsonValue {
|
|
148
|
+
return { ok: false, ran: false, ...refusalVerdict(message), errorCode, error: message } as unknown as JsonValue
|
|
106
149
|
}
|