@furongjun1999/dsh-memory 0.5.0 → 0.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/README.md +572 -465
- package/docs/README.md +1 -0
- package/docs/eval/DSH/346/227/245/345/277/227/347/264/242/345/274/225v2_/345/217/202/350/200/203dsh-TUI_v1.0.md +248 -0
- package/docs/eval/DSH/346/227/245/345/277/227/347/264/242/345/274/225/346/225/210/346/236/234/351/252/214/350/257/201_v1.0.md +209 -0
- package/docs/eval/DSH/347/253/257/347/274/272/351/231/267/344/270/223/351/241/271_v1.0.md +254 -0
- package/docs/eval/P1b2_/350/257/273/351/235/242/344/273/243/351/231/205/344/277/256/345/244/215_v1.0.md +124 -0
- package/docs/eval/bench_lingshu_self/bench_self.py +140 -0
- package/docs/eval/bench_lingshu_self/self_bench_result.json +404 -0
- package/docs/eval/bench_lingshu_self//347/201/265/346/236/242/350/207/252/345/272/223/347/253/257/345/210/260/347/253/257/346/243/200/347/264/242/345/256/236/346/265/213_v1.0.md +38 -0
- package/docs/eval//344/270/215/345/217/257/351/235/240/346/200/247/350/220/275/345/234/260_P0_v1.0.md +185 -0
- package/docs/eval//345/217/221/345/270/20306_/344/270/200/351/224/256/351/205/215/347/275/256/344/270/216DSH0172_v1.0.md +171 -0
- package/docs/eval//346/225/205/351/232/234/346/263/250/345/205/245/345/256/236/346/265/213_v1.0.md +422 -0
- package/docs/eval//347/253/257/345/210/260/347/253/257LoCoMoQA/345/220/214/345/217/243/345/276/204/345/257/271/347/205/247_v1.0.md +100 -0
- package/docs/eval//347/253/257/345/210/260/347/253/257/345/271/262/346/211/260/346/261/240/350/257/204/346/265/213_/347/241/256/345/256/232/346/200/247/350/243/201/345/206/263vsLLM_judge_v1.1.md +197 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v1.md +156 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v10.md +210 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v11.md +227 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v12.md +203 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v13.md +233 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v14.md +191 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v15.md +213 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v16.md +214 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v17.md +199 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v18.md +183 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v19.md +207 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v2.md +156 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v3.md +152 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v4.md +128 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v5.md +114 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v6.md +192 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v7.md +187 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v8.md +207 -0
- package/docs/eval//347/274/272/351/231/267/346/214/226/346/216/230_/350/207/252/344/270/273/350/277/255/344/273/243_v9.md +203 -0
- package/docs/hive//345/256/211/345/205/250/345/256/241/350/256/241/345/256/236/351/224/232_v0.1.md +202 -0
- package/docs/hive//350/234/202/345/267/242/345/217/214/345/256/236/344/276/213/344/272/222/351/252/214_/350/256/276/350/256/241/345/256/232/347/250/277.md +19 -3
- package/docs/images/lingshu-moonlight-covenant-poster-preview.jpg +0 -0
- package/docs/images/lingshu-moonlight-covenant-poster.png +0 -0
- package/docs/mdcg//345/212/237/350/203/275/350/260/203/347/224/250/346/230/240/345/260/204/350/241/250_v0.1.md +40 -40
- package/docs/theory//344/270/215/345/217/257/351/235/240/345/256/232/347/220/206/344/270/216/345/244/261/346/225/210/344/274/230/345/205/210/346/241/206/346/236/266_v0.3.md +365 -0
- package/docs//344/270/215/345/217/257/351/235/240/346/200/247/347/220/206/350/256/272_v0.1.md +343 -0
- package/dsh/cordis-patch-profile-web.example.yml +35 -0
- package/lib/bridge.d.ts +9 -0
- package/lib/bridge.js +35 -0
- package/lib/cli.d.ts +3 -0
- package/lib/cli.js +66 -0
- package/lib/index.js +7 -1
- package/lib/init.d.ts +88 -0
- package/lib/init.js +287 -0
- package/lib/lib/roleplay_web.js +530 -443
- package/lib/lib/token_store.d.ts +7 -1
- package/lib/lib/token_store.js +12 -3
- package/md_cg/audit.py +12 -1
- package/md_cg/backfill.py +16 -15
- package/md_cg/backfill_bucket_zh.py +35 -0
- package/md_cg/bench_e2e_judge.py +532 -0
- package/md_cg/bench_e2e_locomo_qa.py +368 -0
- package/md_cg/bench_e2e_qa.py +256 -0
- package/md_cg/branches.py +18 -2
- package/md_cg/ccgc.py +3 -2
- package/md_cg/chain.py +19 -4
- package/md_cg/consolidate.py +7 -6
- package/md_cg/crosscheck.py +4 -3
- package/md_cg/crypto.py +439 -437
- package/md_cg/datapath.py +395 -335
- package/md_cg/evidence.py +8 -3
- package/md_cg/export.py +3 -1
- package/md_cg/forgetting.py +2 -2
- package/md_cg/fsutil.py +48 -0
- package/md_cg/hotcache.py +255 -238
- package/md_cg/interop.py +161 -22
- package/md_cg/judgment_manifest.py +177 -0
- package/md_cg/links.py +655 -622
- package/md_cg/mcp_server.py +282 -31
- package/md_cg/mdcg.py +702 -126
- package/md_cg/mdcos.py +454 -68
- package/md_cg/mreview/govern.py +5 -4
- package/md_cg/postings.py +4 -2
- package/md_cg/readcache.py +76 -18
- package/md_cg/reconcile.py +228 -0
- package/md_cg/review_cli.py +215 -0
- package/md_cg/routing.py +28 -0
- package/md_cg/run_tests.py +211 -0
- package/md_cg/scrub.py +862 -852
- package/md_cg/security.py +385 -275
- package/md_cg/selfreport.py +3 -2
- package/md_cg/signer.py +565 -562
- package/md_cg/sources.py +3 -2
- package/md_cg/stg.py +6 -0
- package/md_cg/sustain.py +1168 -1138
- package/md_cg/test_access_hints.py +147 -0
- package/md_cg/test_branch_discard_tombstone.py +136 -0
- package/md_cg/test_branches.py +259 -249
- package/md_cg/test_chain_read_isolate.py +168 -0
- package/md_cg/test_datapath_device_name.py +203 -0
- package/md_cg/test_emit_negtail_cache.py +156 -0
- package/md_cg/test_en_pipeline.py +186 -166
- package/md_cg/test_govern_directread.py +421 -0
- package/md_cg/test_i32_hotcache_env_key.py +218 -0
- package/md_cg/test_identity_attribution.py +228 -147
- package/md_cg/test_index_crossprocess_reload.py +301 -0
- package/md_cg/test_index_durability.py +238 -224
- package/md_cg/test_interop.py +4 -2
- package/md_cg/test_interop_judgment.py +228 -0
- package/md_cg/test_issue39_utf8_stdio.py +273 -0
- package/md_cg/test_links_concurrent_write.py +188 -0
- package/md_cg/test_merge_upsert.py +168 -0
- package/md_cg/test_n123_derive_expiry_chain.py +205 -0
- package/md_cg/test_n130_verify_falsified_protect.py +185 -0
- package/md_cg/test_n131_merge_gate.py +205 -0
- package/md_cg/test_none_id_write_guard.py +165 -0
- package/md_cg/test_p1x_ref_root.py +160 -0
- package/md_cg/test_p27_docindex.py +774 -765
- package/md_cg/test_p2_mcp.py +3 -0
- package/md_cg/test_p32_backfill.py +304 -298
- package/md_cg/test_p39_verify_flow.py +90 -50
- package/md_cg/test_p47_session_view.py +60 -25
- package/md_cg/test_propose_tail_index.py +157 -0
- package/md_cg/test_read_scope_b27.py +277 -0
- package/md_cg/test_readcache_default_on.py +168 -0
- package/md_cg/test_readcache_precise_inval.py +270 -0
- package/md_cg/test_readcache_prodpath.py +55 -7
- package/md_cg/test_reconcile_v0.py +294 -0
- package/md_cg/test_retr_s1.py +6 -2
- package/md_cg/test_retr_s1b.py +67 -0
- package/md_cg/test_retr_s7.py +8 -0
- package/md_cg/test_retr_s9_entity_ctx.py +181 -175
- package/md_cg/test_retr_score_once.py +208 -0
- package/md_cg/test_review_cli_attribution.py +177 -0
- package/md_cg/test_review_cli_visibility.py +235 -0
- package/md_cg/test_review_onepass.py +170 -0
- package/md_cg/test_rrf_graph_seed_cache.py +154 -0
- package/md_cg/test_security_audit.py +155 -0
- package/md_cg/test_security_audit_b26.py +161 -0
- package/md_cg/test_security_audit_v21.py +250 -0
- package/md_cg/test_semantic_canonical.py +255 -241
- package/md_cg/test_session_isolation.py +168 -0
- package/md_cg/test_snapshot_autoclose.py +187 -0
- package/md_cg/test_tail_watermark_race.py +208 -0
- package/md_cg/test_tenant_env_override_warn.py +139 -0
- package/md_cg/test_tenant_registry_corrupt_warn.py +151 -0
- package/md_cg/test_v14_fixes.py +415 -397
- package/md_cg/test_verify_dirty_reconcile.py +157 -0
- package/md_cg/theory.py +276 -273
- package/md_cg/tokens.py +734 -677
- package/md_cg/units.py +3 -2
- package/md_cg/vision_evidence.py +4 -3
- package/md_cg/whitebox_kb/wisdom/code_solidified.json +6195 -6195
- package/md_cg/whitebox_kb/wisdom/multilang_ir.py +128 -124
- package/md_cg/writepipe.py +554 -550
- package/package.json +11 -2
- package/src/bridge.ts +434 -401
- package/src/cli.ts +65 -0
- package/src/index.ts +526 -518
- package/src/init.ts +347 -0
- package/src/lib/roleplay_web.ts +1019 -932
- package/src/lib/token_store.ts +202 -192
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# 缺陷挖掘报告 · 自主迭代 v15(安全二轮)
|
|
2
|
+
|
|
3
|
+
- **日期**:2026-09-25
|
|
4
|
+
- **范围**(生效条件):第 15 轮 = 安全二轮,四区复核(legacy / authz / runtime / perimeter)共 **26 条目**(confirmed 24 / rejected 2)→ 跨区重复 4 组(冗余 4 条:租户绑定 3 条→2 缺陷、_spawn 双键 3 条→2 缺陷、children 装载 2 条→1、stop 杀树 2 条→1)→ 独立条目 **20**,剔除「复测通过非缺陷」2 条 → 独立缺陷 **18 项**(本轮新发现 7 项 **N123-N129**:medium 3 / low 4;legacy 复测 11 项:v8 N62〔租户覆盖面 + clearance_cap 面,两项〕、v8 N68 / N69 / N66、v6 N39〔v8 N63 同文件竞态面〕、v10 N82 / N83 / N87 / N89 / N92)→ 本轮修复 **5 个补丁**(F1 止血修 + F2-F5 全闭,全 medium、全 Python 面、零 Rust/TS 改动)→ 遗留 **13 个开口**(medium 8 / low 5)+复测通过结案 2 +证伪/剔除 2
|
|
5
|
+
- **编号口径**:本轮新发现沿历轮 N 口径续编 **N123-N129**(v14 用至 N122,v14.md:4 编号口径行核实);材料 confirmed 的 origin=new 条目未携带编号,由本报告会话统一续编并在第三节逐项标注。legacy 项编号经本报告会话 grep 核实:v8.md:94(N62)/:95(N63)/:104(N66)/:112(N68)/:113(N69)、v6.md:100(N39)、v10.md:77(N82)/:78(N83)/:89(N87)/:103(N89)/:106(N92)、v9.md:109(N62 第 9 轮复测)、v13.md:102(N66 deferred);「令牌文件损坏 fail-closed」复测项的档位锚为 v8 N63 证据面(v8.md:95 python 侧 fail-closed 拒启读证)。
|
|
6
|
+
- **回归**:`python -X utf8 scripts/run_tests.py --jobs 4` 全量——**本会话实跑两次,`===== SUMMARY 195/195 通过,5 跳过(依赖缺失/平台不符) =====`,重定向捕获真实退出码 0**(与材料门禁口径逐字一致;195 = v14 的 194 + 新守卫 test_tenant_env_override_warn 1 件);**swarm cargo test 未运行**(Rust 面零改动——本会话 git status 证实 swarm/ 与 rust/ 无改动);**npm test 未运行**(TS 面零改动——git status 证实 src/ 与 TS 测试未动);**npm run gate 失败——本会话第一手复现**:重定向捕获真实退出码 1,`[FAIL] R4 非追踪件面 命中=1;非追踪=25,允许=24`,命中清单 = 新守卫 md_cg/test_tenant_env_override_warn.py(未 git add;R1/R2/R3 均 PASS),与材料口径逐字一致——untracked 时序性,编排会话提交前裁决(第四节)。
|
|
7
|
+
- **行号口径**:材料缺陷/修复行号为上游复核/修复会话时点快照;F3(+87/-21)使 hive/exec.py 行号整体后移——F2 相关材料口径 `_context_block :313-330` / `_sensitive_read :897` / `tool_read_file :1097` 本会话读核为现行 **:363-380 / :948 / :1148**;exec 空包三通道材料口径 :1221-1227 等现行漂移至 :1287/:1457/:1497 一带;其余修复落点读核与材料口径吻合(第二节逐项双标,以读核为准)。
|
|
8
|
+
- **结构口径**(CCG 六要素):功能名(标题)/ 生效条件(范围与口径行)/ 子功能(第二~五节)/ 执行与验证方式(第四节:实跑命令与结果)/ 不适用条件(第七节:跳过与未运行项)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 一、执行摘要
|
|
13
|
+
|
|
14
|
+
本轮为安全二轮:四区复核 26 条目(confirmed 24 / rejected 2),跨区去重后 20 独立条目 = 18 独立缺陷(新 7 + legacy 11)+ 2 复测通过非缺陷;5 补丁(全 Python 面),F1 止血修 + F2-F5 全闭 5 项,遗留 13 开口。四个主题:
|
|
15
|
+
|
|
16
|
+
1. **三轮老账的安全主题清账(5 修 medium,全部为历轮留档复测项的首次修复)**:v8 N62 租户绑定覆盖面(v8 首报→v9 复测→本轮**第三次成立**)F1 以对照 MDCG_CLEARANCE 先例的 5 行 stderr 告警止血——Principal 判定零闸变、覆盖从不可见变为部署面可审计(cap 夹紧接线按缺陷单口径 deferred 授权链专项);v8 N69 context_files 凭据外发面(第三次成立)F2 复用 tool_read_file 同款 `_sensitive_read`——哑私钥/哑 .env 全文不再进子代理 prompt 发往外部网关,改为 skipped 标注块+留痕,不拒整个 spawn;v10 N82(本轮第一手动态复现主链成立:对撞 FileNotFoundError 外逸→顶层兜底把对撞写者成功终态改写为 error)F3 以 mkstemp 唯一临时名 + FileNotFoundError 自愈重试 + write_error_result 拒覆写成功终态三面闭合;v10 N83(本轮第一手复现:快照失败残留被后续任务 `git add jobs` 扫进 main,BYPASS_TO_MAIN=True)F4 以 artifacts 预检前置 + 外层 try/except 清理重抛闭合;v10 N87(本轮复现:字典构造期求值使 children 装载恒读 CWD 相对清单,换人续跑即重复派发/读进他人清单)F5 以两阶段 _CFG.update 纯求值顺序调整闭合。
|
|
17
|
+
2. **authz 区深挖:新发现 4 项留档 + 1 项复测通过**:N123(derive 子令牌 TTL 无上限夹紧且过期不沿派生链传播——父令牌 5s 过期后 11.6 天子令牌仍 verify 通过;对照组 revoke 级联吊销行为正确)、N124(租户登记表损坏时 _resolve_root 静默 fail-open,except 吞掉后私钥数据根绑定退化为裸 env 信任零告警)、N125(main() 在 _build_principal 之后把 MDCG_SESSION 原样重设进 principal.session——防编造校验对 env 恒被打穿,真实 serve 入口实测)、N126(审计写入 best-effort 吞错——_audit.jsonl 被独占/替换为目录后敏感操作无痕继续);另「令牌文件损坏 fail-closed」复测再次通过(非缺陷,方向正确,结案)。
|
|
18
|
+
3. **runtime / perimeter 区:3 项新发现留档 + 2 项证伪/复测通过剔除**:N127(编排子任务 workdir=编排者 CWD=serve HIVE_DIR,批次 27 fail-closed 读白名单由此覆盖整个 hive/ 目录——兄弟任务 spec/result 与 config.local.json 直值密钥均在子代理可读面,随对话发往外部网关,默认部署即命中)、N128(swarm WAL HMAC 密钥生命周期失效:缺省硬编码「蜂群默认密钥」+ CLI 空串形态 + 密钥明文与 WAL 同盘——默认/空串密钥伪造 trust=0.99 事件通过全部验签)、N129(MDCG_EXPORT_ROOT 未设时 designer 可经 export out 参数把全库明文写到本机任意路径并覆盖既有文件);证伪 2 条(ingest action=hive 元组缺口——写入层 require_write 逐事件拦截 written=0/denied=2,非越权写通道;export 密级过滤与根白名单——复测通过,防线成立)。
|
|
19
|
+
4. **遗留 13 开口的分诊**:8 medium 中 7 项为材料明示的设计决策类(授权链语义 / 部署语义 / 拦截策略 / 密钥管理 / scope 语义 / CSRF 策略),1 项(N123)修复方向简单但名额让位 legacy 欠账;5 low 为加固项让位。含大设计决策项的处置建议见第五节。
|
|
20
|
+
|
|
21
|
+
**对输入口径的核验**:输入称「四区 confirmed 24(legacy 7 / authz 7 / runtime 7 / perimeter 3)、rejected 2 → 5 修复 → 留档未修 13 条」。本会话以 `git status --porcelain` / `git diff --numstat` + 五处落点读核核对:改动面 = **四个修复源文件**(md_cg/tokens.py +15/-1〔F1〕、hive/exec.py +87/-21〔F2+F3〕、hive/wm.py +63/-46〔F4,含生效条件注释改写〕、hive/orch.py +10/-2〔F5〕)+ **一份常驻守卫**(md_cg/test_tenant_env_override_warn.py,未跟踪新文件)——与五项修复一一对应;F2/F3/F4/F5 的攻击复现守卫为临时脚本(材料明示已删,本会话 git status 证实仅 F1 守卫存留);另 `md_cg/whitebox_kb/wisdom/code_solidified.json`(+1/-2)为 v10-v14 报告已注明的先前会话遗留工作区变更,非本轮触点。五项修复由并行修复员会话完成(材料各自声明未触碰他方文件),本报告会话未修改任何源文件。跨区重复 4 组(legacy 区 N62/N68+N69 两条合并形态条目分别与 authz 区两条、runtime 区两条互为同缺陷;children 与 stop 各与 runtime 区一条重复),24 − 4 冗余 = 20 独立条目 = 18 缺陷 + 2 复测通过;5 补丁闭合 5 项,18 − 5 = 13 开口,与材料留档 13 条逐条对应、无多无少。
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 二、修复清单(5 项,逐项 where / 攻击面 / 修复 / 攻击前后对比 / 守卫)
|
|
26
|
+
|
|
27
|
+
### F1(v8 N62 覆盖面,medium)MDCG_TENANT 覆盖租户绑定:静默覆盖止血为必现告警
|
|
28
|
+
|
|
29
|
+
- **where**:材料口径 `md_cg/tokens.py:409-421`(verify_token 返回前新增冲突告警块,:393 生效条件注释同步)+ 新增守卫 `md_cg/test_tenant_env_override_warn.py`;入口 `md_cg/mcp_server.py:3468`(MDCG_TENANT→tenant 形参)经 verify_token 内部告警自动覆盖,mcp_server 零改动。**本会话读核**:告警注释块 :409-414、判定与告警 :415-422、Principal 构造行 :423-424(`tenant=tenant or rec.get("tenant") or "default"` 逐字未动)在位;mcp_server.py:3468 `verify_token(token, tenant=os.environ.get("MDCG_TENANT"))` 调用形态在位。
|
|
30
|
+
- **攻击面**:控制 MCP 进程 env 的部署面(宿主配置/启动器/同机多会话)——tenantA 签发的 designer(secret, can_admin) 令牌在 MDCG_TENANT=tenantB 下以 secret+can_admin 身份对 tenantB 登记根运行(`_resolve_root` 未设 MDCG_ROOT 时随之切根,仅显式 MDCG_ROOT 冲突才 fail-closed),全程零告警。v8 N62 首报(v8.md:94)→ v9 复测成立(v9.md:109)→ 本轮第三次成立。
|
|
31
|
+
- **修复**(止血最小修,对照 MDCG_CLEARANCE 先例 mcp_server.py:3471-3482 同形):verify_token 返回 Principal 前,当 `rec["tenant"]` 与形参 `tenant` 去空白后均非空且不等时,向 sys.stderr 写「⚠ 租户绑定被入参覆盖:令牌按 X 签发,但入参 tenant=Y(MCP 侧来自 MDCG_TENANT)优先生效……」告警(逻辑 5 行)。**零闸变**——形参/env 值仍优先生效。调用面核实(git grep):显式传 tenant 的仅 mcp_server.py:3468 一处,其余调用(derive/CLI/ccgc/crosscheck/hive orch)不传 tenant,恒零告警零误伤。
|
|
32
|
+
- **攻击前后对比**:修复前——verify_token(tok, tenant="tenantB") 得 principal{tenant=tenantB, role=designer, can_admin=True} 且 stderr 零输出(守卫日志「零 stderr 输出——静默覆盖成立」);MCP 进程级 _build_principal() 同形态 err=None、零告警。修复后——同一攻击形态 Principal 判定逐位不变(tenant=tenantB、can_admin=True——零闸变),但 stderr 必现覆盖告警(含两侧租户名)——覆盖从不可见变为部署面可审计;无冲突路径(tenant=None/空串/同值)与 CLI 无 tenant 调用零告警。
|
|
33
|
+
- **守卫**:`md_cg/test_tenant_env_override_warn.py`(哑令牌+临时令牌库 tempfile,测毕清理,未触真实令牌库/真实数据目录)四组:[1] 单元级攻击复现(冲突必告警+两侧租户名可见);[2] 零闸变(形参租户仍优先、权限面原样);[3] 零误伤(None/空串/同值三路径零告警);[4] MCP 进程级(进程内 _build_principal 直调:MDCG_TOKEN+MDCG_TENANT=tenantB 必告警、同值零告警)。材料红证:修前 8 通过/3 失败(3 失败均为告警缺席项,攻击面断言全过=缺陷实证)。**本会话实跑:`python -X utf8 -m md_cg.test_tenant_env_override_warn` → 「通过 11 / 失败 0」**(尾部三条 PASS 实拍:MCP 入口租户被覆盖为 tenantB·攻击面成立 / stderr 含覆盖告警 / MDCG_TENANT 同值零告警)。
|
|
34
|
+
- **verified_by**(材料口径,本会话未重跑的细项如实标注):① 守卫红→绿(上游修复会话实跑);② 既有回归(全部实际运行):test_p21_tokens 38/0、test_p2_mcp 64/0、test_security_audit_b26 17/0、test_security_audit 13/0、test_security_audit_v21 49/0、test_p34_crosscheck 51/0、hive.test_orch 85/0;③ CLI 冒烟 `python -m md_cg.tokens issue --role designer` + `verify --token`(临时 MDCG_TOKEN_FILE,rc=0,stderr 空——无 tenant 路径零误伤);④ 全量 195/195(本会话实跑,第四节)。clearance_cap 夹紧接线与租户强校验按缺陷单口径不在本项(deferred,第五节)。
|
|
35
|
+
|
|
36
|
+
### F2(v8 N69,medium)context_files 通道复用敏感凭据拒读:凭据文件全文不再进子代理 prompt
|
|
37
|
+
|
|
38
|
+
- **where**:材料口径 `hive/exec.py:313-330`(_context_block 入口新增敏感拒读;_sensitive_read 定义 :897、tool_read_file 同款用法 :1097、build_messages 调用点 :372 无需改动);**本会话读核现行**(F3 增行使行号后移):`hive/exec.py:363-380`(生效条件注释 :363、`_context_block` :364、v8 N69 止血注释 :366-372、realpath+_sensitive_read 判定 :373-374、skipped 标注块返回 :378-380)、`_sensitive_read` 定义 :948、tool_read_file 用法 :1148——以读核为准。
|
|
39
|
+
- **攻击面**:编排者模型被提示注入(或任何能调 spawn_subtask/hive_spawn 的宿主模型):`context_files=[私钥/.env 路径]`(orch.py:408-411 与 MCP 面 hive_mcp/mcp_server.py:349-352 均仅 isfile 存在性检查,_spawn_schema 还声明该键为模型正常可用)→ 子任务 spec 携带 → `_context_block` 文本分支读全文零检查零脱敏 → build_messages 直接拼进 user 消息 → 随 API 请求发往 HIVE_API_BASE 外部网关。read_file 的四道防线(scope 白名单 / HIVE_READ_ROOTS / `_sensitive_read` / PII 脱敏)均只挂 tool_read_file,该通道无任何部署开关可关。本轮临时目录哑数据复现(测毕清理):哑私钥全文与哑 API key 行原样进 user 消息、无「已脱敏」占位;同两路径 tool_read_file 均被拒——同文件双通道防线差异实拍。
|
|
40
|
+
- **修复**:_context_block 入口(读文件前)对 `os.path.realpath(path)` 复用既有 `_sensitive_read`(与 tool_read_file :1148 同款),命中则 `meta["notes"]` 追加 + `log(job_dir,...)` 诚实留痕,返回 `<context path="…" skipped="敏感凭据拒读">`(含原因与部署管理员显式通道指引)标注块——**不拒整个 spawn**,其余块照常拼装;未命中路径行为逐位不变。纯 Python 改动(+15 行),不涉 Rust。
|
|
41
|
+
- **攻击前后对比**:修复前——spawn 传 context_files=[id_ed25519, .env] → user 消息含哑私钥全文(BEGIN 块)与 DUMMY_API_KEY 行全文,零脱敏零拦截;同路径 tool_read_file 却被「敏感路径拒读」。修复后——同输入 → 两文件替换为 skipped="敏感凭据拒读" 标注块(含命中原因),全文不再出现;非敏感 notes.txt 照常逐字全文进上下文(spawn 不被整体拒绝);meta.notes 与 job log 各留痕一条。
|
|
42
|
+
- **守卫**:临时攻击复现守卫(**已删**,材料明示):临时目录造哑私钥 id_ed25519 + 哑 .env + 对照 notes.txt,调 build_messages 断言「私钥/.env 全文不进 user 消息 + skipped 标注在位 + 非敏感照常 + meta.notes 留痕 + 同路径 tool_read_file 仍拒」。修复前跑 = EXIT 1(泄露 True / skipped False);修复后跑 = EXIT 0。未触真实 serve/令牌,测毕清理。**本会话无法重跑红证**(守卫已删、旧码不可回退——多轮未提交改动),以现行 :366-380 读核 + 既有测试绿态 + 全量回归替代佐证,如实标注。
|
|
43
|
+
- **verified_by**(材料口径):① 守卫红→绿;② `python hive/test_exec_tools.py` = 87/0(含 F 组 build_messages 上下文护栏与 F4 非敏感文本逐字全文断言);③ `python hive/test_worker_scope.py` = 9/0;④ `md_cg.test_security_audit_b26` 17/0、`test_security_audit_v21` 49/0(敏感名族防线本体无回归);⑤ 全量 195/195(本会话实跑,第四节)。cargo test 未跑(无 Rust 面)。同条缺陷单的 mdcg_root 键透传面与 F2 分拆处理、明确 deferred(第五节)。
|
|
44
|
+
|
|
45
|
+
### F3(v10 N82,medium)write_result 唯一临时名 + 兜底拒覆写成功终态:重投对撞不再改写成功
|
|
46
|
+
|
|
47
|
+
- **where**:材料口径 `hive/exec.py:104-157`(write_result:mkstemp 唯一临时名 :128、FileNotFoundError 自愈重试 :146、finally 清理 :154)+ `:160-181`(新增 write_error_result)+ main 内 7 处 ok=false 写入换用(:1566/:1577/:1592/:1626 spec 面 + :1658 SpecError /:1671 HTTPError /:1683 Exception 兜底;成功终态写 :1650 保持 write_result)+ import tempfile :76。**本会话读核全部在位**:write_result :104-156(docstring 含 v10 N82 止血注释 :117-123、mkstemp :127-134、FileNotFoundError 分支 :146-151、finally :152-156)、write_error_result :159-180(成功终态在位即拒写+log 留痕 :175-178)、grep 7 处调用点 :1566/:1577/:1592/:1626/:1658/:1671/:1683 逐字吻合、`import tempfile` :76。
|
|
48
|
+
- **攻击面**:rust 调度器对无产物 job 的重投(崩溃/超时后 re-claim)与新执行者并发跑同一 job:两个 exec.py 进程同 job_dir 写 result.json,固定共享临时名 `p+".tmp"` 重叠窗口内一者 os.replace 抢先消费共享 tmp → 另一者抛 FileNotFoundError(重试面只捕 PermissionError)→ 外逃到 main 顶层 except 再以 ok=false 覆写 result.json——把对撞写者的成功终态改写为 error 终态。本轮第一手动态复现主链成立(FileNotFoundError 外逸=True + 成功终态被 error 改写=True);**撕裂副面(双 open 交错写产生非法 JSON)本轮进程内模拟未复现**(句柄偏移语义所致,如实标注),v10 档案 40 轮对撞 39 次 FileNotFoundError 为任务材料口径本轮未重跑。
|
|
49
|
+
- **修复**:①临时名 `tempfile.mkstemp(prefix="result.json.", suffix=".tmp", dir=job_dir)` 替代固定 p+".tmp"(同目录保 rename 原子性、随机后缀消除共享名对撞,同 md_cg/fsutil.atomic_write 模板);②FileNotFoundError 并入重试面:replace 扑空(tmp 被瞬态消费/清理)时重建唯一名重写再试不外逸,50 次耗尽才抛;③finally best-effort 清理残留 tmp(成功路径零残留,对齐 K1 口径);④新增 write_error_result:写 error 前回看 result.json,成功终态(ok=true)在位即拒写并 log 留痕「兜底 error 改写被拒(重投对撞保护)」,error→error 更新不受限,退出码语义不变;main 内全部 7 处 ok=false 写入换用。纯 Python 改动。
|
|
50
|
+
- **攻击前后对比**:修复前(守卫注入对撞时序实测,临时 job 目录)——replace 被并发写者抢先消费共享 tmp → FileNotFoundError(WinError 2) 外逸=True;外逃后模拟 main 顶层兜底 → result.json ok=False——对撞写者成功终态被改写实锤。修复后——同注入对撞不外逸(自愈重建唯一名重试)、终态完整落地;成功终态在位时兜底 error 拒覆写且 log 留痕;端到端子进程(哑端口 127.0.0.1:9 + 哑 key 强制 API 失败)exit 3 照实上报、预置成功终态 ok=True 原样幸存。
|
|
51
|
+
- **守卫**:临时守卫脚本(**已删**,材料明示)双形态:旧码跑 = G1a FileNotFoundError 外逸 True + G2a 成功终态被 error 覆写 True → RED(EXIT 1);新码跑 = G1b 对撞自愈不外逸 + 终态完整、G2b/c write_error_result 拒覆写 + log 留痕、G3 无成功终态时 error 正常落盘(不堵死正常失败面)、G4 并发双写者 30×2 轮真实对撞 0 异常 + 终态完整、G5 常规写读一致 + 零 .tmp 残留 → GREEN(EXIT 0)。注入法:mock.patch os.replace 首调先真实消费共享 tmp 落成功终态再抛 FileNotFoundError(模拟并发写者抢先,无时序抖动)。本会话无法重跑(守卫已删),以现行读核 + test_exec_tools K1/K2 + 全量回归佐证,如实标注。
|
|
52
|
+
- **verified_by**(材料口径):① 守卫红→绿;② 端到端子进程(exit 3 + result.ok=True 预置终态幸存 + log 拒覆写留痕);③ `python hive/test_exec_tools.py` = 87/0(含 K1 无 .tmp 残留、K2 并发写读压测 0 撕裂);④ 全量 195/195(本会话实跑,第四节)。cargo test 未跑(纯 Python 无 Rust 面)。
|
|
53
|
+
|
|
54
|
+
### F4(v10 N83,medium)cmd_snapshot staging 残留零留置:快照失败不再绕闸直达 main
|
|
55
|
+
|
|
56
|
+
- **where**:材料口径 `hive/wm.py:111-215`(artifacts 存在性预检 :140-151 前置于任何 staging 写入;staging 拷入起至提交链整体包外层 try/except :156-201,except :202-207 异常清理后原样重抛)。**本会话读核**:`hive/wm.py:110-209`(生效条件注释 :110、cmd_snapshot :111、预检注释+循环 :140-151、staging :153-176、提交链内层 try/finally〔v2 N10〕:178-201、外层 except rmtree 清理重抛 :202-207)在位,与材料口径吻合。
|
|
57
|
+
- **攻击面**:任意一次快照失败(artifacts 路径拼错/缺失即**确定性触发,不需攻击者**)+ 后续任一正常快照合并:artifacts 缺失早退发生在拷入之后、提交链 try/finally 之外且无清理——残留 wm/jobs/<job_id>/(spec/result/log/artifacts)被后续任务快照的 `git add jobs` 全量扫进自己的分支并随其 merge 进 main——失败任务产物(可含其 result 中的敏感内容)绕过自己的凭证闸/专属分支/三级闸合并审查直达 main。本轮第一手动态复现(临时区 git init 哑 wm 仓+哑标记,测毕清理):jobA 失败残留 3 文件 → jobB merge 后 main 分支 ls-tree 含 jobs/jobA 全套且 git grep 命中敏感哑标记(BYPASS_TO_MAIN=True)。该早退发生在 v2 N10 finally 之前(第 8 轮修的是 finally 还原 HEAD,与此不同面,未重复报修)。
|
|
58
|
+
- **修复**:①artifacts 存在性校验前置到 rmtree/makedirs 之前——缺失时零写入直接返回,消除确定性触发面;②staging 拷贝+提交链整体包外层 try/except Exception:任一步失败(copy2 瞬态 OSError / git 链 WmError)先 `shutil.rmtree(dest, ignore_errors=True)` 清理已拷入 staging 再重抛,不留任何可被后续 git add jobs 扫入的绕闸残留;成功路径 staging 保留(分支快照本体,语义不变);内层 v2 N10 finally checkout main 逻辑原样保留。纯 Python 改动。
|
|
59
|
+
- **攻击前后对比**:修复前——jobA 声明 artifacts=missing.txt → cmd_snapshot 失败但 wm/jobs/jobA/ 残留 [artifacts/out.txt, result.json, spec.json];jobB 正常快照 merge 后 main 含 jobA 全套与敏感哑标记。修复后——同场景 jobA 快照失败零写入(wm/jobs 无 jobA),jobB merge 后 main 只含 jobB、无 jobA 痕迹;瞬态注入面(第二次 copy2 抛 OSError)异常照实外逃且 staging 零残留。
|
|
60
|
+
- **守卫**:临时守卫脚本(**已删**,材料明示)双形态:旧码 = A2 staging 残留 True + B3 main 含 jobA 三文件 + B4 BYPASS_TO_MAIN True → RED;新码 = 残留 False + main [] + B4 False + B5 jobB 正常入 main 不回归 → GREEN。另瞬态面补验:mock shutil.copy2 第二调抛 OSError → 异常外逃类型 OSError + staging 残留 False。哑数据 + 临时区自建 git 仓,未触真实 wm/serve,测毕清理。本会话无法重跑(守卫已删),以读核 + test_wm 两件套绿态佐证。
|
|
61
|
+
- **verified_by**(材料口径):① 守卫红→绿;② 瞬态清理补验 EXIT=0;③ `python hive/test_wm_traversal.py` = 10/0(含 C2 CLI 合法 job_id 零回归);④ `python hive/test_wm_progress.py` = 49/0(含 G5 新任务分支从 main 主线创建);⑤ 全量 195/195(本会话实跑,第四节)。
|
|
62
|
+
|
|
63
|
+
### F5(v10 N87,medium)children 装载点两阶段 update:接管者读到自己 job 目录的清单
|
|
64
|
+
|
|
65
|
+
- **where**:材料口径 `hive/orch.py:607-621`(main 内 _CFG.update 拆两阶段::615 先 update job_id/job_dir/jobs/model、:621 再 update children=_load_children());同步更新生效条件注释 :569。**本会话读核**:`hive/orch.py:569`(生效条件注释含两阶段口径)、:606-621(v10 N87 注释块 :607-614、第一阶段 update :615-620、第二阶段 :621)在位。
|
|
66
|
+
- **攻击面**:原单个 _CFG.update 字典字面量中 `"children": _load_children()` 在**字典构造期**求值,此刻 _CFG["job_dir"] 仍为模块初态空串(:240)→ `_children_path()`(:249-250)恒返回 CWD 相对 "_children.json"。编排任务换人续跑(上下文预算交回 need_continue)即触发重复派发(恒视为无子任务全量重派、max_subtasks 从 0 重计可放行翻倍子任务);CWD(worker 继承 serve 的 CWD=HIVE_DIR——serve_start.py:257 Popen cwd=HIVE_DIR、exec.rs:87-96 与 exec_cmd.py 均不设 current_dir)恰有他人/遗留 _children.json 时读进他人清单,poll/read_full 以本编排者身份读他人结果(越权读污染——污染变体前提如实标注:他人文件需来自遗留/外部写入;重复派发变体换人续跑即无条件触发)。本轮动态复现(临时区,测毕清理):CWD 预置他人清单 → 装载他人两条 EVAL_ORDER_BROKEN=True;update 完成后再 load 才读到正确清单(证明断裂在装载点、_save_children 写入位置正确)。
|
|
67
|
+
- **修复**:_CFG.update 拆两阶段——先 update job_id/job_dir/jobs/model,再 update children=_load_children()(装载时 job_dir 已就位,_children_path() 正确解析到编排者 job 目录);纯求值顺序调整零语义变更(缺陷描述指定的最低风险形态),附 v10 N87 病灶注释。_save_children 写回路径随 job_dir 就位一并归正(不再覆写 CWD 他人文件)。纯 Python 改动。
|
|
68
|
+
- **攻击前后对比**:修复前(守卫真实子进程跑 orch.main,CWD=哑 serve 目录放他人 _children.json、job 目录放自有清单)——装载到他人清单 sub_evil_OTHERS=True、自有清单 sub_own_1=False、EVAL_ORDER_BROKEN=True。修复后——同场景装载自有清单 sub_own_1=True、他人清单不再读入、EVAL_ORDER_BROKEN=False。
|
|
69
|
+
- **守卫**:临时守卫脚本(**已删**,材料明示):父进程布置临时场景(job 目录 spec.json+自有 _children.json、CWD 放他人 _children.json、HIVE_JOBS_DIR 指哑目录),spawn 子进程真实执行 orch.main(monkeypatch load_principal=哑 principal、_ex.main=哑 lambda——不触真实令牌库/serve/网关)。旧码 RED / 新码 GREEN。哑清单数据测毕清理。本会话无法重跑(守卫已删),以读核 + orch 三件套绿态佐证。
|
|
70
|
+
- **verified_by**(材料口径):① 守卫红→绿;② `python hive/test_orch.py` = 85 passed/0 failed;③ `python hive/test_orch_int_args.py` = 13/0;④ `python hive/test_orch_poll_cache.py` = 12/0;⑤ 全量 195/195(本会话实跑,第四节)。
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 三、发现明细(四区 confirmed 24 / rejected 2;去重后 20 独立条目 = 18 缺陷 + 2 复测通过)
|
|
75
|
+
|
|
76
|
+
以下每项「证据要点」为上游复核/修复会话的读码+实跑(材料原文;攻击复现均在系统临时目录/临时库/哑令牌/哑密钥/丢弃端口/mock 网关环境,测毕清理);标注★者本报告会话另做了现行代码读核(修复项)或历轮报告 grep 核实(编号归属)。legacy 项标注原轮次与复测轮数;origin=new 者的 N123-N129 为本报告会话续编(v14 用至 N122,v14.md:4)。
|
|
77
|
+
|
|
78
|
+
**跨区重复说明**(4 组冗余 4 条,如实记录不重复计数):legacy 区第 1 条(N62 合并形态:覆盖+cap)≡ authz 区第 1/2 条(覆盖面、cap 面各一);legacy 区第 2 条(N68+N69 合并形态)≡ runtime 区第 1/2 条(context_files、mdcg_root 各一);legacy 区 children 条 ≡ runtime 区第 3 条;legacy 区 stop 条 ≡ runtime 区第 4 条——同一缺陷的多区独立复核互为佐证。
|
|
79
|
+
|
|
80
|
+
### legacy 区(7 confirmed / 0 rejected)
|
|
81
|
+
|
|
82
|
+
| # | where(缺陷时点) | 严重度 | 问题摘要 | 证据要点 | 状态 |
|
|
83
|
+
|---|------|--------|----------|----------|------|
|
|
84
|
+
| v8 N62(合并形态)★ | md_cg/tokens.py:410 + md_cg/mcp_server.py:3468(cap 夹紧 md_cg/security.py:316/:325 权威令牌路径零调用) | medium | 【v8 首报→v9 复测→本轮第三次成立】令牌签发记录的租户绑定被 env MDCG_TENANT 静默覆盖 + 租户 clearance_cap 夹紧从未接线权威令牌路径——跨租户密级上限契约失效。拆解处置:覆盖面已修(F1 止血告警)、cap 面 deferred(第五节) | 本轮动态复现(系统临时区 MDCG_AUX_ROOT 隔离+哑令牌,测毕清理):issue('designer', tenant='tenantA') → verify_token(tok, tenant='tenantB') → principal.tenant=tenantB/clearance=secret/can_admin=True(OVERRIDE_ESTABLISHED);TenantRegistry.register('tenantB', cap='public').principal_for 同参 → clearance=public(夹紧语义在、路径未接线);pop MDCG_ROOT 后 _resolve_root → root=tenantB 登记根;显式 MDCG_ROOT+MDCG_TENANT 冲突 → (None, 冲突说明)(唯一缓解层实测在位) | **覆盖面已修**(F1);cap 面 deferred |
|
|
85
|
+
| v8 N68+N69(合并形态)★ | hive/orch.py:408-420(context_files 仅 isfile :408-411;白名单键元组含 mdcg_root :417-420)+ hive/exec.py:313-334(_context_block 全文读零检查)+ :694/:1454(mdcg_root 兜底与透传) | medium | 【v8 首报→v10 复测→本轮第三次维持】_spawn 白名单键双通道绕过 worker 防线:context_files 把凭据类文件全文注入子代理 prompt 发往外部 LLM 网关(read_file 四道防线该通道零检查);mdcg_root 让不可信 LLM 控制认知图读写落点、任意目录建图并落模型可控内容。拆解处置:context_files 已修(F2)、mdcg_root deferred | 本轮动态复现(临时区哑数据,测毕清理):①build_messages(context_files=[id_ed25519, app.env]) → 哑私钥全文与 DUMMY_API_KEY 密钥行进 user 消息零脱敏;同路径 tool_read_file →「敏感路径拒读」——双通道防线差异实拍。②pop MDCG_ROOT 后 tool_lingshu_cg({'op':'read'}, mdcg_root=任意空目录) → root 被接受;op=write(模型可控内容)→ 内容实落该任意根 hippocampus/inbox.jsonl(CONTENT_ON_DISK=True;write verdict moved_to=review_queue/committed=false——入审核队但内容已落任意目录,如实标注);本轮该根实落 4 项结构文件,与档案 11 项口径差异不改变结论 | **N69 已修**(F2);N68 deferred |
|
|
86
|
+
| v10 N82★ | hive/exec.py:117(固定共享 tmp 名)+ :122-129(重试面仅捕 PermissionError)+ :1616-1627(main 顶层 except 覆写) | medium | 【v10 首报→本轮第一手动态复现主链成立】write_result 固定共享临时名:重投双写者并发重叠时一者 os.replace 抢先消费共享 tmp → 另一者 FileNotFoundError 外逃 → main 顶层兜底以 ok:false 覆写 result.json——把对撞写者的成功终态改写为 error 终态(详 F3) | 本轮动态复现(调用真实 write_result,注入对撞时序,临时 job 目录):FileNotFoundError(WinError 2) 外逸=True;二次 write_result → 终态 ok=False(SUCCESS_OVERWRITTEN_BY_ERROR=True)。撕裂副面进程内模拟未复现(句柄偏移语义,如实标注);v10 40 轮对撞 39 次为档案口径本轮未重跑 | **已修**(F3) |
|
|
87
|
+
| v10 N83★ | hive/wm.py:141-165(staging 拷入)+ :161-162(artifacts 缺失早退在拷入后、提交链 try/finally 之外无清理) | medium | 【v10 首报→本轮第一手复现成立】cmd_snapshot staging 残留绕闸:快照早退残留已拷入的 wm/jobs/<job_id>/,后续任一任务快照的 git add jobs 把残留全量扫进自己的分支并随其 merge 进 main——失败任务产物绕过凭证闸/专属分支/三级闸直达 main(详 F4) | 本轮第一手动态复现(系统临时区 git init 的 wm 仓+哑标记,测毕清理):jobA 失败残留 [artifacts, result.json, spec.json];jobB 正常快照 merge 后 main 含 jobA 与敏感哑标记(BYPASS_TO_MAIN=True);早退发生在 v2 N10 finally 之前(不同面,未重复报修) | **已修**(F4) |
|
|
88
|
+
| v10 N87★ | hive/orch.py:601-613(_CFG.update 字典字面量内 _load_children() 先于 job_dir 键求值)+ :249-250(_children_path 读模块初态空 job_dir) | medium | 【v10 首报→本轮复现成立】children 装载点求值顺序断裂:接管者恒读 CWD 相对 _children.json 而非 job 目录内清单——全量重复派发、max_subtasks 从 0 重计可翻倍;CWD 恰有他人清单文件时读进他人 children 污染越权读边界(详 F5) | 本轮动态复现(系统临时区,全新导入 orch 模块,测毕清理):模块初态 _CFG['job_dir']='' → _children_path()='_children.json'(CWD 相对);CWD 预置他人 _children.json(2 条哑条目)→ _load_children() 返回他人两条;逐字复刻 main 的 _CFG.update 字面量后 children=他人清单(EVAL_ORDER_BROKEN=True)。worker CWD 攻击面读核:exec.rs:87-96 不设 current_dir(继承 serve CWD=HIVE_DIR) | **已修**(F5) |
|
|
89
|
+
| v10 N89★ | hive/hive_mcp/mcp_server.py:85-88(_jobs_dir 只读进程 env)对照 hive/serve_start.py:47-50/:231/:236(config 键胜出的合并环境) | medium | 【v10 首报→本轮双链解析+落点复现成立,第二次】jobs 池双源分叉:config.local.json 设 HIVE_JOBS_DIR 时 hive_spawn 把 job 写进 env 池(或 REPO 默认池)而 serve 跑在 config 池——任务永久 pending 无人领取;spawn/doctor/poll 观测面与实况相悖(ok=true、serve.started=true 全绿) | 本轮动态复现(临时区 config.local.json+哑 spec,**未拉起真实 serve**):load_config → pool_config;start 同式 merged 决策面=pool_config;MCP 侧 _jobs_dir env 未设 → REPO 默认池(DIVERGED=True);_submit 落 env 池 ok=True 且 config 池无该 job。观测面读核:spawn 返回 env 池(:386)、routes/doctor/poll 全走 _jobs_dir()。真实 serve 饥饿回路本轮未验证,如实标注 | 留档(medium——修复涉 MCP 侧复刻 serve 配置合并优先级的部署语义决策) |
|
|
90
|
+
| v10 N92★ | hive/serve_start.py:209-213(Windows taskkill /PID /F 无 /T;unix os.kill(pid,15) 无 killpg)+ :254-258(start 以 start_new_session 成组) | medium | 【v10 首报→本轮读核+哑进程实验维持,第二次】stop/restart/rebuild 的 stop 段不杀进程树:强杀 serve 后其 worker 正在跑的 exec.py 子进程全部成孤儿(自身 timeout 窗口内继续以已配置 API 凭据外呼),晚落 result.json 形成 state=error+result.ok=true 矛盾终态;新 serve recover_orphans 重投与孤儿并发同一 job;同仓 rust 侧 kill_tree 明确带 /T+守卫测试,python 侧漏 | 本轮平台语义实验(哑父/子 python 进程,测毕清理):taskkill /PID <父> /F(stop 的真实形态)→ 父亡子存(孤儿成立);对照加 /T → 双亡(树杀成立)。rust 侧对照读核:exec.rs:63-81 kill_tree 带 /T。unix 分支(无 killpg)仅读核(Windows 机无法动态验证);矛盾终态下游后果沿 v10 档案口径未重验,如实标注 | 留档(medium——修复方向明确〔加 /T+killpg〕但 unix 臂不可动态验证、红守卫只能半覆盖,本轮让位修复风险更低项) |
|
|
91
|
+
|
|
92
|
+
### authz 区(7 confirmed / 0 rejected)
|
|
93
|
+
|
|
94
|
+
| # | where(缺陷时点) | 严重度 | 问题摘要 | 证据要点 | 状态 |
|
|
95
|
+
|---|------|--------|----------|----------|------|
|
|
96
|
+
| v8 N62 覆盖面★ | md_cg/mcp_server.py:3468 + md_cg/tokens.py:409-410 | medium | 【复测成立(第 15 轮,第三次)→本轮止血修复】MDCG_TENANT 环境变量整体覆盖令牌记录的 tenant 绑定且无任何告警(对比 MDCG_CLEARANCE 已有告警)——详 F1 | 临时库实测(%TEMP% 临时区哑令牌库,脚本已清理):issue designer tenant=tenantA 后 verify_token(tok, tenant="tenantB")(即 mcp_server.py:3468 调用形态)→ principal.tenant=tenantB,redirect_stderr 捕获空串=零告警;_resolve_root({MDCG_TENANT:tenantB(未登记), MDCG_ROOT:临时根}) → (该根, None) 证实冲突检查只在登记根与 MDCG_ROOT 之间、令牌记录 tenant 不参与 | **已修**(F1 止血告警;强校验 deferred) |
|
|
97
|
+
| v8 N62 cap 面★ | md_cg/security.py:316-334 + md_cg/tokens.py:394-417 | medium | 【复测成立(第 15 轮仍未修,第三次)】TenantRegistry 的 clearance_cap 完全未接线生产路径——verify_token 与 _build_principal 均不查登记表;mdcos.py:40 导入 TenantRegistry 后零使用(死导入),principal_for/cap_of 生产零调用 | 临时库实测:TenantRegistry.register("pub", clearance_cap="public") 后 issue designer tenant=pub → verify_token 得 clearance=secret(未被夹紧);对照同登记表 principal_for 同参正确夹紧为 public。grep 全仓证实 principal_for/cap_of 仅 security.py 自身定义+test_p3.py 调用;hive/swarm 零引用 | 留档(medium——修复属授权链语义设计〔夹紧 vs 拒绝,v9.md:159 先例口径〕,deferred 授权链专项) |
|
|
98
|
+
| N123 | md_cg/tokens.py:451 + md_cg/tokens.py:394-417 | medium | 【新发现·留档】derive() 子令牌 TTL 可任意超过父令牌有效期(无上限夹紧),且令牌过期不沿派生链传播——「派生只能收窄权限」的时间维度被打破(对照:显式 revoke 会级联吊销,行为正确) | 临时库实测:issue designer ttl=5 → derive(父, role=record, ttl=999999) 得子令牌 expires_at≈999999s(11.6 天)、clamped==[](derive 只夹 clearance 不夹时间,tokens.py:434-437/:451 读证);sleep 6 秒后父 verify 抛「令牌已过期」、子 verify 通过(principal role=record)。对照组:revoke(父) 级联父子双失效(:502-513)、子令牌(delegable=False)再派生被拒——均符合预期。本会话读核 :445-455:clearance 夹紧在位、TTL 无夹紧,与材料一致 | 留档(medium——修复方向简单〔子 expires_at=min(请求值, 父 expires_at)+过期沿链传播〕但名额让位 legacy 欠账,deferred 下轮) |
|
|
99
|
+
| N124 | md_cg/mcp_server.py:3546-3557 | low | 【新发现·留档】_resolve_root 在租户登记表损坏/不可读时静默 fail-open——except Exception 吞掉后 t_root=None 等价「未登记租户」,直接采用显式 MDCG_ROOT,租户根物理隔离守卫无声消失 | 临时环境实测:MDCG_TENANT=pub + MDCG_ROOT=<临时任意路径> + MDCG_TENANT_REGISTRY 指向内容为非法 JSON 的文件 → _resolve_root(env) 返回 (该任意路径, None),redirect_stderr 捕获为空=零告警;同参换正常登记表 → 返回登记根,显式 ROOT 不一致时正确返回冲突 err。根因读证:mcp_server.py:3551-3552 except Exception 吞掉置 t_root=None;security.py:281-282 _load 吞 ValueError/OSError 返回空表 | 留档(low 加固项——损坏时 stderr 告警或 fail-closed,让位 deferred) |
|
|
100
|
+
| N125 | md_cg/mcp_server.py:3624-3626 | low | 【新发现·留档】main() 在 _build_principal(其内 _apply_attribution→_normalize_session,:3482/:3429-3446)之后把 MDCG_SESSION 原样(仅 strip)重设进 principal.session——防编造校验对该 env 恒被打穿 | 真实 serve 入口实测(python -m md_cg.mcp_server,stdin 喂 initialize/tools/call mdcg_whoami/shutdown,临时根/哑密钥/哑令牌库,测毕清理):设编造 DSH 形态 session id + MDCG_DSH_SESSIONS_ROOT 指向存在但为空的目录(归一化本应降级)→ whoami 返回 session 即该编造 id 原文、exit=0;同输入独立调 _normalize_session 返回 'anonymous'(守卫本应生效却被重设覆盖)。实际提权幅度受 crypto AAD 绑定 (node\|tenant\|actor) 限制,故 low | 留档(low——修复=移除/条件化该重设,让位 deferred) |
|
|
101
|
+
| N126 | md_cg/mdcos.py:378-382 + md_cg/crypto.py:399-402 | low | 【新发现·留档】审计写入 best-effort 静默吞错(两处 except OSError: pass)——审计通道坏死(磁盘满/文件被独占/权限回收)时全部写与管理操作无痕继续,「审计不可绕过」缺 I/O 层保障 | 临时库实测(临时根+哑密钥,已清理):MdCGSecure 正常 propose 后 audit_records()==1 含 propose ✓;把 _audit.jsonl 替换为同名目录后再次 propose 仍成功返回、stderr 空=零告警;附注:审计读路径遇同类 OSError 直接抛 PermissionError 崩溃(mdcos.py:396/:402)而非降级 | 留档(low 加固项——至少 stderr 告警(或 fail-closed 选项),让位 deferred) |
|
|
102
|
+
| 令牌损坏 fail-closed 复测★ | md_cg/tokens.py:288-299 | low | 【留档复测通过(非缺陷,方向正确,结案)】令牌文件损坏时 fail 方向为 fail-closed:损坏回落空库 → 所有令牌校验失败 → MCP 侧拒绝启动不降级为可用。档位锚:v8 N63 证据面(v8.md:95 python 侧 fail-closed 拒启读证),本轮独立复测再次通过 | 临时环境复测:把 _tokens.json 写坏后库级 verify_token 抛 TokenError「令牌不存在…」(tokens.py:288-299 _load 损坏回落空库,读证一致);真实 serve 入口(MDCG_TOKEN=哑令牌 + MDCG_TOKEN_FILE 指向坏文件)启动即报「令牌校验失败…拒绝启动(fail-closed)」退出码 3(mcp_server.py:3613-3620 读证一致)。附注同意材料口径:记录字段篡改需令牌文件写权限=信任根本身,按威胁模型不单列 | **复测通过,结案**(非缺陷) |
|
|
103
|
+
|
|
104
|
+
### runtime 区(7 confirmed / 0 rejected)
|
|
105
|
+
|
|
106
|
+
| # | where(缺陷时点) | 严重度 | 问题摘要 | 证据要点 | 状态 |
|
|
107
|
+
|---|------|--------|----------|----------|------|
|
|
108
|
+
| v8 N69★ | hive/orch.py:408-411 + hive/exec.py:313-326(build_messages:356-384) | medium | 【v8→v10→本轮第三次维持→本轮修复】context_files 通道只做 isfile 存在性检查即透传,绕过 read_file 的全部敏感防线——凭据文件全文注入子代理 prompt 发往外部 LLM 网关(与 legacy 区合并形态条目同缺陷,详 F2) | 读码:orch.py:408-411 仅 isfile;MCP 面 hive_mcp/mcp_server.py:349-352 同样仅 isfile;exec.py _context_block 文本分支读全文零检查零脱敏;防线四道仅挂 tool_read_file。本轮临时目录哑数据复现(测毕清理):哑私钥与哑 API key 原样进 user 消息无脱敏占位;同两路径 tool_read_file 均被拒——双通道防线差异实拍 | **已修**(F2) |
|
|
109
|
+
| v8 N68★ | hive/orch.py:417-420(root 解析 hive/exec.py:694;MCP 面 hive/hive_mcp/mcp_server.py:324-329/:377-378) | medium | 【v8→v10→本轮第三次维持】_spawn 白名单键元组仍透传 mdcg_root,编排者模型(或提示注入)可控子任务认知图读写落点——serve 未设 MDCG_ROOT 的部署经 spec 兜底生效(exec.py:694 env 优先、spec 兜底本轮读核在位);MCP 面 hive_spawn 同样接受该键。本会话读核 :418-420:键元组现状仍含 mdcg_root(未修) | 本轮临时环境复现(HIVE_JOBS_DIR 临时隔离,哑任务测毕清理):_spawn({...mdcg_root:临时 evil_root}) → ok=true,读回子 spec.json 确认 mdcg_root 原样透传(C1/C2 true)。下游写入效果(evil_root 建图 _audit.jsonl 等 12 项)为 v10.md 已实测留档,本轮未重跑——如实标注 | 留档(medium——收紧方案〔移除键 vs 根白名单〕涉部署语义决策,与 context_files 止血分拆处理) |
|
|
110
|
+
| v10 N87★ | hive/orch.py:606-613(_children_path:248-250) | medium | 【v10 首报→本轮复现成立→本轮修复】装载点求值顺序断裂:main() 的 _CFG.update 字面量先求值 _load_children(),此刻 job_dir 仍为初始空串 → 装载点=CWD 相对 _children.json——换人接管恒读不到自己 job 目录清单(全量重复派发、max_subtasks 翻倍),CWD 恰有他人清单时读进他人清单(与 legacy 区条目同缺陷,详 F5) | 本轮临时区子进程复现(哑清单,测毕清理):CWD 预置含他人 job_id 的 _children.json、job 目录预置自有清单,按 main() 语句序原样执行 → _children_path()=='_children.json'(CWD 相对)、装载结果=他人清单、update 后再读=自有清单(己方本可读但 main 用的是前者)。链路读码:serve_start.py:257 Popen cwd=HIVE_DIR → exec.rs:87-96 与 exec_cmd.py 均无 current_dir | **已修**(F5) |
|
|
111
|
+
| v10 N92★ | hive/serve_start.py:208-216(对照 hive/src/exec.rs:63-81) | medium | 【v10 首报→本轮维持,第二次】stop/restart/rebuild 的 stop 段不杀进程树——Windows taskkill 无 /T、unix os.kill 无组杀:强杀 serve 后正在跑的 exec.py worker 全成孤儿(自身 timeout 窗口内继续跑外部 API),晚落 result 形成 state=error+result.ok=true 矛盾终态;新 serve recover_orphans 重投与孤儿并发同一 job(与 legacy 区条目同缺陷) | 本轮平台实验(哑长睡进程,测毕 /T /F 清理):以 stop() 的确切形态 taskkill /PID <父> /F → rc=0 父亡、子进程仍存活成孤儿;对照 /T /F 后子进程消失。读码:serve_start.py:209-212 无 /T、:214 无组杀(:258 却 start_new_session 单独成组);对照 exec.rs:63-81 kill_tree 明确 /T+守卫测试;scheduler.rs:251 recover_orphans 在位。「孤儿继续烧配额」受 worker 自身 timeout_s 约束非无限——按实缩减表述 | 留档(medium——加 /T+killpg 方向明确,unix 臂在本 Windows 机不可动态验证、红守卫只能半覆盖,本轮让位) |
|
|
112
|
+
| N127 | hive/orch.py:413 + hive/serve_start.py:254-258 + hive/src/exec.rs:87-96 + hive/exec.py:952-966/:873-907/:1452-1458 | medium | 【新发现·留档】编排子任务的 workdir=编排者进程 CWD(=serve CWD=HIVE_DIR),批次 27 的 fail-closed 读白名单由此覆盖整个 hive/ 目录:默认池 jobs/** 全部兄弟任务的 spec/result/log(跨任务数据聚合)与 hive/config.local.json(serve 凭据存储,直值形态=API key 明文)都在子代理可读面内,内容回喂即发往外部网关;且 P1-6 敏感名单不含 config.local.json/*.token——read_file 防线对该文件同样失效(与其「凭据类文件无论根约束都不进上下文」承诺相悖) | 本轮临时环境复现(哑数据假 HIVE_DIR,测毕清理):_worker_scope(子job_dir,{workdir:假HIVE_DIR}) 含假 HIVE_DIR(D0)→ tool_read_file 哑 config.local.json ok=true、直值哑 key 明文未脱敏(非 sk- 形态不中 _PII_PATTERNS,D1/D2);_sensitive_read 对该文件返回 None(D3,名单 :873-907 只有 .ssh/.aws 目录段与 id_rsa/.env/.pem 文件名族);兄弟 job result 全文可读含哑敏感标记(D4);hive_orch.token 亦不在名单(D5);C3 实拍子 spec workdir==编排者进程 CWD。本部署 config.local.json 实为 env/file 间接形态(直读仅得密钥文件路径),但三形态支持直值且 token/搜索密钥文件路径仍由此泄露——如实标注 | 留档(medium——收紧 workdir scope 会动批次 27 读白名单语义〔workdir 入 scope 是设计面〕,deferred 待 scope 语义专项) |
|
|
113
|
+
| N128 | swarm/rust_swarm.py:24/:29/:38/:68-70 + swarm/rust_runtime/src/main.rs:276-280 + swarm/swarm_cli.py:93(签名 swarm/rust_runtime/src/swarm.rs:376-385) | medium | 【新发现·留档】WAL HMAC 密钥生命周期失效:shared_secret 缺省=硬编码「蜂群默认密钥」(Python/rust 两侧同值),CLI 形态更差——config 缺 shared_secret 时 swarm_cli 传空串(rust 侧 as_str 命中空串不回退默认)→ HMAC 密钥为空字节串;且密钥明文写入 project_dir/swarm.json 与 WAL 同盘。WAL 验签/B6 防操纵/replay_wal 状态重建/health integrity 的完整性保证对知道常量或空串的任何人归零——可伪造/改写事件历史并通过全部验签 | 本轮临时目录复现(哑事件,测毕清理):E1 make_swarm_config 缺省 shared_secret==硬编码默认值(rust_swarm.py:24 常量);E2 CLI 形态传空串(swarm_cli.py:93);E3 以默认密钥伪造「信任提交 trust=0.99 FORGED_BY_ATTACKER」事件行(签名串照 swarm.rs 签名格式)→ verify_wal_signatures all_valid=true;E4 空串密钥伪造同过;E4b 对照:错误密钥猜测验签失败(防线只在密钥保密性上);E5 密钥明文写入 config 与 WAL 同盘同目录。读码:main.rs:276-280 get('shared_secret').and_then(as_str)——值存在(含空串)即用,仅键缺失/非字符串才回退默认 | 留档(medium——修复涉密钥管理策略设计+rust/python 双侧改动,deferred) |
|
|
114
|
+
| exec 空包三通道复测★ | hive/exec.py:1221-1227/:1391-1397/:1431-1437/:1556-1574(材料时点;本会话读核现行漂移至 :1287/:1457/:1497 一带 + main _error 通道) | low | 【复测结论:已修复(非缺陷,第 10 轮 F2 修 v2 N7,本轮守卫复跑通过结案)】call_llm 单发路、工具轮内、超轮次强制终答三处空助手轮(content/tool_calls 双空、content=null)统一 fail-closed 回 _error,main 写 ok=false+EXIT_API,不再有 forced_final 假成功流入下游 | 本轮实跑守卫:`python -X utf8 -m hive.test_exec_empty_response`(mock 网关+哑令牌+临时 job 目录)→「结果: 12 pass / 0 fail」rc=0,含 A 组空包四形态→_error、B 组强制终答空包→_error 不假成功、C 组端到端 rc!=0 且 ok=false(C1/C2/C3)、C4 对照组正常 content 零回归。**本报告会话亦实跑同命令 → 12 pass / 0 fail(第四节)**;代码三处 _empty_turn 防护与 main _error 通道现行读核在位 | **复测通过,结案**(已修复,无需处置,仅留档) |
|
|
115
|
+
|
|
116
|
+
### perimeter 区(3 confirmed / 2 rejected)
|
|
117
|
+
|
|
118
|
+
| # | where(缺陷时点) | 严重度 | 问题摘要 | 证据要点 | 状态 |
|
|
119
|
+
|---|------|--------|----------|----------|------|
|
|
120
|
+
| v8 N66★ | src/lib/roleplay_web.ts:829 | medium | 【v8 首报→v13 deferred→本轮复测仍成立(第三次记录)】POST /roleplay/api/chat 无任何来源校验(无 Origin/Referer/CSRF token/x-edit-key),readBody(:508) 不校验 Content-Type——跨站网页可用 simple-request(text/plain,不触发预检)盲发写请求;GET 数据端点无 CORS 头也无 Host/Origin 校验(全文件 grep 零命中),DNS rebinding 场景可跨站读取转录与角色配置 | 本轮动态复现(临时目录+丢弃端口+mock webServer.register+真实 installRoleplayWeb handler,tsx 直跑,测毕清理):①POST /roleplay/api/chat 带 Origin:evil 域名、Content-Type:text/plain、无任何凭证头 → 请求进业务逻辑;②transcripts/<role>__shared.jsonl 实际落盘注入消息;③GET /roleplay/api/history 回读注入消息(写已持久化);④全部响应无 access-control-allow-origin 头;⑤对照 POST /api/roles/x/meta 同形态 → 403「编辑未开放」(写闸 ROLEPLAY_EDIT_KEY 有效)。写端点已 fail-closed,chat 是唯一无闸写面;appendTranscript(:863) 在 capReady(:865) 检查之前(能力未接入也落盘) | 留档(medium——涉 CSRF 防护范围大设计决策〔Origin/Referer 校验 vs CSRF token vs 只护写面〕按分诊标准④ deferred;最小止血候选〔chat 校验 Origin 同源/127.0.0.1〕已记录在案供设计拍板) |
|
|
121
|
+
| v6 N39 / v8 N63 竞态面★ | src/lib/token_store.ts:188 | low | 【v6 留档(原仅读码)→本轮升级动态实证(第三次记录)】首启签发 check-then-act 竞态:readKeyring(:175) 与 writeKeyring(:192) 之间隔 spawnSync 15s 窗口(:124)无锁,writeKeyring(:97-105) writeFileSync 直接覆盖(无 tmp+rename/O_EXCL),并发首启产生无主活 designer 凭据 | 动态复现(MDCG_AUX_ROOT 指临时目录+临时 keyring,不触真实令牌库;两并发 node 进程跑真实 resolveToken,测毕清理):①两进程均返回 source=issued(都读到空 keyring);②临时 _tokens.json 落 2 条 designer 记录;③keyring 仅剩胜者令牌;④败者令牌经 python -m md_cg.tokens verify → ok:true、can_write:true、can_admin:true——无主活管理员凭据坐实,吊销指引只出现在败者自己的启动日志。注:「极端交错写坏 keyring」变体未复现(推测性,不采信);与本仓 tmp+rename 惯例(roleplay_web.ts:634-636/:656-658)不一致。低危定级维持(同用户进程模型下=凭据残留/可用性) | 留档(low——按标准①让位;修复方向〔O_EXCL/锁/tmp+rename 对齐本仓惯例〕已留档) |
|
|
122
|
+
| N129 | md_cg/export.py:100(闸 mcp_server.py:2665-2676) | low | 【新发现·留档】MDCG_EXPORT_ROOT 未设置时(check_path_root 的明示部署开关语义,security.py:345-347 未配置=放开)designer 可经 export 的 out 参数把全库明文(含 secret 级正文)写到本机任意路径:_write_jsonl 先 makedirs 任意父目录再 tmp+os.replace 覆盖既有文件——缺省部署无兜底(如缺省强制 out 落 cg.root 内) | 动态复现(tempfile 临时库+随机哑主密钥+哑 designer Principal,已清理):臂A(未设 EXPORT_ROOT)export(action=graph, out=<临时库外深层路径>) → ok:true/written:2,预置受害文件内容被覆盖,导出明文同时含 public 与 secret 节点正文,任意父目录被 makedirs;臂B(设根后)同 out → PermissionError(闸门配置后生效),根内导出正常。需 designer/admin(guest 实测 AccessDenied);风险在组合形态:designer 载体(LLM)被提示注入时 export(out=任意路径, include_content 缺省 True) 是把密文记忆整库外发为明文+覆盖任意文件的现成原语 | 留档(low 加固项——涉部署开关缺省语义决策,deferred) |
|
|
123
|
+
|
|
124
|
+
### 复测通过结案小节(confirmed 内非缺陷 2 条,如实单列)
|
|
125
|
+
|
|
126
|
+
| # | where | 结论 |
|
|
127
|
+
|---|------|------|
|
|
128
|
+
| 令牌文件损坏 fail-closed | md_cg/tokens.py:288-299 | **复测通过,结案**(非缺陷,方向正确)——损坏回落空库 → 全部校验失败 → MCP 拒启退出码 3 不降级;档位锚 v8 N63 证据面(v8.md:95),本轮独立复测再次通过(authz 区末行) |
|
|
129
|
+
| exec 空包三通道 | hive/exec.py(现行 :1287/:1457/:1497 一带) | **复测通过,结案**(第 10 轮 F2 修 v2 N7 已成立)——三处 _empty_turn 防护+main _error 通道在位,本轮守卫 12/0(上游与本报告会话双跑一致,runtime 区末行) |
|
|
130
|
+
|
|
131
|
+
### 证伪/剔除小节(rejected 2 条,均在 perimeter 区)
|
|
132
|
+
|
|
133
|
+
| # | where | 证伪/剔除理由 | 附注 |
|
|
134
|
+
|---|------|--------------|------|
|
|
135
|
+
| ingest hive 元组缺口 | md_cg/mcp_server.py:2646 | **证伪(安全主张不成立;仅文档/清单不一致属实)**:_ingest_call 的 can_write 检查列表确不含 hive(与文档不一致);但动态裁决(临时库+临时 hive jobs 目录+直接构造的 can_write=False/ops_allow 含 ingest 哑 Principal,模拟未来只读角色):action=hive 在 _ingest_call 层放行后,写链深处被 MdCGSecure.add(mdcos.py:3765-3769 require_layer_write)→ security.py:199-214 require_write 逐事件拒绝:written=0/denied=2、落盘节点数=0——不存在「can_write=False 身份经 action=hive 落盘写节点的越权写通道」,未来新增只读角色同样被写入层同一闸门拦截 | 附带观察(与候选主张不同的轻微完整性问题,仅记录不入缺陷计数):denied 全拒时 _sources.json 水位仍推进(实测 count=0 而 seq=2)——后续合法令牌重摄会跳过这批被拒事件,属水位推进语义瑕疵,非越权写 |
|
|
136
|
+
| export 密级过滤与根白名单 | md_cg/export.py:40 | **非缺陷复测项——复测通过(候选自身结论「防线成立」本轮全部验证属实)**:①密级过滤动态实证:guest(clearance=internal)export → written=1/skipped_unreadable=1,导出不含 secret 节点正文;designer → 全量(mdcos.py:3943-3947 get 经 _readable、:3835-3860 密级未知按 secret fail-closed);②根白名单一致性:check_path_root 统一入口(security.py:344-362 realpath 归一+多根),ingest/export/link/ref 各面同用各自 env 根;③roleplay 静态面:文件名替换与 clientId 白名单穿越不可达,写端点 403 fail-closed 本轮动态复现 | 无 |
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## 四、验证(门禁结果)
|
|
141
|
+
|
|
142
|
+
以下「本报告会话实跑」均为本报告写作会话在仓库根目录实际运行(第一手);「材料口径」为上游复核/修复/门禁会话已跑、本会话未重跑(如实区分):
|
|
143
|
+
|
|
144
|
+
| 命令 | 结果 | 来源 |
|
|
145
|
+
|------|------|------|
|
|
146
|
+
| `python -X utf8 scripts/run_tests.py --jobs 4`(全量) | `===== SUMMARY 195/195 通过,5 跳过(依赖缺失/平台不符) =====`——本会话**两次实跑**(一次管道观流、一次重定向捕获),**真实退出码 0**;195 = v14 的 194 + 新守卫 1 件,与材料门禁口径逐字一致 | **本会话实跑** |
|
|
147
|
+
| `python -X utf8 -m md_cg.test_tenant_env_override_warn` | 「通过 11 / 失败 0」——与材料修后 11/0 一致(材料红证修前 8 通过/3 失败,3 失败均为告警缺席项;本会话未重跑红证,守卫未回退) | **本会话实跑** |
|
|
148
|
+
| `python -X utf8 -m hive.test_exec_empty_response` | 「结果: 12 pass / 0 fail」——exec 空包复测通过项的本会话独立复核,与材料口径一致 | **本会话实跑** |
|
|
149
|
+
| `npm run gate` | **失败(第一手复现)**:重定向捕获**真实退出码 1**,R1 凭据/密钥面 PASS(文件面=0 内容面=0)、R2 私有数据面 PASS、R3 隐私文本 PASS、`[FAIL] R4 非追踪件面 命中=1;非追踪=25,允许=24`,命中 = md_cg/test_tenant_env_override_warn.py(未 git add),VERDICT=FAIL——与材料口径逐字一致。R1 的 5 条 NOTE 为仓库内既有哑凭据文件名的守卫备注(docs/hive 与 md_cg 测试内的 dummy 形态,非本轮产物、非真实凭据)。**性质判定**:untracked 时序性(守卫文件提交后即入追踪面,R4 应转绿),裁决归编排会话提交前;本会话不 commit 故未验证提交后形态,如实标注 | **本会话实跑**(与材料一致) |
|
|
150
|
+
| swarm cargo test | **未运行**——Rust 面零改动(本会话 git status 证实 swarm/ 与 rust/ 无改动,改动面仅 md_cg/hive 的 python 件),与材料口径一致 | 双方一致 |
|
|
151
|
+
| npm test | **未运行**——TS 面零改动(git status 证实 src/ 与 TS 测试未动),与材料口径一致 | 双方一致 |
|
|
152
|
+
|
|
153
|
+
**上游会话已运行、本会话未重跑的验证**(材料原文,如实区分):F1-F5 五项修复的守卫红证(修前各一跑,红绿数字见第二节各守卫行——其中 F2/F3/F4/F5 为临时守卫脚本、已删,本会话无法重跑,以现行读核+既有测试绿态+全量回归替代佐证);F1 的既有回归七件套(test_p21_tokens 38/0、test_p2_mcp 64/0、test_security_audit_b26 17/0、test_security_audit 13/0、test_security_audit_v21 49/0、test_p34_crosscheck 51/0、hive.test_orch 85/0)与 CLI 冒烟;F2 的 test_exec_tools 87/0 + test_worker_scope 9/0 + b26 17/0 + v21 49/0 与 CI 同款全量 195/195;F3 的端到端子进程(哑端口强制 API 失败 → exit 3 + 预置成功终态幸存 + log 拒覆写留痕)与 test_exec_tools 87/0(含 K1/K2);F4 的 test_wm_traversal 10/0 + test_wm_progress 49/0 与瞬态清理补验;F5 的 test_orch 85/0 + test_orch_int_args 13/0 + test_orch_poll_cache 12/0;四区复核全部攻击复现(第三节证据要点——临时区/哑数据/mock 网关/丢弃端口/临时 serve 形态,测毕清理)。
|
|
154
|
+
|
|
155
|
+
**git 工作树核对**(本会话 `git status --porcelain` / `git diff --numstat` + 五处落点读核):改动面 = **四个修复源文件**(md_cg/tokens.py +15/-1〔F1〕、hive/exec.py +87/-21〔F2+F3〕、hive/wm.py +63/-46〔F4〕、hive/orch.py +10/-2〔F5〕)+ **一份常驻守卫**(md_cg/test_tenant_env_override_warn.py,未跟踪新文件)——与五项修复一一对应;F2/F3/F4/F5 临时守卫已删(git status 证实仅 F1 守卫存留)。另有 `md_cg/whitebox_kb/wisdom/code_solidified.json`(+1/-2)为 v10-v14 报告已注明的先前会话遗留工作区变更,非本轮触点。未做任何 commit。
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## 五、遗留清单(13 个开口:medium 8 / low 5;+ 复测结案 2 + 证伪 2)
|
|
160
|
+
|
|
161
|
+
### 留档项(13 项,材料「留档未修」清单;★=本会话抽查读核在位性)
|
|
162
|
+
|
|
163
|
+
| # | where(缺陷时点) | 严重度 | 问题 | 留档理由 / 处置建议(材料口径) |
|
|
164
|
+
|---|------|------|------|------------------------------|
|
|
165
|
+
| v8 N62 cap 面★ | md_cg/security.py:316-334 + md_cg/tokens.py:394-417 | medium | TenantRegistry clearance_cap 夹紧从未接线权威令牌路径(principal_for/cap_of 生产零调用,mdcos.py:40 死导入) | 修复属授权链语义设计(公开租户 designer 令牌应被夹到 public;夹紧 vs 拒绝行为决策——v9.md:159 先例口径),不在 MDCG_TENANT 告警止血范围,**留档待授权链专项设计**;本轮第三次成立,建议下轮优先 |
|
|
166
|
+
| v8 N68★ | hive/orch.py:417-420(exec.py:694;MCP 面 :324-329/:377-378) | medium | _spawn 白名单键仍透传 mdcg_root,编排者可控子任务认知图读写落点 | 收紧方案(移除键 vs 根白名单)涉部署语义决策,与 context_files 止血分拆处理,**明确 deferred**;本会话读核 :418-420 键元组现状未变 |
|
|
167
|
+
| v10 N89 | hive/hive_mcp/mcp_server.py:85-88 对照 serve_start.py:47-50/:231/:236 | medium | jobs 池双源分叉:config 设 HIVE_JOBS_DIR 时 spawn 落 env 池而 serve 跑 config 池,任务永久 pending 且观测面全绿 | 修复需 MCP 侧 _jobs_dir 复刻 serve 的配置合并优先级,涉配置语义决策;且真实 serve 饥饿回路本轮未拉起真 serve 验证(复现不完整),deferred |
|
|
168
|
+
| v10 N92★ | hive/serve_start.py:208-216(对照 exec.rs:63-81) | medium | stop 段不杀进程树(Windows 无 /T、unix 无 killpg) | 修复方向明确(加 /T + killpg,rust 侧 kill_tree 有先例),但 unix killpg 臂在本 Windows 机不可动态验证、红守卫只能半覆盖,本轮让位给修复风险更低的 children 项,**留档下轮优先**;本会话读核 :209-214 现状未变 |
|
|
169
|
+
| v8 N66 | src/lib/roleplay_web.ts:829 | medium | chat 无来源校验(v8 首报→v13 deferred→本轮复测仍成立) | 涉 CSRF 防护范围大设计决策(Origin/Referer 校验 vs CSRF token vs 只护写面),按分诊标准④明确 deferred;**最小止血候选(chat 校验 Origin 同源/127.0.0.1)已记录在案供设计拍板** |
|
|
170
|
+
| N123 | md_cg/tokens.py:451 + :394-417 | medium | derive() 子令牌 TTL 无上限夹紧且过期不沿派生链传播(new 本轮首证) | 修复方向简单(子 expires_at=min(请求值, 父 expires_at)+过期沿链传播)但名额按标准②让给 legacy 多轮欠账,**deferred 下轮**;本会话读核 :445-455 确认只夹 clearance 不夹时间 |
|
|
171
|
+
| N127 | hive/orch.py:413 + serve_start.py:254-258 + exec.rs:87-96 + exec.py:952-966/:873-907/:1452-1458 | medium | 编排子任务 workdir=编排者 CWD(=HIVE_DIR),批次 27 读白名单覆盖整个 hive/:兄弟任务产物与 config.local.json 在子代理可读面 | 收紧 workdir scope 会动批次 27 读白名单语义(workdir 入 scope 是设计面),破坏正常读功能风险高,**deferred 待 scope 语义专项**;敏感名单补 config.local.json/*.token 可作止血子项一并评估 |
|
|
172
|
+
| N128 | swarm/rust_swarm.py:24/:29/:38/:68-70 + main.rs:276-280 + swarm_cli.py:93 | medium | WAL HMAC 密钥生命周期失效:缺省硬编码默认密钥、CLI 空串形态、密钥明文与 WAL 同盘——WAL 完整性保证对知常量者归零 | 修复涉密钥管理策略设计 + rust/python 双侧改动,**deferred**;最小止血候选:CLI 侧缺键不传(让 rust 回退或显式拒绝)与密钥不入 project_dir 明文可先行评估 |
|
|
173
|
+
| v6 N39/v8 N63 竞态面 | src/lib/token_store.ts:188 | low | 首启签发 check-then-act 竞态(readKeyring↔writeKeyring 15s 窗口无锁+直接覆盖写),并发首启产生无主活 designer 凭据 | low 级按标准①让位;修复方向(O_EXCL/锁/tmp+rename 对齐本仓惯例 roleplay_web.ts:634-636)已留档 |
|
|
174
|
+
| N124 | md_cg/mcp_server.py:3546-3557 | low | _resolve_root 在租户登记表损坏/不可读时静默 fail-open(零告警) | 加固项:损坏时 stderr 告警或 fail-closed,low 让位 deferred |
|
|
175
|
+
| N125 | md_cg/mcp_server.py:3624-3626 | low | main() 把 MDCG_SESSION 原样重设进 principal.session——防编造校验对 env 恒被打穿 | low 让位 deferred;修复=移除/条件化该重设 |
|
|
176
|
+
| N126 | md_cg/mdcos.py:378-382 + md_cg/crypto.py:399-402 | low | 审计写入 best-effort 吞错:审计通道坏死时敏感操作无痕继续 | 加固项:至少 stderr 告警(或 fail-closed 选项),low 让位 deferred |
|
|
177
|
+
| N129 | md_cg/export.py:100(闸 :2665-2676) | low | MDCG_EXPORT_ROOT 未设时 designer 可经 export out 参数全库明文写任意路径+覆盖既有文件 | 涉部署开关缺省语义决策(如缺省强制 out 落 cg.root 内),low 加固项 deferred |
|
|
178
|
+
|
|
179
|
+
### 复测结案(2 项)与证伪(2 项)
|
|
180
|
+
|
|
181
|
+
见第三节末两个小节:令牌损坏 fail-closed 与 exec 空包三通道均复测通过结案(非缺陷);perimeter 区 2 条 rejected(ingest hive 越权写证伪——写入层闸门拦截;export 防线复测通过)如实记录,其附带观察(_sources.json 水位推进语义瑕疵)仅记录不入缺陷计数。
|
|
182
|
+
|
|
183
|
+
**优先级建议**(据材料处置线索汇总):①N123(TTL 夹紧+过期沿链传播)与 N92(/T+killpg)修复方向明确,为下轮速收候选(N92 的 unix 臂须在有 linux 环境的轮次补动态验证);②N62 cap 面与 N127/N128 同涉「授权/密钥/范围」语义专项,建议合并一轮做接入面设计决策再动代码(v8.md:175 先例口径:先设计决策后代码);③N68/N89/N66/N129 四项涉部署/接入语义,最小止血候选(N66 chat Origin 校验、N128 CLI 缺键不传+密钥不明文落盘)已留档可先行;④五项 low 加固项随各自域下轮顺带收。
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## 六、纪律合规声明
|
|
188
|
+
|
|
189
|
+
1. **定位先读索引**:本报告写作前已读 WORKSPACE_INDEX.md(按职责定位 md_cg/ 为「灵枢大脑」、hive/ 为「蜂巢并发引擎」、swarm/ 为「蜂群运行时——WAL-HMAC」、src/ 为「DSH 插件 TypeScript 源码」、docs/eval 为历轮报告所在),未做全盘浏览。
|
|
190
|
+
2. **结论引证**:所有修复与缺陷均引 path:line(材料口径为上游会话时点快照行号;F3 增行使 hive/exec.py 行号漂移处另注本会话读核现行行号——如 F2 材料称 _context_block :313-330/_sensitive_read :897/tool_read_file :1097、读核实为现行 :363-380/:948/:1148,exec 空包材料 :1221-1227 等现行 :1287/:1457/:1497 一带,以读核值为准);第三节证据要点摘自任务输入的四区复核材料(上游会话读码+实跑);第四节「本报告会话实跑」六项为第一手命令与输出(两次全量回归含真实退出码 0、新守卫 11/0、空包守卫 12/0、gate 失败现场含真实退出码 1、git 核对、五处落点读核),材料口径与未跑项均如实标注来源,无一冒充;留档缺陷抽查读核(security.py cap_of :316-319、orch.py 键元组 :418-420、serve_start.py :207-216 无 /T、tokens.py derive :445-455 只夹 clearance 不夹 TTL)与材料「在位/未修」结论一致。
|
|
191
|
+
3. **编号续编声明**:材料 confirmed 的 origin=new 条目未携带编号,本报告会话按历轮 N 口径续编 N123-N129(v14 用至 N122,v14.md:4 编号口径行核实);legacy 项编号经 v6.md:100、v8.md:94/:95/:104/:112/:113、v9.md:109、v10.md:77/:78/:89/:103/:106、v13.md:102 grep 核实。「令牌文件损坏 fail-closed」复测项材料未带原编号,本报告锚定 v8 N63 证据面(v8.md:95)如实标注;v6 N39 与 v8 N63 为同文件 writeKeyring 面的两个历轮条目,本轮竞态实证按「v6 N39/v8 N63 竞态面」合并记,不新编号不冒称独立缺陷史。
|
|
192
|
+
4. **安全测试纪律合规**:材料全部攻击复现均在系统临时目录/临时库/哑令牌/哑密钥/丢弃端口/mock 网关/临时 serve 形态(MDCG_AUX_ROOT/MDCG_TOKEN_FILE/MDCG_MASTER_KEY/MDCG_ROOT 全指向临时或哑值)进行且测毕清理,未触真实令牌库/真实 serve/真实数据目录(材料逐项声明,本报告照录);F1 常驻守卫自带 tempfile 临时库+清理;本报告会话仅运行功能门禁与守卫(自含临时环境)与读码,未触任何真实凭据/数据根、未修改任何源文件。
|
|
193
|
+
5. **已修项不重复报**:第 8/9/10/12/13/14 轮已修清单(含 v2 N7 空包、v2 N10 finally 还原 HEAD、v8 F5 结果原子写等)未再报——本轮 F3 是 v8 F5 原子写**之上的共享名对撞次生缺口**(v10 N82 已立项口径)、F4 是 v2 N10 **之外的 staging 残留面**(材料明示不同面);exec 空包与令牌损坏为复测通过结案项不立项为缺陷;第 10 轮已修的 MCP 入口三层守卫等未再报。本轮 5 修全部为历轮留档复测项的**首次修复**,非重复修复。
|
|
194
|
+
6. **隐私脱敏**:全文只写仓库相对路径;材料与本会话输出的本机绝对路径(系统临时区路径、盘符根、用户目录)一律转录为「系统临时目录/临时区/哑值」等占位描述;哑令牌/哑密钥字面量以形态描述替代(不录完整字面量);gate 输出中的 NOTE 条目为仓库内既有哑凭据文件名的守卫备注(非本轮产物、非真实凭据)。定稿前经机械扫描复查(盘符/用户目录/真实凭据形态零命中,见下方自查)。
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## 七、跳过项及原因
|
|
199
|
+
|
|
200
|
+
- **swarm cargo test 未运行**:Rust 面零改动(本会话 git status 证实 swarm/ 与 rust/ 无改动,改动面仅 md_cg/hive 的 python 件)——材料与本会话口径一致;后续 N128 处置 swarm/rust 双侧时须补跑。
|
|
201
|
+
- **npm test 未运行**:TS 面零改动(git status 证实 src/ 与 TS 测试未动)——材料与本会话口径一致。
|
|
202
|
+
- **npm run gate 的 R4 失败未在本会话消除**:根因是新守卫文件未 git add(untracked 时序性);消除需 commit/add——裁决归编排会话(材料口径「编排会话提交前裁决」),本会话不 commit,故未验证提交后 gate 转绿形态,如实标注。gate 链在 R4 后停止(其后的 cogmap_sync/link_check/workspace_index/verify_discipline 未到达)。
|
|
203
|
+
- **F2/F3/F4/F5 的守卫红证未重跑**:四项的攻击复现守卫为临时脚本且材料明示已删(git status 证实仅 F1 常驻守卫存留),旧码回退在多轮未提交改动的工作树上不可行——以现行落点读核(第二节逐项现行行号)+ 既有测试绿态 + 全量回归 195/195 替代佐证,如实标注。F1 守卫红证未重跑同理(守卫绿态 11/0 本会话实跑覆盖)。
|
|
204
|
+
- **全部攻击复现未在本会话重跑**:四区复核的动态复现(临时区/哑数据/mock 网关/丢弃端口/临时 serve)为上游会话执行且逐项声明清理(第三节证据要点来源均标注为材料原文);本会话以五处修复落点读核 + 留档项在位性抽查读核 + 门禁实跑替代,未重跑任何攻击场景。
|
|
205
|
+
- **N89 真实 serve 饥饿回路与 N92 unix killpg 臂未验证**:材料自身如实声明(前者未拉起真实 serve、后者 Windows 机无法动态验证)——照录不升格为实证。
|
|
206
|
+
- **N123-N129 及其余留档项未修**:分诊标准与处置建议见第五节;本报告会话为报告撰写会话,不做修复。
|
|
207
|
+
- **git 未提交**:commit 需任务方指令;工作树保持四源文件补丁 + 一常驻守卫新增原状(及一件 v10-v14 已注明归属的先前会话 wisdom json 变更)。
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
*报告依据:任务输入的第 15 轮材料(四区复核 24 confirmed / 2 rejected 明细及证据〔legacy 7 / authz 7 / runtime 7 / perimeter 3+2〕、五项修复的 where/攻击面/修复/攻击前后对比/守卫/verified_by、留档未修 13 条、门禁结果);本报告会话的五处修复落盘读核(现行行号锚点:tokens.py :409-422/:423-424、exec.py :104-180/:363-380/:948/:1148/:1566-1683、wm.py :110-209、orch.py :569/:606-621,均带 v8 N62/N69、v10 N82/N83/N87 病灶注释)、mcp_server.py:3468 调用形态读核、新守卫实跑(11/0)、空包守卫实跑(12/0)、全量回归两次实跑(195/195 通过、5 跳过,真实退出码 0)、npm run gate 失败第一手复现(真实退出码 1,R4 命中与材料逐字一致)、legacy 编号历轮报告 grep 核实(v6/v8/v9/v10/v13/v14)、留档缺陷在位性抽查读核(security.py/orch.py/serve_start.py/tokens.py derive)、git 工作树核对(numstat 与五修复一一对应 + 一件先前遗留 json)、报告脱敏机械扫描。*
|
|
212
|
+
|
|
213
|
+
*自查双清单:①材料覆盖——四区 26 条目全部入文(confirmed 24:legacy 7 / authz 7 / runtime 7 / perimeter 3;rejected 2 如实单列),跨区重复 4 组(冗余 4 条)合并说明单列,去重后 20 独立条目 = 18 独立缺陷(新 N123-N129 共 7:medium 3/low 4 + legacy 复测 11 项)+ 2 复测通过非缺陷,数目吻合;5 补丁逐项六要素齐全(where 双标/攻击面/修复/攻击前后对比/守卫/verified_by)且修复与遗留的拆分口径(N62 覆盖面已修+cap 面留档、N68+N69 分拆)与材料一致;18 − 5 = 13 开口与材料留档 13 条逐条对应无多无少;复测通过 2 项与证伪 2 项(含附带观察不入计数的声明)如实入第三节小节;legacy 项全部标注原轮次与复测轮数(编号经 v6/v8/v9/v10/v13 报告 grep 核实,无编号项锚定 v8 N63 证据面显式声明);门禁四项(python 通过/cargo 未运行/npm test 未运行/gate 失败)与跳过原因一一对应;材料与本会话不一致处无(全量 195/195 与 gate R4 双双第一手复现一致)。②纪律——全部结论引 path:line 或注明材料来源,六项第一手实跑命令与输出在第四节(两次全量回归真实退出码 0、守卫 11/0、空包守卫 12/0、gate 真实退出码 1、git numstat 与五落点读核、留档项抽查读核),未跑项(cargo/npm test/守卫红证/攻击复现/N89 真实 serve 回路/N92 unix 臂/提交后 gate)无一冒充为已跑,新发现续编编号(N123-N129)与 v6 N39/v8 N63 合并口径显式声明而非暗改,exec.py 行号漂移逐项双标以读核为准,全文无本机绝对路径、无真实 key/token/密钥字面量(机械扫描盘符/用户目录/凭据字面量形态零命中),本会话未 commit、未触碰真实令牌库/serve/数据根。*
|