progmune-runtime 3.7.23 → 3.7.24

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 CHANGED
@@ -1,10 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.7.24] — 2026-09-06
4
+
5
+ ### 审计复检三项修复
6
+
7
+ - **空规则集 fail-closed**:`evaluatePolicy` 对空规则数组直接 BLOCK(合成 `policy_config` 违规)——空数组是 truthy,原实现零规则→零违规→ALLOW;写盘门 / policy CLI / MCP 三路径同步收口,测试锁定
8
+ - **loadEnterprisePolicyConfig 解析失败显式携带 configError**(与 loadPolicyConfig 同口径,六条 fail-open 中第 4 条全修)
9
+ - **写盘门口径修正**(README 双语 / TIERED_POLICY / AUDIT_RESPONSE):「写盘策略门」→「**写后回滚门——BLOCK 时文件不残留**」,明确为补偿控制而非写前拦截,写盘与回滚之间进程中断的残留为已知边界
10
+ - **落地页 66 金标口径自解释**:「66 金标 检出 64(97%)/ 100% / 0 FP——2 条为注解依赖前置的已知漏检(基线文档单列)」,与发布门 64 一致
11
+ - npm gitHead 溯源核对:npm gitHead = tag v3.7.23 commit,三点对齐(发布产物 ↔ tag ↔ 发布 commit)
12
+ - 回归 29 green;check 免疫正常
13
+
3
14
  ## [3.7.23] — 2026-09-06
4
15
 
5
16
  ### 第三方审计修复批次 + Oracle 隔离政策 + 分资产分级策略
6
17
 
7
- - **治理层 fail-open 修复**(Kimi 行号级审计 P0):risk 规则 fail-closed(不再伪造 SSL 输入,真实调用提取,无数据/模块不可用 → 显式违规);kb_coverage 显式化;策略配置解析失败拒绝静默评估(policy CLI exit 2);**execute 写盘策略门**(项目 opt-in `.progmune-policy.json` 后写盘即时验证,BLOCK 自动回滚——策略引擎首次获得写盘强制力);`PROGMUNE_STRICT=false` 逃生门写入审计事件日志;决策层注释与实现对齐(乘积→加权平均);证书时间戳贯通 PolicyContext;**潜伏 bug**:certify 的 plsbRecall 恒为 0(metadata 从未有 recall 字段,HIGH 置信度门槛永远不可达)→ 修为 verified/total
18
+ - **治理层 fail-open 修复**(Kimi 行号级审计 P0):risk 规则 fail-closed(不再伪造 SSL 输入,真实调用提取,无数据/模块不可用 → 显式违规);kb_coverage 显式化;策略配置解析失败拒绝静默评估(policy CLI exit 2);**execute 写后回滚门**(项目 opt-in `.progmune-policy.json` 后写盘随即验证,BLOCK 时文件不残留——补偿控制而非写前拦截,写盘与回滚间进程中断为已知边界;策略引擎首次获得写盘强制力);`PROGMUNE_STRICT=false` 逃生门写入审计事件日志;决策层注释与实现对齐(乘积→加权平均);证书时间戳贯通 PolicyContext;**潜伏 bug**:certify 的 plsbRecall 恒为 0(metadata 从未有 recall 字段,HIGH 置信度门槛永远不可达)→ 修为 verified/total
8
19
  - **跨命名空间死规则归位 + 活性守卫**(Kimi 发现 3 系统化):全量扫描 14 条死规则——4 条归位(logout_without_invalidate/admin_action_without_check/double_commit/check_resource_ownership 挪进 pre 状态所在命名空间)、10 条 printlab 业务链为文档化例外(待跨命名空间状态引用特性);`protocol-rules-liveness.test.ts` 使死规则永久回归可防
9
20
  - **P1 批**:SUPPRESS 等全部决策持久化审计事件日志(含 fpRate/envFactor/importance 全输入);截断序列覆盖率显式降级上报(truncatedSequences + summary 标注);README 双语边界声明(刻意规避不在防护目标内 / BLOCK 强制力三执行点);FAQ 澄清 LLM 密钥为可选增强;落地页免疫叙事收敛
