progmune-runtime 3.5.0 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/README.md +13 -5
- package/README.zh-CN.md +12 -4
- package/dist/planner.js +4 -20
- package/dist/ssg-validator.js +24 -1
- package/dist/trust/ssg-bridge.js +68 -10
- package/dist/trust/ssg-bridge.test.js +10 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.6.0] — 2026-08-23
|
|
4
|
+
|
|
5
|
+
### 新增:SSG endState 检查(序列末尾资源未释放)
|
|
6
|
+
|
|
7
|
+
- trust 桥接路径(`src/trust/ssg-bridge.ts`)补齐 endState 检测:函数序列末尾仍有未释放资源状态 → 违规(`endState: true`、`fixPath=[releaseFn]`、追加式修复文案、独立 rule_id `SSG_*_END_STATE_VIOLATION`)
|
|
8
|
+
- 与 planner 语义对齐:共享判定 `findHeldResourceStates` + `RESOURCE_NAMESPACE_RE` 入 `ssg-validator.ts`(planner 重构换用,语义不变)
|
|
9
|
+
- 边界:仅资源生命周期命名空间(auth/session 合法地以活跃会话结束不检查);仅本序列新获取的状态(继承自初始态不算泄漏)
|
|
10
|
+
- **Python 协议盲测 v1 复测:40/40 全检出(Recall/Precision 100%,0 FP)**,基线 `BASELINE_PROTOCOL_PYTHON_v1.md`
|
|
11
|
+
|
|
12
|
+
### 新增:Python 协议盲测基准(v1)
|
|
13
|
+
|
|
14
|
+
- `blind-benchmark/generate-projects-protocol-python.ts` + `scan-protocol-python.ts` + `expand-gold-protocol-python.ts`:6 违规类型 × 4 结构风格 = 24 项目,金标 `annotations-protocol-python-v1.json`
|
|
15
|
+
- 测量生产 SSG 桥接校验器(确定性、无 LLM);回归测试 `tests/python-protocol-benchmark.test.ts`
|
|
16
|
+
|
|
17
|
+
### 文档
|
|
18
|
+
|
|
19
|
+
- README 新增「社区与反馈」章节:讨论群二维码(`assets/wechat-group.png`,当前为占位图待替换真实群码)+ GitHub Issues 通道(中英双语)
|
|
20
|
+
- README 删除双峰(Two-Hump)内容:科学基础章节的双峰类比段与 P0-P3 节的双峰报告链接
|
|
21
|
+
- 覆盖矩阵(中英)刷新至 2026-08-23 并新增英文版 `coverage-matrix-en.md`;架构图规则数修正 140→148(与 protocols.json 实测一致)
|
|
22
|
+
|
|
3
23
|
## [3.5.0] — 2026-08-22
|
|
4
24
|
|
|
5
25
|
### 新增:多语言合并 IR(注册表式提取)
|
package/README.md
CHANGED
|
@@ -118,7 +118,7 @@ Progmune is honest about what it can and cannot verify.
|
|
|
118
118
|
- **Framework internals** — well-known framework dispatch/cache machinery (e.g. django-unicorn internals) can produce a small number of boundary false positives; they are documented per-corpus in the benchmark gold files.
|
|
119
119
|
- **Known failure boundaries are documented** rather than hidden: if Progmune cannot verify a language (e.g. Go), Confidence is lowered instead of pretending 100%.
|
|
120
120
|
|
|
121
|
-
→ [Full Coverage Matrix](https://github.com/shenlian19831109/progmune-runtime/blob/main/docs/coverage-matrix.md)
|
|
121
|
+
→ [Full Coverage Matrix](https://github.com/shenlian19831109/progmune-runtime/blob/main/docs/coverage-matrix-en.md)
|
|
122
122
|
|
|
123
123
|
---
|
|
124
124
|
|
|
@@ -162,7 +162,7 @@ C analysis is **research-only**: gold benchmark F1=16.5% across 4 repos (curl, l
|
|
|
162
162
|
- Bootstrapping deadlock broken: all 21 protocol namespaces now have rule vocabulary
|
|
163
163
|
- `excludePatterns` + `languages` architecture for FP management
|
|
164
164
|
|
|
165
|
-
→ [
|
|
165
|
+
→ [P0-P3 Final Report](https://github.com/shenlian19831109/progmune-runtime/blob/main/docs/p0-p3-final-report.md)
|
|
166
166
|
|
|
167
167
|
---
|
|
168
168
|
|
|
@@ -179,7 +179,7 @@ SDK (src/sdk.ts) verify() → APPROVED / NEEDS_REVIEW / BLOCKED
|
|
|
179
179
|
│ source-level markers: taint tracking, import resolution,
|
|
180
180
|
│ qualified call chains, cross-file template analysis
|
|
181
181
|
├─ Repair Executor detect → plan → fix → validate → commit/rollback
|
|
182
|
-
└─ Knowledge Base 31 domains,
|
|
182
|
+
└─ Knowledge Base 31 domains, 148 rules, evidence chains
|
|
183
183
|
```
|
|
184
184
|
|
|
185
185
|
### Interfaces
|
|
@@ -194,12 +194,20 @@ SDK (src/sdk.ts) verify() → APPROVED / NEEDS_REVIEW / BLOCKED
|
|
|
194
194
|
|
|
195
195
|
---
|
|
196
196
|
|
|
197
|
+
## Community & Feedback
|
|
198
|
+
|
|
199
|
+
<p align="center">
|
|
200
|
+
<img src="https://raw.githubusercontent.com/shenlian19831109/progmune-runtime/main/assets/wechat-group.png" width="240" alt="Progmune user discussion group QR code" />
|
|
201
|
+
</p>
|
|
202
|
+
|
|
203
|
+
Your feedback shapes Progmune. Scan the QR code to join the user discussion group (WeChat), or open a [GitHub Issue](https://github.com/shenlian19831109/progmune-runtime/issues) for bug reports, feature requests, and suggestions.
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
197
207
|
## Scientific Foundation
|
|
198
208
|
|
|
199
209
|
Progmune is built on the premise that **LLM outputs are statistical performances, not reasoning** — a view developed by Subbarao Kambhampati et al. in the position paper ["Stop Anthropomorphizing Intermediate Tokens as Reasoning/Thinking Traces!"](https://arxiv.org/abs/2505.22285) (arXiv:2505.22285, 2025) and elaborated in his ICML 2026 talk "On the Role of Verifiers and Thinking Traces in Reasoning Models". Rather than trusting what the model says about code, Progmune verifies what the program actually does — using protocol state machines, IR extraction, and evidence-backed decision chains.
|
|
200
210
|
|
|
201
|
-
Coverage-gap analysis borrows the "two-hump problem" terminology **as a cross-domain analogy** from Sergei Gukov's work in mathematical physics (the Andrews-Curtis conjecture in group theory, 2026) — it describes a bimodal coverage distribution, not a collaboration. See [Two-Hump Report](https://github.com/shenlian19831109/progmune-runtime/blob/main/docs/two-hump-report.md) for the full methodology.
|
|
202
|
-
|
|
203
211
|
→ [Investor Whitepaper](https://github.com/shenlian19831109/progmune-runtime/blob/main/docs/Progmune_投资人白皮书_v2.0.html) · [Trust Decision Model](https://github.com/shenlian19831109/progmune-runtime/blob/main/docs/ai-trust-decision-model-v1.md)
|
|
204
212
|
|
|
205
213
|
---
|
package/README.zh-CN.md
CHANGED
|
@@ -162,7 +162,7 @@ C 分析**仅研究**:黄金基准 F1=16.5%,覆盖 4 个仓库(curl、libs
|
|
|
162
162
|
- 打破引导死锁:全部 21 个协议命名空间已有规则词汇
|
|
163
163
|
- `excludePatterns` + `languages` 架构管理误报
|
|
164
164
|
|
|
165
|
-
→ [
|
|
165
|
+
→ [P0-P3 终报](https://github.com/shenlian19831109/progmune-runtime/blob/main/docs/p0-p3-final-report.md)
|
|
166
166
|
|
|
167
167
|
---
|
|
168
168
|
|
|
@@ -178,7 +178,7 @@ SDK (src/sdk.ts) verify() → APPROVED / NEEDS_REVIEW / BLOCKED
|
|
|
178
178
|
│ 合并为每项目一份函数 IR;
|
|
179
179
|
│ 源码级标记:污点追踪、import 解析、限定调用链、跨文件模板分析
|
|
180
180
|
├─ 修复执行器 detect → plan → fix → validate → commit/rollback
|
|
181
|
-
└─ 知识库 31 个域、
|
|
181
|
+
└─ 知识库 31 个域、148 条规则、证据链
|
|
182
182
|
```
|
|
183
183
|
|
|
184
184
|
### 接口
|
|
@@ -193,12 +193,20 @@ SDK (src/sdk.ts) verify() → APPROVED / NEEDS_REVIEW / BLOCKED
|
|
|
193
193
|
|
|
194
194
|
---
|
|
195
195
|
|
|
196
|
+
## 社区与反馈
|
|
197
|
+
|
|
198
|
+
<p align="center">
|
|
199
|
+
<img src="https://raw.githubusercontent.com/shenlian19831109/progmune-runtime/main/assets/wechat-group.png" width="240" alt="Progmune 用户讨论群二维码" />
|
|
200
|
+
</p>
|
|
201
|
+
|
|
202
|
+
你的意见塑造 Progmune。扫码加入用户讨论群(微信),或通过 [GitHub Issue](https://github.com/shenlian19831109/progmune-runtime/issues) 提交缺陷报告、功能需求与建议。
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
196
206
|
## 科学基础
|
|
197
207
|
|
|
198
208
|
Progmune 建立在"**LLM 输出是统计表演而非推理**"这一前提上——该观点源自 Subbarao Kambhampati 等人的立场论文 ["Stop Anthropomorphizing Intermediate Tokens as Reasoning/Thinking Traces!"](https://arxiv.org/abs/2505.22285)(arXiv:2505.22285,2025),并在其 ICML 2026 演讲 "On the Role of Verifiers and Thinking Traces in Reasoning Models" 中展开。Progmune 不信任模型对代码的说法,而是用协议状态机、IR 提取与证据链验证程序实际行为。
|
|
199
209
|
|
|
200
|
-
覆盖缺口分析借用"双峰问题"术语作为**跨域类比**,源自 Sergei Gukov 在数学物理领域的工作(群论中的 Andrews-Curtis 猜想,2026)——它描述的是双峰覆盖分布,而非合作关系。详见 [双峰报告](https://github.com/shenlian19831109/progmune-runtime/blob/main/docs/two-hump-report.md)。
|
|
201
|
-
|
|
202
210
|
→ [投资人白皮书](https://github.com/shenlian19831109/progmune-runtime/blob/main/docs/Progmune_投资人白皮书_v2.0.html) · [信任决策模型](https://github.com/shenlian19831109/progmune-runtime/blob/main/docs/ai-trust-decision-model-v1.md)
|
|
203
211
|
|
|
204
212
|
---
|
package/dist/planner.js
CHANGED
|
@@ -392,26 +392,10 @@ function validateProtocolWithTransitions(actions, protocols, namespaceInitialSta
|
|
|
392
392
|
}
|
|
393
393
|
}
|
|
394
394
|
// End-of-sequence check: held resources must be released (resource leak).
|
|
395
|
-
//
|
|
396
|
-
//
|
|
397
|
-
//
|
|
398
|
-
|
|
399
|
-
const RESOURCE_NS = /^(file|db|database|connection|conn|socket|stream|resource|io)/i;
|
|
400
|
-
const heldStates = [];
|
|
401
|
-
for (const p of protocols) {
|
|
402
|
-
const ann = p.protocol;
|
|
403
|
-
if (!ann)
|
|
404
|
-
continue;
|
|
405
|
-
const ns = ann.namespace || "";
|
|
406
|
-
if (!RESOURCE_NS.test(ns))
|
|
407
|
-
continue;
|
|
408
|
-
const inv = ann.invalidate || [];
|
|
409
|
-
const pre = ann.pre_states || [];
|
|
410
|
-
for (const s of inv) {
|
|
411
|
-
if (pre.includes(s))
|
|
412
|
-
heldStates.push({ state: s, releaseFn: p.function, namespace: ns });
|
|
413
|
-
}
|
|
414
|
-
}
|
|
395
|
+
// 共享判定见 ssg-validator.findHeldResourceStates:资源生命周期命名空间 +
|
|
396
|
+
// pre/invalidate 交集(获取/释放语义)。会话/认证流合法地以活跃会话结束,
|
|
397
|
+
// 不在检查范围(SESSION_ACTIVE 不是泄漏)。
|
|
398
|
+
const heldStates = (0, ssg_validator_1.findHeldResourceStates)(rules);
|
|
415
399
|
// 只检查"本序列中获取"的持有状态——继承自命名空间初始状态的
|
|
416
400
|
// (如 db 初始即 DB_CONNECTED)不算泄漏。
|
|
417
401
|
const acquiredStates = new Set();
|
package/dist/ssg-validator.js
CHANGED
|
@@ -33,7 +33,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.StateMachineValidator = exports.InvariantViolationError = void 0;
|
|
36
|
+
exports.StateMachineValidator = exports.InvariantViolationError = exports.RESOURCE_NAMESPACE_RE = void 0;
|
|
37
|
+
exports.findHeldResourceStates = findHeldResourceStates;
|
|
37
38
|
exports.rebuildState = rebuildState;
|
|
38
39
|
exports.applyTransitionDelta = applyTransitionDelta;
|
|
39
40
|
exports.findFixPathStatic = findFixPathStatic;
|
|
@@ -51,6 +52,28 @@ exports.explainRejection = explainRejection;
|
|
|
51
52
|
exports.rejectionToJSON = rejectionToJSON;
|
|
52
53
|
exports.parseProtocolsFromJSON = parseProtocolsFromJSON;
|
|
53
54
|
const crypto = __importStar(require("crypto"));
|
|
55
|
+
/** 资源生命周期命名空间:会话/认证流合法地以活跃会话结束(SESSION_ACTIVE 不是泄漏),
|
|
56
|
+
* 只有资源类命名空间(文件/数据库/连接/流等)做序列末尾持有状态检查。 */
|
|
57
|
+
exports.RESOURCE_NAMESPACE_RE = /^(file|db|database|connection|conn|socket|stream|resource|io)/i;
|
|
58
|
+
/**
|
|
59
|
+
* 找出资源持有状态候选:某规则的 pre_states 与 invalidate 的交集
|
|
60
|
+
* (获取/释放语义——如 FILE_OPEN 由 open_file 设置、close_file 释放),
|
|
61
|
+
* 仅限资源生命周期命名空间。planner 与 trust 桥接共用(endState 检查)。
|
|
62
|
+
*/
|
|
63
|
+
function findHeldResourceStates(rules) {
|
|
64
|
+
const held = [];
|
|
65
|
+
for (const [fn, ann] of rules) {
|
|
66
|
+
const ns = ann.namespace || "";
|
|
67
|
+
if (!exports.RESOURCE_NAMESPACE_RE.test(ns))
|
|
68
|
+
continue;
|
|
69
|
+
for (const s of ann.invalidate || []) {
|
|
70
|
+
if ((ann.pre_states || []).includes(s)) {
|
|
71
|
+
held.push({ state: s, releaseFn: fn, namespace: ns });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return held;
|
|
76
|
+
}
|
|
54
77
|
const DEFAULT_NAMESPACE = "_global";
|
|
55
78
|
class InvariantViolationError extends Error {
|
|
56
79
|
constructor(message, detail) {
|
package/dist/trust/ssg-bridge.js
CHANGED
|
@@ -342,6 +342,18 @@ function validateSequenceWithSSG(steps, rules, namespaceInitialStates, file, ali
|
|
|
342
342
|
return undefined;
|
|
343
343
|
}
|
|
344
344
|
})();
|
|
345
|
+
// 本序列中"新获取"的资源状态(endState 检查只针对本序列获取、未释放的状态——
|
|
346
|
+
// 继承自命名空间初始状态的不算泄漏,与 planner 语义一致)
|
|
347
|
+
const acquiredStates = new Set();
|
|
348
|
+
const trackAcquiredStates = (before, after) => {
|
|
349
|
+
for (const ns of Object.keys(after)) {
|
|
350
|
+
const prev = before?.[ns] || [];
|
|
351
|
+
for (const s of after[ns]) {
|
|
352
|
+
if (!prev.includes(s))
|
|
353
|
+
acquiredStates.add(`${ns}::${s}`);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
};
|
|
345
357
|
for (let i = 0; i < steps.length; i++) {
|
|
346
358
|
const step = steps[i];
|
|
347
359
|
const namespace = DOMAIN_TO_NAMESPACE[step.domain] || "stateless";
|
|
@@ -385,6 +397,7 @@ function validateSequenceWithSSG(steps, rules, namespaceInitialStates, file, ali
|
|
|
385
397
|
// Advance state
|
|
386
398
|
ctx.ledger.push(result.transition);
|
|
387
399
|
ctx.currentState = result.transition.statesAfter;
|
|
400
|
+
trackAcquiredStates(result.transition.statesBefore, result.transition.statesAfter);
|
|
388
401
|
}
|
|
389
402
|
else {
|
|
390
403
|
violatedCalls++;
|
|
@@ -414,6 +427,7 @@ function validateSequenceWithSSG(steps, rules, namespaceInitialStates, file, ali
|
|
|
414
427
|
// Still advance state on rejection (best-effort: apply transition anyway
|
|
415
428
|
// so subsequent calls can be validated)
|
|
416
429
|
ctx.ledger.push(result.transition);
|
|
430
|
+
trackAcquiredStates(result.transition.statesBefore, result.transition.statesAfter);
|
|
417
431
|
}
|
|
418
432
|
}
|
|
419
433
|
catch {
|
|
@@ -440,6 +454,39 @@ function validateSequenceWithSSG(steps, rules, namespaceInitialStates, file, ali
|
|
|
440
454
|
valid: true,
|
|
441
455
|
});
|
|
442
456
|
}
|
|
457
|
+
// ── End-of-sequence check: held resources must be released (resource leak).
|
|
458
|
+
// 共享判定见 ssg-validator.findHeldResourceStates:仅资源生命周期命名空间 +
|
|
459
|
+
// pre/invalidate 交集;只报本序列获取且最终仍持有的状态(对齐 planner)。
|
|
460
|
+
for (const hs of (0, ssg_validator_1.findHeldResourceStates)(rules)) {
|
|
461
|
+
const ctx = contexts.get(hs.namespace);
|
|
462
|
+
if (!ctx)
|
|
463
|
+
continue;
|
|
464
|
+
if (!acquiredStates.has(`${hs.namespace}::${hs.state}`))
|
|
465
|
+
continue;
|
|
466
|
+
const cur = ctx.currentState[hs.namespace] || [];
|
|
467
|
+
if (!cur.includes(hs.state))
|
|
468
|
+
continue;
|
|
469
|
+
violatedCalls++;
|
|
470
|
+
violations.push({
|
|
471
|
+
callName: "(end-of-sequence)",
|
|
472
|
+
namespace: hs.namespace,
|
|
473
|
+
currentState: cur,
|
|
474
|
+
requiredState: [],
|
|
475
|
+
fixPath: [hs.releaseFn],
|
|
476
|
+
matchedRule: hs.releaseFn,
|
|
477
|
+
endState: true,
|
|
478
|
+
explanation: `SSG end-state violation: resource state [${hs.state}] ` +
|
|
479
|
+
`acquired in this function is still held at end of sequence ` +
|
|
480
|
+
`(namespace ${hs.namespace}, current [${cur.join(", ")}]) — ` +
|
|
481
|
+
`missing release call: ${hs.releaseFn}.`,
|
|
482
|
+
});
|
|
483
|
+
trace.push({
|
|
484
|
+
call: "(end-of-sequence)",
|
|
485
|
+
namespace: hs.namespace,
|
|
486
|
+
matchedRule: hs.releaseFn,
|
|
487
|
+
valid: false,
|
|
488
|
+
});
|
|
489
|
+
}
|
|
443
490
|
return {
|
|
444
491
|
passed: violations.length === 0,
|
|
445
492
|
trace,
|
|
@@ -459,19 +506,30 @@ function validateSequenceWithSSG(steps, rules, namespaceInitialStates, file, ali
|
|
|
459
506
|
function ssgViolationsToTrustViolations(ssgResult, file, funcName) {
|
|
460
507
|
return ssgResult.violations.map((v) => ({
|
|
461
508
|
severity: "medium",
|
|
462
|
-
rule_id:
|
|
509
|
+
rule_id: v.endState
|
|
510
|
+
? `SSG_${v.namespace.toUpperCase()}_END_STATE_VIOLATION`
|
|
511
|
+
: `SSG_${v.namespace.toUpperCase()}_STATE_VIOLATION`,
|
|
463
512
|
file,
|
|
464
513
|
function: funcName,
|
|
465
514
|
message: v.explanation,
|
|
466
|
-
evidence:
|
|
467
|
-
`
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
? `
|
|
474
|
-
|
|
515
|
+
evidence: v.endState
|
|
516
|
+
? `End-of-sequence: held resource state [${v.currentState.join(", ")}] | ` +
|
|
517
|
+
`Release call: ${v.fixPath.join(" → ") || "unknown"}`
|
|
518
|
+
: `Call: ${v.callName} | Rule: ${v.matchedRule || "unknown"} | ` +
|
|
519
|
+
`Required: [${v.requiredState.join(", ")}] | ` +
|
|
520
|
+
`Current: [${v.currentState.join(", ")}]`,
|
|
521
|
+
why: v.endState
|
|
522
|
+
? `Protocol state machine violation in namespace "${v.namespace}": ` +
|
|
523
|
+
`a resource acquired in this function ([${v.currentState.join(", ")}]) ` +
|
|
524
|
+
`is still held when the function ends — resource leak.`
|
|
525
|
+
: `Protocol state machine violation in namespace "${v.namespace}": ` +
|
|
526
|
+
`function "${v.callName}" cannot be called in current state ` +
|
|
527
|
+
`[${v.currentState.join(", ")}]. Required pre-states: [${v.requiredState.join(", ")}].`,
|
|
528
|
+
fix: v.endState
|
|
529
|
+
? `Append the release call at the end of the function: ${v.fixPath.join(" → ")}`
|
|
530
|
+
: v.fixPath.length > 0
|
|
531
|
+
? `Insert before the violating call: ${v.fixPath.join(" → ")}`
|
|
532
|
+
: `Review protocol documentation for namespace "${v.namespace}" to understand required state transitions.`,
|
|
475
533
|
policy_ref: `protocol-safety.ssg.${v.namespace}`,
|
|
476
534
|
}));
|
|
477
535
|
}
|
|
@@ -167,17 +167,22 @@ function step(api, domain, description = "") {
|
|
|
167
167
|
}
|
|
168
168
|
});
|
|
169
169
|
(0, vitest_1.it)("detects missing cleanup (file opened but not closed)", () => {
|
|
170
|
-
// open_file without close_file —
|
|
170
|
+
// open_file without close_file — held FILE_OPEN at end of sequence
|
|
171
171
|
const steps = [
|
|
172
172
|
step("fs.openSync", "conn_mgmt", "Open file"),
|
|
173
173
|
step("fs.readFileSync", "conn_mgmt", "Read file contents"),
|
|
174
174
|
// Missing: close_file
|
|
175
175
|
];
|
|
176
176
|
const result = validate(steps);
|
|
177
|
-
//
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
(0, vitest_1.expect)(
|
|
177
|
+
// endState 检查:序列末尾资源未释放 → 违规 + 追加式修复路径
|
|
178
|
+
const endState = result.violations.filter((v) => v.endState);
|
|
179
|
+
(0, vitest_1.expect)(endState).toHaveLength(1);
|
|
180
|
+
(0, vitest_1.expect)(endState[0].namespace).toBe("file");
|
|
181
|
+
(0, vitest_1.expect)(endState[0].currentState).toContain("FILE_OPEN");
|
|
182
|
+
(0, vitest_1.expect)(endState[0].fixPath).toEqual(["close_file"]);
|
|
183
|
+
(0, vitest_1.expect)(result.passed).toBe(false);
|
|
184
|
+
// trace 含步骤节点 + 末尾 endState 节点
|
|
185
|
+
(0, vitest_1.expect)(result.trace.length).toBe(steps.length + 1);
|
|
181
186
|
});
|
|
182
187
|
});
|
|
183
188
|
(0, vitest_1.describe)("violation → TrustViolation conversion", () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "progmune-runtime",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.0",
|
|
4
4
|
"description": "Progmune — AI Trust Decision Engine. Verify AI-generated code before it reaches production. Outputs APPROVED / NEEDS_REVIEW / BLOCKED with evidence.",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist/",
|