progmune-runtime 3.7.13 → 3.7.14

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,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.7.14] — 2026-09-02
4
+
5
+ ### Go 提取器修复 + 恢复率裁决 + 框架诚实分层 + 三语料实验
6
+
7
+ - **提取器两处修复**:①无函数体声明行(`//go:linkname` 类)吞并下一个函数(Getuid/RoundTrip 漏检根因——与 C 3.7.4「# 行吞函数」同族);②接收者方法 receiver 括号组误当参数组(returnType 取到整签名)——回归测试锁定
8
+ - **恢复率裁决**(评审第 3 条落地):tools/go-fn-list.go(go/parser 金标,同一文件集+只计有体函数)+ scan-go-recovery.ts——stdlib 四包 **2434/2434 = 100.0%** → **维持纯词法,go/parser 桥推迟**
9
+ - **命名鸿沟测量**(孵化器理论核心数据):词段可桥接 0-1.9%——Go stdlib 惯用命名无法桥接内置规则词汇(与 C 命名鸿沟同构)
10
+ - **框架诚实分层**(评审第 5 条落地):「12/13 结构级」→「**12 专用检测器 = 4 结构级(AST:NestJS/FastAPI/Django/Flask)+ 8 启发式(代码串:Express/tRPC/Fastify/Next.js/Koa/Hapi/Gin/Fiber)**」;转正门槛 = 真实项目 FP 数据点;CLAUDE.md 矛盾行修复;落地页/矩阵/README 双语同步
11
+ - **Go 三语料实验**(REALWORLD_GO_V1.md,评审第 4 条落地):stdlib 4 FP 全 FP(readColonFile 词段桥接跨窗口类);govwa(vendored benchmarks/go-apps/)B 路径 0 flags;**A 路径 demo-real-go-govwa**:真实代码 3 注解(loginAction=verify/SetSession=establish/AuthCheck=guard)→ 0 FP + 植入违规精确定位 + 3 注解/协议——**Go 定位维持注解驱动(Beta)**
12
+ - **TS 795 完整复跑**(评审第 6 条落地):recall 98.5%(有效 100%)/ precision 100% / FP 0——12 个框架探测器全上线后与历史基线一致
13
+ - 验证:35 定向测试;Python 盲测 v1.2 64 零漂移;check 免疫正常
14
+
3
15
  ## [3.7.13] — 2026-09-02
4
16
 
5
17
  ### Go 语言支持 + Gin/Fiber 框架适配——12/13
package/README.md CHANGED
@@ -109,7 +109,7 @@ Progmune is honest about what it can and cannot verify.
109
109
 
110
110
  **Multi-language IR (registry-based).** TypeScript (ts-morph) and Python (AST) extractors are registered entries in one registry (`src/extract-project-ir.ts`); `extractProjectIR` merges every detected language into a single function IR shared by the agent loop, `execute()`, and the MCP server — the agent composes function-protocol chains across both languages. Adding a language (Go, Java, …) = register one extractor entry; callers don't change.
111
111
 
112
- **Framework adapters: 12/13.** Express ✅, tRPC ✅, FastAPI ✅, Django ✅ (structural route-level auth analysis — every mutation route checked for auth), Flask ✅ (route/before_request auth guard analysis), Fastify ✅ (route preHandler/hook auth analysis) and Next.js ✅ (App Router route-handler auth analysis), NestJS ✅ (decorator route parsing + global APP_GUARD recognition + @Public exemption), Koa ✅, Hapi ✅ (route-config auth strategy analysis), Gin ✅ and Fiber ✅ (Go route/auth-middleware analysis) have dedicated detectors. Next.js version-aware governance also exists. Spring Boot/Go frameworks and a few TS frameworks remain — framework adaptation is the #1 product gap.
112
+ **Framework adapters: 12 dedicated detectors (4 structural + 8 heuristic).** Express ✅, tRPC ✅, FastAPI ✅, Django ✅ (structural route-level auth analysis — every mutation route checked for auth), Flask ✅ (route/before_request auth guard analysis), Fastify ✅ (route preHandler/hook auth analysis) and Next.js ✅ (App Router route-handler auth analysis), NestJS ✅ (decorator route parsing + global APP_GUARD recognition + @Public exemption), Koa ✅, Hapi ✅ (route-config auth strategy analysis), Gin ✅ and Fiber ✅ (Go route/auth-middleware analysis) have dedicated detectors. Next.js version-aware governance also exists. Spring Boot/Go frameworks and a few TS frameworks remain — framework adaptation is the #1 product gap.
113
113
 
114
114
  ### What Progmune does NOT cover (honest boundaries)
115
115
 
@@ -235,7 +235,7 @@ High-impact contribution areas:
235
235
  - **Runtime Pipeline:** Detect → Explain → Repair → Validate (L1–L4)
236
236
  - **Trust Engine:** 4-dimension scoring with binary explainability gate
237
237
  - **MCP Tools:** 19 — `progmune_trust_check`, `progmune_score`, `progmune_policy_check`, `progmune_certify`, and more
238
- - **Framework Adapters:** Express ✅, tRPC ✅, FastAPI ✅, Django ✅, Flask ✅, Fastify ✅, Next.js ✅, NestJS ✅ (12/13)
238
+ - **Framework Adapters:** 12 dedicated detectors 4 structural (NestJS/FastAPI/Django/Flask) + 8 heuristic (Express/tRPC/Fastify/Next.js/Koa/Hapi/Gin/Fiber)
239
239
  - **Knowledge Base:** 31 domains, 148 protocol rules, 22 detectors, 26 safeguards, PLSB 13/13 categories — plus 15 source-level detection rules (Python)
240
240
  - **Corpus:** 2,500+ trajectories across 6+ repositories; blind benchmarks 100 (TS) + 90 (Python) projects; real-world validation on 4 application repos
241
241
  - **Current focus:** Enterprise PoC validation + remaining framework-internal boundary FPs
package/README.zh-CN.md CHANGED
@@ -109,7 +109,7 @@ Progmune 对能验证什么、不能验证什么保持诚实。
109
109
 
110
110
  **多语言 IR(注册表式)。** TypeScript(ts-morph)与 Python(AST)提取器是同一注册表(`src/extract-project-ir.ts`)中的注册项;`extractProjectIR` 把检测到的所有语言合并为一份函数 IR,由 agent loop、`execute()` 与 MCP server 共享——agent 可在两种语言上编排函数协议链。新增语言(Go、Java……)= 注册一条提取器,调用方零改动。
111
111
 
112
- **框架适配器:12/13。** Express ✅、tRPC ✅、FastAPI ✅、Django ✅(结构级路由认证分析——逐条检查写操作入口的认证)、Flask ✅(路由/before_request 认证守卫分析)、Fastify ✅(路由 preHandler/钩子认证分析)与 Next.js ✅(App Router 路由处理器认证分析)、NestJS ✅(装饰器路由解析 + 全局 APP_GUARD 守卫识别 + @Public 豁免)、Koa ✅、Hapi ✅(路由配置认证策略分析)、Gin ✅ 与 Fiber ✅(Go 路由/认证中间件分析)有专用检测器;Next.js 另有版本感知治理。Spring Boot、Go 框架及少数 TS 框架待适配——框架适配是 #1 产品缺口。
112
+ **框架适配器:12 专用检测器(4 结构级 + 8 启发式)。** Express ✅、tRPC ✅、FastAPI ✅、Django ✅(结构级路由认证分析——逐条检查写操作入口的认证)、Flask ✅(路由/before_request 认证守卫分析)、Fastify ✅(路由 preHandler/钩子认证分析)与 Next.js ✅(App Router 路由处理器认证分析)、NestJS ✅(装饰器路由解析 + 全局 APP_GUARD 守卫识别 + @Public 豁免)、Koa ✅、Hapi ✅(路由配置认证策略分析)、Gin ✅ 与 Fiber ✅(Go 路由/认证中间件分析)有专用检测器;Next.js 另有版本感知治理。结构级 = AST 解析(NestJS/FastAPI/Django/Flask——合成金标 P=R=100%);启发式 = 代码串模式(Express/tRPC/Fastify/Next.js/Koa/Hapi/Gin/Fiber——单测覆盖,真实项目 FP 数据待补)。Spring Boot 待适配——框架适配是 #1 产品缺口。
113
113
 
114
114
  ### Progmune 不覆盖什么(诚实边界)
115
115
 
@@ -234,7 +234,7 @@ Progmune 建立在"**LLM 输出是统计表演而非推理**"这一前提上—
234
234
  - **运行时管线:** 检测 → 解释 → 修复 → 验证(L1–L4)
235
235
  - **信任引擎:** 四维评分 + 二元可解释性门
236
236
  - **MCP 工具:** 19 个——`progmune_trust_check`、`progmune_score`、`progmune_policy_check`、`progmune_certify` 等
237
- - **框架适配器:** Express ✅、tRPC ✅、FastAPI ✅、Django ✅、Flask ✅、Fastify ✅、Next.js ✅、NestJS ✅(12/13
237
+ - **框架适配器:** 12 专用检测器——4 结构级(NestJS/FastAPI/Django/Flask)+ 8 启发式(Express/tRPC/Fastify/Next.js/Koa/Hapi/Gin/Fiber
238
238
  - **知识库:** 31 个域、148 条协议规则、22 个检测器、26 条防护规则、PLSB 13/13 类别——另加 15 条源码级检测规则(Python)
239
239
  - **语料:** 6+ 仓库 2,500+ 轨迹;盲测基准 100(TS)+ 90(Python)个项目;4 个应用仓库真实验证
240
240
  - **当前重点:** 企业 PoC 验证 + 剩余框架内部边界误报
@@ -230,11 +230,15 @@ function extractGoFile(filePath) {
230
230
  const name = plain ? plain[1] : receiver ? receiver[1] : null;
231
231
  if (!name)
232
232
  continue;
233
- // 多行签名:从 func 起拼接直到找到 { 或 ;
233
+ // 多行签名:从 func 起拼接直到找到 { 或 ;——遇到下一个 func 行即停
234
+ // (无函数体声明行如 `func runtime_args() []string // in package runtime`
235
+ // 不能吞掉紧随其后的函数定义——proc.go::Getuid 漏检根因)
234
236
  let sigText = lines[i];
235
237
  let j = i;
236
238
  while (!sigText.includes("{") && !sigText.includes(";") && j < lines.length - 1) {
237
239
  j++;
240
+ if (/^\s*func\b/.test(lines[j]) && j > i)
241
+ break;
238
242
  sigText += "\n" + lines[j];
239
243
  }
240
244
  const braceIdx = sigText.indexOf("{");
@@ -274,15 +278,47 @@ function extractGoFile(filePath) {
274
278
  const requires = docTag(commentText, "requires")?.split(/[,\s]+/).filter(Boolean);
275
279
  const produces = docTag(commentText, "produces")?.split(/[,\s]+/).filter(Boolean);
276
280
  const useWhen = docTag(commentText, "useWhen")?.split(/[,\s]+/).filter(Boolean);
277
- // 参数列表:签名中第一个 ( ... )
278
- const openParen = signature.indexOf("(");
279
- const closeParen = signature.indexOf(")", openParen);
281
+ // 参数列表:签名中第一个 ( ... )——接收者方法的 receiver 括号组要先跳过
282
+ // (bug 修复:func (s *Service) Login(...) 的 (s *Service) 曾被当作参数组,
283
+ // returnType 取到整个签名)
284
+ let sigAfterReceiver = signature;
285
+ if (receiver) {
286
+ let depth = 0;
287
+ for (let ci = signature.indexOf("("); ci < signature.length; ci++) {
288
+ if (signature[ci] === "(")
289
+ depth++;
290
+ else if (signature[ci] === ")") {
291
+ depth--;
292
+ if (depth === 0) {
293
+ sigAfterReceiver = signature.slice(ci + 1);
294
+ break;
295
+ }
296
+ }
297
+ }
298
+ }
299
+ const openParen = sigAfterReceiver.indexOf("(");
300
+ let closeParen = -1;
301
+ if (openParen >= 0) {
302
+ // 平衡括号匹配(参数可含 func 类型嵌套括号)
303
+ let depth = 0;
304
+ for (let ci = openParen; ci < sigAfterReceiver.length; ci++) {
305
+ if (sigAfterReceiver[ci] === "(")
306
+ depth++;
307
+ else if (sigAfterReceiver[ci] === ")") {
308
+ depth--;
309
+ if (depth === 0) {
310
+ closeParen = ci;
311
+ break;
312
+ }
313
+ }
314
+ }
315
+ }
280
316
  let params = [];
281
317
  if (openParen >= 0 && closeParen > openParen) {
282
- params = splitTopLevelParams(signature.slice(openParen + 1, closeParen));
318
+ params = splitTopLevelParams(sigAfterReceiver.slice(openParen + 1, closeParen));
283
319
  }
284
320
  // 返回类型:签名尾部(剥除泛型括号)
285
- const returnType = signature.slice(closeParen + 1).replace(/\[[^\]]*\]/g, "").trim();
321
+ const returnType = sigAfterReceiver.slice(closeParen + 1).replace(/\[[^\]]*\]/g, "").trim();
286
322
  // 函数体:从签名行(j)的 { 起逐行扫描到匹配 }(掩码后括号平衡,
287
323
  // 增量计数——每行只数一次,避免累积体重复计数)
288
324
  let body = "";
@@ -85,6 +85,23 @@ func (r *Repo) SaveUser(u User) error {
85
85
  (0, vitest_1.expect)(ir.some((f) => f.name === "SaveUser")).toBe(true);
86
86
  (0, vitest_1.expect)(ir.find((f) => f.name === "SaveUser")?.exported).toBe(true);
87
87
  });
88
+ (0, vitest_1.it)("接收者方法 returnType 与参数正确(receiver 括号组不被误取——回归)", () => {
89
+ write("svc.go", `
90
+ package main
91
+
92
+ func (s *Service) Login(ctx Context, user, password string) (Token, error) {
93
+ return Token{}, nil
94
+ }
95
+ `);
96
+ const ir = (0, extract_ir_go_1.extractIRGo)(dir);
97
+ const fn = ir.find((f) => f.name === "Login");
98
+ (0, vitest_1.expect)(fn?.returnType).toBe("(Token, error)");
99
+ // Go 语义:ctx / user / password 是 3 个参数(user 与 password 共享类型)
100
+ (0, vitest_1.expect)(fn?.params).toHaveLength(3);
101
+ (0, vitest_1.expect)(fn?.params[0].type).toContain("ctx");
102
+ (0, vitest_1.expect)(fn?.params[1].type).toContain("user");
103
+ (0, vitest_1.expect)(fn?.params[2].type).toContain("string");
104
+ });
88
105
  (0, vitest_1.it)("多行签名 + 返回类型", () => {
89
106
  write("multi.go", `
90
107
  package main
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.13";
23
+ exports.RUNTIME_VERSION = "3.7.14";
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.13",
3
+ "version": "3.7.14",
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/",