dsh-model-everything 0.4.1 → 0.5.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.
Files changed (78) hide show
  1. package/README.en-US.md +63 -19
  2. package/README.md +373 -345
  3. package/cordis.patch.yml +9 -0
  4. package/diagram/package.json +5 -0
  5. package/lib/client.js +1273 -0
  6. package/lib/diagram-diff-tool.js +90 -0
  7. package/lib/diagram-render-tool.js +102 -0
  8. package/lib/diagram-review-tool.js +99 -0
  9. package/lib/diagram.js +43 -0
  10. package/lib/gate.js +14 -12
  11. package/lib/presentation.js +10 -0
  12. package/lib/render/budget.js +99 -0
  13. package/lib/render/collapse.js +163 -0
  14. package/lib/render/diff.js +138 -0
  15. package/lib/render/from-mermaid.js +211 -0
  16. package/lib/render/from-plantuml.js +158 -0
  17. package/lib/render/index.js +42 -0
  18. package/lib/render/layout.js +52 -0
  19. package/lib/render/model.js +17 -0
  20. package/lib/render/paint.js +194 -0
  21. package/lib/render/palette.js +127 -0
  22. package/lib/render/place.js +210 -0
  23. package/lib/render/svg.js +107 -0
  24. package/lib/render/viewmodel.js +126 -0
  25. package/lib/render/write.js +14 -0
  26. package/lib/scan.js +248 -8
  27. package/lib/structure-tool.js +2 -2
  28. package/lib/types/client.d.ts +83 -0
  29. package/lib/types/diagram-diff-tool.d.ts +8 -0
  30. package/lib/types/diagram-render-tool.d.ts +8 -0
  31. package/lib/types/diagram-review-tool.d.ts +8 -0
  32. package/lib/types/diagram.d.ts +34 -0
  33. package/lib/types/presentation.d.ts +7 -0
  34. package/lib/types/render/budget.d.ts +55 -0
  35. package/lib/types/render/collapse.d.ts +23 -0
  36. package/lib/types/render/diff.d.ts +44 -0
  37. package/lib/types/render/from-mermaid.d.ts +27 -0
  38. package/lib/types/render/from-plantuml.d.ts +27 -0
  39. package/lib/types/render/index.d.ts +38 -0
  40. package/lib/types/render/layout.d.ts +22 -0
  41. package/lib/types/render/model.d.ts +56 -0
  42. package/lib/types/render/paint.d.ts +94 -0
  43. package/lib/types/render/palette.d.ts +41 -0
  44. package/lib/types/render/place.d.ts +39 -0
  45. package/lib/types/render/svg.d.ts +19 -0
  46. package/lib/types/render/viewmodel.d.ts +20 -0
  47. package/lib/types/render/write.d.ts +14 -0
  48. package/lib/types/scan.d.ts +10 -2
  49. package/lib/types/structure.d.ts +1 -0
  50. package/package.json +35 -19
  51. package/skills/model-everything/SKILL.md +454 -454
  52. package/skills/model-everything/references/architecture-domains.md +137 -0
  53. package/skills/model-everything/references/architecture-views.md +119 -0
  54. package/skills/model-everything-diagram/SKILL.md +82 -0
  55. package/src/client.ts +307 -0
  56. package/src/diagram-diff-tool.ts +94 -0
  57. package/src/diagram-render-tool.ts +108 -0
  58. package/src/diagram-review-tool.ts +109 -0
  59. package/src/diagram.ts +61 -0
  60. package/src/gate.ts +14 -12
  61. package/src/presentation.ts +12 -0
  62. package/src/render/budget.ts +135 -0
  63. package/src/render/collapse.ts +155 -0
  64. package/src/render/diff.ts +162 -0
  65. package/src/render/from-mermaid.ts +236 -0
  66. package/src/render/from-plantuml.ts +178 -0
  67. package/src/render/index.ts +73 -0
  68. package/src/render/layout.ts +62 -0
  69. package/src/render/model.ts +67 -0
  70. package/src/render/paint.ts +290 -0
  71. package/src/render/palette.ts +164 -0
  72. package/src/render/place.ts +234 -0
  73. package/src/render/svg.ts +127 -0
  74. package/src/render/viewmodel.ts +136 -0
  75. package/src/render/write.ts +17 -0
  76. package/src/scan.ts +807 -564
  77. package/src/structure-tool.ts +2 -2
  78. package/src/structure.ts +1 -1