10
21
  - **Oracle 隔离政策**(Hunyuan 定律 5 落地,`docs/ORACLE_ISOLATION_POLICY.md`):四类评估体系变更(规则/匹配策略/阈值/别名)必须人工确认,AI 只提案;protocols.json 全量 `status: "confirmed"` + 加载端跳过 proposed + `scripts/rule-propose.js` 提案脚手架;evaluateTrust 输出 **oracleIndependence**(confirmedRules / sameSourceAnnotations / confirmedAliases)
package/README.md CHANGED
@@ -119,7 +119,7 @@ Progmune is honest about what it can and cannot verify.
119
119
  - **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.
120
120
  - **Known failure boundaries are documented** rather than hidden: if Progmune cannot verify a language (e.g. Go), Confidence is lowered instead of pretending 100%.
121
121
  - **Deliberate evasion is out of scope** — the annotation-driven model catches *accidental* AI protocol mistakes (missing prerequisites, wrong ordering); it does not defend against adversarial renaming/obfuscation (true of any static tool).
122
- - **BLOCK enforcement is the integrator's responsibility** — Progmune outputs decisions and evidence; it does not intercept at runtime. OS-level enforcement points: `trust --ci` exit code (CI gates), `policy CLI` exit code, and the opt-in write-gate (with `.progmune-policy.json`, `execute` verifies immediately after writing and rolls back on BLOCK).
122
+ - **BLOCK enforcement is the integrator's responsibility** — Progmune outputs decisions and evidence; it does not intercept at runtime. OS-level enforcement points: `trust --ci` exit code (CI gates), `policy CLI` exit code, and the opt-in **write-then-rollback gate** (with `.progmune-policy.json`, `execute` writes then verifies immediately; on BLOCK the file does not persist. This is a compensating control, not pre-write interception: a process killed between write and rollback may leave the content behind — a known boundary).
123
123
 
