| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
docs(m5): 出 docs/stability-report.md —— 两跑合并,各自的限制写明 主跑(测试机,跑的就是要发布的 v0.1.1)3 小时 03 分 / 38 轮,被外部 docker 重启打断(今天第 4 次);旁证跑(香港)4.00 小时 / 48 轮 / 48 成功,但 20:06 起 hca-web 镜像被另一方重建过。两跑都不完美,合起来才够用,结论里凡是只有一跑 支持的都写明出处。 顺带修了生成器一个真 bug:§2 循环里的展示字符串变量与目录 Path 同名(都叫 src), 把它覆盖掉了 —— 报告最后一行打出「原始记录: 全程(未重起)/rounds.jsonl」, 照着去找只会找到一个不存在的目录。改名 + 补一条回归测试(219 条)。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> | 29 天前 | |
docs(m5): 出 docs/stability-report.md —— 两跑合并,各自的限制写明 主跑(测试机,跑的就是要发布的 v0.1.1)3 小时 03 分 / 38 轮,被外部 docker 重启打断(今天第 4 次);旁证跑(香港)4.00 小时 / 48 轮 / 48 成功,但 20:06 起 hca-web 镜像被另一方重建过。两跑都不完美,合起来才够用,结论里凡是只有一跑 支持的都写明出处。 顺带修了生成器一个真 bug:§2 循环里的展示字符串变量与目录 Path 同名(都叫 src), 把它覆盖掉了 —— 报告最后一行打出「原始记录: 全程(未重起)/rounds.jsonl」, 照着去找只会找到一个不存在的目录。改名 + 补一条回归测试(219 条)。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> | 29 天前 | |
fix(m5): e2e 第 5 处 —— R3 的「全中文」判据压根没有断言 m4-regression.mjs R3 的第 ② 条只把 enBad.length 写进返回串、没有 throw, 多少段英文都算「过」;而且判的是整页 innerText,混着用户那句、工具卡里 akshare 的英文列名、界面英文标签,既会误伤也会漏判。 改成从后端取这一轮 role=assistant 的 text part(刷新时前端调的同一个端点, BFF 这一跳会用 cachedFix 回放出口守卫的修正),只判助手正文,并且真的 throw。 买卖指令那条也一并改成只判助手正文。 判据对四个样本验过(真实中文回答过、中文夹 PE/TTM/ROE 过、整段英文拒、 中文里夹英文散文拒),0 条不符合预期。 README 的规矩补一句:断言不光要认被测系统产出的东西,还得真的会失败; 自查办法是先拿人造坏样本跑一遍看它拒不拒。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> | 29 天前 | |
fix(m5): 拿 37 条真实 bash 重放白名单 —— 两个误伤 + 一个自己写错的数 决定把 3.7b 那张「换白名单的代价」表重放验证,而不是读着记录估。 三件事: R-18(红线 1):那张表自己是错的。原写「29 次是 python3 -c 调 akshare」, 逐条读命令原文后,调 akshare 的只有 4 次;29 其实是旧 guard 判 proceed 的条数。 真实分布:该拦 12 条,正当 25 条(其中 20 条是 python3 -c 读文件/解析 JSON/算数, 白名单本来就放行 -c 内联)。结论仍成立,但支撑它的证据是假的,所以必须改。 报告、发布说明、guard.py 两处注释全部更正,新增 §3.7e 记更正过程。 R-16(误伤,M2 就写进去的):INLINE_WRITE_RE 的 [waxr]\+? 把只读的 'r' 也算成写, 拦掉了 python3 -c "with open('x','r') as f: ..." —— 那正是白名单刻意要放行的用法。 改成只有 w/a/x(可带 b/t/+)与 r 带 + 才算写,16 个模式逐个验过。 R-17(误伤):2>/dev/null 被当成写盘。只放行目标恰好是 /dev/null 的, 且该 token 不再当命令参数(否则被「参数指向工作区外」接着拦,第一版就栽在这)。 两个误伤修完重放同一批 25 条:deny 8 / proceed 17,与「按意图该不该拦」不符 0 条。 tools/tests 206 → 208 passed;hook 用例 25/25;前面几轮的 probe 全部复跑 0 条不符。 另记 R-19:等测试机安静的脚本用 pgrep -f 撞上自己上一轮留下的等待壳, 恒返回 4、永远等不到安静(真实 cargo 进程是 0),改成 pgrep -x。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> | 29 天前 | |
fix(m5): bash 的首词判据从 denylist 改成 allowlist —— 一轮又找出 12 条绕过 修完「解释器跑外部脚本」之后照同一条思路继续试,又有 7 条放行: find -exec python3 {} ; awk 'BEGIN{system(…)}' . reports/x.sh source reports/x.sh eval "$(cat reports/x.sh)" perl -e 'system(…)' node reports/x.js ./reports/x.py 这 12 条彼此毫无关系。问题不在「这次漏了几条」,而在 **denylist 永远只覆盖 已经想到的那些**;而 write_file 本来就允许往 reports/ 与 theses/ 写, 漏网一条就能接成「先写脚本再执行」的完整绕过。 所以首词判据改成白名单 BASH_ALLOW:只收不会写文件、不会联网、不会执行外部 代码的东西。刻意不收 awk / perl / node / ruby / php / Rscript(都能 system() 出去)、sed(GNU 的 e 标志能执行命令、w 能写文件)、tar / zip(能写)、 eval / source / .、tee。另外单独拦 find 的 -exec/-execdir/-delete 一族。 **换白名单的代价实测很低**:翻部署中容器的 guard.jsonl(真实会话),模型 发出的 37 次 bash 里 29 次是 python3 -c 调 akshare(本来就该拦), 2 次是直接跑 /opt/hca 下的 MCP 源码(该拦),1 次 curl(该拦), 正当用途只有 3 次 echo 与 2 次 env —— 两个都在白名单里。 复验 23 条该拦 / 18 条该放,全部符合预期;既有 33 条 guard 单测与 25 条 hook 用例一条没红。补 2 条单测,tools/tests 199 → 201 条。 证据:docs/evidence/M5/guard-解释器绕过-前后对照.txt Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> | 29 天前 | |
fix(m5): e2e 第 4 处「断言认了用户输入」—— Kronos 那一步 m3-web.mjs 第 07 步输入「预测 600519 未来 5 天走势」,断言却是 /600519|贵州茅台/ —— 600519 就在用户刚输进去的那句话里,报错页、占位页、 「600519 预测失败」全都照样算过。规矩就写在同一个目录的 README 里,这一处漏了。 改成认报告特有的结构(综合评分/因子明细/每日预测/置信度/预测涨跌幅/Kronos ≥4 个) 加一张真有数据的每日预测表(≥3 行「日期+价格」)。 用测试机数据库里那份**真报告**(600519,26 775 字节,M3/M4 真跑出来的)验证: 真报告 6/6 标志 + 6 行过;三种假冒(错误页带 600519、只有用户原话、有标志无数据) 全部判拒,其中前两种旧断言会判「过」。0 条不符合预期。 证据:docs/evidence/M5/e2e-kronos断言-前后对照.txt Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> | 29 天前 | |
docs(m5): §4 补 hook 在部署中的 v0.1.1 上的真实验证(hooks test 9/9、注册 8 条、容器内用例 25/25) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> | 29 天前 | |
docs(m5): 报告补 §3.11 —— v0.1.1 部署、Kronos 接线、全套回归、全新安装验证 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> | 29 天前 | |
docs(m5): 报告 §3.14 + 待办池 P0-10 + 运维文档两条排查项(都来自实测) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> | 29 天前 | |
fix(m5): P0-10 的兜底把「一轮的失效」修成了「持续失效」—— 浸泡实测打出来的 4 小时浸泡第 16 轮真实复现 P0-10:8 次工具调用全是 read_file/bash,一个 mcp__* 都没有,而发消息前 /mcp/status 是 9/9。检测正确、重挂也发出去了,然后: · 重挂后 9 个 stdio server 同时重新 initialize,2 核机器实测要 2~4 分钟; · forceMcpReload 只等 60 秒,而且只在状态是 connecting 时等 —— 超时后它们变成 error,循环立刻退出,函数打一行「仍有未连上的」就返回; · 没有任何节流:我(当运维)照着「重挂能修」又手动发了三次,每次都把 initialize 的计时清零,实测从 1/9 掉到 0/9; · 最后什么都不做、干等 3 分半,自己回到 9/9。 也就是说这个本来来救场的函数,把一轮的间歇失效变成了持续失效。 证据:docs/evidence/M5/p0-10-浸泡里真实复现-兜底反而变成持续失效.txt 三道约束,缺一不可:单飞(同一时刻只许一次在跑)、冷却(默认 5 分钟内不再发)、 等够(默认 240 秒,且 error 也算「还在安定中」——进程其实活着,只是 daemon 先判了超时)。 ensureMcp 里「连发 3 次、每次只等 60 秒」是同一个坑,一并改成「最多两轮、每轮等够」。 判据抽成 mcpReloadAllowed() 并配 4 条单测,其中一条直接用实测那三次的间隔 (48 秒)钉住「这一步必须被拦住」。适配层单测 39 → 43。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> | 29 天前 | |
fix(m5): kronos / truesource 这两个 MCP 漏在大小闸之外,procurement 真实返回 18KB 已超阈值 v0.1.1 原先只给 akshare + 6 个 hunter 系 MCP 上了大小闸。kronos / truesource 跑在 /opt/hca/venv(pip 装的包),import 不到 /opt/hca/mcp/hca_size_guard.py。 **不是理论风险,是现在就在发生**:容器里真实调用 truesource_procurement(days=30) 返回 **18 084 字节**,超过内核 16 384 阈值 → 正被砍成头尾各 4 KB 的断裂 JSON。条数只有 15 条、没超 MAX_ITEMS=40, 所以 _cap 原样放行 —— 与 akshare 宽表同一类「只限条数压不住字节」。 修法不复制代码:.mcp.json 给这两个条目加 PYTHONPATH=/opt/hca/mcp, 用镜像里已有的同一份闸;truesource 的 _cap 三个出口与 kronos_predict 出口过 fit()。 修复后同一接口真实复调:**14 099 字节**,预算与内核阈值都过, 并带明确裁剪说明(15 条 signals 给了 11 条,写明「不是不存在」)。 证据:docs/evidence/M5/p0-11-truesource-kronos-大小闸.txt Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> | 29 天前 | |
feat(m5): P0-11 前后对照探针 + 修复前的容器实测记录 零 token 的探针:拿一张 50 行 x 84 列的合成宽表(仿财务指标接口)量 akshare-mcp 的返回字节数,判据是内核写死的 16384。 修复前在部署中的 v0.1.0 容器里实测:**206 832 字节**(阈值的 12.6 倍), 而且 truncated 是 None —— 因为 50 行没超过 AKSHARE_MAX_ROWS=50, server 自己认为它给全了。只限行数对宽表完全无效,这正是 P0-11 的要害。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> | 29 天前 | |
docs(m5): §3.4 补出口守卫的 api 端点四条实测(含反误伤) 「BFF 只做搬运」要成立,得先证明搬到的端点真在、真判得对。 四条对着部署中的 api 实跑,存证 docs/evidence/M5/。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> | 29 天前 | |
fix(m5): 浸泡报告的「容器重启」是假全绿 —— RestartCount 数不到 docker 自己重起 浸泡第 21 轮被打断,查出是共用这台测试机的另一条链路重起了 docker 服务 (ActiveEnterTimestamp=08:08:32 UTC,两条链路的容器全部一起重起)。 顺带暴露报告生成器一个真缺陷:六个容器的 StartedAt 全部跳到 08:08:14Z, 而 RestartCount 全是 0(它只数重启策略触发的次数),restart_line() 只比 RestartCount —— 报告本来会打出「**0 次**(RestartCount 首尾一致)」, 而浸泡期间整个栈其实被重起过一次。 改成两个都比,StartedAt 变了同样算重起过,并点明多半是 docker 守护进程自己重起。 三个用例验过。证据:docs/evidence/M5/浸泡-docker守护进程重启事件.txt Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> | 29 天前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 29 天前 | ||
| 29 天前 | ||
| 29 天前 | ||
| 29 天前 | ||
| 29 天前 | ||
| 29 天前 | ||
| 29 天前 | ||
| 29 天前 | ||
| 29 天前 | ||
| 29 天前 | ||
| 29 天前 | ||
| 29 天前 | ||
| 29 天前 | ||
| 29 天前 |