[mimosa 1.0.4] git-gate 钩子 spawnSync maxBuffer 64MiB:大仓 deep 扫描 JSON ≈116MiB 必现 ENOBUFS 失败开放(黑盒根因取证 + 修复建议)
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 44/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- node.js
- 领域
- security
调研方向
The issue identifies the git-gate hook's spawnSync call for cli.js scan <dir> --deep --no-deps --json as the failure point; start by locating that hook and comparing it with the file-writing security-scan run path. Check how the hook consumes scan output and whether it needs the full call graph and evidence fields. Done means the reported large-repository scan no longer hits ENOBUFS and gate decisions still use the required findings and coverage.
由索引模型根据 Issue 内容生成。
描述
插件与版本
- 插件:mimosa(Code Security Protection)1.0.4,官方市场安装,macOS,node v24
- 官方市场 2026-10-12 最新即 1.0.4(CDN marketplace.json 核对),无修复版可升
- 场景:大型仓库(约 1,900 个被选中的真实业务源文件),
MIMOSA_GIT_GATE_FAILURE_MODE保持默认open - 1.0.3 时期已有同类症状报告(#17 现象二);本 issue 在 1.0.4 上黑盒定位到根因,并给出修复选项
现象
大仓里每一次 git commit(与提交内容无关),mimosa L3 git-gate(PreToolUse/Bash)都报:
Mimosa L3:git commit 前深度扫描为 INCONCLUSIVE(scanner_enobufs);不能视为安全。当前兼容模式失败开放。
稳定复现率 100%,提交一律被降级放行——大仓场景下这道门禁实际失效。
根因(黑盒取证,2026-10-12)
钩子链用 spawnSync 收集 cli.js scan <dir> --deep --no-deps --json 的全量 stdout,maxBuffer 上限 64 MiB(67,108,864 B)。以 NODE_OPTIONS --require 一次性探针包裹 child_process 实测钩子内部的 spawnSync 调用:
spawnSync git -C <worktree> diff --cached --name-only --diff-filter=ACMR maxBuffer=8388608 err=null
spawnSync git -C <worktree> log --format=%H --name-only --no-renames maxBuffer=131072 err=null
spawnSync node <cli.js> scan <worktree> --deep --no-deps --json maxBuffer=67108864 err=ENOBUFS stdoutLen=66318284
第三行即故障点:子进程 stdout 在 66,318,284 B 处被截断、子进程被杀,error.code === "ENOBUFS"——这是 Node 对「spawnSync 子进程输出超 maxBuffer」的标准错误码(独立对照:spawnSync 一个输出 2 MB 的子进程即可稳定复现同码,与磁盘/物理内存无关)。
同一命令把 stdout 重定向到文件,得全量输出 121,988,881 B ≈ 116.3 MiB——约为上限的 1.8 倍。体积构成(按文件内原始字节跨度切分,与总大小逐字节对账):
| 部分 | 原始字节 | 占比 |
|---|---|---|
callGraph.factsV1.edges(45,204 条调用边,来自 1,610 个 caller 文件) |
96,159,597 B | 78.8% |
businessLogicEvidence(主体为 .graph) |
25,813,821 B | 21.2% |
| 其余全部顶层字段(coverage / files / findings 等) | < 20,000 B | ~0% |
| 合计 | 121,988,881 B | 100% |
两个关键结论:
- 超限元凶是调用图导出 + 业务证据图(合计 99%+ 字节),finding 本身极小;且元凶是真实业务源码的正当产物,不是垃圾文件——仓库只会增长,任何大仓的 deep 扫描输出都必然超过 64 MiB。
- 只有走管道的钩子链路被卡死:同一仓库的密封扫描链路(
security-scan run,结果写文件)全程正常、seal 校验 ALL OK。钩子拿到的其实只是 findings/coverage 级别的判定输入,却被迫在管道里搬运全量调用图。
影响
- 大仓
git commit门禁 100% 降级为 fail-open(默认MIMOSA_GIT_GATE_FAILURE_MODE=open),安全闸失效且用户难以区分「无风险」与「工具故障」; - 若用户为求拦截而切
strict,则大仓变成 100% 无法提交——两个模式在大仓下都不可用。
建议(任一即可消除故障;③ 可与 ①/② 叠加)
- 加大 / 支持配置
maxBuffer(如默认 256 MiB 或允许环境变量覆盖)。注意输出体积随仓库规模线性增长,固定上限只是推迟复发,长期仍建议配合 ③。 - 扫描结果写临时文件而非管道:
spawnSync收集改为落临时文件、钩子按需读取。密封链路security-scan run已经是写文件做法,可直接参照。 - 给钩子链路提供裁剪版 JSON 输出(如
--json-summary或按调用方声明裁剪):callGraph.factsV1.edges+businessLogicEvidence占 99%+ 字节,而 git-gate 判定只需要 findings / coverage 汇总;全量调用图保留给密封链路即可。
English summary
mimosa 1.0.4's git-gate hook (PreToolUse/Bash) collects the full scan --deep --no-deps --json output through spawnSync with maxBuffer capped at 64 MiB. On a ~1,900-source-file repository the JSON output is 121,988,881 B (~116.3 MiB, ~1.8× the cap) — 78.8% is callGraph.factsV1.edges (45,204 edges), 21.2% businessLogicEvidence, while the findings themselves are <20 KB — so every git commit deterministically dies with ENOBUFS (Node's standard maxBuffer-exceeded error; verified with a one-shot child_process probe: maxBuffer=67108864 err=ENOBUFS stdoutLen=66318284) and the gate fails open under the default MIMOSA_GIT_GATE_FAILURE_MODE=open. The sealed scan path (security-scan run, which writes output to files) works fine on the same repository — only the pipe-bound hook path is affected. Suggested fixes (any one unblocks; #3 composes with the others): (1) raise / make maxBuffer configurable; (2) write scan output to a temp file like the sealed path already does; (3) offer a trimmed summary JSON for the hook path — call graph + evidence graph are 99%+ of the bytes and not needed for gate decisions. Related symptom report on 1.0.3: #17.
- 主要语言
- Python
- 星标
- 95
- 派生
- 57
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
zai-org/zcode-plugins 的其他 Issue
-
video-agent-kit (0.4.3): hooks invoke python3, which doesn't exist on Windows — SessionStart/UserPromptSubmit/Stop hooks fail on every trigger可能已有人在做 @dvd233 于 20 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 85/100
zai-org/zcode-plugins#14 ·
维护者通常 1 天内回复
-
难度 4/5 3-5 天 新手友好度 35/100
zai-org/zcode-plugins#88 ·
维护者通常 1 天内回复
-
难度 5/5 一周以上 新手友好度 25/100
zai-org/zcode-plugins#86 ·
维护者通常 1 天内回复
-
难度 3/5 1-2 天 新手友好度 45/100
zai-org/zcode-plugins#80 ·
维护者通常 1 天内回复
-
难度 4/5 3-5 天 新手友好度 43/100
zai-org/zcode-plugins#76 · 1 条评论 ·
维护者通常 1 天内回复
查看 zai-org/zcode-plugins 的全部 Issue
相似的 Issue
-
area: agents area: docs good first issue
难度 2/5 1-3 小时 新手友好度 88/100
openapi/gknowledge#23 ·
-
get() for StrEnum可能已有人在做 @FeJo5952 今天认领。 未关闭good first issue
难度 2/5 1-3 小时 新手友好度 72/100
collective/icalendar#1921 · 1 条评论 ·
维护者通常 1 天内回复
-
Improvement Python Spans
难度 2/5 1-3 小时 新手友好度 68/100
getsentry/sentry-python#7994 · 1 条评论 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 82/100
alphagov/notifications-api#5004 ·
维护者通常 2 天内回复
-
难度 2/5 1-3 小时 新手友好度 68/100
equinor/radix-flux#3922 ·
维护者通常 1 天内回复