Repository navigation
[RFC] 核心进一步中立化:解除 scanner 引导,评估多方向发行版的最小工具集 #148
Description
背景
cyber-harness 已经确立"一切皆扩展"的组装方式:机制(core/*、pkg/harness)与内容(scanner、skills、prompt)分离,cmd/harness/testdata/neutralhost + gomoku 验收场景已经证明 Agent/Session/IOA 运行时可以在不加载任何安全能力的情况下工作。
下一步计划以独立二进制的形式提供新方向发行版:cyber-audit(代码审计)、cyber-re(逆向)、cyber-ti(威胁情报)。每个方向 = 一个 cmd/ 组合根 + 一个 pkg/exts/<domain> 领域扩展 + 领域 skill bundle。
评估发现:机制层(extension 契约、工具双协议、资源系统)已经中立,但共享层仍残留若干 scanner/cyber 内容。这些内容会被每一个新二进制无条件继承,形成"scanner 引导"——新方向要么默默带上 cyber 提示词与技能字节,要么靠 SkillExclude 这类绕过手段。本 issue 目标是把这些内容从共享层搬回领域扩展(content inversion),并同步评估三个方向的最小工具集。
一、核心中立化任务(按优先级)
| # | 位置 | 现状问题 | 方案 | 优先级 |
|---|---|---|---|---|
| 1 | pkg/exts/prompt/defaults.go |
基础 prompt 扩展无条件注入 cyber 身份("Cyber Harness for cybersecurity benchmarks")、授权段落、scan 流水线伪命令文档 | 默认贡献整体迁入 pkg/exts/scanner(或独立 cyberprompt 扩展),由 aiscan 组合根安装;promptext.New() 变为中立(或提供 WithDefaults(false)) |
🔴 最高 |
| 2 | agent/prompt |
Target 枚举 scanner 化(ScannerSystem),AgentContext.ScannerName/ScannerDocs |
Target 开放化(string 或领域 target),ScannerName/Docs 泛化为 DomainName/Docs,由贡献方携带 | 🟡 |
| 3 | agent/skills/embed.go |
//go:embed all:* 把 cyber/ + scan/ 技能树编译进每个二进制;SkillExclude 只是运行时不加载,字节仍随二进制分发 |
技能树移到独立 embed 包,作为 skills.Bundle 由 scanner 扩展贡献(Bundle 机制已存在,ioa 已这么用) |
🟡 |
| 4 | core/types(生成 proto) |
DistributeConfig{llm, cyberhub, recon, scan, ...}:cyber 配置 schema 在 core;仅当新发行版复用 pkg/config 时受影响 |
长期:cyber section 随 scanner 扩展迁出;短期:新发行版用自己的 Declare section + extensions Values 逃生舱,不动 core |
🟡 可延后 |
| 5 | 零散泄漏 | aop/tool/artifact.go artifact kinds(service/web/weakpass/vuln);web.Config.ScanTimeout;terminal WithScannerProxy 命名;okf 扩展指向 ScannerSystem target |
artifact kinds 保持字符串开放(领域自定义,如 finding/sample);命名类随缘清理 |
🟢 |
原则:不为中立化引入新机制(不加依赖图/插件发现/注册中心),只做内容搬迁。core/extension 契约(Load(*Scope) + Define/Add/Provide/Use)保持不变。
二、工具集评估:哪些是必要的
选择纪律
- 技能优先:能用 OKF skill 文档(方法论 + AI 自主判断)解决的,不建工具;
- 档位递增:优先 C 档(arsenal 安装外部二进制,零 Go 代码) → 必要时 B 档(策展伪命令
tool.Command+toolargs.Base:策展 flag、流式输出、类型化 artifact、挂 skill 文档) → 谨慎 A 档(Go 原生tool.Tool:高频、结构化 I/O); - 与架构搭配:工具的可见性/准入由扩展成员资格 + admission hooks(fail-closed)+ build tags 控制,不引入逐工具权限元数据;
- 许可证与成本:arsenal 是运行期下载外部二进制,入选工具需 license 允许此分发方式,且优先免费/开源(商用 API 类如 Tavily 走用户自带 key)。
三个方向的最小工具集
cyber-audit |
cyber-re |
cyber-ti |
|
|---|---|---|---|
| C 档(arsenal) | semgrep、ast-grep、codeql、osv-scanner、gitleaks | radare2/rizin、yara、capa、die、binwalk、floss、upx | yara、MISP CLI |
| B 档(策展伪命令) | 无(证据充分后再考虑 audit 编排命令,类比 tools/scan) |
r2(r2pipe JSON → 结构化函数/反编译/导入表,LLM 消化 JSON 远好于自由文本)——三方向唯一预留的 Go 开发点 |
ti(VT/AbuseIPDB/OTX/MISP 的 API key 管理、分页、响应归一化——相对纯 curl 的不可替代价值) |
| 复用已有 | files、terminal/bash、search、subagent(分模块并行)、okf | tmux(r2/ghidra 交互会话的天然载体)、files、bash | search(web_search/fetch)、curl、passive 扩展(fofa/hunter 测绘,本质就是 TI) |
| Skills(OKF) | 审计方法论、semgrep 规则编写、taint 流程、误报 triage、findings/<result_id>.md 报告规约 |
triage→静态→动态方法论、样本处理规约(隔离、哈希登记) | 情报循环、IOC 类型与置信度、源可靠性分级、报告模板 |
关键判断:cyber-audit 首个版本可以做到零领域 Go 代码(arsenal + skills + prompt 贡献),它是验证"最小工具组"假设的最佳第一个发行版。
需要同步解决的架构搭配问题
- build tag 粒度:现在
full是整块(browser + passive + headless 一把抓)。cyber-ti想要 passive 但不想要 browser——需要把full拆成browser/passive/record独立 tag(沿用现有xxx.go/xxx_absent.go成对模式),editions.env按二进制组合。 - 运行期产物共享:三个二进制共用
<DataDir>/arsenal/bin(工具装一次,yara 等跨方向复用);~/.cyber/cyber.yamlLLM 配置天然共享,领域配置各自Declare独立 section。
三、验收标准
-
promptext.New()(中立形态)不注入任何 cyber/scanner 文本;aiscan 行为不变(由 scanner 扩展贡献同样的内容) - 新方向二进制不包含
cyber/、scan/skill 字节(embed 已迁出 base 模块) -
cyber-audit以零领域 Go 代码构建并跑通一个审计 demo(arsenal 装 semgrep → skill 引导 → 产出 findings 报告) -
cmd/harness为每个新二进制配一个非安全验收场景(对标 gomoku) -
fulltag 拆分后TestBuildManifestIsConsistent通过
阶段规划
- Phase 0(本 issue 主体):prompt 默认贡献倒置 + skills embed 迁出 + target 开放化 → 此后任何方向发行版是纯叠加
- Phase 1:
cyber-audit零代码二进制,端到端验证 arsenal + skills 模式 - Phase 2:由实际运行证据驱动补 B 档(
r2r2pipe、ti) - Phase 3:配置 schema 解耦、artifact kinds 领域化等沉淀
附:评估依据——core/extension 契约(core/extension/extension.go:20-22)、基座组合(pkg/harness/base.go:43-81)、中立宿主样板(cmd/harness/testdata/neutralhost/main.go)、cyber prompt 默认值(pkg/exts/prompt/defaults.go)、arsenal 机制(tools/arsenal/arsenal_tool.go、cmd/aiscan/extensions.go 的 PATH 注入)。
Activity
M09Ic commentedon Sep 23, 2026
Phase 1 完成回顾 + 剩余非中立机制清单
Phase 1(核心机制中立化,内容倒置)已在分支
refactor/neutral-core完成(612bf891→b45f2d96,6 commits):cyber 提示词内容迁回pkg/exts/scanner(golden 逐字节对齐)、agent/skills内嵌技能清空(scanner bundle +cyber://skills/runtime/中立文档架)、session 去 scanner 化(CommandName/SkipBaseSkills)、okf/terminal 去 scanner 命名。验证:STANDARD/FULL 构建、全量测试、cmd/agent二进制无 scanner 内容、neutralhost 依赖图零 scanner 包。在此之上对全仓库做了一轮"非中立机制"扫描,剩余项按层汇总如下(均已核实文件:行号)。
A. 配置管线(
pkg/config)— 机制性耦合最重Option根结构内嵌ScannerOptions(options.go:23)、ReconOptions(options.go:29)、ScanConfig(options.go:32):cyberhub/fofa/hunter/verify 与 LLM/Node 等中立字段混在同一结构,中立发行版被迫携带这些配置段与 CLI flag。defaults.go:9-15、option_defaults.go:15-16、env.go:60-61,148-189(CYBER_CYBERHUB_*、FOFA_KEY)、inspect.go:17-18、loader.go:49,68-76。projection.go:31-40DistributeFromOption无条件填充 cyberhub/recon/scan 段;env.go:350ResolveExecutionConfig自述只解析 scanner 配置。options.go:229无 prompt 时的兜底任务硬编码"Scan the provided targets using scan and summarize results."——中立发行版会得到指向不存在工具的默认任务。options.go:94AgentOptions.Inputs(-i)是 scanner 目标语法。Sections扩展注册机制已存在(sections.go),scanner 段整体下沉为扩展注册段(含 Environment/Normalize 钩子),core 只留中立字段。B. 协议 schema(
proto/→core/types、pkg/rpc)proto/types/scan.proto整个文件(ScanStatus/Scan/ScanOptions{verify,sniper,deep}/SubmitScan/SessionBinding{scan_id}/SessionScanEvent/ScanProtocolMessage)编译进 core types,所有发行版的 wire 协议携带 scan 域。proto/types/config.proto:DistributeConfig内嵌 cyberhub/recon/scan/search 段,ConfigView同样。proto/types/chat.proto:25SessionRecord.scan_ids——每个发行版的会话记录都带 scanner ID 列表。cyber.*(全部 proto package 名)进入 Any type URL 并持久化进会话 JSONL:需要决策"cyber 即 harness 中立命名空间"还是一次性迁移到harness.*(wire-breaking)。extensionsmap;scan_ids泛化为 binding/workload ids。C. Web 管理面(
pkg/web)service/scan.go整文件:scan.go:218把 scan 拼成 bash CLI("scan " + ...)下发节点,scanArgsForScan硬编码--mode/--verify/--sniper/--deep,ValidateTarget/ValidateMode是 scanner 目标语义——管理面直接知道 scanner 产品的 CLI 语法,最深的执行面耦合。service.go:30ServiceConfig.ScanTimeout、scanNodeIDs;store_models.goscans/session_scans表内建;events.go:203/agents_mux.go:239,274/commands.go:243/application_dispatch.go:246的 scan 特判。connect.go:89-90已有api.Scans != nil才挂路由的判定——构造端目前恒为非 nil,把 scan 服务改为可选模块即可激活。D. 构建标签(
editions.env)— 解锁 cyber-ti 的关键fulltag 捆死 browser(playwright+headless) + passive + katana + uncover + web UI + recon_options。cyber-ti 需要 passive-only 形态,目前做不到。sqlite无源码约束(只选依赖行为),应与 full 解绑。browser/recon(passive+uncover)/crawl(katana)/webui;full退化为发行版组合标签。TestBuildManifestIsConsistent是现成回归网。E. 工具包级耦合
tools/search包内 cyberhub(scanner 指纹库)与 tavily/fetch(中立)同包:cyberhub.go:8-11import fingers/neutron/association,Go 以包为编译单位,pkg/exts/search一旦引入就全部链入。注册层已解耦,包层未解耦。→ cyberhub 移子包。tools/passive/register.go:14依赖engine.Set.Uncover(full-only),passive 借 scanner 引擎集初始化——TI 版要 passive 就得拉整个 scanner 引擎集。→ uncover 引擎拆成可独立 Init 的子组件。tools/katana/katana.go:21无 tag 依赖tools/headless,含 katana 的构建必然链入浏览器栈。→ 显式 tag + headless 爬取可选化。pkg/exts/scanner/declaration.go:27-33夹带 recon(fofa/hunter) 连接检查声明。→ 随 recon 扩展迁出。F. 运行时默认值与命名残留(轻量)
agent/types.go:229AgentName默认"cyber",打在每条 AOP 事件上;agent/session/runtime.go:190NodeName 兜底"cyber";session.go:544agentName 兜底"cyber"。→ 删除本层兜底,composition root 必传。agent/skills/embed.go:21,85,100项目技能目录硬编码.cyber/skills/。→ 目录名作为参数由 composition root 传入。agent/subagent/sessionexec/tool.go:41内建 subagent 工具的模型可见 Description 引用ioa send(只有装了 ioa 的发行版才有)。→ 描述由注册方注入。agent/session/commands.go:90内建/status描述含"扫描器"且AdvertiseRemote: true对外广播。→ 中立措辞。agent/loop.go:31、session/protocol.go:38错误串、agent/agent_test.go:340+的 scanner 集成测试宜迁往 scanner 扩展包等。已确认中立(无需改动)
pkg/harness(BaseExtensions/BaseConfig 零 scanner 假设)、pkg/node、pkg/profile、core/extension、core/tool(注册表已有防 scanner flag 注入测试)、core/egress、core/events/eventbus、core/hooks、agent/prompt、agent/compact、agent/evaluator、agent/aop_emit。建议的阶段映射
A/B/C 中 web 的两个挂点(
connect.go:89条件挂载、recon_optionsbuild-tag 双文件模式)说明解耦机制已存在,Phase 3 主要是"把硬编码改为注册"。M09Ic commentedon Oct 24, 2026
进度核实(2026-10-24,master 0d812fe):
ScannerSystem/ScannerDocs也已移除。agent/skills已无go:embed,技能树改由 bundle 由扩展贡献。cyber-audit已存在:cmd/audit为独立模块,含 arsenal bundle、skills 与构建说明。editions.env仍是整块FULL_CAPS_TAGS=full sqlite,full尚未拆成browser/passive/record;对应的TestBuildManifestIsConsistent验收未做。本 issue 保持 open,剩余工作主要是 tag 粒度拆分与发行版组合验证。
M09Ic commentedon Oct 25, 2026
已完成当前实现的真实模型验收,按更新后的范围关闭此 issue。
实现由 PR #188 合入 master,提交
c289e3c820d196b92e3144b172ead2abee150b20。CI 的 17 项检查全部通过,包含中立依赖边界、扫描/JEV、浏览器 SPA 与录制回放、Web E2E、Windows 变体、跨平台构建及发行包验证:https://github.com/chainreactors/cyber-harness/actions/runs/40205246139。2026-10-26 使用真实 OpenAI 兼容服务和
deepseek-flash,启用CYBER_AUDIT_LIVE=1后,在独立 audit 模块执行:TestLiveModelAudit实际通过(465.88 秒,未跳过)。报告状态为 completed,无运行错误,coverage.reviewed 为 true,包含 6 个证据文件;随后独立运行cyber-audit validate <report-directory>,得到Audit report valid。handlers.py:6命令注入handlers.py:19-20跨租户对象访问handlers.py:11-13白名单及参数化调用handlers.py:26-28租户校验关闭口径同步更新为当前已实现的架构:browser/passive/Katana 由 cmd 的显式 imports 组装,保留 aiscan 的 full 产品组合,不新增 browser/passive/crawl 能力 tags;原生 record/CGO/平台及资源内嵌约束继续保留。audit 采用现有 rg、ast-grep、osv-scanner、proton/OKF 和有独立语义的报告/证据校验,不再将原文的 semgrep demo 或“零领域 Go 代码”作为硬性验收。re/ti 新入口按实际需求后续推进。
本次没有提交临时评估/验收 Markdown,也未将模型凭证写入仓库、验收产物或 issue。原有真实模型验收缺口现已补齐。