dsh-logicprobe 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Amethyst Luna
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Amethyst Luna
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.en-US.md CHANGED
@@ -13,10 +13,11 @@ Design documents are not truth — code is. A claim-verification skill that chec
13
13
  | Phase | What |
14
14
  |-------|------|
15
15
  | Phase 1-2 | Enumerate every verifiable claim (API names, file paths, enum values, counts, mechanism feasibility) → verify each against the codebase with evidence |
16
- | Phase 2a | **7 structural checks** on extracted state-machine models: reachability, deadlock, liveness, determinism, event/guard completeness, invariant validity |
17
- | Phase 2b | **7 adversarial probes**: unexpected events, race interleaving, order permutation, pair symmetry (lock/unlock), boundary blast, resource injection, minimal counter-example |
16
+ | Phase 2a | **8 structural checks** on extracted state-machine models: reachability, deadlock, liveness, determinism, event/guard completeness, invariant validity, monotonic variables |
17
+ | Phase 2b | **11 adversarial probes**: unexpected events, race interleaving, order permutation, pair symmetry (lock/unlock), boundary blast, resource injection, minimal counter-example, idempotent replay, leads-to, sequence, atomicity |
18
18
  | Refactoring | Before/after model comparison — behavioral preservation, invariant continuity, deadlock regression, complexity claims |
19
19
  | Data models | DataModelV1 verification — DS/DA/DD checks, migration coverage, copy consistency, before/after breaking-change regression |
20
+ | Concurrency risk mining | Scans documents/plans for concurrency safety claims (thread-safe, lock-free, race condition, interrupt safety, etc.) and flags them for dedicated verification |
20
21
  | Output | Structured findings with exact file:line evidence, severity classification, correction direction — never inline fixes |
21
22
 
22
23
  The model is always shown as a transition table and **confirmed with the user before running** — extraction errors are the dominant failure mode.
package/README.md CHANGED
@@ -11,10 +11,11 @@
11
11
  | 阶段 | 内容 |
12
12
  |------|------|
13
13
  | Phase 1-2 | 枚举每个可验证声称(API 名、文件路径、枚举值、数量、机制可行性)→ 逐条对照代码库给出证据 |
14
- | Phase 2a | 对提取的状态机模型执行 **7 项结构检查**:可达性、死锁、活性、确定性、事件/守卫完备性、不变量有效性 |
15
- | Phase 2b | **7 种对抗探针**:意外事件、竞态交错、顺序置换、配对对称(lock/unlock)、边界轰炸、资源注入、最小反例 |
14
+ | Phase 2a | 对提取的状态机模型执行 **8 项结构检查**:可达性、死锁、活性、确定性、事件/守卫完备性、不变量有效性、单调变量 |
15
+ | Phase 2b | **11 种对抗探针**:意外事件、竞态交错、顺序置换、配对对称(lock/unlock)、边界轰炸、资源注入、最小反例、幂等重放、必达、顺序、原子性 |
16
16
  | 重构模式 | 前后模型对比——行为保持、不变量连续性、死锁回归、复杂度声称 |
17
17
  | 数据模型模式 | DataModelV1 数据模型验证——DS/DA/DD 检查,迁移覆盖、copy 一致性、before/after 破坏性变更回归 |
18
+ | 并发风险挖掘 | 扫描文档/计划中的并发安全声称(thread-safe、lock-free、race condition、中断安全等),标记需要专用验证 |
18
19
  | 输出 | 结构化发现:精确 file:line 证据、严重性分级、修正方向——绝不在核查中直接改代码 |
19
20
 
20
21
  模型永远先以转换表形式展示并**经用户确认后才运行**——模型提取错误是验证的头号失败模式。
