dsh-logicprobe 1.4.0 → 1.4.2

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.
@@ -1,293 +1,293 @@
1
- /**
2
- * UML front end for LogicModelV1 — model a code flow as a UML diagram, then
3
- * review the modelling itself.
4
- *
5
- * Two halves, one data flow:
6
- *
7
- * 1. `renderUml` turns a validated LogicModelV1 into Mermaid or PlantUML text
8
- * (state machine, activity/flow, or sequence trace). The diagram is a
9
- * *view*: it never invents structure the model does not have, and anything
10
- * the notation cannot express is reported as a warning instead of being
11
- * dropped silently.
12
- * 2. `parseUml` reads that text back into a LogicModelV1, and `reviewUml`
13
- * compares the two. That comparison is the point of the feature: a UML
14
- * diagram of a code flow is itself a model, and a model can be wrong —
15
- * ambiguous branches, dead ends, flows nobody can enter, symbols the
16
- * source never names. A diagram that does not round-trip to the model it
17
- * was drawn from is mis-modelled, and the review says so.
18
- *
19
- * Why the round trip is the fidelity check: rendering and parsing are inverse
20
- * only if every construct survives the notation. The generated text carries
21
- * `logicprobe:` directives (ignored by Mermaid/PlantUML renderers) that pin the
22
- * initial state, the terminal states and any state id the notation cannot spell
23
- * verbatim, so an exact comparison is possible rather than a fuzzy one.
24
- *
25
- * The review deliberately does NOT replace `logicprobe_verify`: it checks the
26
- * modelling (structure the diagram claims, documentation coverage, notation
27
- * fidelity), while S1-S8/A1-A14 check the machine's behaviour (guard
28
- * exhaustiveness under real valuations, invariant paths, deadlock/liveness in
29
- * the runtime state space). Findings name the engine check to run next.
30
- *
31
- * @module logicprobe-uml
32
- */
33
- import { type HashSpec, type NarrativeCoverage, type ReportSchema, type Verdict } from './engine.js';
34
- import type { GuardNode, LogicModelV1, UpdateSpec } from './engine.js';
35
- export type UmlNotation = 'mermaid' | 'plantuml';
36
- export type UmlDiagram = 'state' | 'activity' | 'sequence';
37
- export declare const UML_NOTATIONS: readonly UmlNotation[];
38
- export declare const UML_DIAGRAMS: readonly UmlDiagram[];
39
- /**
40
- * What the caller is going to do with the artifact, declared up front.
41
- *
42
- * The view follows the question, not the machine, so the tool cannot pick it. What it
43
- * can do is refuse a pairing that cannot serve the question — before the work, not as
44
- * a finding after it.
45
- */
46
- export type UmlIntent = 'present' | 'verify' | 'fidelity';
47
- export declare const UML_INTENTS: readonly UmlIntent[];
48
- /** The tool actions, for the entry check. `labels` is `action=explain-labels`. */
49
- export type UmlIntentAction = 'render' | 'parse' | 'review' | 'labels';
50
- export interface UmlRenderResult {
51
- notation: UmlNotation;
52
- diagram: UmlDiagram;
53
- /** The diagram source; hand this to the user or a renderer as-is. */
54
- primary: string;
55
- warnings: string[];
56
- }
57
- export interface UmlParseResult {
58
- notation: UmlNotation;
59
- diagram: UmlDiagram;
60
- model: LogicModelV1;
61
- /**
62
- * Display labels found in the diagram, keyed by state id. They are how a
63
- * reader learns what a symbol means; a missing entry is an undocumented
64
- * symbol, which the review reports.
65
- */
66
- labels: Record<string, string>;
67
- /**
68
- * Declarations found in the text that LogicModelV1 cannot represent. A non-empty
69
- * list means the parsed model is NOT this diagram: the text belongs to another
70
- * diagram family (component, package, class, deployment, …), so whatever came
71
- * out is a by-product of reading keywords the parser does not own.
72
- */
73
- discardedConstructs: DiscardedConstruct[];
74
- /**
75
- * Arrows whose endpoints were declared by a discarded construct. They survive
76
- * parsing as state transitions, which is exactly why they are counted out loud.
77
- */
78
- discardedEdges: number;
79
- warnings: string[];
80
- }
81
- /** One declaration the parser could not represent, with the source line that carried it. */
82
- export interface DiscardedConstruct {
83
- /** The construct keyword, lower-cased (`component`, `package`, `classDiagram`). */
84
- construct: string;
85
- /** 1-based line number in the diagram source. */
86
- line: number;
87
- /** The source line, trimmed. */
88
- text: string;
89
- }
90
- export interface UmlFinding {
91
- code: string;
92
- severity: 'error' | 'warning' | 'info';
93
- message: string;
94
- states?: string[];
95
- events?: string[];
96
- transitions?: Array<{
97
- from: string;
98
- event: string;
99
- to: string;
100
- }>;
101
- detail?: string;
102
- /** Machine-readable context for the finding (ids, coverage, rule matches), same shape as the engine's findings. */
103
- evidence?: Record<string, unknown>;
104
- }
105
- export interface UmlRoundTripReport {
106
- notation: UmlNotation;
107
- diagram: UmlDiagram;
108
- ok: boolean;
109
- /** Which published hash specification the two hashes follow (see references/hash-spec.md). */
110
- hashSpec: HashSpec;
111
- modelHash: string;
112
- parsedHash: string;
113
- diffs: string[];
114
- warnings: string[];
115
- }
116
- export interface UmlReviewReport {
117
- /** The review ran and produced this report. It does NOT mean the modelling passed — read `verdict`. */
118
- ok: boolean;
119
- ran: boolean;
120
- verdict: Verdict;
121
- verdictReason: string;
122
- /** The versioned report contract this result follows. */
123
- schema: ReportSchema;
124
- source: 'model' | 'diagram' | 'model+diagram';
125
- summary: {
126
- errors: number;
127
- warnings: number;
128
- info: number;
129
- states: number;
130
- events: number;
131
- transitions: number;
132
- terminalStates: number;
133
- reachableStates: number;
134
- documentedStates: number;
135
- };
136
- findings: UmlFinding[];
137
- roundTrip: UmlRoundTripReport | null;
138
- /** Diagram display labels, when a diagram took part in the review. */
139
- labels?: Record<string, string>;
140
- /** Model parsed from the diagram, when a diagram was given (feed it to `logicprobe_verify`). */
141
- model?: LogicModelV1;
142
- /** Diagram rendered from the model, when only a model was given. */
143
- primary?: string;
144
- /** Paths of the `_`-prefixed metadata keys found in the supplied model, when it carried any. */
145
- metadataKeys?: string[];
146
- /** How much of the model the narrative documents; absent when there is no narrative. */
147
- narrativeCoverage?: NarrativeCoverage;
148
- /** Hashes of what was reviewed, in one place. */
149
- hashes: {
150
- hashSpec: HashSpec;
151
- modelHash?: string;
152
- parsedHash?: string;
153
- };
154
- /** Declarations the parser could not represent; a non-empty list fails the review. */
155
- discardedConstructs?: DiscardedConstruct[];
156
- /** Arrows whose endpoints came from a discarded construct. */
157
- discardedEdges?: number;
158
- warnings: string[];
159
- nextSteps: string[];
160
- }
161
- /**
162
- * A UML front-end refusal. `code` lets the tool report *why* it refused instead of
163
- * collapsing every refusal into a generic input error.
164
- */
165
- export declare class UmlError extends Error {
166
- readonly code: string;
167
- constructor(message: string, code?: string);
168
- }
169
- /** Canonical guard text. Rendering wraps every composite node in parentheses, and the parser flattens same-operator chains, so render∘parse is the identity. */
170
- export declare function guardText(node: GuardNode): string;
171
- /**
172
- * The `(notation, view)` cells this module can draw.
173
- *
174
- * PlantUML activity is the cell that does not exist: its activity syntax is a
175
- * structured flowchart language, so a graph with merges or cycles needs a while/if
176
- * reconstruction this module does not perform. Refusing is the honest outcome —
177
- * quietly emitting a state diagram under an "activity" request would mislabel the
178
- * model.
179
- */
180
- export declare function assertUmlView(notation: UmlNotation, diagram: UmlDiagram): void;
181
- /**
182
- * Refuse, before any work, a request whose declared purpose the view cannot serve.
183
- *
184
- * Without an intent this changes nothing: the review still reports `UML019` when the
185
- * fidelity check does not apply to the view it was given. With one, an impossible
186
- * pairing is an error carrying a code, instead of a report about the wrong artifact —
187
- * which is the failure this check exists to prevent.
188
- *
189
- * @param intent - the declared purpose, or `undefined` to leave the behaviour unchanged.
190
- * @param action - which action is about to run.
191
- * @param view - the requested `(notation, diagram)`, for the actions that have one.
192
- */
193
- export declare function checkUmlIntent(intent: UmlIntent | undefined, action: UmlIntentAction, view?: {
194
- notation: UmlNotation;
195
- diagram: UmlDiagram;
196
- }): void;
197
- /**
198
- * Render a LogicModelV1 as UML.
199
- *
200
- * Mermaid covers all three views; PlantUML covers state and sequence (see
201
- * `assertUmlView` for why activity is refused).
202
- *
203
- * @param input - candidate LogicModelV1.
204
- * @param notation - `mermaid` (default) or `plantuml`.
205
- * @param diagram - `state` (default), `activity`, or `sequence`.
206
- * @param maxSteps - cap on the sequence trace length.
207
- * @param intent - what the diagram is for; a view that cannot serve it is refused first.
208
- */
209
- export declare function renderUml(input: unknown, notation?: UmlNotation, diagram?: UmlDiagram, maxSteps?: number, intent?: UmlIntent): UmlRenderResult;
210
- /** Parse a guard expression such as `(retry < 3 && armed == true)`. */
211
- export declare function parseGuardText(text: string): GuardNode;
212
- /** Parse a UML action clause such as `retry := retry + 1, armed := true`. */
213
- export declare function parseUpdatesText(text: string, warnings: string[]): UpdateSpec[];
214
- /**
215
- * Findings a parse result carries on its own. A diagram from another family parses
216
- * into something; without this finding that something is presented as a model of the
217
- * file, which is a false guarantee of exactly the kind this plugin exists to prevent.
218
- */
219
- export declare function parseFindings(parsed: UmlParseResult): UmlFinding[];
220
- /** One accepted way of writing a state's meaning into a diagram label. */
221
- export interface LabelForm {
222
- form: string;
223
- example: string;
224
- note: string;
225
- }
226
- export interface LabelExplanation {
227
- notation: UmlNotation;
228
- /** The comment prefix a `logicprobe:` directive uses in this notation. */
229
- directivePrefix: string;
230
- directiveLines: Array<{
231
- example: string;
232
- meaning: string;
233
- }>;
234
- /** Accepted label spellings, in the order `documentedMeaning` accepts them. */
235
- acceptedLabelForms: LabelForm[];
236
- /** What the renderer itself writes, so a hand-edited diagram can match it. */
237
- renderedForm: string;
238
- ignoredLines: Array<{
239
- pattern: string;
240
- behaviour: string;
241
- }>;
242
- rules: string[];
243
- }
244
- /**
245
- * What the front end expects of labels and comments, so "why does my hand-drawn diagram
246
- * report label drift or ignored lines?" has a printed answer instead of a guess.
247
- * `tests/uml/run.mjs` feeds every claim here back through the parser, so this text cannot
248
- * drift away from the behaviour it describes.
249
- */
250
- export declare function explainLabels(notation?: UmlNotation): LabelExplanation;
251
- /**
252
- * Parse a Mermaid or PlantUML diagram back into a LogicModelV1.
253
- *
254
- * State and activity diagrams carry the whole machine, so they parse into a
255
- * complete model. Sequence diagrams do not: a trace shows the paths that were
256
- * walked, not the branches that were not, so parsing one would silently prune
257
- * the machine. That case is refused rather than approximated.
258
- *
259
- * @param text - diagram source.
260
- * @param notation - `auto` (default) detects Mermaid vs PlantUML from the text.
261
- */
262
- export declare function parseUml(text: string, notation?: UmlNotation | 'auto'): UmlParseResult;
263
- /** Compare two machines by structure — the fidelity measure behind the round-trip check. */
264
- export declare function diffModels(left: LogicModelV1, right: LogicModelV1): string[];
265
- export interface UmlReviewOptions {
266
- /** LogicModelV1 to review. Provide it, `diagram`, or both. */
267
- model?: unknown;
268
- /** Diagram text: reviewed on its own, or compared against `model` when both are given. */
269
- diagram?: string;
270
- notation?: UmlNotation | 'auto';
271
- diagramKind?: UmlDiagram;
272
- /** Render-and-reparse fidelity check (default true; only meaningful with a model). */
273
- roundTrip?: boolean;
274
- /** Cap on the sequence trace used for the fidelity check. */
275
- maxSteps?: number;
276
- /** What the review is for; a view that cannot serve it is refused before any work. */
277
- intent?: UmlIntent;
278
- }
279
- /**
280
- * Review a UML model of a code flow.
281
- *
282
- * Three inputs are possible and each answers a different question:
283
- *
284
- * - `model` only — "is this machine well-modelled?" The review checks the
285
- * structure the diagram would draw, then renders and re-parses it to prove the
286
- * diagram carries the machine faithfully (round trip).
287
- * - `diagram` only — "what does this diagram actually say?" The diagram is parsed
288
- * into a model, and that model is reviewed; nothing can be said about fidelity
289
- * to a machine the caller did not provide.
290
- * - both — "does this diagram match this model?" Any structural difference is a
291
- * modelling defect and is reported both as round-trip diffs and as a finding.
292
- */
293
- export declare function reviewUml(options: UmlReviewOptions): UmlReviewReport;
1
+ /**
2
+ * UML front end for LogicModelV1 — model a code flow as a UML diagram, then
3
+ * review the modelling itself.
4
+ *
5
+ * Two halves, one data flow:
6
+ *
7
+ * 1. `renderUml` turns a validated LogicModelV1 into Mermaid or PlantUML text
8
+ * (state machine, activity/flow, or sequence trace). The diagram is a
9
+ * *view*: it never invents structure the model does not have, and anything
10
+ * the notation cannot express is reported as a warning instead of being
11
+ * dropped silently.
12
+ * 2. `parseUml` reads that text back into a LogicModelV1, and `reviewUml`
13
+ * compares the two. That comparison is the point of the feature: a UML
14
+ * diagram of a code flow is itself a model, and a model can be wrong —
15
+ * ambiguous branches, dead ends, flows nobody can enter, symbols the
16
+ * source never names. A diagram that does not round-trip to the model it
17
+ * was drawn from is mis-modelled, and the review says so.
18
+ *
19
+ * Why the round trip is the fidelity check: rendering and parsing are inverse
20
+ * only if every construct survives the notation. The generated text carries
21
+ * `logicprobe:` directives (ignored by Mermaid/PlantUML renderers) that pin the
22
+ * initial state, the terminal states and any state id the notation cannot spell
23
+ * verbatim, so an exact comparison is possible rather than a fuzzy one.
24
+ *
25
+ * The review deliberately does NOT replace `logicprobe_verify`: it checks the
26
+ * modelling (structure the diagram claims, documentation coverage, notation
27
+ * fidelity), while S1-S8/A1-A14 check the machine's behaviour (guard
28
+ * exhaustiveness under real valuations, invariant paths, deadlock/liveness in
29
+ * the runtime state space). Findings name the engine check to run next.
30
+ *
31
+ * @module logicprobe-uml
32
+ */
33
+ import { type HashSpec, type NarrativeCoverage, type ReportSchema, type Verdict } from './engine.js';
34
+ import type { GuardNode, LogicModelV1, UpdateSpec } from './engine.js';
35
+ export type UmlNotation = 'mermaid' | 'plantuml';
36
+ export type UmlDiagram = 'state' | 'activity' | 'sequence';
37
+ export declare const UML_NOTATIONS: readonly UmlNotation[];
38
+ export declare const UML_DIAGRAMS: readonly UmlDiagram[];
39
+ /**
40
+ * What the caller is going to do with the artifact, declared up front.
41
+ *
42
+ * The view follows the question, not the machine, so the tool cannot pick it. What it
43
+ * can do is refuse a pairing that cannot serve the question — before the work, not as
44
+ * a finding after it.
45
+ */
46
+ export type UmlIntent = 'present' | 'verify' | 'fidelity';
47
+ export declare const UML_INTENTS: readonly UmlIntent[];
48
+ /** The tool actions, for the entry check. `labels` is `action=explain-labels`. */
49
+ export type UmlIntentAction = 'render' | 'parse' | 'review' | 'labels';
50
+ export interface UmlRenderResult {
51
+ notation: UmlNotation;
52
+ diagram: UmlDiagram;
53
+ /** The diagram source; hand this to the user or a renderer as-is. */
54
+ primary: string;
55
+ warnings: string[];
56
+ }
57
+ export interface UmlParseResult {
58
+ notation: UmlNotation;
59
+ diagram: UmlDiagram;
60
+ model: LogicModelV1;
61
+ /**
62
+ * Display labels found in the diagram, keyed by state id. They are how a
63
+ * reader learns what a symbol means; a missing entry is an undocumented
64
+ * symbol, which the review reports.
65
+ */
66
+ labels: Record<string, string>;
67
+ /**
68
+ * Declarations found in the text that LogicModelV1 cannot represent. A non-empty
69
+ * list means the parsed model is NOT this diagram: the text belongs to another
70
+ * diagram family (component, package, class, deployment, …), so whatever came
71
+ * out is a by-product of reading keywords the parser does not own.
72
+ */
73
+ discardedConstructs: DiscardedConstruct[];
74
+ /**
75
+ * Arrows whose endpoints were declared by a discarded construct. They survive
76
+ * parsing as state transitions, which is exactly why they are counted out loud.
77
+ */
78
+ discardedEdges: number;
79
+ warnings: string[];
80
+ }
81
+ /** One declaration the parser could not represent, with the source line that carried it. */
82
+ export interface DiscardedConstruct {
83
+ /** The construct keyword, lower-cased (`component`, `package`, `classDiagram`). */
84
+ construct: string;
85
+ /** 1-based line number in the diagram source. */
86
+ line: number;
87
+ /** The source line, trimmed. */
88
+ text: string;
89
+ }
90
+ export interface UmlFinding {
91
+ code: string;
92
+ severity: 'error' | 'warning' | 'info';
93
+ message: string;
94
+ states?: string[];
95
+ events?: string[];
96
+ transitions?: Array<{
97
+ from: string;
98
+ event: string;
99
+ to: string;
100
+ }>;
101
+ detail?: string;
102
+ /** Machine-readable context for the finding (ids, coverage, rule matches), same shape as the engine's findings. */
103
+ evidence?: Record<string, unknown>;
104
+ }
105
+ export interface UmlRoundTripReport {
106
+ notation: UmlNotation;
107
+ diagram: UmlDiagram;
108
+ ok: boolean;
109
+ /** Which published hash specification the two hashes follow (see references/hash-spec.md). */
110
+ hashSpec: HashSpec;
111
+ modelHash: string;
112
+ parsedHash: string;
113
+ diffs: string[];
114
+ warnings: string[];
115
+ }
116
+ export interface UmlReviewReport {
117
+ /** The review ran and produced this report. It does NOT mean the modelling passed — read `verdict`. */
118
+ ok: boolean;
119
+ ran: boolean;
120
+ verdict: Verdict;
121
+ verdictReason: string;
122
+ /** The versioned report contract this result follows. */
123
+ schema: ReportSchema;
124
+ source: 'model' | 'diagram' | 'model+diagram';
125
+ summary: {
126
+ errors: number;
127
+ warnings: number;
128
+ info: number;
129
+ states: number;
130
+ events: number;
131
+ transitions: number;
132
+ terminalStates: number;
133
+ reachableStates: number;
134
+ documentedStates: number;
135
+ };
136
+ findings: UmlFinding[];
137
+ roundTrip: UmlRoundTripReport | null;
138
+ /** Diagram display labels, when a diagram took part in the review. */
139
+ labels?: Record<string, string>;
140
+ /** Model parsed from the diagram, when a diagram was given (feed it to `logicprobe_verify`). */
141
+ model?: LogicModelV1;
142
+ /** Diagram rendered from the model, when only a model was given. */
143
+ primary?: string;
144
+ /** Paths of the `_`-prefixed metadata keys found in the supplied model, when it carried any. */
145
+ metadataKeys?: string[];
146
+ /** How much of the model the narrative documents; absent when there is no narrative. */
147
+ narrativeCoverage?: NarrativeCoverage;
148
+ /** Hashes of what was reviewed, in one place. */
149
+ hashes: {
150
+ hashSpec: HashSpec;
151
+ modelHash?: string;
152
+ parsedHash?: string;
153
+ };
154
+ /** Declarations the parser could not represent; a non-empty list fails the review. */
155
+ discardedConstructs?: DiscardedConstruct[];
156
+ /** Arrows whose endpoints came from a discarded construct. */
157
+ discardedEdges?: number;
158
+ warnings: string[];
159
+ nextSteps: string[];
160
+ }
161
+ /**
162
+ * A UML front-end refusal. `code` lets the tool report *why* it refused instead of
163
+ * collapsing every refusal into a generic input error.
164
+ */
165
+ export declare class UmlError extends Error {
166
+ readonly code: string;
167
+ constructor(message: string, code?: string);
168
+ }
169
+ /** Canonical guard text. Rendering wraps every composite node in parentheses, and the parser flattens same-operator chains, so render∘parse is the identity. */
170
+ export declare function guardText(node: GuardNode): string;
171
+ /**
172
+ * The `(notation, view)` cells this module can draw.
173
+ *
174
+ * PlantUML activity is the cell that does not exist: its activity syntax is a
175
+ * structured flowchart language, so a graph with merges or cycles needs a while/if
176
+ * reconstruction this module does not perform. Refusing is the honest outcome —
177
+ * quietly emitting a state diagram under an "activity" request would mislabel the
178
+ * model.
179
+ */
180
+ export declare function assertUmlView(notation: UmlNotation, diagram: UmlDiagram): void;
181
+ /**
182
+ * Refuse, before any work, a request whose declared purpose the view cannot serve.
183
+ *
184
+ * Without an intent this changes nothing: the review still reports `UML019` when the
185
+ * fidelity check does not apply to the view it was given. With one, an impossible
186
+ * pairing is an error carrying a code, instead of a report about the wrong artifact —
187
+ * which is the failure this check exists to prevent.
188
+ *
189
+ * @param intent - the declared purpose, or `undefined` to leave the behaviour unchanged.
190
+ * @param action - which action is about to run.
191
+ * @param view - the requested `(notation, diagram)`, for the actions that have one.
192
+ */
193
+ export declare function checkUmlIntent(intent: UmlIntent | undefined, action: UmlIntentAction, view?: {
194
+ notation: UmlNotation;
195
+ diagram: UmlDiagram;
196
+ }): void;
197
+ /**
198
+ * Render a LogicModelV1 as UML.
199
+ *
200
+ * Mermaid covers all three views; PlantUML covers state and sequence (see
201
+ * `assertUmlView` for why activity is refused).
202
+ *
203
+ * @param input - candidate LogicModelV1.
204
+ * @param notation - `mermaid` (default) or `plantuml`.
205
+ * @param diagram - `state` (default), `activity`, or `sequence`.
206
+ * @param maxSteps - cap on the sequence trace length.
207
+ * @param intent - what the diagram is for; a view that cannot serve it is refused first.
208
+ */
209
+ export declare function renderUml(input: unknown, notation?: UmlNotation, diagram?: UmlDiagram, maxSteps?: number, intent?: UmlIntent): UmlRenderResult;
210
+ /** Parse a guard expression such as `(retry < 3 && armed == true)`. */
211
+ export declare function parseGuardText(text: string): GuardNode;
212
+ /** Parse a UML action clause such as `retry := retry + 1, armed := true`. */
213
+ export declare function parseUpdatesText(text: string, warnings: string[]): UpdateSpec[];
214
+ /**
215
+ * Findings a parse result carries on its own. A diagram from another family parses
216
+ * into something; without this finding that something is presented as a model of the
217
+ * file, which is a false guarantee of exactly the kind this plugin exists to prevent.
218
+ */
219
+ export declare function parseFindings(parsed: UmlParseResult): UmlFinding[];
220
+ /** One accepted way of writing a state's meaning into a diagram label. */
221
+ export interface LabelForm {
222
+ form: string;
223
+ example: string;
224
+ note: string;
225
+ }
226
+ export interface LabelExplanation {
227
+ notation: UmlNotation;
228
+ /** The comment prefix a `logicprobe:` directive uses in this notation. */
229
+ directivePrefix: string;
230
+ directiveLines: Array<{
231
+ example: string;
232
+ meaning: string;
233
+ }>;
234
+ /** Accepted label spellings, in the order `documentedMeaning` accepts them. */
235
+ acceptedLabelForms: LabelForm[];
236
+ /** What the renderer itself writes, so a hand-edited diagram can match it. */
237
+ renderedForm: string;
238
+ ignoredLines: Array<{
239
+ pattern: string;
240
+ behaviour: string;
241
+ }>;
242
+ rules: string[];
243
+ }
244
+ /**
245
+ * What the front end expects of labels and comments, so "why does my hand-drawn diagram
246
+ * report label drift or ignored lines?" has a printed answer instead of a guess.
247
+ * `tests/uml/run.mjs` feeds every claim here back through the parser, so this text cannot
248
+ * drift away from the behaviour it describes.
249
+ */
250
+ export declare function explainLabels(notation?: UmlNotation): LabelExplanation;
251
+ /**
252
+ * Parse a Mermaid or PlantUML diagram back into a LogicModelV1.
253
+ *
254
+ * State and activity diagrams carry the whole machine, so they parse into a
255
+ * complete model. Sequence diagrams do not: a trace shows the paths that were
256
+ * walked, not the branches that were not, so parsing one would silently prune
257
+ * the machine. That case is refused rather than approximated.
258
+ *
259
+ * @param text - diagram source.
260
+ * @param notation - `auto` (default) detects Mermaid vs PlantUML from the text.
261
+ */
262
+ export declare function parseUml(text: string, notation?: UmlNotation | 'auto'): UmlParseResult;
263
+ /** Compare two machines by structure — the fidelity measure behind the round-trip check. */
264
+ export declare function diffModels(left: LogicModelV1, right: LogicModelV1): string[];
265
+ export interface UmlReviewOptions {
266
+ /** LogicModelV1 to review. Provide it, `diagram`, or both. */
267
+ model?: unknown;
268
+ /** Diagram text: reviewed on its own, or compared against `model` when both are given. */
269
+ diagram?: string;
270
+ notation?: UmlNotation | 'auto';
271
+ diagramKind?: UmlDiagram;
272
+ /** Render-and-reparse fidelity check (default true; only meaningful with a model). */
273
+ roundTrip?: boolean;
274
+ /** Cap on the sequence trace used for the fidelity check. */
275
+ maxSteps?: number;
276
+ /** What the review is for; a view that cannot serve it is refused before any work. */
277
+ intent?: UmlIntent;
278
+ }
279
+ /**
280
+ * Review a UML model of a code flow.
281
+ *
282
+ * Three inputs are possible and each answers a different question:
283
+ *
284
+ * - `model` only — "is this machine well-modelled?" The review checks the
285
+ * structure the diagram would draw, then renders and re-parses it to prove the
286
+ * diagram carries the machine faithfully (round trip).
287
+ * - `diagram` only — "what does this diagram actually say?" The diagram is parsed
288
+ * into a model, and that model is reviewed; nothing can be said about fidelity
289
+ * to a machine the caller did not provide.
290
+ * - both — "does this diagram match this model?" Any structural difference is a
291
+ * modelling defect and is reported both as round-trip diffs and as a finding.
292
+ */
293
+ export declare function reviewUml(options: UmlReviewOptions): UmlReviewReport;