@@ -1,454 +1,454 @@
1
- ---
2
- name: model-everything
3
- description: "Use when a document claims something checkable about code: API names, paths, enums, feasibility, protocol behaviour, timing, 'always/never'. It enumerates the claims, verifies each against the code with file:line evidence, then builds an executable model when behaviour, safety or deadlock is at stake. Diagrams: model-everything-uml; design principles: model-everything-design; concurrency: model-everything-interleaving; data: model-everything-datamodel; dependencies: model-everything-structure."
4
- ---
5
-
6
- # Model Everything
7
-
8
- For an unverified design, failure is only a matter of time. Complex code becomes clear once you model it and run it. Check every claim before you act on it.
9
-
10
- ## When This Skill Applies
11
-
12
- **This is the entry point.** Load this skill when a claim about the code has to be settled and a reading will not settle it. It owns the doctrine: enumerate the claims, verify each against the code, cite `file:line`, read `verdict`. It also owns the executable verification for behaviour. A neighbouring domain goes to its own skill through the routing table below.
13
-
14
- **It decides small models, not programs.** The engine enumerates states, so a model that explodes is reported `truncated` with the undecided check named. That is not a bug to retry with a larger `maxStates`: reduce the model first (drop variables the property does not read, collapse symmetric states), and if it still explodes the property needs a tool that does not enumerate - SPIN for partial-order reduction, NuSMV for symbolic search, CBMC for bounded SAT. This plugin builds no abstraction and reads no program source.
15
-
16
- **This costs more than reading, and less the larger the task.** On a fixture of a few hundred lines it costs several times a plain reading, because the fixed cost has nothing to amortise against. On a tree of tens of thousands of lines the ratio falls to roughly parity. Spend it where the object is large enough for one decision to replace many reads. Reach for it when the claim is about all paths rather than one, when nothing in the repository will go red if it is false, or when the verdict has to be reproducible later. A claim one reading settles belongs in a sentence, not in a model.
17
-
18
- | The task involves… | What it does |
19
- |---|---|
20
- | Any claim about code: design doc, spec, plan, review comment, README, commit message, refactor proposal, "this is safe", "this always holds", "this can't deadlock" | Enumerate the verifiable claims (Phase 1), verify each with `file:line` evidence (Phase 2), classify the gaps (Phase 3) |
21
- | A state machine or protocol with three or more states, guards, ACK/NACK/retry, lock/unlock, or start/stop ordering | Build an executable model. Run the S1-S8 structural checks and the A1-A14 adversarial probes |
22
- | A quantitative or temporal guarantee: worst-case cost within a budget, "90% of runs reach SAFE", "must leave within 2 ticks" | A12 budget, A13 probabilistic reachability, A14 deadlines. Each returns a counterexample path |
23
- | A handshake or power-up sequence across two or more components | `model_compose_verify`: C1 composition deadlock, C2 rendezvous that never fires |
24
- | A refactoring that changes state topology or guards | Compare BEFORE and AFTER models for behaviour preservation, invariant continuity and deadlock regression (D1-D4) |
25
- | An explicit request to prove code correct, verify a module, or check a migration for breakage | Route by domain through [Routing to the Sibling Skills](#routing-to-the-sibling-skills). Keep the doctrine |
26
- | An architecture or dependency question about a component, package or class diagram | `model-everything-structure`: parse it into a dependency graph, judge every edge against the dependency matrix |
27
- | Whether a design keeps its own declarations: layering, a responsibility boundary, an interface wider than its callers, a subtype that cannot replace its base | `model-everything-design`: `model_design_review` decides the declared contracts (`DES1`-`DES11`) and reports the graph's shape |
28
-
29
- **Catalog budget**: DSH renders only the frontmatter `description` and truncates it at 500 characters. Every description here fits. Triggers that do not fit live in this table.
30
-
31
- ## Verification Depth (Plan-Mode Gate)
32
-
33
- When loaded as a plan-mode verification gate, this skill's execution is **mandatory**. The model has no discretion to bypass it. Depth classification is gated on objective plan features extracted in Phase 0.
34
-
35
- ### Phase 0: Feature Extraction (Mandatory)
36
-
37
- Before any verification, output the plan's feature summary to context:
38
-
39
- ```text
40
- Plan features:
41
- Files: [N]
42
- Functions added/modified: [list or "none"]
43
- Behavioral claims: [none / "invariants listed" / "always/never/guaranteed assertions"]
44
- State machine changes: [none / describe topology delta]
45
- → Depth: LIGHTWEIGHT | STANDARD | ESCALATED
46
- ```
47
-
48
- This step is NOT skippable — it creates an explicit, auditable record of what the plan claims before verification begins.
49
-
50
- ### Depth Classification
51
-
52
- | Plan Feature | Depth |
53
- |-------------|-------|
54
- | Single file, zero function signatures added/modified, no behavioral claims of any kind | LIGHTWEIGHT |
55
- | Multi-file, OR new/modified function signatures, OR implicit behavioral claims (invariants, equivalence assertions, "behavior is unchanged") | STANDARD |
56
- | "Always"/"never"/"guaranteed" language, OR state machine topology changes (≥1 state or ≥2 transitions modified) | ESCALATED |
57
-
58
- **"No behavioral claims" is narrow**: if the plan asserts anything about behavior preservation — including listing invariants, claiming equivalence, or saying "refactoring only, no behavior change" — that IS a behavioral claim. The absence of the literal words "always"/"never" does NOT mean there are no behavioral claims.
59
-
60
- ### Output Requirements
61
-
62
- | Depth | Required |
63
- |-------|----------|
64
- | LIGHTWEIGHT | All 5 checklist items (file paths, API/type names, line numbers, behavioral claims, mechanism feasibility) answered in context with explicit results per item |
65
- | STANDARD | Phase 1-2: enumerate every verifiable claim → verify each against codebase with evidence |
66
- | ESCALATED | Full pipeline: Phase 1-5 including Logic Primitive Verification (Phase 2a structural, Phase 2b adversarial) |
67
-
68
- ### Plan Verification Block
69
-
70
- After verification, append a summary to the plan file:
71
-
72
- ```markdown
73
- ## Plan Verification
74
-
75
- - **Depth**: [LIGHTWEIGHT / STANDARD / ESCALATED]
76
- - **Scope**: [N] file paths, [M] API/type names, [K] line citations confirmed
77
- - **Escalation**: [skipped — no behavioral claims detected] or [see transcript for N-check results]
78
- ```
79
-
80
- This block is the audit trail. A future reviewer must be able to see what was verified and when.
81
- </HARD-GATE>
82
-
83
- ## Methodology
84
-
85
- ### Phase 1: Enumerate Claims
86
-
87
- Read the document fully. Extract every claim that is verifiable:
88
-
89
- - Numeric claims (counts, sizes, frequencies)
90
- - API/type/enum names
91
- - File paths and line numbers
92
- - Mechanism descriptions ("compile-time resolution", "static dispatch")
93
-
94
- ### Phase 2: Verify Against Codebase
95
-
96
- For each claim, run the relevant verification:
97
-
98
- - **Numeric claims**: `grep -c` or `grep -rn` to get the real count
99
- - **API/type names**: extract actual signatures from headers
100
- - **Enum/constant values**: list actual values from BSP/config headers
101
- - **Mechanism feasibility**: check language standard and compiler support
102
-
103
- ### Phase 2 Trigger: Escalate to Logic Primitive?
104
-
105
- If the document under review contains ANY of the following, escalate to [Logic Primitive Verification](#logic-primitive-verification) IMMEDIATELY:
106
-
107
- - State machine or statechart with ≥3 states OR with guard conditions on transitions
108
- - Protocol handshake, ACK/NACK, retry, or timeout sequence logic
109
- - Claims using absolute language: "always", "never", "guaranteed", "all paths", "cannot", "impossible"
110
- - Lock/unlock, alloc/free, start/stop paired operations where ordering matters
111
- - Any logic where correctness depends on transition completeness or event ordering
112
- - **Refactoring that modifies state topology**: splitting/merging states, adding/removing transitions, changing guard conditions, extracting sub-machines
113
-
114
- **Heuristic**: If the transition-to-state ratio > 1.5 or any transition has a guard condition, the machine is complex enough to warrant verification — regardless of state count. For refactoring, trigger if the refactoring changes ≥1 state or ≥2 transitions from the original model.
115
-
116
- ### Phase 3: Gap Analysis
117
-
118
- Classify findings by severity:
119
-
120
- 1. **Architecture-level**: claims that make the design unimplementable (fake APIs, missing modules)
121
- 2. **Mechanism-level**: claims the language/compiler cannot fulfill
122
- 3. **Consistency-level**: internal contradictions across documents
123
-
124
- ### Phase 4: Root Cause
125
-
126
- For each error, identify why it happened:
127
-
128
- - Wrong mental model (C++ constexpr thinking in C99)?
129
- - Incomplete search scope?
130
- - Copy-paste from other projects without verification?
131
- - Misunderstanding of compiler/linker behavior?
132
-
133
- ### Phase 5: Structured Output
134
-
135
- Each finding includes:
136
-
137
- - Exact location (file:line or section)
138
- - What the document claims
139
- - What the codebase actually contains (with evidence — grep output, line numbers)
140
- - Correction direction
141
-
142
- ---
143
-
144
- ## Logic Primitive Verification
145
-
146
- When Phase 2 triggers escalation, do NOT proceed to Phase 3 until the verification pipeline below is complete. Trust models, not intuition.
147
-
148
- ### Pipeline Overview
149
-
150
- ```text
151
- Document claims → Extract model → Runtime check:
152
- ├── DSH + `model_verify` tool available → build Model schema v1 (references/dsh-model-schema.md) → call the tool → structured report
153
- └── No engine available → Manual Verification Mode (see references/logic-verification-guide.md#manual-verification-mode)
154
-
155
- Refactoring variant:
156
- Old code + Refactoring plan → Extract BEFORE model + AFTER model
157
- → Run the pipeline on the AFTER model (the same checks)
158
- → Compare BEFORE vs AFTER: behavioral preservation, regression, complexity delta
159
- → Flag any invariant that held in BEFORE but fails in AFTER
160
-
161
- UML modelling variant (the task is to draw a flow, not to check a claim):
162
- Code flow → model with a citation per element → uml_render → diagram
163
- → uml_review → modelling findings + render/parse round-trip fidelity
164
- → model_verify → the behavioural checks (S1-S8 / A1-A14)
165
- ```
166
-
167
- ### Budgeting the Model Before You Run It
168
-
169
- Search cost is the declared domain times the number of states — and a declared range is
170
- not a bound on the search.
171
-
172
- - **`inc`/`dec` are never clamped to `min`/`max`.** The declaration is a property the
173
- checks verify, not a limit the engine enforces. A counter whose guard does not pin it
174
- ranges past its own declaration, so the reachable set is unbounded however small the
175
- declared range looks; S8 reports that as `S8_DOMAIN_NOT_ENFORCED`.
176
- - **Bound a counter with a guard, not a narrower declaration.** `max: 4` with a guard
177
- `retry < 4` closes the loop. `max: 4` alone does not.
178
- - **Say the budget before running**: values per variable x states. A product in the
179
- 10^5-and-up range will hit the cap and come back undecided.
180
- - **Model the check where the code performs it.** A cap check that lives inside the tick
181
- handler is a guarded branch of the tick event, not a separate event: as a separate event
182
- the environment can starve it, and the leads-to failure you then read is an artefact of
183
- the model rather than a property of the code.
184
-
185
- ### Native dsh Tools
186
-
187
- The tools are `model_verify`, `model_edit`, `model_compose_verify`, `model_datamodel_verify`, `model_design_review`, `model_interleaving_scan`, `model_export`, `report_diff`, `uml_render`, `uml_parse`, `uml_review`, `uml_explain_labels`, `uml_structure_verify` and `model_automaton_verify`. `model_automaton_verify` decides a finite-word language and its relation to another automaton, returning the shortest word that separates them; `references/automata.md` states what each of its checks decides, on what authority, and where it stops. `model_edit` changes a model file by naming the change and returns the structural diff plus the difference in findings, so a fix round costs one call instead of three. `uml_structure_verify` builds its graph from a source tree when given `repoPath`, reading each language's own import construct, so a dependency question about code does not start with drawing. Each tool's description states what it decides and what it does not. Read the description before calling it, and read the report's `verdict` afterwards.
188
-
189
- A model is the largest argument these tools take. When it is long, or you have edited it more than once, write it to a file and pass `modelPath` instead of inlining it: a streamed argument that long is where invalid JSON comes from, and the file accepts any formatting.
190
-
191
- These tools carry every capability this plugin claims. Anything outside them is out of scope, and the skills name where that claim is answered instead.
192
-
193
- ### Reading a Report: `ok` Is Not a Verdict
194
-
195
- **`ok` records that a report was produced. `verdict` records how the review went.** A report can carry `ok: true` and still be a failed review. Gate on `verdict`.
196
-
197
- - `pass`: no error and no warning. Report the result as verified, together with the scope the model covered.
198
- - `pass_with_findings`: verification ran clean and warnings exist. Report the pass and the warnings. Do not restate it as "no issues".
199
- - `fail`: an error finding exists, or the engine rejected the input (`MODEL_INVALID`). State that the claim is not verified, quote the counterexample path, then propose a correction. Do not describe a `fail` as a successful run.
200
-
201
- `summary.truncated: true` and any code ending in `_UNDECIDED` both mean the search stopped before deciding. Name the invariant that went undecided and report the property as undecided.
202
-
203
- A tool prints a readable body. Passing checks stay in the `CHECKS` inventory line, and a fact that several checks report appears once. Only error findings inline their evidence. When the body truncates a check, pass `check: "<id>"` to print that check in full. `reportView: "full"` returns the whole report as compact JSON. Use it only to hand the report to `report_diff`; it costs the most tokens of any request you can make.
204
-
205
- ### Writing the Answer: Name the Finding, Not Its Code
206
-
207
- `S2_NO_TRANSITIONS`, `UML019`, `DA2` are values of `findings[].code`, not names. A reader
208
- who has not memorized the schema learns nothing from one, and cannot tell whether their
209
- machine is sound or stuck.
210
-
211
- - **Say what it means**, in the user's language and in the terms of their own code:
212
- 「启动超时后 ERROR 没有任何出口迁移,机器会停在那里」, not 「S2 命中」. The finding's
213
- `message` is written for the report; the sentence for the user is written from it.
214
- - **Keep the identifier where the identifier is the subject**: a report field quoted
215
- verbatim, a baseline diff, a test name, or a question about the check itself.
216
- - **Name the property, not the checking.** "This path locks without unlocking" beats
217
- "A4 failed". A check's name earns its place when the reader asked about the checking.
218
- - **Carry the verdict in words.** "Not verified" or "verified, within the scope of this
219
- model" — never a bare pass, and never a warning presented without its label.
220
-
221
- A reader who cannot tell what failed will either trust a report they cannot read, or
222
- ignore one they should act on.
223
-
224
- ### Slice Acceptance: Baseline Diffs
225
-
226
- The acceptance criterion for a refactoring slice is usually "no **new** findings", not
227
- "zero findings". Do not compare two JSON reports by eye — run the comparison:
228
-
229
- - DSH: `report_diff { baseline: <earlier report>, current: <new report> }`
230
- - Any host without the tools: run the repository engine against the same JSON.
231
- (also available on `compose`, `structure` and `uml-review`)
232
-
233
- A finding's identity is its **check id + code + canonical locator** (built from
234
- `evidence`/`path`; the message only when a finding carries neither), so a reworded
235
- message reads as `changed`, never as a new finding. The diff's `verdict` describes the
236
- **delta** — a newly added error finding fails it — while `currentVerdict` keeps the
237
- absolute result visible, and a clean delta over a still-failing report says so in
238
- `nextSteps` rather than passing quietly. Two runs over the same input add zero findings:
239
- run that self-check before trusting any baseline.
240
-
241
- ### Archiving a Model: `_`-Prefixed Metadata
242
-
243
- Keep provenance with the model instead of in a sidecar that drifts:
244
-
245
- - Any key starting with `_` at any level (`_source`, `_verified`, `_uml`, `_extraction_caveats`, `states[0]._note`) is **annotation metadata**: the schema ignores it, `modelHash` excludes it, and the report echoes it as `metadataKeys`.
246
- - Everything else stays closed — a mistyped `sttes` is still a validation error, and that is deliberate.
247
- - Because the hash ignores `_` keys, "the model as archived" and "the model with metadata stripped" hash identically; record the reported `hashSpec` next to the hash so a later reader can reproduce it (`verify model.json --hash-check <hex>` answers whether a recorded hash belongs to a published spec at all).
248
-
249
- ### Refactoring Verification Mode
250
-
251
- When the document under review is a refactoring plan (modifying existing state machine logic, not designing from scratch), adapt the pipeline:
252
-
253
- 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)
254
- 2. **Extract the AFTER model** from the refactoring plan
255
- 3. **Show both tables AND their model narratives** to the user side by side and confirm the delta is intentional
256
- 4. **Run Phase 2a + 2b on the AFTER model** — the same checks a new design gets
257
- 5. **Compare BEFORE vs AFTER**:
258
-
259
- | Check | Method | Severity if Violated |
260
- |-------|--------|:---:|
261
- | Behavioral preservation | Every event sequence accepted by BEFORE must also be accepted by AFTER (or explicitly removed per plan) | Error — regression |
262
- | Invariant continuity | Any invariant that held in BEFORE must hold in AFTER (unless the refactoring explicitly changes it) | Error — undocumented behavior change |
263
- | Deadlock regression | New states or transitions must not introduce deadlocks not present in BEFORE | Error |
264
- | Complexity claim | If plan claims "simpler": count states + transitions + guards. Is AFTER objectively simpler? | Warning — unsubstantiated claim |
265
- | Unreachable code | New states added in AFTER must be reachable (otherwise they're dead code from the start) | Warning |
266
-
267
- In DSH, pass `beforeModel` and optional `stateMapping` to `model_verify`; the engine runs D1 Behavioral Preservation, D2 Invariant Continuity, D3 Regression Delta, and D4 Deadlock/Liveness Regression automatically.
268
-
269
- 6. **Flag any behavioral delta not documented in the plan** — the most common refactoring bug is an unintended side effect that the plan doesn't acknowledge
270
-
271
- Run the checks with the native `model_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`.
272
-
273
- ### Phase 2a: Structural Primitives
274
-
275
- Run these FIRST. They establish basic well-formedness before adversarial probing.
276
-
277
- | # | Primitive | Method | Severity if Violated |
278
- |:--:|-----------|--------|:---:|
279
- | S1 | **Reachability** | BFS from init state; flag all states not in visited set | Warning — dead code |
280
- | S2 | **Deadlock** | Any non-terminal state with zero outgoing transitions? | Error — machine can get stuck |
281
- | S3 | **Liveness** | Does the transition graph contain an absorbing cycle that excludes expected terminal/recovery states? (e.g. ERROR→RECOVERING→ERROR→... with no exit) | Error — infinite loop |
282
- | S4 | **Determinism** | Same state + same event → multiple different targets? | Error — ambiguous behavior |
283
- | S5 | **Event completeness** | For each state, are there plausible events with no defined transition? | Warning — implicit ignore |
284
- | S6 | **Guard completeness** | For each transition with a guard condition, are ALL branch outcomes defined? `if (cnt<3) RETRY else FATAL` → both paths must exist in model | Error — undefined behavior path |
285
- | S7 | **Invariant validity** | Does every reachable state satisfy the plan's stated "always/never/guaranteed" assertions? | Error — plan claim is false |
286
- | S8 | **Monotonic variables** | If a variable is declared `monotonic: inc/dec`, do all updates respect that direction? | Error — counter can move backwards |
287
-
288
- ### Phase 2b: Adversarial Probes
289
-
290
- Run these second. Each probe tries to break the model, and a probe that finds a violation proves a behaviour gap.
291
-
292
- | # | Attack | Method | Claim it refutes |
293
- |:--:|--------|--------|-------------|
294
- | A1 | **Unexpected event** | Inject every event E into every state S that has no transition for (S, E). Record whether the model ignores it or crashes. | "All events are handled in all states" |
295
- | A2 | **Race interleaving** | Deliver every pair of concurrent events in both orders. Report a differing terminal state. | "Behaviour is independent of ordering" |
296
- | A3 | **Order permutation** | Permute N independent events. Report differing final states or broken invariants. | "Outcome is order-independent" |
297
- | A4 | **Pair symmetry** | Match every `start/stop`, `lock/unlock`, `alloc/free` pair. Report a path where a pair is unbalanced. `onEntry` and `onExit` count as acquire and release. | "Resources are always released" |
298
- | A5 | **Boundary blast** | Probe counters at 0, 1, max-1, max and max+1, and timestamps at 0 and wraparound. Report overflow, underflow or undefined behaviour. | "Handles all counter and timer values" |
299
- | A6 | **Resource injection** | Simulate `malloc` returning NULL, a full queue and a semaphore timeout at each state that calls them. Report a state with no recovery path. | "Degrades gracefully under resource pressure" |
300
- | A7 | **Counter-example witness** | For a failing invariant, emit the exact violating sequence. The breadth-first searches (state, sequence, atomicity, budget) return the shortest witness. Leads-to and probability return the witness they found without claiming minimality. | "This invariant holds" |
301
- | A8 | **Idempotent replay** | Apply each `idempotentEvents` entry twice from every reachable state. Report a second application that changes state. | "This event is safe to replay" |
302
- | A9 | **Leads-to** | From a declared source state, every path must reach the target state or a member of the declared target set. | "Always progresses to completion" |
303
- | A10 | **Sequence order** | Declared events must occur in the declared order. | "backup before modify before commit" |
304
- | A11 | **Atomicity** | An atomic event must commit or roll back before the scope is left or the machine terminates. | "all-or-nothing" |
305
- | A12 | **Budget** | With `cost` per transition (absent means 1) and a `budget` invariant, every reachable path must stay within budget. The probe returns the shortest over-budget path and reports reachable positive-cost cycles as unbounded. | "Worst case fits the budget" |
306
- | A13 | **Probability reachability** | With `weight` per transition (absent means 1) and a `probability` invariant, P(ever hitting the target) must meet the bound, by value iteration over the absorbing chain. | "90% of runs reach SAFE" |
307
- | A14 | **Deadline** | State `maxTicks` plus top-level `tickEvents`. A tick step must not keep a state resident past its deadline. The probe returns the over-residency path. | "Must leave within 2 ticks" |
308
-
309
- ### Integration Back to Phase 3
310
-
311
- For every probe failure:
312
-
313
- 1. **Quote** the plan claim verbatim
314
- 2. **Show** the counter-example event sequence
315
- 3. **Classify** severity (Architecture / Mechanism / Consistency)
316
- 4. **Propose** correction direction — never fix inline
317
-
318
- ### Extraction Rule
319
-
320
- Before writing any verification code, output the model in one of the rendering
321
- forms below. Default is Form A; switch forms when the machine is large or the
322
- display area is narrow — never let a table row wrap.
323
-
324
- **Form A — integrated transition table (default)**: formal symbols with their
325
- natural-language meaning inlined; the scenario each (state, event) combination
326
- represents is the last column:
327
-
328
- ```text
329
- 状态(含义) | 事件(含义) | 下一状态(含义) | Guard? | 场景(状态+事件)
330
- ------------------------|-----------------------|----------------------|---------|--------------------
331
- INIT(上电待就绪) | power_ready(电源就绪)| IDLE(空闲待命) | - | 就绪后进入待命
332
- IDLE(空闲待命) | start_cmd(启动命令) | STARTING(启动中) | - | 收到命令开始启动
333
- STARTING(启动中) | ack_received(收到ACK)| ACTIVE(运行中) | - | 启动成功进入运行
334
- STARTING(启动中) | timeout(等待超时) | ERROR(出错待恢复) | retry==0 | 首次超时进入重试
335
- STARTING(启动中) | timeout(等待超时) | FATAL(不可恢复) | retry>=1 | 重试耗尽转致命
336
- ERROR(出错待恢复) | cooldown_elapsed(冷却结束)| RECOVERING(重初始化)| - | 冷却结束开始恢复
337
- ```
338
-
339
- Width discipline (Form A): keep parenthetical meanings short (state/event ≤ 6
340
- characters, scenario ≤ 10) and estimate every row's display width (CJK counts as
341
- 2) to fit the available area. If any row would wrap, shorten the meanings; if it
342
- still will not fit, switch to Form C. A wrapped table row loses column alignment
343
- and is harder to read than no table at all.
344
-
345
- **Form B — sentence blocks (reading-accessible)**: one transition per block,
346
- scenario sentence first, fixed three-line frame. Use for detailed confirmation,
347
- users with reading difficulties, or machines with ≤ 10 transitions:
348
-
349
- ```text
350
- 第 1 步:就绪后进入待命
351
- 状态 INIT(上电待就绪)
352
- 发生 power_ready(电源就绪)
353
- 进入 IDLE(空闲待命)
354
- ```
355
-
356
- **Form C — grouped by source state (large machines / narrow panes)**: one
357
- section per state, each rendered as its own small 3-column table
358
- (事件(含义)| 下一状态(含义)| 场景); no cross-group column alignment to track:
359
-
360
- ```text
361
- DEGRADED_LOADING(降级加载)
362
- 事件(含义) | 下一状态(含义) | 场景
363
- first_data(首帧数据)| OK_READY(正常就绪) | 收到首帧转就绪
364
- fault(故障) | FAULT(故障锁存) | 故障锁存
365
- power_off(下电) | POWER_OFF(下电) | 下电
366
- ```
367
-
368
- Each group table is narrow (3 columns, roughly ≤ 60 display columns with short
369
- meanings). If one group's table would still wrap, fall back to a one-line-per-event
370
- bullet list for that group only.
371
-
372
- Reading rule: every row/block is one sentence — "在【状态(含义)】下发生【事件(含义)】
373
- → 进入【下一状态(含义)】,即【实际场景】"。Meanings repeat on purpose: each entry is
374
- self-contained. The machine-readable model keeps the same information in its
375
- `narrative` block (`narrative.states`, `narrative.events`, `narrative.scenarios`).
376
-
377
- **CRITICAL**: Show the chosen form to the user and ask for confirmation before
378
- generating the harness. Because the natural language is inlined, any entry that
379
- reads wrong to the user — a state/event meaning that is off, or a scenario that
380
- does not match reality — means the model is wrong even if the symbols are
381
- consistent. The #1 failure mode of verification is extracting the wrong model. If
382
- the plan is ambiguous, flag it as a finding first — don't guess.
383
-
384
- **Exception**: If the user has already told you to proceed without confirmation in this session, do NOT call
385
- `ask_user_question`. Instead: (a) cite evidence for every cell/entry — each
386
- state/event meaning and each scenario must trace to a source sentence, (b)
387
- round-trip the filled model (including its `narrative` block) back into the SAME
388
- rendering form and compare it with the extraction, and (c) mark the report
389
- `UNCONFIRMED`.
390
-
391
- ### Code-Level Behavioral Suggestion
392
-
393
- When the task is NOT document/plan review but involves code-level behavioral questions — e.g., the user is editing source files and asks:
394
-
395
- - "check this timing sequence for bugs"
396
- - "could this state machine deadlock here"
397
- - "is this retry limit safe"
398
- - "what happens if event X arrives during state Y"
399
-
400
- → **Proactively suggest** this plugin as an optional verification pass. Do NOT escalate automatically — plan-level verification was likely already done. The suggestion is: "I can run a logic-primitive verification on this state machine to check for deadlocks, unreachable states, and boundary issues. Want me to?"
401
-
402
- If the user says yes, extract the model from the existing code (not a plan document), and run the standard pipeline. Output the findings as suggestions, not requirements.
403
-
404
- This covers the gap where behavioral verification is useful even when no design document is being reviewed.
405
-
406
- ### When NOT to Escalate
407
-
408
- Skip logic-primitive verification when:
409
-
410
- - The document makes no behavioral/logic claims (pure API listings, config tables, data schemas)
411
- - The state machine has ≤2 states, no guards, and trivial transitions (IDLE↔ACTIVE)
412
- - The claim is purely structural (file paths, type names, numeric constants) — Phase 2 grep verification is sufficient
413
-
414
- ### Routing to the Sibling Skills
415
-
416
- This skill owns behavioural claims. Three neighbouring domains have their own skill, and loading the wrong one wastes the verification:
417
-
418
- | Domain | Skill |
419
- |---|---|
420
- | Drawing a code flow as UML, or auditing a diagram somebody drew (render / parse / review / explain-labels, round-trip fidelity, component and class diagrams refused) | `model-everything-uml` |
421
- | Reviewing architecture, module structure or a dependency diagram (isolated nodes, dangling endpoints, cycles, allowed-dependency and layer violations, missing required edges) | `model-everything-structure` |
422
- | Concurrency, synchrony and async claims — "thread-safe", "lock-free", "no data race", "ISR-safe", "non-blocking", `async`/`await` — mined and routed to TSan/Helgrind/CBMC/TLA+/UPPAAL, never proven here; a shared-location update is decided here by `model_compose_verify` (C5) | `model-everything-interleaving` |
423
- | Entities, fields, relationships, data invariants, schema migrations (DS1-DS4, DA1-DA12, DD1-DD4) | `model-everything-datamodel` |
424
-
425
- ---
426
-
427
- ## Warning Signs
428
-
429
- If you catch yourself thinking any of these, stop:
430
-
431
- | You think | Reality |
432
- |-----------|---------|
433
- | "Too simple to check" | The check is cheap. The silent skip is not. |
434
- | "I read the code, so I know" | Knowing is not evidence. Cite `file:line`, or run the model, or call the claim unverified. |
435
- | "The spec or the diagram says so" | Both are claims about the code. Reconcile them with a source-side scan. |
436
- | "I'll check while implementing" | Check before the decision, not after. |
437
- | "Reasoning is enough" | Reasoning is not a run. One counter-example kills a universal claim. |
438
- | "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. |
439
- | "The declared range limits the search" | The declaration is a property to verify. `inc`/`dec` are never clamped to it; only a guard bounds the value. |
440
- | "The check found nothing" | Read the verdict: `truncated` and `_UNDECIDED` mean the search stopped, not that the property holds. |
441
-
442
- ## Rules
443
-
444
- 1. Verify a document's claim against the code before you trust it.
445
- 2. State mechanism boundaries plainly. When the language standard cannot do the thing, say so.
446
- 3. Cite evidence as `file:line`.
447
- 4. Point the way during review. Implementation happens after approval.
448
- 5. Verify behavioural claims by running code. A plan that says "always", "never" or "guaranteed" gets a model, and one counterexample refutes a universal claim.
449
- 6. Confirm the model before you run it, unless this session already told you to proceed. Extraction errors are the dominant failure mode of formal verification. In auto mode, extract with cited evidence, validate the round trip, and mark the report `UNCONFIRMED`.
450
- 7. Cite the existing check instead of re-verifying it. Compile-time assertions, static analysis and runtime checks already settle that property.
451
- 8. Hand a neighbouring domain to its own skill. A diagram is a model, and auditing one belongs to `model-everything-uml`. A concurrency claim is mined and routed by `model-everything-interleaving`. Schema, data invariants and migrations belong to `model-everything-datamodel`. This skill keeps the doctrine and the behavioural checks.
452
- 9. Say what this does not prove. Hard real time, preemptive concurrency, hybrid-control stability, probabilistic reliability and execution-cost budgets go to the tool named in `references/gap-routing-guide.md`. `model_verify` reports carry the same routing as `coverageNotes`.
453
- 10. A declared range is a property, not a bound. `inc` and `dec` are never clamped; only a guard pins the value. A `truncated` report or an `_UNDECIDED` check means the property is undecided. Report it that way.
454
- 11. Write-site analysis is out of scope. "Only the ISR writes this flag" is a question about source code. `model_interleaving_scan` routes it. Neither the model nor the diagram settles it.
1
+ ---
2
+ name: model-everything
3
+ description: "Use when a document claims something checkable about code: API names, paths, enums, feasibility, protocol behaviour, timing, 'always/never'. Enumerates the claims and verifies each with file:line evidence, then builds an executable model when behaviour or safety is at stake. Siblings: model-everything-diagram, -uml, -design, -interleaving, -datamodel, -structure.""
4
+ ---
5
+
6
+ # Model Everything
7
+
8
+ For an unverified design, failure is only a matter of time. Complex code becomes clear once you model it and run it. Check every claim before you act on it.
9
+
10
+ ## When This Skill Applies
11
+
12
+ **This is the entry point.** Load this skill when a claim about the code has to be settled and a reading will not settle it. It owns the doctrine: enumerate the claims, verify each against the code, cite `file:line`, read `verdict`. It also owns the executable verification for behaviour. A neighbouring domain goes to its own skill through the routing table below.
13
+
14
+ **It decides small models, not programs.** The engine enumerates states, so a model that explodes is reported `truncated` with the undecided check named. That is not a bug to retry with a larger `maxStates`: reduce the model first (drop variables the property does not read, collapse symmetric states), and if it still explodes the property needs a tool that does not enumerate - SPIN for partial-order reduction, NuSMV for symbolic search, CBMC for bounded SAT. This plugin builds no abstraction and reads no program source.
15
+
16
+ **This specialises in medium-to-large, medium-to-high-complexity projects**, where one decision replaces dozens of reads and the fixed cost is amortised; at that scale the measured ratio falls to roughly parity. Spend it where the object is large enough for that, and where the claim is about all paths rather than one. Reach for it when the claim is about all paths rather than one, when nothing in the repository will go red if it is false, or when the verdict has to be reproducible later. A claim one reading settles belongs in a sentence, not in a model.
17
+
18
+ | The task involves… | What it does |
19
+ |---|---|
20
+ | Any claim about code: design doc, spec, plan, review comment, README, commit message, refactor proposal, "this is safe", "this always holds", "this can't deadlock" | Enumerate the verifiable claims (Phase 1), verify each with `file:line` evidence (Phase 2), classify the gaps (Phase 3) |
21
+ | A state machine or protocol with three or more states, guards, ACK/NACK/retry, lock/unlock, or start/stop ordering | Build an executable model. Run the S1-S8 structural checks and the A1-A14 adversarial probes |
22
+ | A quantitative or temporal guarantee: worst-case cost within a budget, "90% of runs reach SAFE", "must leave within 2 ticks" | A12 budget, A13 probabilistic reachability, A14 deadlines. Each returns a counterexample path |
23
+ | A handshake or power-up sequence across two or more components | `model_compose_verify`: C1 composition deadlock, C2 rendezvous that never fires |
24
+ | A refactoring that changes state topology or guards | Compare BEFORE and AFTER models for behaviour preservation, invariant continuity and deadlock regression (D1-D4) |
25
+ | An explicit request to prove code correct, verify a module, or check a migration for breakage | Route by domain through [Routing to the Sibling Skills](#routing-to-the-sibling-skills). Keep the doctrine |
26
+ | An architecture or dependency question about a component, package or class diagram | `model-everything-structure`: parse it into a dependency graph, judge every edge against the dependency matrix |
27
+ | Whether a design keeps its own declarations: layering, a responsibility boundary, an interface wider than its callers, a subtype that cannot replace its base | `model-everything-design`: `model_design_review` decides the declared contracts (`DES1`-`DES11`) and reports the graph's shape |
28
+
29
+ **Catalog budget**: DSH renders only the frontmatter `description` and truncates it at 500 characters. Every description here fits. Triggers that do not fit live in this table.
30
+
31
+ ## Verification Depth (Plan-Mode Gate)
32
+
33
+ When loaded as a plan-mode verification gate, this skill's execution is **mandatory**. The model has no discretion to bypass it. Depth classification is gated on objective plan features extracted in Phase 0.
34
+
35
+ ### Phase 0: Feature Extraction (Mandatory)
36
+
37
+ Before any verification, output the plan's feature summary to context:
38
+
39
+ ```text
40
+ Plan features:
41
+ Files: [N]
42
+ Functions added/modified: [list or "none"]
43
+ Behavioral claims: [none / "invariants listed" / "always/never/guaranteed assertions"]
44
+ State machine changes: [none / describe topology delta]
45
+ → Depth: LIGHTWEIGHT | STANDARD | ESCALATED
46
+ ```
47
+
48
+ This step is NOT skippable — it creates an explicit, auditable record of what the plan claims before verification begins.
49
+
50
+ ### Depth Classification
51
+
52
+ | Plan Feature | Depth |
53
+ |-------------|-------|
54
+ | Single file, zero function signatures added/modified, no behavioral claims of any kind | LIGHTWEIGHT |
55
+ | Multi-file, OR new/modified function signatures, OR implicit behavioral claims (invariants, equivalence assertions, "behavior is unchanged") | STANDARD |
56
+ | "Always"/"never"/"guaranteed" language, OR state machine topology changes (≥1 state or ≥2 transitions modified) | ESCALATED |
57
+
58
+ **"No behavioral claims" is narrow**: if the plan asserts anything about behavior preservation — including listing invariants, claiming equivalence, or saying "refactoring only, no behavior change" — that IS a behavioral claim. The absence of the literal words "always"/"never" does NOT mean there are no behavioral claims.
59
+
60
+ ### Output Requirements
61
+
62
+ | Depth | Required |
63
+ |-------|----------|
64
+ | LIGHTWEIGHT | All 5 checklist items (file paths, API/type names, line numbers, behavioral claims, mechanism feasibility) answered in context with explicit results per item |
65
+ | STANDARD | Phase 1-2: enumerate every verifiable claim → verify each against codebase with evidence |
66
+ | ESCALATED | Full pipeline: Phase 1-5 including Logic Primitive Verification (Phase 2a structural, Phase 2b adversarial) |
67
+
68
+ ### Plan Verification Block
69
+
70
+ After verification, append a summary to the plan file:
71
+
72
+ ```markdown
73
+ ## Plan Verification
74
+
75
+ - **Depth**: [LIGHTWEIGHT / STANDARD / ESCALATED]
76
+ - **Scope**: [N] file paths, [M] API/type names, [K] line citations confirmed
77
+ - **Escalation**: [skipped — no behavioral claims detected] or [see transcript for N-check results]
78
+ ```
79
+
80
+ This block is the audit trail. A future reviewer must be able to see what was verified and when.
81
+ </HARD-GATE>
82
+
83
+ ## Methodology
84
+
85
+ ### Phase 1: Enumerate Claims
86
+
87
+ Read the document fully. Extract every claim that is verifiable:
88
+
89
+ - Numeric claims (counts, sizes, frequencies)
90
+ - API/type/enum names
91
+ - File paths and line numbers
92
+ - Mechanism descriptions ("compile-time resolution", "static dispatch")
93
+
94
+ ### Phase 2: Verify Against Codebase
95
+
96
+ For each claim, run the relevant verification:
97
+
98
+ - **Numeric claims**: `grep -c` or `grep -rn` to get the real count
99
+ - **API/type names**: extract actual signatures from headers
100
+ - **Enum/constant values**: list actual values from BSP/config headers
101
+ - **Mechanism feasibility**: check language standard and compiler support
102
+
103
+ ### Phase 2 Trigger: Escalate to Logic Primitive?
104
+
105
+ If the document under review contains ANY of the following, escalate to [Logic Primitive Verification](#logic-primitive-verification) IMMEDIATELY:
106
+
107
+ - State machine or statechart with ≥3 states OR with guard conditions on transitions
108
+ - Protocol handshake, ACK/NACK, retry, or timeout sequence logic
109
+ - Claims using absolute language: "always", "never", "guaranteed", "all paths", "cannot", "impossible"
110
+ - Lock/unlock, alloc/free, start/stop paired operations where ordering matters
111
+ - Any logic where correctness depends on transition completeness or event ordering
112
+ - **Refactoring that modifies state topology**: splitting/merging states, adding/removing transitions, changing guard conditions, extracting sub-machines
113
+
114
+ **Heuristic**: If the transition-to-state ratio > 1.5 or any transition has a guard condition, the machine is complex enough to warrant verification — regardless of state count. For refactoring, trigger if the refactoring changes ≥1 state or ≥2 transitions from the original model.
115
+
116
+ ### Phase 3: Gap Analysis
117
+
118
+ Classify findings by severity:
119
+
120
+ 1. **Architecture-level**: claims that make the design unimplementable (fake APIs, missing modules)
121
+ 2. **Mechanism-level**: claims the language/compiler cannot fulfill
122
+ 3. **Consistency-level**: internal contradictions across documents
123
+
124
+ ### Phase 4: Root Cause
125
+
126
+ For each error, identify why it happened:
127
+
128
+ - Wrong mental model (C++ constexpr thinking in C99)?
129
+ - Incomplete search scope?
130
+ - Copy-paste from other projects without verification?
131
+ - Misunderstanding of compiler/linker behavior?
132
+
133
+ ### Phase 5: Structured Output
134
+
135
+ Each finding includes:
136
+
137
+ - Exact location (file:line or section)
138
+ - What the document claims
139
+ - What the codebase actually contains (with evidence — grep output, line numbers)
140
+ - Correction direction
141
+
142
+ ---
143
+
144
+ ## Logic Primitive Verification
145
+
146
+ When Phase 2 triggers escalation, do NOT proceed to Phase 3 until the verification pipeline below is complete. Trust models, not intuition.
147
+
148
+ ### Pipeline Overview
149
+
150
+ ```text
151
+ Document claims → Extract model → Runtime check:
152
+ ├── DSH + `model_verify` tool available → build Model schema v1 (references/dsh-model-schema.md) → call the tool → structured report
153
+ └── No engine available → Manual Verification Mode (see references/logic-verification-guide.md#manual-verification-mode)
154
+
155
+ Refactoring variant:
156
+ Old code + Refactoring plan → Extract BEFORE model + AFTER model
157
+ → Run the pipeline on the AFTER model (the same checks)
158
+ → Compare BEFORE vs AFTER: behavioral preservation, regression, complexity delta
159
+ → Flag any invariant that held in BEFORE but fails in AFTER
160
+
161
+ UML modelling variant (the task is to draw a flow, not to check a claim):
162
+ Code flow → model with a citation per element → uml_render → diagram
163
+ → uml_review → modelling findings + render/parse round-trip fidelity
164
+ → model_verify → the behavioural checks (S1-S8 / A1-A14)
165
+ ```
166
+
167
+ ### Budgeting the Model Before You Run It
168
+
169
+ Search cost is the declared domain times the number of states — and a declared range is
170
+ not a bound on the search.
171
+
172
+ - **`inc`/`dec` are never clamped to `min`/`max`.** The declaration is a property the
173
+ checks verify, not a limit the engine enforces. A counter whose guard does not pin it
174
+ ranges past its own declaration, so the reachable set is unbounded however small the
175
+ declared range looks; S8 reports that as `S8_DOMAIN_NOT_ENFORCED`.
176
+ - **Bound a counter with a guard, not a narrower declaration.** `max: 4` with a guard
177
+ `retry < 4` closes the loop. `max: 4` alone does not.
178
+ - **Say the budget before running**: values per variable x states. A product in the
179
+ 10^5-and-up range will hit the cap and come back undecided.
180
+ - **Model the check where the code performs it.** A cap check that lives inside the tick
181
+ handler is a guarded branch of the tick event, not a separate event: as a separate event
182
+ the environment can starve it, and the leads-to failure you then read is an artefact of
183
+ the model rather than a property of the code.
184
+
185
+ ### Native dsh Tools
186
+
187
+ The tools are `model_verify`, `model_edit`, `model_compose_verify`, `model_datamodel_verify`, `model_design_review`, `model_interleaving_scan`, `model_export`, `report_diff`, `uml_render`, `uml_parse`, `uml_review`, `uml_explain_labels`, `uml_structure_verify` and `model_automaton_verify`. `model_automaton_verify` decides a finite-word language and its relation to another automaton, returning the shortest word that separates them; `references/automata.md` states what each of its checks decides, on what authority, and where it stops. `references/architecture-views.md` carries the doctrine for reading a design as views and levels, with the three hierarchy rules; `references/architecture-domains.md` says, per domain - services, event-driven, data, protocols, embedded and real-time, hardware, machine learning, safety - what is decidable here and where the rest has to go. `model_edit` changes a model file by naming the change and returns the structural diff plus the difference in findings, so a fix round costs one call instead of three. `uml_structure_verify` builds its graph from a source tree when given `repoPath`, reading each language's own import construct, so a dependency question about code does not start with drawing. Each tool's description states what it decides and what it does not. Read the description before calling it, and read the report's `verdict` afterwards.
188
+
189
+ A model is the largest argument these tools take. When it is long, or you have edited it more than once, write it to a file and pass `modelPath` instead of inlining it: a streamed argument that long is where invalid JSON comes from, and the file accepts any formatting.
190
+
191
+ These tools carry every capability this plugin claims. Anything outside them is out of scope, and the skills name where that claim is answered instead.
192
+
193
+ ### Reading a Report: `ok` Is Not a Verdict
194
+
195
+ **`ok` records that a report was produced. `verdict` records how the review went.** A report can carry `ok: true` and still be a failed review. Gate on `verdict`.
196
+
197
+ - `pass`: no error and no warning. Report the result as verified, together with the scope the model covered.
198
+ - `pass_with_findings`: verification ran clean and warnings exist. Report the pass and the warnings. Do not restate it as "no issues".
199
+ - `fail`: an error finding exists, or the engine rejected the input (`MODEL_INVALID`). State that the claim is not verified, quote the counterexample path, then propose a correction. Do not describe a `fail` as a successful run.
200
+
201
+ `summary.truncated: true` and any code ending in `_UNDECIDED` both mean the search stopped before deciding. Name the invariant that went undecided and report the property as undecided.
202
+
203
+ A tool prints a readable body. Passing checks stay in the `CHECKS` inventory line, and a fact that several checks report appears once. Only error findings inline their evidence. When the body truncates a check, pass `check: "<id>"` to print that check in full. `reportView: "full"` returns the whole report as compact JSON. Use it only to hand the report to `report_diff`; it costs the most tokens of any request you can make.
204
+
205
+ ### Writing the Answer: Name the Finding, Not Its Code
206
+
207
+ `S2_NO_TRANSITIONS`, `UML019`, `DA2` are values of `findings[].code`, not names. A reader
208
+ who has not memorized the schema learns nothing from one, and cannot tell whether their
209
+ machine is sound or stuck.
210
+
211
+ - **Say what it means**, in the user's language and in the terms of their own code:
212
+ 「启动超时后 ERROR 没有任何出口迁移,机器会停在那里」, not 「S2 命中」. The finding's
213
+ `message` is written for the report; the sentence for the user is written from it.
214
+ - **Keep the identifier where the identifier is the subject**: a report field quoted
215
+ verbatim, a baseline diff, a test name, or a question about the check itself.
216
+ - **Name the property, not the checking.** "This path locks without unlocking" beats
217
+ "A4 failed". A check's name earns its place when the reader asked about the checking.
218
+ - **Carry the verdict in words.** "Not verified" or "verified, within the scope of this
219
+ model" — never a bare pass, and never a warning presented without its label.
220
+
221
+ A reader who cannot tell what failed will either trust a report they cannot read, or
222
+ ignore one they should act on.
223
+
224
+ ### Slice Acceptance: Baseline Diffs
225
+
226
+ The acceptance criterion for a refactoring slice is usually "no **new** findings", not
227
+ "zero findings". Do not compare two JSON reports by eye — run the comparison:
228
+
229
+ - DSH: `report_diff { baseline: <earlier report>, current: <new report> }`
230
+ - Any host without the tools: run the repository engine against the same JSON.
231
+ (also available on `compose`, `structure` and `uml-review`)
232
+
233
+ A finding's identity is its **check id + code + canonical locator** (built from
234
+ `evidence`/`path`; the message only when a finding carries neither), so a reworded
235
+ message reads as `changed`, never as a new finding. The diff's `verdict` describes the
236
+ **delta** — a newly added error finding fails it — while `currentVerdict` keeps the
237
+ absolute result visible, and a clean delta over a still-failing report says so in
238
+ `nextSteps` rather than passing quietly. Two runs over the same input add zero findings:
239
+ run that self-check before trusting any baseline.
240
+
241
+ ### Archiving a Model: `_`-Prefixed Metadata
242
+
243
+ Keep provenance with the model instead of in a sidecar that drifts:
244
+
245
+ - Any key starting with `_` at any level (`_source`, `_verified`, `_uml`, `_extraction_caveats`, `states[0]._note`) is **annotation metadata**: the schema ignores it, `modelHash` excludes it, and the report echoes it as `metadataKeys`.
246
+ - Everything else stays closed — a mistyped `sttes` is still a validation error, and that is deliberate.
247
+ - Because the hash ignores `_` keys, "the model as archived" and "the model with metadata stripped" hash identically; record the reported `hashSpec` next to the hash so a later reader can reproduce it (`verify model.json --hash-check <hex>` answers whether a recorded hash belongs to a published spec at all).
248
+
249
+ ### Refactoring Verification Mode
250
+
251
+ When the document under review is a refactoring plan (modifying existing state machine logic, not designing from scratch), adapt the pipeline:
252
+
253
+ 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)
254
+ 2. **Extract the AFTER model** from the refactoring plan
255
+ 3. **Show both tables AND their model narratives** to the user side by side and confirm the delta is intentional
256
+ 4. **Run Phase 2a + 2b on the AFTER model** — the same checks a new design gets
257
+ 5. **Compare BEFORE vs AFTER**:
258
+
259
+ | Check | Method | Severity if Violated |
260
+ |-------|--------|:---:|
261
+ | Behavioral preservation | Every event sequence accepted by BEFORE must also be accepted by AFTER (or explicitly removed per plan) | Error — regression |
262
+ | Invariant continuity | Any invariant that held in BEFORE must hold in AFTER (unless the refactoring explicitly changes it) | Error — undocumented behavior change |
263
+ | Deadlock regression | New states or transitions must not introduce deadlocks not present in BEFORE | Error |
264
+ | Complexity claim | If plan claims "simpler": count states + transitions + guards. Is AFTER objectively simpler? | Warning — unsubstantiated claim |
265
+ | Unreachable code | New states added in AFTER must be reachable (otherwise they're dead code from the start) | Warning |
266
+
267
+ In DSH, pass `beforeModel` and optional `stateMapping` to `model_verify`; the engine runs D1 Behavioral Preservation, D2 Invariant Continuity, D3 Regression Delta, and D4 Deadlock/Liveness Regression automatically.
268
+
269
+ 6. **Flag any behavioral delta not documented in the plan** — the most common refactoring bug is an unintended side effect that the plan doesn't acknowledge
270
+
271
+ Run the checks with the native `model_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`.
272
+
273
+ ### Phase 2a: Structural Primitives
274
+
275
+ Run these FIRST. They establish basic well-formedness before adversarial probing.
276
+
277
+ | # | Primitive | Method | Severity if Violated |
278
+ |:--:|-----------|--------|:---:|
279
+ | S1 | **Reachability** | BFS from init state; flag all states not in visited set | Warning — dead code |
280
+ | S2 | **Deadlock** | Any non-terminal state with zero outgoing transitions? | Error — machine can get stuck |
281
+ | S3 | **Liveness** | Does the transition graph contain an absorbing cycle that excludes expected terminal/recovery states? (e.g. ERROR→RECOVERING→ERROR→... with no exit) | Error — infinite loop |
282
+ | S4 | **Determinism** | Same state + same event → multiple different targets? | Error — ambiguous behavior |
283
+ | S5 | **Event completeness** | For each state, are there plausible events with no defined transition? | Warning — implicit ignore |
284
+ | S6 | **Guard completeness** | For each transition with a guard condition, are ALL branch outcomes defined? `if (cnt<3) RETRY else FATAL` → both paths must exist in model | Error — undefined behavior path |
285
+ | S7 | **Invariant validity** | Does every reachable state satisfy the plan's stated "always/never/guaranteed" assertions? | Error — plan claim is false |
286
+ | S8 | **Monotonic variables** | If a variable is declared `monotonic: inc/dec`, do all updates respect that direction? | Error — counter can move backwards |
287
+
288
+ ### Phase 2b: Adversarial Probes
289
+
290
+ Run these second. Each probe tries to break the model, and a probe that finds a violation proves a behaviour gap.
291
+
292
+ | # | Attack | Method | Claim it refutes |
293
+ |:--:|--------|--------|-------------|
294
+ | A1 | **Unexpected event** | Inject every event E into every state S that has no transition for (S, E). Record whether the model ignores it or crashes. | "All events are handled in all states" |
295
+ | A2 | **Race interleaving** | Deliver every pair of concurrent events in both orders. Report a differing terminal state. | "Behaviour is independent of ordering" |
296
+ | A3 | **Order permutation** | Permute N independent events. Report differing final states or broken invariants. | "Outcome is order-independent" |
297
+ | A4 | **Pair symmetry** | Match every `start/stop`, `lock/unlock`, `alloc/free` pair. Report a path where a pair is unbalanced. `onEntry` and `onExit` count as acquire and release. | "Resources are always released" |
298
+ | A5 | **Boundary blast** | Probe counters at 0, 1, max-1, max and max+1, and timestamps at 0 and wraparound. Report overflow, underflow or undefined behaviour. | "Handles all counter and timer values" |
299
+ | A6 | **Resource injection** | Simulate `malloc` returning NULL, a full queue and a semaphore timeout at each state that calls them. Report a state with no recovery path. | "Degrades gracefully under resource pressure" |
300
+ | A7 | **Counter-example witness** | For a failing invariant, emit the exact violating sequence. The breadth-first searches (state, sequence, atomicity, budget) return the shortest witness. Leads-to and probability return the witness they found without claiming minimality. | "This invariant holds" |
301
+ | A8 | **Idempotent replay** | Apply each `idempotentEvents` entry twice from every reachable state. Report a second application that changes state. | "This event is safe to replay" |
302
+ | A9 | **Leads-to** | From a declared source state, every path must reach the target state or a member of the declared target set. | "Always progresses to completion" |
303
+ | A10 | **Sequence order** | Declared events must occur in the declared order. | "backup before modify before commit" |
304
+ | A11 | **Atomicity** | An atomic event must commit or roll back before the scope is left or the machine terminates. | "all-or-nothing" |
305
+ | A12 | **Budget** | With `cost` per transition (absent means 1) and a `budget` invariant, every reachable path must stay within budget. The probe returns the shortest over-budget path and reports reachable positive-cost cycles as unbounded. | "Worst case fits the budget" |
306
+ | A13 | **Probability reachability** | With `weight` per transition (absent means 1) and a `probability` invariant, P(ever hitting the target) must meet the bound, by value iteration over the absorbing chain. | "90% of runs reach SAFE" |
307
+ | A14 | **Deadline** | State `maxTicks` plus top-level `tickEvents`. A tick step must not keep a state resident past its deadline. The probe returns the over-residency path. | "Must leave within 2 ticks" |
308
+
309
+ ### Integration Back to Phase 3
310
+
311
+ For every probe failure:
312
+
313
+ 1. **Quote** the plan claim verbatim
314
+ 2. **Show** the counter-example event sequence
315
+ 3. **Classify** severity (Architecture / Mechanism / Consistency)
316
+ 4. **Propose** correction direction — never fix inline
317
+
318
+ ### Extraction Rule
319
+
320
+ Before writing any verification code, output the model in one of the rendering
321
+ forms below. Default is Form A; switch forms when the machine is large or the
322
+ display area is narrow — never let a table row wrap.
323
+
324
+ **Form A — integrated transition table (default)**: formal symbols with their
325
+ natural-language meaning inlined; the scenario each (state, event) combination
326
+ represents is the last column:
327
+
328
+ ```text
329
+ 状态(含义) | 事件(含义) | 下一状态(含义) | Guard? | 场景(状态+事件)
330
+ ------------------------|-----------------------|----------------------|---------|--------------------
331
+ INIT(上电待就绪) | power_ready(电源就绪)| IDLE(空闲待命) | - | 就绪后进入待命
332
+ IDLE(空闲待命) | start_cmd(启动命令) | STARTING(启动中) | - | 收到命令开始启动
333
+ STARTING(启动中) | ack_received(收到ACK)| ACTIVE(运行中) | - | 启动成功进入运行
334
+ STARTING(启动中) | timeout(等待超时) | ERROR(出错待恢复) | retry==0 | 首次超时进入重试
335
+ STARTING(启动中) | timeout(等待超时) | FATAL(不可恢复) | retry>=1 | 重试耗尽转致命
336
+ ERROR(出错待恢复) | cooldown_elapsed(冷却结束)| RECOVERING(重初始化)| - | 冷却结束开始恢复
337
+ ```
338
+
339
+ Width discipline (Form A): keep parenthetical meanings short (state/event ≤ 6
340
+ characters, scenario ≤ 10) and estimate every row's display width (CJK counts as
341
+ 2) to fit the available area. If any row would wrap, shorten the meanings; if it
342
+ still will not fit, switch to Form C. A wrapped table row loses column alignment
343
+ and is harder to read than no table at all.
344
+
345
+ **Form B — sentence blocks (reading-accessible)**: one transition per block,
346
+ scenario sentence first, fixed three-line frame. Use for detailed confirmation,
347
+ users with reading difficulties, or machines with ≤ 10 transitions:
348
+
349
+ ```text
350
+ 第 1 步:就绪后进入待命
351
+ 状态 INIT(上电待就绪)
352
+ 发生 power_ready(电源就绪)
353
+ 进入 IDLE(空闲待命)
354
+ ```
355
+
356
+ **Form C — grouped by source state (large machines / narrow panes)**: one
357
+ section per state, each rendered as its own small 3-column table
358
+ (事件(含义)| 下一状态(含义)| 场景); no cross-group column alignment to track:
359
+
360
+ ```text
361
+ DEGRADED_LOADING(降级加载)
362
+ 事件(含义) | 下一状态(含义) | 场景
363
+ first_data(首帧数据)| OK_READY(正常就绪) | 收到首帧转就绪
364
+ fault(故障) | FAULT(故障锁存) | 故障锁存
365
+ power_off(下电) | POWER_OFF(下电) | 下电
366
+ ```
367
+
368
+ Each group table is narrow (3 columns, roughly ≤ 60 display columns with short
369
+ meanings). If one group's table would still wrap, fall back to a one-line-per-event
370
+ bullet list for that group only.
371
+
372
+ Reading rule: every row/block is one sentence — "在【状态(含义)】下发生【事件(含义)】
373
+ → 进入【下一状态(含义)】,即【实际场景】"。Meanings repeat on purpose: each entry is
374
+ self-contained. The machine-readable model keeps the same information in its
375
+ `narrative` block (`narrative.states`, `narrative.events`, `narrative.scenarios`).
376
+
377
+ **CRITICAL**: Show the chosen form to the user and ask for confirmation before
378
+ generating the harness. Because the natural language is inlined, any entry that
379
+ reads wrong to the user — a state/event meaning that is off, or a scenario that
380
+ does not match reality — means the model is wrong even if the symbols are
381
+ consistent. The #1 failure mode of verification is extracting the wrong model. If
382
+ the plan is ambiguous, flag it as a finding first — don't guess.
383
+
384
+ **Exception**: If the user has already told you to proceed without confirmation in this session, do NOT call
385
+ `ask_user_question`. Instead: (a) cite evidence for every cell/entry — each
386
+ state/event meaning and each scenario must trace to a source sentence, (b)
387
+ round-trip the filled model (including its `narrative` block) back into the SAME
388
+ rendering form and compare it with the extraction, and (c) mark the report
389
+ `UNCONFIRMED`.
390
+
391
+ ### Code-Level Behavioral Suggestion
392
+
393
+ When the task is NOT document/plan review but involves code-level behavioral questions — e.g., the user is editing source files and asks:
394
+
395
+ - "check this timing sequence for bugs"
396
+ - "could this state machine deadlock here"
397
+ - "is this retry limit safe"
398
+ - "what happens if event X arrives during state Y"
399
+
400
+ → **Proactively suggest** this plugin as an optional verification pass. Do NOT escalate automatically — plan-level verification was likely already done. The suggestion is: "I can run a logic-primitive verification on this state machine to check for deadlocks, unreachable states, and boundary issues. Want me to?"
401
+
402
+ If the user says yes, extract the model from the existing code (not a plan document), and run the standard pipeline. Output the findings as suggestions, not requirements.
403
+
404
+ This covers the gap where behavioral verification is useful even when no design document is being reviewed.
405
+
406
+ ### When NOT to Escalate
407
+
408
+ Skip logic-primitive verification when:
409
+
410
+ - The document makes no behavioral/logic claims (pure API listings, config tables, data schemas)
411
+ - The state machine has ≤2 states, no guards, and trivial transitions (IDLE↔ACTIVE)
412
+ - The claim is purely structural (file paths, type names, numeric constants) — Phase 2 grep verification is sufficient
413
+
414
+ ### Routing to the Sibling Skills
415
+
416
+ This skill owns behavioural claims. Three neighbouring domains have their own skill, and loading the wrong one wastes the verification:
417
+
418
+ | Domain | Skill |
419
+ |---|---|
420
+ | Drawing a code flow as UML, or auditing a diagram somebody drew (render / parse / review / explain-labels, round-trip fidelity, component and class diagrams refused) | `model-everything-uml` |
421
+ | Reviewing architecture, module structure or a dependency diagram (isolated nodes, dangling endpoints, cycles, allowed-dependency and layer violations, missing required edges) | `model-everything-structure` |
422
+ | Concurrency, synchrony and async claims — "thread-safe", "lock-free", "no data race", "ISR-safe", "non-blocking", `async`/`await` — mined and routed to TSan/Helgrind/CBMC/TLA+/UPPAAL, never proven here; a shared-location update is decided here by `model_compose_verify` (C5) | `model-everything-interleaving` |
423
+ | Entities, fields, relationships, data invariants, schema migrations (DS1-DS4, DA1-DA12, DD1-DD4) | `model-everything-datamodel` |
424
+
425
+ ---
426
+
427
+ ## Warning Signs
428
+
429
+ If you catch yourself thinking any of these, stop:
430
+
431
+ | You think | Reality |
432
+ |-----------|---------|
433
+ | "Too simple to check" | The check is cheap. The silent skip is not. |
434
+ | "I read the code, so I know" | Knowing is not evidence. Cite `file:line`, or run the model, or call the claim unverified. |
435
+ | "The spec or the diagram says so" | Both are claims about the code. Reconcile them with a source-side scan. |
436
+ | "I'll check while implementing" | Check before the decision, not after. |
437
+ | "Reasoning is enough" | Reasoning is not a run. One counter-example kills a universal claim. |
438
+ | "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. |
439
+ | "The declared range limits the search" | The declaration is a property to verify. `inc`/`dec` are never clamped to it; only a guard bounds the value. |
440
+ | "The check found nothing" | Read the verdict: `truncated` and `_UNDECIDED` mean the search stopped, not that the property holds. |
441
+
442
+ ## Rules
443
+
444
+ 1. Verify a document's claim against the code before you trust it.
445
+ 2. State mechanism boundaries plainly. When the language standard cannot do the thing, say so.
446
+ 3. Cite evidence as `file:line`.
447
+ 4. Point the way during review. Implementation happens after approval.
448
+ 5. Verify behavioural claims by running code. A plan that says "always", "never" or "guaranteed" gets a model, and one counterexample refutes a universal claim.
449
+ 6. Confirm the model before you run it, unless this session already told you to proceed. Extraction errors are the dominant failure mode of formal verification. In auto mode, extract with cited evidence, validate the round trip, and mark the report `UNCONFIRMED`.
450
+ 7. Cite the existing check instead of re-verifying it. Compile-time assertions, static analysis and runtime checks already settle that property.
451
+ 8. Hand a neighbouring domain to its own skill. A diagram is a model, and auditing one belongs to `model-everything-uml`. A concurrency claim is mined and routed by `model-everything-interleaving`. Schema, data invariants and migrations belong to `model-everything-datamodel`. This skill keeps the doctrine and the behavioural checks.
452
+ 9. Say what this does not prove. Hard real time, preemptive concurrency, hybrid-control stability, probabilistic reliability and execution-cost budgets go to the tool named in `references/gap-routing-guide.md`. `model_verify` reports carry the same routing as `coverageNotes`.
453
+ 10. A declared range is a property, not a bound. `inc` and `dec` are never clamped; only a guard pins the value. A `truncated` report or an `_UNDECIDED` check means the property is undecided. Report it that way.
454
+ 11. Write-site analysis is out of scope. "Only the ISR writes this flag" is a question about source code. `model_interleaving_scan` routes it. Neither the model nor the diagram settles it.