dsh-logicprobe 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.en-US.md +237 -0
- package/README.md +234 -0
- package/cordis.patch.yml +12 -0
- package/lib/engine.js +1103 -0
- package/lib/index.js +277 -0
- package/lib/tool.js +45 -0
- package/lib/types/engine.d.ts +133 -0
- package/lib/types/index.d.ts +46 -0
- package/lib/types/tool.d.ts +8 -0
- package/package.json +81 -0
- package/skills/logicprobe/SKILL.md +266 -0
- package/skills/logicprobe/references/dsh-model-schema.md +104 -0
- package/skills/logicprobe/references/logic-verification-guide.md +413 -0
- package/skills/logicprobe/references/verification-harness.py +582 -0
- package/src/engine.ts +1164 -0
- package/src/index.ts +301 -0
- package/src/tool.ts +48 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: logicprobe
|
|
3
|
+
description: "Use when reviewing design documents, architecture specs, technical proposals, or refactoring plans that make claims about API names, file locations, enum values, or mechanism feasibility. When the document contains state machines, protocol logic, or behavioral claims (≥3 states, ACK/NACK/retry sequences, 'always'/'never'/'guaranteed' assertions, or refactoring that modifies state topology), escalate into logic-primitive verification — generate and run executable models to check mathematical completeness before trusting any claim. For refactoring specifically, the pipeline compares before/after models to verify behavioral preservation and regression freedom. ALSO proactively SUGGEST this skill (do not require) when a user asks code-level behavioral questions — 'check this timing for bugs', 'could this state machine deadlock', 'is this retry limit safe' — since plan-level verification has usually already been done."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Logic Probe
|
|
7
|
+
|
|
8
|
+
Documents are not truth — code is. Verify every verifiable claim before accepting or acting on any design.
|
|
9
|
+
|
|
10
|
+
<HARD-GATE>
|
|
11
|
+
|
|
12
|
+
## Verification Depth (Plan-Mode Gate)
|
|
13
|
+
|
|
14
|
+
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.
|
|
15
|
+
|
|
16
|
+
### Phase 0: Feature Extraction (Mandatory)
|
|
17
|
+
|
|
18
|
+
Before any verification, output the plan's feature summary to context:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
Plan features:
|
|
22
|
+
Files: [N]
|
|
23
|
+
Functions added/modified: [list or "none"]
|
|
24
|
+
Behavioral claims: [none / "invariants listed" / "always/never/guaranteed assertions"]
|
|
25
|
+
State machine changes: [none / describe topology delta]
|
|
26
|
+
→ Depth: LIGHTWEIGHT | STANDARD | ESCALATED
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
This step is NOT skippable — it creates an explicit, auditable record of what the plan claims before verification begins.
|
|
30
|
+
|
|
31
|
+
### Depth Classification
|
|
32
|
+
|
|
33
|
+
| Plan Feature | Depth |
|
|
34
|
+
|-------------|-------|
|
|
35
|
+
| Single file, zero function signatures added/modified, no behavioral claims of any kind | LIGHTWEIGHT |
|
|
36
|
+
| Multi-file, OR new/modified function signatures, OR implicit behavioral claims (invariants, equivalence assertions, "behavior is unchanged") | STANDARD |
|
|
37
|
+
| "Always"/"never"/"guaranteed" language, OR state machine topology changes (≥1 state or ≥2 transitions modified) | ESCALATED |
|
|
38
|
+
|
|
39
|
+
**"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.
|
|
40
|
+
|
|
41
|
+
### Output Requirements
|
|
42
|
+
|
|
43
|
+
| Depth | Required |
|
|
44
|
+
|-------|----------|
|
|
45
|
+
| LIGHTWEIGHT | All 5 checklist items (file paths, API/type names, line numbers, behavioral claims, mechanism feasibility) answered in context with explicit results per item |
|
|
46
|
+
| STANDARD | Phase 1-2: enumerate every verifiable claim → verify each against codebase with evidence |
|
|
47
|
+
| ESCALATED | Full pipeline: Phase 1-5 including Logic Primitive Verification (Phase 2a + 2b, 14 checks) |
|
|
48
|
+
|
|
49
|
+
### Plan Verification Block
|
|
50
|
+
|
|
51
|
+
After verification, append a summary to the plan file:
|
|
52
|
+
|
|
53
|
+
```markdown
|
|
54
|
+
## Plan Verification
|
|
55
|
+
|
|
56
|
+
- **Depth**: [LIGHTWEIGHT / STANDARD / ESCALATED]
|
|
57
|
+
- **Scope**: [N] file paths, [M] API/type names, [K] line citations confirmed
|
|
58
|
+
- **Escalation**: [skipped — no behavioral claims detected] or [see transcript for N-check results]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
This block is the audit trail. A future reviewer must be able to see what was verified and when.
|
|
62
|
+
</HARD-GATE>
|
|
63
|
+
|
|
64
|
+
## Methodology
|
|
65
|
+
|
|
66
|
+
### Phase 1: Enumerate Claims
|
|
67
|
+
|
|
68
|
+
Read the document fully. Extract every claim that is verifiable:
|
|
69
|
+
|
|
70
|
+
- Numeric claims (counts, sizes, frequencies)
|
|
71
|
+
- API/type/enum names
|
|
72
|
+
- File paths and line numbers
|
|
73
|
+
- Mechanism descriptions ("compile-time resolution", "static dispatch")
|
|
74
|
+
|
|
75
|
+
### Phase 2: Verify Against Codebase
|
|
76
|
+
|
|
77
|
+
For each claim, run the relevant verification:
|
|
78
|
+
|
|
79
|
+
- **Numeric claims**: `grep -c` or `grep -rn` to get the real count
|
|
80
|
+
- **API/type names**: extract actual signatures from headers
|
|
81
|
+
- **Enum/constant values**: list actual values from BSP/config headers
|
|
82
|
+
- **Mechanism feasibility**: check language standard and compiler support
|
|
83
|
+
|
|
84
|
+
### Phase 2 Trigger: Escalate to Logic Primitive?
|
|
85
|
+
|
|
86
|
+
If the document under review contains ANY of the following, escalate to [Logic Primitive Verification](#logic-primitive-verification) IMMEDIATELY:
|
|
87
|
+
|
|
88
|
+
- State machine or statechart with ≥3 states OR with guard conditions on transitions
|
|
89
|
+
- Protocol handshake, ACK/NACK, retry, or timeout sequence logic
|
|
90
|
+
- Claims using absolute language: "always", "never", "guaranteed", "all paths", "cannot", "impossible"
|
|
91
|
+
- Lock/unlock, alloc/free, start/stop paired operations where ordering matters
|
|
92
|
+
- Any logic where correctness depends on transition completeness or event ordering
|
|
93
|
+
- **Refactoring that modifies state topology**: splitting/merging states, adding/removing transitions, changing guard conditions, extracting sub-machines
|
|
94
|
+
|
|
95
|
+
**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.
|
|
96
|
+
|
|
97
|
+
### Phase 3: Gap Analysis
|
|
98
|
+
|
|
99
|
+
Classify findings by severity:
|
|
100
|
+
|
|
101
|
+
1. **Architecture-level**: claims that make the design unimplementable (fake APIs, missing modules)
|
|
102
|
+
2. **Mechanism-level**: claims the language/compiler cannot fulfill
|
|
103
|
+
3. **Consistency-level**: internal contradictions across documents
|
|
104
|
+
|
|
105
|
+
### Phase 4: Root Cause
|
|
106
|
+
|
|
107
|
+
For each error, identify why it happened:
|
|
108
|
+
|
|
109
|
+
- Wrong mental model (C++ constexpr thinking in C99)?
|
|
110
|
+
- Incomplete search scope?
|
|
111
|
+
- Copy-paste from other projects without verification?
|
|
112
|
+
- Misunderstanding of compiler/linker behavior?
|
|
113
|
+
|
|
114
|
+
### Phase 5: Structured Output
|
|
115
|
+
|
|
116
|
+
Each finding includes:
|
|
117
|
+
|
|
118
|
+
- Exact location (file:line or section)
|
|
119
|
+
- What the document claims
|
|
120
|
+
- What the codebase actually contains (with evidence — grep output, line numbers)
|
|
121
|
+
- Correction direction
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Logic Primitive Verification
|
|
126
|
+
|
|
127
|
+
When Phase 2 triggers escalation, do NOT proceed to Phase 3 until the verification pipeline below is complete. Trust models, not intuition.
|
|
128
|
+
|
|
129
|
+
### Pipeline Overview
|
|
130
|
+
|
|
131
|
+
```text
|
|
132
|
+
Document claims → Extract model → Runtime check:
|
|
133
|
+
├── DSH + `logicprobe_verify` tool available → build Model schema v1 (references/dsh-model-schema.md) → call the tool → structured report
|
|
134
|
+
├── Python available → fill in references/verification-harness.py → run → report
|
|
135
|
+
└── No Python → Manual Verification Mode (see references/logic-verification-guide.md#manual-verification-mode)
|
|
136
|
+
|
|
137
|
+
Refactoring variant:
|
|
138
|
+
Old code + Refactoring plan → Extract BEFORE model + AFTER model
|
|
139
|
+
→ Run pipeline on AFTER model (14 checks)
|
|
140
|
+
→ Compare BEFORE vs AFTER: behavioral preservation, regression, complexity delta
|
|
141
|
+
→ Flag any invariant that held in BEFORE but fails in AFTER
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Refactoring Verification Mode
|
|
145
|
+
|
|
146
|
+
When the document under review is a refactoring plan (modifying existing state machine logic, not designing from scratch), adapt the pipeline:
|
|
147
|
+
|
|
148
|
+
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)
|
|
149
|
+
2. **Extract the AFTER model** from the refactoring plan
|
|
150
|
+
3. **Show both tables** to the user side by side and confirm the delta is intentional
|
|
151
|
+
4. **Run Phase 2a + 2b on the AFTER model** — same 14 checks as new design
|
|
152
|
+
5. **Compare BEFORE vs AFTER**:
|
|
153
|
+
|
|
154
|
+
| Check | Method | Severity if Violated |
|
|
155
|
+
|-------|--------|:---:|
|
|
156
|
+
| Behavioral preservation | Every event sequence accepted by BEFORE must also be accepted by AFTER (or explicitly removed per plan) | Error — regression |
|
|
157
|
+
| Invariant continuity | Any invariant that held in BEFORE must hold in AFTER (unless the refactoring explicitly changes it) | Error — undocumented behavior change |
|
|
158
|
+
| Deadlock regression | New states or transitions must not introduce deadlocks not present in BEFORE | Error |
|
|
159
|
+
| Complexity claim | If plan claims "simpler": count states + transitions + guards. Is AFTER objectively simpler? | Warning — unsubstantiated claim |
|
|
160
|
+
| Unreachable code | New states added in AFTER must be reachable (otherwise they're dead code from the start) | Warning |
|
|
161
|
+
|
|
162
|
+
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
|
|
163
|
+
|
|
164
|
+
**Detection step**: Before generating any verification code, run `python3 --version 2>&1` or `python --version 2>&1`. Check the output:
|
|
165
|
+
|
|
166
|
+
- Returns `Python 3.x.y` with x ≥ 6 → use Python harness
|
|
167
|
+
- Returns anything else (command not found, "Python was not found" Windows stub, version < 3.6) → fall back to Manual Verification Mode
|
|
168
|
+
- On Windows, if `python` launches the Microsoft Store, treat as unavailable
|
|
169
|
+
|
|
170
|
+
Do NOT attempt to install Python — the user's embedded development machine may be air-gapped or locked down.
|
|
171
|
+
|
|
172
|
+
In DSH, prefer the native `logicprobe_verify` tool (model JSON, structured guard DSL, path-aware invariants) — see `references/dsh-model-schema.md`. For non-DSH hosts, the reusable Python harness is `references/verification-harness.py`. For detailed probe patterns, model extraction methodology, and manual verification procedures, load `references/logic-verification-guide.md`.
|
|
173
|
+
|
|
174
|
+
### Phase 2a: Structural Primitives (7 Checks)
|
|
175
|
+
|
|
176
|
+
Run these FIRST. They establish basic well-formedness before adversarial probing.
|
|
177
|
+
|
|
178
|
+
| # | Primitive | Method | Severity if Violated |
|
|
179
|
+
|:--:|-----------|--------|:---:|
|
|
180
|
+
| S1 | **Reachability** | BFS from init state; flag all states not in visited set | Warning — dead code |
|
|
181
|
+
| S2 | **Deadlock** | Any non-terminal state with zero outgoing transitions? | Error — machine can get stuck |
|
|
182
|
+
| 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 |
|
|
183
|
+
| S4 | **Determinism** | Same state + same event → multiple different targets? | Error — ambiguous behavior |
|
|
184
|
+
| S5 | **Event completeness** | For each state, are there plausible events with no defined transition? | Warning — implicit ignore |
|
|
185
|
+
| 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 |
|
|
186
|
+
| S7 | **Invariant validity** | Does every reachable state satisfy the plan's stated "always/never/guaranteed" assertions? | Error — plan claim is false |
|
|
187
|
+
|
|
188
|
+
### Phase 2b: Adversarial Probes (7 Attacks)
|
|
189
|
+
|
|
190
|
+
Run these SECOND. Each probe actively tries to BREAK the model. If any probe succeeds (finds a violation), the plan has a behavior gap.
|
|
191
|
+
|
|
192
|
+
| # | Attack | Method | Target Claim |
|
|
193
|
+
|:--:|--------|--------|-------------|
|
|
194
|
+
| A1 | **Unexpected event** | For each state S, inject every event E where no transition is defined for (S, E). Log whether the model silently ignores or crashes. | "All events are handled in all states" |
|
|
195
|
+
| A2 | **Race interleaving** | For every pair of concurrent events (E1, E2), simulate arrival in both orders: E1-then-E2 vs E2-then-E1. Flag if terminal state differs. | "Behavior is independent of event ordering" |
|
|
196
|
+
| A3 | **Order permutation** | For N independent events, permute arrival order. Flag if different permutations produce different final states or violate invariants. | "Outcome is order-independent" |
|
|
197
|
+
| A4 | **Pair symmetry** | Match every `start/stop`, `lock/unlock`, `alloc/free` pair. Flag if any state allows a path where a pair is unbalanced (start without stop, lock without unlock). | "Resources are always released" |
|
|
198
|
+
| A5 | **Boundary blast** | Probe counters at 0, 1, max-1, max, max+1. Probe timestamps at 0, tick_wraparound. Flag overflow, underflow, or undefined behavior. | "Handles all counter/timer values" |
|
|
199
|
+
| A6 | **Resource injection** | Simulate `malloc→NULL`, `queue→full`, `semaphore→timeout` at each state that calls them. Flag if any state has no recovery path. | "Graceful degradation under resource pressure" |
|
|
200
|
+
| A7 | **Minimal counter-example** | For any invariant that fails, find the SHORTEST event sequence that violates it (BFS from init to violating state). Output the exact path. | "This invariant holds" → refuted by shortest path |
|
|
201
|
+
|
|
202
|
+
### Integration Back to Phase 3
|
|
203
|
+
|
|
204
|
+
For every probe failure:
|
|
205
|
+
|
|
206
|
+
1. **Quote** the plan claim verbatim
|
|
207
|
+
2. **Show** the counter-example event sequence
|
|
208
|
+
3. **Classify** severity (Architecture / Mechanism / Consistency)
|
|
209
|
+
4. **Propose** correction direction — never fix inline
|
|
210
|
+
|
|
211
|
+
### Extraction Rule
|
|
212
|
+
|
|
213
|
+
Before writing any verification code, output a transition table:
|
|
214
|
+
|
|
215
|
+
```text
|
|
216
|
+
State | Event/Condition | Next State | Guard?
|
|
217
|
+
------------|----------------------------|---------------|-------
|
|
218
|
+
INIT | power_ready | IDLE | -
|
|
219
|
+
IDLE | start_cmd | STARTING | -
|
|
220
|
+
IDLE | error_detected | ERROR | -
|
|
221
|
+
STARTING | ack_received | ACTIVE | -
|
|
222
|
+
STARTING | timeout | ERROR | retry==0
|
|
223
|
+
STARTING | timeout | FATAL | retry>=1
|
|
224
|
+
ACTIVE | done | IDLE | -
|
|
225
|
+
ERROR | cooldown_elapsed | RECOVERING | -
|
|
226
|
+
RECOVERING | reinit_complete | IDLE | -
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**CRITICAL**: Show this table to the user and ask for confirmation before generating the harness. The #1 failure mode of verification is extracting the wrong model. If the plan is ambiguous, flag it as a finding first — don't guess.
|
|
230
|
+
|
|
231
|
+
**Exception**: If the runtime reports `logicprobe interaction=auto`, do NOT call `ask_user_question`. Instead: (a) cite evidence for every extracted state/transition/guard, (b) round-trip the filled model back into a transition table and compare it with the extraction table, and (c) mark the report `UNCONFIRMED`.
|
|
232
|
+
|
|
233
|
+
### Code-Level Behavioral Suggestion
|
|
234
|
+
|
|
235
|
+
When the task is NOT document/plan review but involves code-level behavioral questions — e.g., the user is editing source files and asks:
|
|
236
|
+
|
|
237
|
+
- "check this timing sequence for bugs"
|
|
238
|
+
- "could this state machine deadlock here"
|
|
239
|
+
- "is this retry limit safe"
|
|
240
|
+
- "what happens if event X arrives during state Y"
|
|
241
|
+
|
|
242
|
+
→ **Proactively suggest** logicprobe 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?"
|
|
243
|
+
|
|
244
|
+
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.
|
|
245
|
+
|
|
246
|
+
This covers the gap where behavioral verification is useful even when no design document is being reviewed.
|
|
247
|
+
|
|
248
|
+
### When NOT to Escalate
|
|
249
|
+
|
|
250
|
+
Skip logic-primitive verification when:
|
|
251
|
+
|
|
252
|
+
- The document makes no behavioral/logic claims (pure API listings, config tables, data schemas)
|
|
253
|
+
- The state machine has ≤2 states, no guards, and trivial transitions (IDLE↔ACTIVE)
|
|
254
|
+
- The claim is purely structural (file paths, type names, numeric constants) — Phase 2 grep verification is sufficient
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Rules
|
|
259
|
+
|
|
260
|
+
1. Never trust a document's claim without codebase verification.
|
|
261
|
+
2. Be honest about mechanism boundaries — if the language standard can't do it, say so.
|
|
262
|
+
3. Cite evidence with specific file:line references.
|
|
263
|
+
4. Don't fix during review — point the way, let implementation happen after approval.
|
|
264
|
+
5. **For behavioral claims: verify with code, not reasoning.** If a plan says "always", "never", or "guaranteed", generate and run a model. One counter-example is enough to refute a universal claim.
|
|
265
|
+
6. **Confirm the model before running it** — unless the runtime reports `logicprobe interaction=auto`. Extraction errors are the dominant failure mode of formal verification. In auto mode, substitute evidence-cited extraction + round-trip validation and mark the report `UNCONFIRMED`.
|
|
266
|
+
7. **Don't verify what the code already checks.** If the existing codebase has compile-time assertions, static analysis, or runtime checks for a property, cite those — don't re-verify in a Python model.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# DSH Model Schema v1 — logicprobe_verify
|
|
2
|
+
|
|
3
|
+
The dsh-native `logicprobe_verify` tool accepts a structured JSON model. The engine runs 14 checks (S1-S7 structural, A1-A7 adversarial) and returns a JSON report. Guards and updates are structured data — no code strings, no arbitrary execution.
|
|
4
|
+
|
|
5
|
+
## Top-level model
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"schemaVersion": 1,
|
|
10
|
+
"init": "INIT",
|
|
11
|
+
"states": [{ "id": "INIT" }, { "id": "ACTIVE", "terminal": true }],
|
|
12
|
+
"transitions": [
|
|
13
|
+
{ "from": "INIT", "event": "go", "to": "ACTIVE" }
|
|
14
|
+
],
|
|
15
|
+
"variables": [],
|
|
16
|
+
"invariants": [],
|
|
17
|
+
"concurrentPairs": [],
|
|
18
|
+
"boundaryChecks": [],
|
|
19
|
+
"resourcePairs": []
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
| Field | Required | Meaning |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| `schemaVersion` | yes | Must be `1` |
|
|
26
|
+
| `init` | yes | Initial state id |
|
|
27
|
+
| `states` | yes | `{ id, terminal? }`; `terminal` exempts S2/S3/S5/A1 |
|
|
28
|
+
| `transitions` | yes | `{ from, event, to, guard?, updates? }` |
|
|
29
|
+
| `variables` | no | `{ name, kind: integer\|boolean, init, min?, max? }` |
|
|
30
|
+
| `invariants` | no | See invariant kinds below |
|
|
31
|
+
| `concurrentPairs` | no | `["eventA", "eventB"]` pairs for A2 |
|
|
32
|
+
| `boundaryChecks` | no | `{ variable, values: number[] }` for A5 |
|
|
33
|
+
| `resourcePairs` | no | `{ resource, acquireEvent, releaseEvent, failEvent? }` for A4/A6 |
|
|
34
|
+
|
|
35
|
+
## Guards
|
|
36
|
+
|
|
37
|
+
A guard is exactly one of:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{ "variable": "retry", "op": "<", "value": 3 }
|
|
41
|
+
{ "all": [ { "variable": "armed", "op": "==", "value": true }, { "variable": "retry", "op": ">", "value": 0 } ] }
|
|
42
|
+
{ "any": [ { "variable": "mode", "op": "==", "value": 1 }, { "variable": "mode", "op": "==", "value": 2 } ] }
|
|
43
|
+
{ "not": { "variable": "locked", "op": "==", "value": true } }
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- Boolean variables only support `==` / `!=`.
|
|
47
|
+
- A transition with **no guard** is the default/else branch for its `(from, event)` group. It fires only when no guarded branch in that group is true.
|
|
48
|
+
- Multiple true guards in one `(from, event)` group are reported as S4 nondeterminism; a group with guards and no default must be exhaustive or S6 flags the missing branch.
|
|
49
|
+
|
|
50
|
+
## Updates
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{ "variable": "retry", "op": "inc", "value": 1 }
|
|
54
|
+
{ "variable": "retry", "op": "set", "value": 0 }
|
|
55
|
+
{ "variable": "retry", "op": "dec", "value": 1 }
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`inc`/`dec` default to 1 when `value` is omitted. `set` defaults to 0.
|
|
59
|
+
|
|
60
|
+
## Invariants
|
|
61
|
+
|
|
62
|
+
| Kind | Shape | Checks |
|
|
63
|
+
|---|---|---|
|
|
64
|
+
| `never-states` | `{ states: ["ERROR"] }` | No reachable runtime state may be in the forbidden set |
|
|
65
|
+
| `var-in-range` | `{ variable, min?, max? }` | Every reachable runtime state keeps the variable in range |
|
|
66
|
+
| `event-before-state` | `{ event: "power_ready", state: "ACTIVE" }` | Every path entering `state` must have passed through `event` first |
|
|
67
|
+
|
|
68
|
+
A7 reports the shortest violating path for each failed invariant. An empty path means the initial state already violates it.
|
|
69
|
+
|
|
70
|
+
## Permission presets and interaction mode
|
|
71
|
+
|
|
72
|
+
| Preset | sandbox | approval | logicprobe behavior |
|
|
73
|
+
|---|---|---|---|
|
|
74
|
+
| `workspace-write` | workspace-write | ask | Evidence stays in workspace; model confirmation defaults to ask |
|
|
75
|
+
| `danger-full-access` | danger-full-access | never | Full file access; interaction resolves to auto; never request sandbox escalation |
|
|
76
|
+
| custom | any | any | The session folds the last `sandbox/mode` and `approval/policy` events; interaction follows approval only |
|
|
77
|
+
|
|
78
|
+
In `interaction=auto`, do NOT call `ask_user_question` for model confirmation. Round-trip the extracted model into a transition table, compare it against the source extraction, and mark the report `UNCONFIRMED`.
|
|
79
|
+
|
|
80
|
+
## Minimal example
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"schemaVersion": 1,
|
|
85
|
+
"init": "INIT",
|
|
86
|
+
"states": [
|
|
87
|
+
{ "id": "INIT" },
|
|
88
|
+
{ "id": "RETRY" },
|
|
89
|
+
{ "id": "FATAL", "terminal": true }
|
|
90
|
+
],
|
|
91
|
+
"transitions": [
|
|
92
|
+
{ "from": "INIT", "event": "timeout", "guard": { "variable": "retry", "op": "<", "value": 3 }, "to": "RETRY", "updates": [{ "variable": "retry", "op": "inc" }] },
|
|
93
|
+
{ "from": "INIT", "event": "timeout", "guard": { "variable": "retry", "op": ">=", "value": 3 }, "to": "FATAL" }
|
|
94
|
+
],
|
|
95
|
+
"variables": [{ "name": "retry", "kind": "integer", "init": 0, "min": 0, "max": 3 }],
|
|
96
|
+
"boundaryChecks": [{ "variable": "retry", "values": [0, 1, 2, 3] }]
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Limits
|
|
101
|
+
|
|
102
|
+
- State-space exploration caps at `maxStates` (default 10000); larger guards/domains may report truncation instead of a false pass.
|
|
103
|
+
- A3 samples the first `maxPermutationEvents` events (default 5).
|
|
104
|
+
- The engine is a finite-state model checker. It cannot prove properties of the real implementation; follow with code-level review.
|