@@ -1,34 +1,34 @@
1
- import { defineTool } from '@deepseek-ai/dsh-tools';
2
- import { runConcurrencyScan } from './concurrency.js';
3
- export const LOGICPROBE_CONCURRENCY_SCAN_TOOL_NAME = 'logicprobe_concurrency_scan';
4
- /**
5
- * Model-visible DSH tool that mines design documents/plans for concurrency-related
6
- * claims and risk keywords. It does not prove concurrency safety; it flags terms
7
- * such as "thread-safe", "lock-free", "race condition", "atomic", "mutex", etc.,
8
- * so the model can either provide dedicated evidence or mark the claim unverified.
9
- */
10
- export const logicProbeConcurrencyScanTool = defineTool({
11
- name: LOGICPROBE_CONCURRENCY_SCAN_TOOL_NAME,
12
- description: 'Scan a document or plan text for concurrency risk points. Use ONLY after confirming the target actually has concurrency requirements or behavior (threads, async tasks, interrupts, shared state, parallel execution). If the target is purely sequential, do not call this tool. Returns findings for keywords like thread-safe, lock-free, data race, race condition, atomic, synchronized, mutex, semaphore, shared variable, reentrant, interrupt-safe. Absolute claims (thread-safe, lock-free, no data race) are flagged as errors requiring dedicated verification.',
13
- parameters: {
14
- text: {
15
- type: 'string',
16
- required: true,
17
- description: 'Document or plan text to scan for concurrency-related claims.',
18
- },
19
- },
20
- output: {
21
- schema: {
22
- type: 'json',
23
- description: 'Concurrency scan report with findings and summary.',
24
- },
25
- render(_args, value) {
26
- return [{ type: 'text', text: JSON.stringify(value, null, 2) }];
27
- },
28
- },
29
- timeoutMs: 10_000,
30
- isConcurrencySafe: () => true,
31
- async execute(args) {
32
- return runConcurrencyScan(args.text);
33
- },
34
- });
1
+ import { defineTool } from '@deepseek-ai/dsh-tools';
2
+ import { runConcurrencyScan } from './concurrency.js';
3
+ export const LOGICPROBE_CONCURRENCY_SCAN_TOOL_NAME = 'logicprobe_concurrency_scan';
4
+ /**
5
+ * Model-visible DSH tool that mines design documents/plans for concurrency-related
6
+ * claims and risk keywords. It does not prove concurrency safety; it flags terms
7
+ * such as "thread-safe", "lock-free", "race condition", "atomic", "mutex", etc.,
8
+ * so the model can either provide dedicated evidence or mark the claim unverified.
9
+ */
10
+ export const logicProbeConcurrencyScanTool = defineTool({
11
+ name: LOGICPROBE_CONCURRENCY_SCAN_TOOL_NAME,
12
+ description: 'Scan a document or plan text for concurrency risk points. Use ONLY after confirming the target actually has concurrency requirements or behavior (threads, async tasks, interrupts, shared state, parallel execution). If the target is purely sequential, do not call this tool. Returns findings for keywords like thread-safe, lock-free, data race, race condition, atomic, synchronized, mutex, semaphore, shared variable, reentrant, interrupt-safe. Absolute claims (thread-safe, lock-free, no data race) are flagged as errors requiring dedicated verification.',
13
+ parameters: {
14
+ text: {
15
+ type: 'string',
16
+ required: true,
17
+ description: 'Document or plan text to scan for concurrency-related claims.',
18
+ },
19
+ },
20
+ output: {
21
+ schema: {
22
+ type: 'json',
23
+ description: 'Concurrency scan report with findings and summary.',
24
+ },
25
+ render(_args, value) {
26
+ return [{ type: 'text', text: JSON.stringify(value, null, 2) }];
27
+ },
28
+ },
29
+ timeoutMs: 10_000,
30
+ isConcurrencySafe: () => true,
31
+ async execute(args) {
32
+ return runConcurrencyScan(args.text);
33
+ },
34
+ });
@@ -1,76 +1,76 @@
1
- const KEYWORD_RULES = [
2
- { pattern: /\bthread\s*-?\s*safe\b/i, label: 'thread-safe', absolute: true },
3
- { pattern: /\block\s*-?\s*free\b/i, label: 'lock-free', absolute: true },
4
- { pattern: /\bwait\s*-?\s*free\b/i, label: 'wait-free', absolute: true },
5
- { pattern: /\bno\s+data\s+race\b/i, label: 'no data race', absolute: true },
6
- { pattern: /\brace\s*-?\s*free\b/i, label: 'race-free', absolute: true },
7
- { pattern: /\bdata\s+race\b/i, label: 'data race', absolute: false },
8
- { pattern: /\brace\s+condition\b/i, label: 'race condition', absolute: false },
9
- { pattern: /\bthread\s*-?\s*safety\b/i, label: 'thread safety', absolute: false },
10
- { pattern: /\bconcurrent\b/i, label: 'concurrent', absolute: false },
11
- { pattern: /\bparallel\b/i, label: 'parallel', absolute: false },
12
- { pattern: /\bmulti-?threaded\b/i, label: 'multi-threaded', absolute: false },
13
- { pattern: /\bmultithreaded\b/i, label: 'multithreaded', absolute: false },
14
- { pattern: /\batomic\b/i, label: 'atomic', absolute: false },
15
- { pattern: /\bsynchronized\b/i, label: 'synchronized', absolute: false },
16
- { pattern: /\bmutex\b/i, label: 'mutex', absolute: false },
17
- { pattern: /\bsemaphore\b/i, label: 'semaphore', absolute: false },
18
- { pattern: /\bspinlock\b/i, label: 'spinlock', absolute: false },
19
- { pattern: /\bshared\s+variable\b/i, label: 'shared variable', absolute: false },
20
- { pattern: /\bshared\s+memory\b/i, label: 'shared memory', absolute: false },
21
- { pattern: /\bglobal\s+state\b/i, label: 'global state', absolute: false },
22
- { pattern: /\breentrant\b/i, label: 'reentrant', absolute: false },
23
- { pattern: /\binterrupt\s*-?\s*safe\b/i, label: 'interrupt-safe', absolute: true },
24
- { pattern: /\bISR\s*-?\s*safe\b/i, label: 'ISR-safe', absolute: true },
25
- { pattern: /\binterrupt\s+safety\b/i, label: 'interrupt safety', absolute: false },
26
- { pattern: /\binterrupt\s+context\b/i, label: 'interrupt context', absolute: false },
27
- { pattern: /\bISR\b/i, label: 'ISR', absolute: false },
28
- { pattern: /\bIRQ\b/i, label: 'IRQ', absolute: false },
29
- { pattern: /\bNMI\b/i, label: 'NMI', absolute: false },
30
- { pattern: /\bcritical\s+section\b/i, label: 'critical section', absolute: false },
31
- { pattern: /\bdisable_irq\b/i, label: 'disable_irq', absolute: false },
32
- { pattern: /\benable_irq\b/i, label: 'enable_irq', absolute: false },
33
- { pattern: /\bspin_lock_irqsave\b/i, label: 'spin_lock_irqsave', absolute: false },
34
- ];
35
- export function runConcurrencyScan(text) {
36
- const lines = text.split(/\r?\n/);
37
- const findings = [];
38
- const seen = new Set();
39
- lines.forEach((line, index) => {
40
- const lineNumber = index + 1;
41
- const lower = line.toLowerCase();
42
- for (const rule of KEYWORD_RULES) {
43
- if (!rule.pattern.test(line))
44
- continue;
45
- const key = rule.label + ':' + lineNumber;
46
- if (seen.has(key))
47
- continue;
48
- seen.add(key);
49
- const finding = {
50
- code: rule.absolute ? 'CONCURRENCY_ABSOLUTE_CLAIM' : 'CONCURRENCY_KEYWORD',
51
- severity: rule.absolute ? 'error' : 'warning',
52
- message: rule.absolute
53
- ? 'Concurrency safety claim "' + rule.label + '" detected; this requires dedicated verification (TSan, model checker, or explicit proof).'
54
- : 'Concurrency-related term "' + rule.label + '" detected; review whether the plan addresses this risk.',
55
- line: lineNumber,
56
- snippet: line.trim().slice(0, 200),
57
- keyword: rule.label,
58
- };
59
- findings.push(finding);
60
- }
61
- });
62
- const errors = findings.filter((finding) => finding.severity === 'error').length;
63
- const warnings = findings.filter((finding) => finding.severity === 'warning').length;
64
- const absoluteClaims = findings.filter((finding) => finding.code === 'CONCURRENCY_ABSOLUTE_CLAIM').length;
65
- return {
66
- ok: true,
67
- findings,
68
- summary: {
69
- lines: lines.length,
70
- keywords: findings.length,
71
- absoluteClaims,
72
- warnings,
73
- errors,
74
- },
75
- };
76
- }
1
+ const KEYWORD_RULES = [
2
+ { pattern: /\bthread\s*-?\s*safe\b/i, label: 'thread-safe', absolute: true },
3
+ { pattern: /\block\s*-?\s*free\b/i, label: 'lock-free', absolute: true },
4
+ { pattern: /\bwait\s*-?\s*free\b/i, label: 'wait-free', absolute: true },
5
+ { pattern: /\bno\s+data\s+race\b/i, label: 'no data race', absolute: true },
6
+ { pattern: /\brace\s*-?\s*free\b/i, label: 'race-free', absolute: true },
7
+ { pattern: /\bdata\s+race\b/i, label: 'data race', absolute: false },
8
+ { pattern: /\brace\s+condition\b/i, label: 'race condition', absolute: false },
9
+ { pattern: /\bthread\s*-?\s*safety\b/i, label: 'thread safety', absolute: false },
10
+ { pattern: /\bconcurrent\b/i, label: 'concurrent', absolute: false },
11
+ { pattern: /\bparallel\b/i, label: 'parallel', absolute: false },
12
+ { pattern: /\bmulti-?threaded\b/i, label: 'multi-threaded', absolute: false },
13
+ { pattern: /\bmultithreaded\b/i, label: 'multithreaded', absolute: false },
14
+ { pattern: /\batomic\b/i, label: 'atomic', absolute: false },
15
+ { pattern: /\bsynchronized\b/i, label: 'synchronized', absolute: false },
16
+ { pattern: /\bmutex\b/i, label: 'mutex', absolute: false },
17
+ { pattern: /\bsemaphore\b/i, label: 'semaphore', absolute: false },
18
+ { pattern: /\bspinlock\b/i, label: 'spinlock', absolute: false },
19
+ { pattern: /\bshared\s+variable\b/i, label: 'shared variable', absolute: false },
20
+ { pattern: /\bshared\s+memory\b/i, label: 'shared memory', absolute: false },
21
+ { pattern: /\bglobal\s+state\b/i, label: 'global state', absolute: false },
22
+ { pattern: /\breentrant\b/i, label: 'reentrant', absolute: false },
23
+ { pattern: /\binterrupt\s*-?\s*safe\b/i, label: 'interrupt-safe', absolute: true },
24
+ { pattern: /\bISR\s*-?\s*safe\b/i, label: 'ISR-safe', absolute: true },
25
+ { pattern: /\binterrupt\s+safety\b/i, label: 'interrupt safety', absolute: false },
26
+ { pattern: /\binterrupt\s+context\b/i, label: 'interrupt context', absolute: false },
27
+ { pattern: /\bISR\b/i, label: 'ISR', absolute: false },
28
+ { pattern: /\bIRQ\b/i, label: 'IRQ', absolute: false },
29
+ { pattern: /\bNMI\b/i, label: 'NMI', absolute: false },
30
+ { pattern: /\bcritical\s+section\b/i, label: 'critical section', absolute: false },
31
+ { pattern: /\bdisable_irq\b/i, label: 'disable_irq', absolute: false },
32
+ { pattern: /\benable_irq\b/i, label: 'enable_irq', absolute: false },
33
+ { pattern: /\bspin_lock_irqsave\b/i, label: 'spin_lock_irqsave', absolute: false },
34
+ ];
35
+ export function runConcurrencyScan(text) {
36
+ const lines = text.split(/\r?\n/);
37
+ const findings = [];
38
+ const seen = new Set();
39
+ lines.forEach((line, index) => {
40
+ const lineNumber = index + 1;
41
+ const lower = line.toLowerCase();
42
+ for (const rule of KEYWORD_RULES) {
43
+ if (!rule.pattern.test(line))
44
+ continue;
45
+ const key = rule.label + ':' + lineNumber;
46
+ if (seen.has(key))
47
+ continue;
48
+ seen.add(key);
49
+ const finding = {
50
+ code: rule.absolute ? 'CONCURRENCY_ABSOLUTE_CLAIM' : 'CONCURRENCY_KEYWORD',
51
+ severity: rule.absolute ? 'error' : 'warning',
52
+ message: rule.absolute
53
+ ? 'Concurrency safety claim "' + rule.label + '" detected; this requires dedicated verification (TSan, model checker, or explicit proof).'
54
+ : 'Concurrency-related term "' + rule.label + '" detected; review whether the plan addresses this risk.',
55
+ line: lineNumber,
56
+ snippet: line.trim().slice(0, 200),
57
+ keyword: rule.label,
58
+ };
59
+ findings.push(finding);
60
+ }
61
+ });
62
+ const errors = findings.filter((finding) => finding.severity === 'error').length;
63
+ const warnings = findings.filter((finding) => finding.severity === 'warning').length;
64
+ const absoluteClaims = findings.filter((finding) => finding.code === 'CONCURRENCY_ABSOLUTE_CLAIM').length;
65
+ return {
66
+ ok: true,
67
+ findings,
68
+ summary: {
69
+ lines: lines.length,
70
+ keywords: findings.length,
71
+ absoluteClaims,
72
+ warnings,
73
+ errors,
74
+ },
75
+ };
76
+ }