124
124
  **Tiered adoption by asset class** ([TIERED_POLICY](https://github.com/shenlian19831109/progmune-runtime/blob/main/docs/TIERED_POLICY.md)): don't gate all code alike — pick a tier by "cost of failure × AI involvement", one command to install:
125
125
 
package/README.zh-CN.md CHANGED
@@ -119,7 +119,7 @@ Progmune 对能验证什么、不能验证什么保持诚实。
119
119
  - **框架内部件**——知名框架的分发/缓存机制(如 django-unicorn 内部件)可能产生少量边界误报;各语料基准 gold 文件中已逐条记录。
120
120
  - **已知失败边界一律记录**而非隐藏:如果 Progmune 无法验证某语言(如 Go),置信度会降低而不是假装 100%。
121
121
  - **刻意规避不在防护目标内**——注解驱动模型拦截的是 AI 的「意外」协议错误(漏写前置步骤、顺序颠倒);对故意改名/混淆的对抗性规避不设防(任何静态工具同理)。
122
- - **BLOCK 的强制力由集成方承担**——Progmune 输出判定与证据,不运行时拦截。OS 级强制执行点:`trust --ci` 退出码(CI 门禁)、`policy CLI` 退出码、以及 opt-in 的写盘策略门(项目配置 `.progmune-policy.json` 后,execute 写盘即时验证,BLOCK 自动回滚)。
122
+ - **BLOCK 的强制力由集成方承担**——Progmune 输出判定与证据,不运行时拦截。OS 级强制执行点:`trust --ci` 退出码(CI 门禁)、`policy CLI` 退出码、以及 opt-in 的**写后回滚门**(项目配置 `.progmune-policy.json` 后,execute 写盘随即验证,BLOCK 时文件不残留。注意这是补偿控制而非写前拦截:写盘与回滚之间若进程被中断,违规内容可能短暂/持续残留——已知边界)。
123
123
 
124
124
  **分资产分级接入**([TIERED_POLICY](https://github.com/shenlian19831109/progmune-runtime/blob/main/docs/TIERED_POLICY.md)):不要给所有代码同一套门禁——按「出错代价 × AI 参与度」选档,一条命令落地:
125
125
 
@@ -135,6 +135,28 @@ function extractCallsBestEffort(file) {
135
135
  function evaluatePolicy(ctx, rules) {
136
136
  const activeRules = rules || types_1.DEFAULT_POLICY;
137
137
  const violations = [];
138
+ // fail-closed(审计复检 2026-09-06):空数组是 truthy,原实现会
139
+ // 零规则 → 零违规 → ALLOW——空规则集必须拒绝而非放行
140
+ if (activeRules.length === 0) {
141
+ return {
142
+ passed: false,
143
+ verdict: "BLOCK",
144
+ rules: 0,
145
+ passed_rules: 0,
146
+ failed_rules: 1,
147
+ violations: [{
148
+ rule: {
149
+ type: "policy_config",
150
+ severity: "block",
151
+ description: "Empty policy ruleset is rejected (fail-closed)",
152
+ },
153
+ actual: "0 active rules",
154
+ expected: ">= 1 active rule",
155
+ detail: "empty ruleset passes nothing — refusing to ALLOW (fail-closed)",
156
+ }],
157
+ summary: "BLOCK: empty policy ruleset",
158
+ };
159
+ }
138
160
  for (const rule of activeRules) {
139
161
  switch (rule.type) {
140
162
  // ── Confidence ──
@@ -391,7 +413,13 @@ function loadEnterprisePolicyConfig(projectPath, configPath) {
391
413
  };
392
414
  }
393
415
  catch (e) {
394
- console.error(`⚠️ Failed to load enterprise policy config: ${e.message}. Using defaults.`);
395
- return emptyResult;
416
+ console.error(`⚠️ Failed to load enterprise policy config: ${e.message}.`);
417
+ // fail-closed 信号(审计复检 2026-09-06):与 loadPolicyConfig 同口径——
418
+ // 显式携带 configError,调用方拒绝静默评估
419
+ return {
420
+ ...emptyResult,
421
+ source: "built-in defaults (enterprise config error)",
422
+ configError: `Failed to parse ${cfgFile}: ${e.message}`,
423
+ };
396
424
  }
397
425
  }
@@ -97,6 +97,14 @@ function baseCtx(file) {
97
97
  (0, vitest_1.expect)(res.configError).toBeDefined();
98
98
  (0, vitest_1.expect)(res.configError).toContain("Failed to parse");
99
99
  });
100
+ (0, vitest_1.it)("空规则集 fail-closed:[] 是 truthy 但必须拒绝(BLOCK,非 ALLOW)", () => {
101
+ const f = path.join(dir, "empty.ts");
102
+ fs.writeFileSync(f, "");
103
+ const result = (0, engine_1.evaluatePolicy)(baseCtx(f), []);
104
+ (0, vitest_1.expect)(result.passed).toBe(false);
105
+ (0, vitest_1.expect)(result.verdict).toBe("BLOCK");
106
+ (0, vitest_1.expect)(result.violations.some((v) => v.rule.type === "policy_config")).toBe(true);
107
+ });
100
108
  });
101
109
  (0, vitest_1.describe)("execute 写盘策略门(opt-in)", () => {
102
110
  const MARKED = `// @progmune-generated session=s1 timestamp=2026-09-06T00:00:00.000Z
package/dist/sdk.js CHANGED
@@ -20,7 +20,7 @@ const risk_model_1 = require("./risk-model");
20
20
  const protocol_knowledge_1 = require("./protocol-knowledge");
21
21
  const evidence_repository_1 = require("./evidence-repository");
22
22
  /** Runtime version — stable public identifier. Internal layers evolve underneath. */
23
- exports.RUNTIME_VERSION = "3.7.23";
23
+ exports.RUNTIME_VERSION = "3.7.24";
24
24
  function verify(filePath) {
25
25
  const cert = (0, certify_1.certify)(filePath);
26
26
  const kb = (0, protocol_knowledge_1.buildKnowledgeBase)();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "progmune-runtime",
3
- "version": "3.7.23",
3
+ "version": "3.7.24",
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/",