架构风险审计待办 · v5.2.3 一致性加固(2026-09-26)
A-1 熔断计数器跨任务单调累积、永不复位
架构风险审计待办 · v5.2.3 一致性加固(2026-09-26)
来源:2026-09-26 高级架构风险审计官【纯只读审计】(3 个高层视图 + 定向取证,未改任何文件)
性质:审计结论 → 可执行待办(本文件只描述要做什么,本身不执行修改)
状态:✔ 已执行(2026-09-26,批次 A→B→C→D 全部落地;见
00 驾驶舱(投资MOC).md§九 · v5.2.3 条目)收官验收(2026-09-26 实测):
state_digest --guard --mode EXEC_SUGGESTIONS={"loop":4,"cost_est":0.15,"break":false,...,"cost_wired":true}rc=0|arch_check11/11 ✔(md=213 / 出链 750 / 死链 0 / 孤儿 0)|doc_sync_check --strictrc=0|测试逐类前台全绿 64 项 / 13 类|技能 v1.7.2(镜像 md51c27c84b)|备份/var/minis/shared/backup/DUCKERRY_pre_v523_20260926/(pre 全量 +post_B/ post_C/ post_D/+md5_after_*.txt)目标产出:系统版本 v5.2.3(熔断/监护/一致性加固)—— 已达成(
arch_check 11/11(本待办撰写时为 10/10,C 批新增第 11 项) +doc_sync_check --strictrc=0 + 测试全绿)仓库:
/var/minis/mounts/DUCKERRY_Warehouse审计时的机械基线:
arch_check10/10 ✔(md=212 / 出链 748 / 死链 0 / 孤儿 0 / 第 10 项 0 个点不到);doc_sync_check --strictrc=0(面板 85 行 / target 2026-09-25);state_digest --guard→{"loop":13,"cost_est":0.0,"no_progress":0,"break":false}rc=0;技能与仓库镜像 md5 一致5ca15c2c
〇、执行纪律(红线,违反即停)
- 备份先行:动手前全量备份到
/var/minis/shared/backup/DUCKERRY_pre_v523_20260926/(至少scripts/、state/、00 驾驶舱(投资MOC).md、框架/技能/、optimization/),并记md5_before.txt。 - 一次一批:按 批次 A → B → C → D 顺序,每批独立回报后再进下一批;P0(批次 A)必须最先。
- 不动历史:不改
复盘/历史原始记录/、不改归档区、不删任何*.bak*(沿用 F1 决策:保留不清理)、不改任何已有复盘正文。 - 不伪造数据:任何数值必须来自脚本输出;不确定的标
[待验证]。 - iSH 环境铁律:测试每次 shell_execute 只跑 1 类、前台、不重定向(并发/连续跑必被静默 kill);重脚本用
DK_DISABLE_MCAL=1。 - 熔断提示(本次审计重点):
state_digest --guard在批次 A 修好前已剩 2 步余量(loops=13/15)。若新对话开跑不久即rc=3且reason只有loops=...≥15(而本任务实际步骤 ≤5),属已知假熔断——先执行批次 A 修复,再继续,不得据此中止任务或写 BUDGET BREAK。 - 收尾必绿:每批结束时
python3 scripts/moc_index.py→python3 scripts/arch_check.py(期望 10/10)→python3 scripts/doc_sync_check.py --strict(期望 rc=0);任何一项 ✘ 先修再回报。
一、审计发现(证据已固化,无需重审)
P0(致命,1 条)
A-1 熔断计数器跨任务单调累积、永不复位
- 位置:
scripts/state_digest.py:222b["loops"] = max(int(b.get("loops", 0)), a.step);阈值MAX_LOOPS=15(--guard分支 L199-205) - 证据:
state/budget.json实测loops=13,history[].t跨 2026-09-25→09-26 多个会话、mode从DAILY_REVIEW变为EXEC_SUGGESTIONS均未重置;实测--guard输出{"loop":13,...,"break":false}rc=0 - 影响:下一次日常任务第 3 步即 rc=3 假熔断 → Agent 按 SOP 写
BUDGET BREAK并放弃当日发布,而任务本身完全正常。安全方向失败,但直接打断每日发布流程。
P1(严重,4 条)
B-1 max_budget 熔断是死代码
- 位置:
scripts/state_digest.py:200(唯一读取方);技能 YAMLmax_budget: 0.5 - 证据:全库
cost_est只有读取、无任何写入方;实测--guard输出"cost_est": 0.0→0.0 >= 0.5永假 - 影响:「两天 $200」事故的目标防线从未生效,当前唯一有效防线是被 A-1 破坏的
loops。
B-2 预测台账锁无超时、无逃生出口
- 位置:
scripts/predict_regime_conditional.py:180-189fcntl.flock(lockf, fcntl.LOCK_EX)+LOCK_UN - 证据:无
LOCK_NB、无 timeout、无 CLI 开关;历史事故已有归档数据/predictions/incident_20260916_concurrent_write.jsonl;数据/predictions/predictions.lock为 0 字节残留(mtime 09-21) - 影响:持有者卡死 → 预测写入无限阻塞(即「GLM 卡在 locklocklock」场景);主线其它环节均有逃生开关(
--no-bond/--no-aux/--no-wf/--no-recompute/DK_SKIP_*/DK_DISABLE_MCAL),唯独此处没有。
C-1 SOP 提示词与系统版本脱节 3 个版本
- 位置:
optimization/每日发布运行提示词_2026-09-23.md(自称 v5.0.1、仍标「新对话直接粘贴」) - 证据:文中 L209「arch_check 期望 9/9」、L218「完整测试 15 项」、§6.5「登记索引=强制步骤」;不含
state_digest --guard/--step、state/current.md剪枝、--no-aux、pattern_abc、doc_sync 11 项(版本时点:v5.2.3 时 doc_sync 为 11 项;v5.3.2 / 技能 v1.7.5 起为 13 项,新增第 12/13 项——本行所述为 2026-09-26 审计时的事实,不改写)。另optimization/继续任务提示词_2026-09-25_v5.2二级源与空头腿.md亦漂移(写「44 项」测试,实测 47) - 影响:粘贴旧 SOP = 绕过熔断与状态外置、按 v5.0 口径验收,与驾驶舱 v5.2.2 / 技能 v1.7.1 冲突。
C-2 state/current.md 零监护(污染直入决策)
- 位置:
state/current.md;arch_check.py/doc_sync_check.py/moc_index.py中 grepstate/零命中 - 证据:v1.7.0 SOP 要求「每 ≤3 步只读本文件」,但无任何自检解析它;
state_digest覆盖写无.bak,budget.json.history只存 hash,无法回看上一份摘要 - 影响:Agent 误写 target/L0/L1 或写盘中断留半截文件 → 无告警、污染直接进入后续判断;自愈只能人工再跑
--step。
P2(建议,5 条)
D-1 AUTO 区块自愈能力不对称
AUTO:DATA:手改会被下次fetch.py整段覆盖(L348-358),标记缺失会回退插到「## 一、核心框架」前 → 自愈 ✔AUTO:INDEX:fetch.py:575-580标记缺失时只记{"updated":false,"error":"缺少 AUTO:INDEX 标记"},moc_index.py亦只打印错误不重建标记 → 索引永久停更(「写入了但点不到」复发)- 另:两类告警均只 warning 不阻断(设计如此,保留)
D-2 状态摘要内部自相矛盾(跨 run 证据混入)
- 位置:
scripts/state_digest.py:105_tail(p, 400) - 证据:本次实测
state/current.md同时含doc_sync=True与⚠ 排版同步检查: 3 项待同步(见上)——后者来自数据/logs/fetch_c1_20260926.log:33的历史 run 遗留行,而数据/latest.json.doc_sync = {"ok": true, "issues": []} - 影响:Agent 会去重复修文档 → 浪费 loops(与 A-1 叠加加速假熔断)
D-3 一致性判据锚定已停用的文件命名族(假绿)
- 位置:
scripts/doc_sync_check.py:113-118glob("optimization/系统架构优化报告_*.md") - 证据:最新命中
系统架构优化报告_2026-09-23_v5.0.md,而 09-24/25/26 报告已改名为「路径防呆…/v5.2…/v5.2.1…/仓库文件修改建议…」→ §九 版本记录对最新报告从未被校验
D-4 文档—代码口径漂移
- 驾驶舱 L114、L605 写「债券腿子进程 240s 超时」,代码
scripts/fetch.py:37实为refresh_bond_leg(timeout=480) - 技能/提示词声明测试「44 项」,实测
tests/test_pipeline.py= 47 项 / 9 类(PipelineSafety / Paper / BondLeg / RegimeWf / DocSync / PathGuard / AuxSource / PatternAbc / PaperShortReduce)
D-5 冗余与维护成本
scripts/recompute3.py零引用孤儿(fetch.py:152哈希清单只含recompute2/recompute4);scripts/legacy/8 个 +audit_evidence/scripts/recompute*.py平行副本 + 内置scripts/pandas_market_calendars/- 保留建议:治理层 4 脚本职责不重叠(
arch_check死链/孤儿/地图 ↔doc_sync_check跨文件数值 ↔moc_index可达性 ↔state_digest --guard熔断),不合并
二、已验证无风险(不要去"修"这些,避免无谓消耗)
| 维度 | 结论 | 证据 |
|---|---|---|
| 死链/孤儿/导航可达性 | 无风险 | arch_check 10/10 ✔:md=212 出链 748 死链 0 孤儿 0;第 3 项 0 未引用;第 10 项 0 个点不到 |
| 跨文件数值一致性 | 无风险 | doc_sync_check --strict rc=0;latest.json.doc_sync={"ok":true,"issues":[]} |
| AUTO 区块内容层防越权 | 有效 | fetch.py:348-358 整段覆盖 + 标记缺失回退插入;doc_sync #2/#4 内容级比对 |
| 主线逃生出口 | 完备 | --no-bond/DK_SKIP_BOND、--no-aux/DK_SKIP_AUX、--no-wf/DK_SKIP_WF、--no-recompute、DK_DISABLE_MCAL;债券腿 timeout=480 且失败永不阻断发布 |
| 二级源越权替换权威源 | 无风险 | v5.2.1 报告 §一 回归断言:权威源有值绝不顶替;dkanalysis 用 upto[-1]==tkey;反推值必标 [待验证] |
| 债券腿「盘中伪收盘」 | 无风险 | update_bond_etf._is_session_final()(now_utc ≥ D 21:00Z)+ provisional_dropped 自愈剪除;当前 82 天,末行 09-25 TLT 79.32 / AGG 95.12 |
| 技能主副本 ↔ 仓库镜像 | 一致 | 双端 md5 5ca15c2cdc82df8a4281e308cdd7bc07(v1.7.1) |
三、批次任务
批次 A(P0,必须最先)— 熔断状态机复位
A-1 修复(scripts/state_digest.py)
budget.json增加分桶:"loops_by": {"<YYYY-MM-DD>|<MODE>": N};--step只写当前桶,loops顶层字段保留为「当前桶值」(兼容旧读法)。- 复位规则:
--step时若mode变化(b["mode"] != a.mode)或日期变化 → 当前桶从 0 起算、no_progress=0;不同 mode 不共享计数。 - 新增子命令
--reset [--mode M]:显式把当前桶清 0(供用户/Agent 在确认真假熔断后使用),打印改动后的budget.json关键字段。 --guard输出增加"bucket"字段(如"2026-09-26|EXEC_SUGGESTIONS"),便于人工判定。- 一次性数据修复:现有
loops=13迁移为loops=0+loops_by保留历史桶(迁移前cp state/budget.json state/budget.json.bak_pre_v523)。
A-1 验证
python3 scripts/state_digest.py --guard→loops归零、break=falserc=0;- 连续两次
--step 1 --mode DAILY_REVIEW→ 桶=1;再--step 1 --mode EXEC_SUGGESTIONS→ 新桶=1(互不影响); - 新增测试类
StateDigestTests(≥3 项:mode 变化复位 / 同日累计 /--reset生效),逐项前台跑。
批次 B(P1)— 成本熔断接线 + 台账锁逃生
B-1(scripts/state_digest.py)
- 二选一并明确记录:
- (a) 接线:
--step新增可选--cost <usd>,累加b["cost_est"] = round(b.get("cost_est",0.0)+inc, 4);--guard输出cost_est;SOP 中说明「每步由 Agent 估算并传--cost」。 - (b) 降级声明:技能 YAML 把
max_budget: 0.5标注为max_budget: 0.5 # unwired(未接线,仅记录,不参与熔断),并写入驾驶舱 §九 已知口径。 - 无论选哪条,不得留下"看起来有保护实际没有"的状态。
B-2(scripts/predict_regime_conditional.py)
flock(..., LOCK_EX | LOCK_NB)+ 最多 5 次 × 2s 重试;仍失败 → 打印LOCK_TIMEOUT: 台账被占用,已跳过本批追加,rc=0,并把latest.json.predictions = {"appended": 0, "skipped": "lock_timeout"}(不阻塞发布、不写坏数据)。- 新增
--no-lock(无锁直写,仅排障用);--lock-timeout <sec>可调。 - 清理
数据/predictions/predictions.lock(0 字节、mtime 09-21):移入数据/predictions/__obsolete__/,不要rm。 - 测试:
PaperShortReduceTests旁新增用例(锁占用时跳过且 rc=0),或复用既有类追加 1 项。
批次 C(P1)— 状态监护 + SOP 废止 + 口径对齐
C-1
optimization/每日发布运行提示词_2026-09-23.md头部加醒目标记:> ⚠️ 已废止(v5.0.1,2026-09-23):请改用 框架/技能/duckerry-daily-review SKILL.md v1.7.1,并把「9/9 → 10/10」「15 项 → 实测 47 项」就地更正(或整文件移入复盘/历史原始记录/并在驾驶舱留跳转)。- 技能 §1 顶部加硬规则:「任何手写提示词若未含
state_digest --guard与 10/10 自检口径,一律视为过期,以 SKILL.md 为准」。 继续任务提示词_2026-09-25_...md的「44 项」→「以grep -c "def test" tests/test_pipeline.py实测为准」。
C-2
arch_check.py新增 第 11 项「state/current.md可解析性」:首行# STATE · DUCKERRY;含target=/gate=/L0=/L1=;doc_sync=True时不得同时出现待同步;尾部含===完成行。仅告警(rc 语义不变),并同步更新驾驶舱「arch_check 10 项 → 11 项」口径。state_digest.py覆盖写前shutil.copy(CUR, CUR + ".bak");证据切片改为只取最后一条=== DUCKERRY … ===之后的段落(修 D-2)。- 技能 §0.3 补一句:「
state/current.md只允许state_digest.py写入;Agent 手工编辑视为违规,发现即重跑--step」。
批次 D(P2)— 一致性加固与整洁度
D-1 moc_index._block_text() 找不到 AUTO:INDEX 标记时自动重建标记对(插在 §7 标题后)并写回,日志 索引标记缺失→已重建;fetch.py:575-580 分支改为调用该自愈函数。 D-2 已在批次 C-2 处理(证据切片)。 D-3 doc_sync_check.py 第 8 项改为扫描 optimization/*.md 全部取文件名内最大日期做 §九 校验(或加「§九 最新条目日期 ≥ optimization 最新 mtime 日期 −1 天」判据)。 D-4 驾驶舱 L114/L605 240s → 480s;技能/提示词测试项数改为实测口径。 D-5 scripts/recompute3.py 移入 scripts/legacy/;驾驶舱 §〇 架构表补一行「audit_evidence/ 与 scripts/legacy/ 为历史证据,不作为当前判据」。
四、DoD(完成判定)
python3 scripts/state_digest.py --guard→loops为本任务步数(不是 13+),break=false;python3 scripts/arch_check.py→ 11/11 ✔(批次 C 后)或 10/10 ✔(批次 A/B 后);python3 scripts/doc_sync_check.py --strict→ rc=0;- 测试逐类前台跑全绿(PipelineSafety 10 / Paper 5 / BondLeg 5 / RegimeWf 3 / DocSync 4 / PathGuard 4 / AuxSource 6 / PatternAbc 4 / PaperShortReduce 6 + 新增类),并记录实际项数;
- 驾驶舱:§九 新增 v5.2.3 记录(本待办 4 批次)、§〇 架构表/系统概览按需更新、§〇·五
optimization/计数同步; - 技能
duckerry-daily-review升 1.7.2(或 1.8.0):记录熔断分桶复位、状态监护、锁逃生;同步仓库镜像并核对 md5 一致; - 备份点与 md5 全部记录在回报中。
五、每批回报模板(≤15 行)
批次 X:改动文件(含 md5_before → md5_after)
核心变更:(每条 ≤1 行)
自检:arch_check ?/? ; doc_sync rc=? ; state_digest --guard = {...}
测试:逐类结果(类名 → OK/项数)
备份:/var/minis/shared/backup/DUCKERRY_pre_v523_20260926/...
遗留/待确认:六、供新对话粘贴的最小提示词(执行阶段)
按 DUCKERRY_Warehouse 架构风险审计待办执行 v5.2.3 加固。
待办文件(必读,含全部审计证据):optimization/架构风险审计待办_v5.2.3_2026-09-26.md
仓库:/var/minis/mounts/DUCKERRY_Warehouse|技能口径:框架/技能/duckerry-daily-review SKILL.md v1.7.1
规则:只做待办里的事;按 批次 A→B→C→D 一次一批,每批完成即回报(改动文件+md5 / 自检 / 测试 / 备份路径),未获确认不跨批。
红线:改前全量备份到 /var/minis/shared/backup/DUCKERRY_pre_v523_20260926/;不改复盘/历史原始记录、不动归档、不删 *.bak*;不伪造数值。
熔断提示:开跑先执行 python3 scripts/state_digest.py --guard;若报 loops≥15 而本任务实际步骤 ≤5(已知假熔断),先做批次 A 再继续,禁止据此中止或写 BUDGET BREAK。
环境:iSH 上测试每次只跑 1 类、前台、不重定向;重脚本加 DK_DISABLE_MCAL=1。
收尾:moc_index → arch_check(11/11 或 10/10)→ doc_sync_check --strict(rc=0);技能升版并同步仓库镜像、核对 md5。
先只回报:批次 A 的改动计划 + 备份结果,等我确认后再动手。