Commit Graph
148 Commits
Author SHA1 Message Date
Autumn-27 96ff07579e fix(digest): 给 per-task planner 接上 Compactor,修复冷节点压缩从不触发
引擎经权威解析器实际驱动的是 agentsForTask 构建的 per-task planner,但
cold-digest 落地时只在 buildPlannerWorker(全局 fallback pair)接了
SetCompactor,而该 pair 被解析器旁路、从不跑规划轮。结果 per-task planner
的 compactor 恒为 nil,OnPlannerRound 每轮直接 no-op —— round_no 不递增、
cold_since_round 从不盖章、digest 从不生成,与阈值无关。

在 agentsForTask 补上 SetCompactor,provider 用 plannerRuntime、model 用
task-router,与该 planner 实际运行所用模型一致(§4)。
2026-09-17 08:52:52 -04:00
Autumn-27 c03e008d7b feat(web): 任务详情页新增探索链路播报板
按创建时间分页平铺展示探索节点,作为探索链路图的时间轴视图,
复用同一份 exploration_nodes 数据,不影响链路图。

- 后端 NodesPage/NodesByIDs/EdgesTouching:分页下推 SQL,
  支持 kind/state 过滤、payload/origin 搜索、正倒序,
  并补出当页节点的相邻边与对端节点
- 新增 GET /api/exploration/nodes(仅本任务节点,不含继承)
- 播报板:时间轴分行、按天分组、类型快筛、搜索防抖、
  自动刷新、直播位未读提示、展开看上下游与 payload
- 补 mock,NEXT_PUBLIC_MOCK=1 下可无后端预览
2026-09-17 08:42:49 -04:00
Autumn-27 13ce2ea6e3 Merge PR #139: 支持按状态和判定来源筛选审批记录
合并 codex/approval-record-filters,解决与 #133 在
web/src/components/approval-records.tsx 的冲突:

- 导入同时保留 InterceptApprovalFilter 与 InterceptPending。
- load() 采用 #133 的独立待审批队列(Promise.allSettled 拉取
  /intercept/pending),并把 #139 的 filter 参数透传给历史分页调用;
  筛选只作用于历史记录,待处理队列不受 filter 影响,保证跨页/被筛
  记录仍可审批。
- decide() 保留 #133 的乐观更新(移除 pendingRows 对应项)叠加 #139
  决策后重新拉取以对齐筛选后的计数与行。

验证:前端 tsc 通过、Biome 仅剩预存告警;go build/vet 通过;
db TestInterceptApprovalFilters(8 子用例)与 server
TestInterceptFilterHTTP 在本地 dev 库均通过。

Closes #139
2026-09-16 11:16:26 -04:00
RuoJi6 f6b5c11352 feat(chat): 支持多类型记录 @ 引用及滚动分页 (#135) 2026-09-16 22:36:07 +08:00
ji ruo a91c0a7223 feat: filter approval records by status and decision source 2026-09-16 17:24:15 +08:00
Autumn-27 95bcd4ef9c Merge branch 'feat/noa-experimental':noa 实验性上下文压缩 2026-09-15 12:09:24 -04:00
RuoJi6 04d25eb133 精简动作审查输入并支持审批来源定位 (#125)
* fix: 精简审查背景并区分人工消息与调度输入

* fix: 模型审查仅提交当前调用与选定背景

* feat: 审批来源定位原会话并移除 Worker 审查背景
2026-09-15 23:51:37 +08:00
Autumn-27 865d52267d feat(settings): 增加实验功能开关,可开启 noa 上下文压缩
系统设置新增「实验功能」区块,内含 noa 模型驱动上下文压缩开关(默认关)。
开启后平台接入的四类 agent(planner / worker / 主 agent / 对话)由 noa 接管
上下文压缩,取代内置 compaction;关闭即恢复内置压缩。

- agent: 新增 enableNoa 共享接入器(noaadapter.Enable 唯一入口,all-or-nothing),
  四类 agent 各加 noaEnabledFn 解析器 + SetNoaEnabled,每 run 读一次,切换只影响
  之后启动的 run,无需重建 agent。归档落在各 agent 本 run 工作目录下(任务级持久),
  session id 与 transcript 同规则。启用失败经 onWarn 上报并回退内置压缩,不中断任务。
- server: settings key noa_compaction + Manager 读写;8 处 agent 装配点注入平台级
  解析器(server 5 + task_llm 3);GET/PUT /api/settings 增加字段。
- web: 系统设置页新增实验功能卡片与开关(乐观更新、失败回滚),类型与 mock 补字段。

官方默认行为不变:开关默认关闭时 noaadapter.Enable 不被调用,内置 compaction
原样工作。
2026-09-15 09:20:35 -04:00
RuoJi6 c0d1aa6f37 feat(intercept): 模型审查补充任务上下文与裁决说明 (#124)
审查模型改为接收版本化 JSON:任务描述/目标/操作约束、工作目录、Worker 意图、当前轮输入,以及按 tool_use_id 配对的近期工具执行记录;末尾是完整的 tool_name 与 arguments。

- 任务约束每次审查从数据库重新读取;读取失败或约束超预算转人工。
- 历史只保留唯一配对的执行事实,排除 Agent 自述、未完成请求与平台拒绝反馈。
- 裁决改为 JSON decision(allow/ask/deny) + comment,三种结果均须说明实际操作、成功后果与命中规则。
- 所有模型裁决(含自动放行)保存实际模型输入与 SHA-256 指纹,详情页可展开。
- 对话审批卡片支持展开完整请求、模型输入、裁决与执行结果。
- 修复父目录 lockfile 导致的 Turbopack 根目录误判。

官方默认拦截规则、工具范围与优先级不变。
2026-09-15 20:08:12 +08:00
Autumn-27 234bd8bf8e test(side): SSE 扫描出错直接失败,不再误判为未收到累积请求 2026-09-15 07:54:33 -04:00
Autumn-27 5963281582 fix(agent): 探索图工具在无任务上下文时拒绝而非 nil 崩溃
buildDomainReg 构造的 server 级 ToolSet 恒持 nil ExplorationStore(taskID=0),
tools 表可把其中任一工具绑给不在任务内运行的 agent(auto/pentest/reporter/
自定义/旁路提问)。node_detail 等探索图工具直接解引用 t.ts,被这类 agent 调用即
nil deref;panic 发生在 harness 自己的 goroutine 上,server 侧任何 recover 都
够不到,整进程退出,重启后调度器又拉起同一 agent 再崩,形成崩溃循环。

- 新增 readExpTool/writeExpTool + needExploration:t.ts==nil 时返回可读的工具
  错误(提示改用带 task_id 的跨任务读取工具),把 17 个探索图工具切过去
- anchorOwner 补判空
- AugmentTools 出口给每个工具套 guardPanic:handler panic 降级成工具错误并打
  stack,覆盖域工具/SDK/MCP/skill,进程不再陪葬
- 注明 buildDomainReg 的 nil-store 契约
2026-09-14 13:56:56 -04:00
RuoJi6 1a388e3e9e feat: support legacy SSE MCP servers (#117) 2026-09-15 00:56:16 +08:00
RuoJi6 71fa919599 feat: 为审批记录增加翻页 (#115) 2026-09-15 00:52:48 +08:00
Autumn-27 5db71f7c53 fix(evidence): traffic_search 描述迁移出错不再中断后续 reporter 迁移
description UPDATE 失败时原会 return 整个 seedFindingWorkflowTools,连累
independent 的 v2_reporter 迁移一起被跳过。改为出错仅 log、不置 flag(下次
启动重试),继续执行后续迁移。
2026-09-14 12:44:15 -04:00
RuoJi6 7c8b55ca6c fix(traffic): match recorded hosts with port-aware search (#114) 2026-09-15 00:43:20 +08:00
Autumn-27 edbc296e29 feat(agent): add_hint 触发的规划轮显式播报「本轮由新增 hint 触发」
此前 add_hint 走裸 notify,触发的规划轮 triggers 为空,开场白说"无具体变动",
hint 只折在 graph_overview 里让 planner 自己发现。仿照 set_goals/NotifyGoal,
让 add_hint 记一条 hint 触发事件并带上提示文本。

- TriggerEvent 增加 Hints 字段;renderTriggers 增加 hint 分支,播报「人新增了
  N 条战略提示:…」
- ToolSet 增加 notifyHint 回调 + SetNotifyHint;add_hint 整批写完统一唤醒一次
  (优先 notifyHint,未接则退回裸 notify),notify 从 addOneHint 上移到 handler
- 主 agent(server.go) 与跨任务编排(orchestration.go) 均接上 Task.NotifyHint
2026-09-13 11:36:31 -04:00
Autumn-27 c9bfa35113 feat(agent): node_detail 也默认给 worker,并随回看工具一起补绑
worker 已能通过 search_all_worker_traces / get_worker_trace 拿到 intent_id/
节点 id,配套把 node_detail 也下放给 worker,便于就地查节点完整详情。

- WorkerTools() 增加 node_detail
- 从 seedWorkerReadToolsUnbind 解绑清单去掉 node_detail(保留 list_facts/
  list_companies/list_worker_traces)
- 原 seedWorkerCrossTraceRebind 泛化为 seedWorkerReadbackRebind,补绑清单追加
  node_detail,flag 升到 v2 让已跑过旧迁移的库也补上
2026-09-13 09:35:18 -04:00
Autumn-27 2ba395856d fix(agent): worker 跨 work 回看工具被旧迁移误删,改绑定并补绑回
seedWorkerReadToolsUnbind 的解绑清单里仍列着 search_all_worker_traces /
get_worker_trace,而 d531ea9 已把这两个加进 WorkerTools()——新库启动时先
seed 进去又被这段迁移撸掉,导致 worker(含 benchmark 镜像)实际拿不到。

- 从解绑清单去掉这两个,只保留 list_facts/node_detail/list_companies/list_worker_traces
- 新增一次性 seedWorkerCrossTraceRebind:把这两个补绑回 worker,修复已跑过旧
  v1 迁移、被误删的现存库;新库为无害 no-op
2026-09-13 08:58:17 -04:00
Autumn-27 44194a9ebc fix(trigger): 合并触发会话按任务去重任务描述/目标,避免长目标重复撑爆消息
on_tool_call 等事件触发在 merge 时,每条事件都重复整段任务描述+目标;
当任务目标很长(如续跑继承事实)且短时间多次触发时,合并消息体积爆炸
(实测 39 条 submit_flag 连击 → 十几万字)。

- triggeredRun 拆出 taskDesc/taskGoal 任务级字段,message 只留事件正文
- by_task 合并:同任务头只写一次
- all 合并:按任务分组(首次出现排序、任务内保序),每任务头只写一次,
  交错触发也不重复
- 单条触发由 finalTriggerMessage 补一次任务头
- 任务描述截 200 字、目标截 500 字,单份也有界
- 新增 trigger_merge_test.go 覆盖去重/交错/截断/定时无头
2026-09-12 09:26:38 -04:00
Autumn-27 e4c744a318 feat(search): 网络搜索新增 DeepSeek 官方来源
不单独配置凭据,直接复用当前激活的 LLM 配置(base_url/api_key/model)。

这个来源与 ddgs/brave/tavily 性质不同:DeepSeek 没有可直接调用的搜索接口,
搜索只存在于其 Anthropic 兼容 messages 接口内部,以 web_search_20250305
服务端工具的形式由 DeepSeek 服务端执行。由此带来几个必须让用户知道的差异,
已在设置页写明:

- 仅支持 DeepSeek 官方端点 + anthropic 协议。实测其 OpenAI 协议端点会直接以
  "unknown variant, expected `function`" 拒绝一切服务端工具,web_search_options
  之类的顶层字段则被静默忽略,没有可用的替代写法。
- 每次搜索额外消耗一次模型调用。
- 搜索请求由 DeepSeek 服务端发出,不经过搜索出口代理,也不计入流量留痕。
- 返回结果只有标题与链接,没有摘要(DeepSeek 只给 encrypted_content),需要正文
  时仍由 WebFetch 抓取。

上述条件不做程序校验,仅在界面说明,由用户自行确认——配置不满足时搜索会在实际
调用时报错,与其它来源填错 Key 的反馈路径一致,可用「测试搜索」按钮实跑验证。

依赖 norma v0.3.8。
2026-09-12 07:13:46 -04:00
Autumn-27 44156a0a4c feat(update): 页面一键更新 + 守护启动脚本
系统配置页新增「版本与更新」卡片,顶栏版本号旁在有新版时亮出提示胶囊。
更新链路:下载发布包 → 比对 SHA256SUMS → -h 冒烟测试 → 暂存 artex.new
→ 以退出码 75 退出 → 守护脚本重新拉起并完成换装,页面轮询 /api/health
等版本号变化后自动刷新。

新增 start.sh / start.bat 作为正式启动入口,只按退出码决定是否重新拉起
(0 停止 / 75 应用新版 / 其余崩溃退避)。校验、冒烟、换装、回滚全部收在
selfupdate 包里而不写进脚本:这些逻辑在 sh 和 bat 上要写两套,而它们恰恰
最不能出错——换上跑不起来的二进制后守护进程会反复拉起它,只能上机器手工救。
Docker 的 ENTRYPOINT 一并改为该脚本,并由它转发 SIGTERM,否则 docker stop
只发给 PID 1,artex 做不了优雅关闭会被 SIGKILL 硬杀。

失败保护两道闸门互补:无法 exec 由换装前的冒烟挡住,能执行但初始化崩溃
由启动计数兜住(连续 3 次失败自动回滚 artex.old,坏的留作 artex.failed)。

GitHub 查询结果后端缓存 30 分钟(失败 2 分钟)。未认证 API 是每 IP 每小时
60 次,且这 60 次是服务器 IP 上所有用户共用的,顶栏每次整页加载都查一次,
不缓存会很快耗光配额导致真想更新时反而查不动。手动「检查更新」带 force=1
绕过缓存。

安全:只认 GitHub 域名且强制 HTTPS(逐跳校验重定向),发布源写死不可配置;
升级文件挂在可执行文件所在目录而非 CWD(服务化运行时 CWD 可能是 /);
开发构建版本号不可比较,禁用一键更新。

走完整 zip 而非裸二进制,因为现有 Release 的 SHA256SUMS 只覆盖 zip,
这样无需改 CI,也兼容已发布的历史版本。

已知限制:Docker 下只换程序不换镜像(工具链不同步、重建容器会退回镜像
版本);不同步发布包里的 skills/;更新即重启会中断运行中的任务。
2026-09-11 12:39:59 -04:00
Autumn-27 557317491b feat(assets): 任务测试资产支持 DSL 搜索
任务详情「测试资产」接口/服务多时不好找。复用资产管理页的 DSL
搜索(字段自动补全 + 分页),搜索始终限定在当前任务范围内。

- 抽出共享组件 asset-dsl-search.tsx,资产页与任务页复用,UI/交互一致
- QueryDSL/CountDSL 增加 taskID 参数,taskID>0 时强制 AND $N = ANY(task_ids)
  并补 task 来源信息;即便 DSL 内写 task_id 也无法越出当前任务
- 任务资产 tab 接入搜索框:有 DSL 走 searchTaskAssets,否则走 taskAssets

Closes #107
2026-09-11 11:59:46 -04:00
Autumn-27 25b82f2544 fix(mcp): http 传输支持跳过 TLS 证书校验(自签证书)
MCP server 走 HTTPS 且用自签证书时,客户端 TLS 校验失败,报
"tls: failed to verify certificate" 无法连接。

mcp_servers 增加 insecure 开关(默认 false),置 true 时远程 MCP
客户端使用 InsecureSkipVerify 的 transport。stdio 传输不受影响。

- mcphttp.New 增加 insecure 参数
- db: MCPServer.Insecure 字段 + schema 加列(补 ALTER 兼容旧库)
- create_mcp/update_mcp 工具与前端 http 配置项增加勾选框

Closes #108
2026-09-11 11:37:56 -04:00
Autumn-27 151bedcdf5 fix(btw): 无 Postgres 时跳过旁路测试,go.mod 补 uuid 直接依赖
server/side_questions_test.go 的 fixture 在拿不到数据库配置时走 t.Fatal,
导致未设置 ARTEX_PG_DSN 的环境跑 go test ./server 直接失败,掩盖真实回归。
改为 t.Skipf,与 server 包其余测试一致。

db/side_questions.go 直接引用 github.com/google/uuid,go mod tidy 将其
从 indirect 移到 direct。
2026-09-11 11:10:32 -04:00
Autumn 4d7d65a1cf Merge pull request #106 from RuoJi6/codex/btw-side-question
feat: add /btw side questions
2026-09-11 23:08:46 +08:00
Autumn-27 399f971f41 fix(llm): 测试连接补发自定义会话头,修 opencode zen 400
testLLM 单发路径既没往 context 挂 session id,也没把 profile 的
session_header_key 透传给 cfg,导致强制要求 x-opencode-session 的端点
(opencode zen)在"对话正常"时"点击测试"却 400 MissingSessionID。

- provider.go: TestConnection 挂一个一次性随机 session id 作头值
- server.go: testLLM 透传 session_header_key,并从已存 profile 兜底
- web: api.ts / llm page 把该字段传到 /llm/test
2026-09-11 10:45:27 -04:00
ji ruo 272004c2e4 Merge upstream/main into codex/btw-side-question
同步官方 main 的任务会话与 spawn_task 更新,保留 /btw 旁路上下文能力。
2026-09-11 08:47:57 +08:00
Autumn-27 f34cc82873 feat(orchestration): spawn_task 支持 source_task_ids 只读继承来源任务
- spawn_task 新增 source_task_ids 参数(字符串数组,上限 MaxTaskSourceCount),
  子任务可只读继承来源任务已探明的资产/结论;校验规则(数量/有效/去重/存在)
  与 HTTP 建任务一致,底层由 CreateTask 改走 CreateTaskWithOptions。
- 修复既有 bug:参数 struct 字段缺 json tag,导致带下划线的键无法匹配,
  parent_ref 实际从未生效。为全部字段补齐显式 json tag。
2026-09-10 13:34:34 -04:00
Autumn-27 6b59d4126e fix(agent): 主 Agent 每个会话均可交互,修实时徽章滞留
上一版把非当前段设为只读、且仅当前段可发消息,与"像会话页一样在任一
会话都能对话"的诉求不符;同时实时徽章改用 recentLive 后,turn 结束仍
会在 5s 窗口内继续显示"实时流式中"。

- server: chat 接口接收目标段 seg,消息写到用户正在看的会话段(缺省=最新段)
- web: 去掉只读/当前/历史区分,任一主 Agent 会话都可直接对话;send 带 seg
- web: 实时徽章改回按真实运行状态(sending/mainChatRunning)判断,且收到
  终结记录(result/报错)即刻熄灭;输入框同样在终结记录后立即解禁
2026-09-10 13:14:54 -04:00
Autumn-27 ee3eb22433 feat(agent): 任务内主 Agent 支持多会话,可切换且上下文可重置
主 Agent 会话原为一个任务恒定单例,对话历史随 transcript 只增不减、
上下文越滚越大。现引入会话分段(seq):新建会话切一个干净的 transcript
段,任务的图谱/资产/目标共享保留,旧段以只读历史随时切回查看。

- db: 新增 main_sessions 表与 activity.main_seg 列(ALTER ADD COLUMN
  IF NOT EXISTS 兼容旧库);ActivitySessionFilter 按段过滤(段 0 兼容
  旧 NULL 行);新增 CurrentMainSeg/ListMainSessions/NewMainSession;
  per-session token 统计按 main:<seg> 分段
- agent: MainAgent.Chat 增加 mainSeg,transcript SessionID 分段
  (段 0 保留旧名 exp<id>-main 兼容既有对话)
- server: parseActivitySession 支持 main:<seq>;chat handler 每轮
  stamp 当前段;新增 GET main-sessions / POST main-session/new
- web: 主 Agent 分组渲染多段会话,支持新建(轻确认)、切换、旧段只读
2026-09-10 12:56:59 -04:00
ji ruo 2930c4b915 Merge origin/main into codex/btw-side-question
合入 main 的 norma v0.3.7、会话分组与流量证据更新,保留 /btw 快照和输入布局。同步自动放行、关闭流量绑定的测试断言,并等待归档测试夹具的旁路后台退出。
2026-09-11 00:54:51 +08:00
ji ruo d893861d00 fix(btw): 修复长对话上下文预算与旁路输入布局 2026-09-11 00:41:01 +08:00
Autumn-27 3c2a60fba7 fix(agent): 空转回合注入续跑指令,复用空响应重试次数
模型有时一整轮只输出思考、既不给正文也不调工具,harness 视为自然结束
(end_turn 且无 tool_use),直接以 completed + 空总结收场,一条未完成的意图
断在半路,表现为「任务正常结束但没有文字总结」。五层 LLM 重试均够不着它
(非错误路径),SDK 空响应重试也够不着(以是否 yield 过事件判空,而思考增量
本身就是事件)。

work 的 Stop 钩子现识别这种回合并注入一条续跑指令,让模型带着已有思考继续
执行下一步——不选原样重发,因这类空转由提示词与上下文形状决定,是稳定行为
而非随机抽风。次数复用 LLM 页「空响应重试次数」(默认 2、-1 关闭),是一条
意图的总量闸而非连续次数(harness 已限死连续空转只推一次)。
2026-09-10 10:49:11 -04:00
Autumn-27 97ce284c98 refactor(worker): 关闭跨 engagement 记忆,收敛默认工具面
- 移除 worker 的 memory 挂载:删掉两处 SetMemory 调用及 worker.go
  里的 mem 字段/SetMemory 方法/opts.Memory 装配,RecallMemory、
  RecordMemory 两个工具及每轮记忆自动注入不再启用。
- worker 默认工具集剔除 MultiEdit/Glob/Grep:新增 defaultToolsExcept
  按名过滤 SDK 默认工具;文件精改用 Edit、检索走 Bash(grep/find)。
  planner/mainagent 不受影响。
2026-09-10 10:29:35 -04:00
Autumn-27 72a52e9202 fix: 修复合并后审查发现的 6 个中/高问题
#102 高:证据正文下载在全局 advisory lock 事务内 io.Copy 给 HTTP 客户端,
verifyFile 又要整读一遍算 SHA-256 —— 一次大文件下载或慢客户端就会挂住
全进程的证据写入。改为事务内只解析绑定元数据(Store.Binding),出锁后再校验
与串流;blob 内容寻址且 GC 有 24h 宽限,已打开的 fd 也不受 unlink 影响。

#102 高:traffic_evidence_snapshots 的 url/req_head/resp_head 直接来自目标
原始报文,未清洗就写 PG TEXT。目标返回非 UTF-8 头(GBK filename)或 NUL 会让
RecordFindingTx 整个事务回滚,已确认的漏洞完全不落库。新增
TrafficEvidenceSnapshot.Normalize(),在算 ID 之前套用仓库既有的 utf8Clean,
保证哈希与入库字节一致。

#102 中:自动绑定默认关闭,reporter 便不会传 evidence_version,
SetFindingReportVersionByNodeID 按 legacy 语义写 -1,报告永久显示「待更新」
且 UI 无处清除;老库还因 reporter_agent_seed_v1 守卫拿不到新触发文案。
触发消息改为无条件先读 get_finding_traffic(只读工具,不依赖捕获开关)并回传
版本,并加一次性迁移刷新老库中未被用户改动的默认文案。

#102 中:开关关闭时 report_finding 只要收到 traffic_refs/evidence_hint_id
就在写入前报错,模型幻觉出多余字段即丢掉一个真实漏洞。改为忽略这两个参数
照常登记,由既有的 evidence_status=not_bound 说明未绑定。

#101 中:删掉 RuleID!=0 判断后,每次模型放行都写一行带完整审计快照的
intercept_pending(单行最坏 24×8KiB 上下文 + 32KiB 输入)。开启兜底裁判的
渗透任务会灌入数百 MB,并经 task_archives 的 SELECT * 进入归档。放行行改为
只留决策元数据与执行结果,丢掉重放快照;ask/deny 路径不变。

#103 中:FindingRetestForConversation 出错时在收尾 defer 注册前就 return,
复测行永远停在 pending —— 漏洞列表常驻「复测中」,后续发起复测被去重拦下,
只有重启才能清。新增 FailPendingRetestForConversation 按会话 ID 收尾。
2026-09-10 10:15:24 -04:00
Autumn-27 e8efce605c Merge PR #102: feat: 支持漏洞关联多条流量证据
冲突解决:
- db/schema.sql: 复测表(#103)与流量证据表(#102)均为追加,两者保留
- server/server.go: 启动序列同时保留 seedFindingRetester 与 evidence GC
- web/src/lib/types.ts: InterceptAudit/InterceptDetail(#101) 与流量证据类型(#102)并存
- findings/detail/page.tsx: 去掉 #103 带入的重复 import,仅保留 FindingRetestPanel
- chat/page.tsx: 保留 #103 的 Spinner import
2026-09-10 10:04:53 -04:00
Autumn-27 071d87896d Merge PR #103: feat: 支持会话级漏洞复测与运行状态展示 2026-09-10 10:02:39 -04:00
ji ruo 555539bc8e feat(agent): 支持持久化 /btw 旁路提问 2026-09-10 21:42:25 +08:00
ji ruo 82c1ed9cbb feat: 支持会话级漏洞复测与运行状态展示 2026-09-10 16:06:08 +08:00
ji ruo 9ad323dc4c feat(intercept): 增加审批记录详情与执行审计 2026-09-10 15:10:50 +08:00
ji ruo dbd00b846e feat: 由报告 Agent 自动关联流量证据 2026-09-10 14:26:15 +08:00
ji ruo a3bb2c7959 feat: 增加 Agent 流量绑定开关并补齐证据交接 2026-09-10 14:08:40 +08:00
ji ruo ec4ef35fff feat: 支持漏洞关联多条流量证据 2026-09-10 13:03:20 +08:00
Autumn-27 5327f88ebc refactor(worker): 收敛 work agent 默认工具集与资产写回提示
work agent 只负责单条意图的执行与写回,读上下文/跨 work 复盘属规划职责:
- 从 WorkerTools() 移除 list_facts / node_detail / list_companies 及跨 work 检索
  (search_all_worker_traces / list_worker_traces / get_worker_trace),只留
  list_findings(报漏洞前查重) + add_finding/record_fact + insert_assets/list_assets。
- 旧库迁移 seedWorkerReadToolsUnbind(flag worker_readtools_unbind_v1):逐个
  RemoveAgentFromTool 把上述工具从 worker 默认绑定剥离,planner/main 同名绑定不动。
- worker 提示词「查上下文」段收敛为 list_assets/list_findings;insert_assets 段删掉
  与工具 schema 冲突的陈旧字段(type=tech/on_url/props/props.http),字段填法交回工具
  自身说明,只留路由与边界。reseedWorkerPrompt 版本 bump v3→v4 下发旧库。
2026-09-09 13:59:47 -04:00
Autumn-27 a50bf02428 feat(llm): 五层重试的次数与间隔可配
一次模型调用的失败由内到外经过五层重试:建连(SDK)、空响应(SDK)、同 provider
安全窗口、轮询熔断、意图重跑。此前五层的次数与间隔全是写死的常量,遇到脾气各异
的中转站只能改代码。现在都能在 LLM 页配置,不配就是原来的默认值。

配置语义五层统一(db.RetryRule):次数 0=内置默认 / -1=关掉这层 / >0=该值;
间隔 0=原本的指数退避 / >0=改用固定间隔。0 被"未配置"占用,故关闭用 -1。
写库前夹紧到 次数 [-1,20]、间隔 [0,1h],DB 另有 CHECK 兜底。

粒度按层的性质分:前三层跟着端点走,可在每个模型配置里逐字段覆盖全局默认(只钉
间隔的仍继承全局次数);熔断与意图重跑是进程级语义,只有全局一份。

生效路径:①②是 provider 构建参数,保存后重建缓存;③随每次 hooks.current()
解析,故障转移换配置时重试节奏跟着换;④在失败路径上每次都要读,由 applyRetryPolicy
推给 llmpool.Registry;⑤每条意图收尾读一次。全部热生效,无需重启。

连接测试刻意不带这些参数——它有 30s 硬超时,叠上用户配的重试只会把本来能用的
端点测成超时失败。

norma 升 v0.3.5(llm.Config 新增 RetryInterval / EmptyResponseRetries /
EmptyResponseInterval)。旧库升级后行为逐字节不变:新列默认 0,settings 键不
存在即全默认。设计见 docs/LLM重试设计.md。
2026-09-09 13:35:04 -04:00
Autumn-27 4f088e519b feat(digest): 探索图冷节点压缩(cold-digest)
把老且长期不活跃的意图/事实折叠成 digest 节点进 graph_overview 展示,
原始节点永久保留、按 id 可完整还原(存储无损、只压呈现、折叠可逆)。

- 数据模型:KindDigest 节点 + RelCovers 边(真相源);新列 content_version、
  cold_since_round(节点级)、round_no(任务级 planner 轮次);均带旧库迁移。
- 纯算法(coldgraph.go):冷热判定(逆向可达 + 任一活分支即热) + R=6 轮防抖 +
  连通分量分组(§3) + §3.1 同父兄弟归组(救"热 hub+扁平死叶") + §5.3 签名。
- 后台压缩(compaction.go):minor 折未覆盖冷块(tiered)、major 回源重压合并碎片;
  签名幂等复用 body;提交时活跃度复核(绝不覆盖已复活节点);60s 冷却 + 互斥。
- 概览折叠(§6):recent_* 剔除已折成员 + 渲染时复活检查;cold_digests + 按资产
  索引 cold_index(§6.2);expand_digest/expand_index 还原;covered_members 反查
  悬空血缘 id;60 兜底截断均衡保 live。
- planner 每轮 OnPlannerRound 维护戳记并触发后台压缩,绝不上热路径。

纯算法单测覆盖 §附/§3.1/§2.3/§5.3;已对 437 节点真实图验证:热 86、冷候选 324、
§3.1 分组 47 块 + 14 孤立冷点(对齐设计文档实测校验)。
2026-09-09 11:52:15 -04:00
Autumn-27 f270ca66bc feat(tasks): 任务列表新增「运行中 Worker」列
TaskListMetricsAll 增加一个 LATERAL 子查询统计 kind='intent' 且
state='running' 的节点数,随 TaskDTO.in_flight 一并返回,口径与任务
详情页概览的「运行中 Worker」完全一致。列表页在「目标进度」后新增该
列,无运行中 Worker 时显示 0。
2026-09-08 14:25:49 -04:00
Autumn-27 7d4223c535 refactor(worker): record_fact 删否定结论段、confidence 与穷尽解耦、facts 分条收紧
worker 默认提示词的 record_fact 段易误导规划者:
- 删掉「否定类结论只写观察+试探性读法」整句,worker 不再被引导写“看不出/放弃”式判断
- confidence(observed/inferred) 与「是否穷尽本意图手段」解耦,回归“直接看到 vs 据现象推断”
- facts 数组分条收紧为「彼此完全独立、无法归并」的极少数例外,默认写一条并进 detail

reseedWorkerPrompt flag bump v2→v3,存量库再刷一次新默认。
2026-09-08 12:39:40 -04:00
Autumn-27 1dffe05728 refactor(prompts): 精简 planner/worker 正文并修正实战问题,reseed 推送存量库
- planner/worker 默认正文精简(合并重复复述,逻辑无损)
- planner: recent_done 按 state 区分处理(blocked/exhausted 先查 trace 再决定,
  不当死路也不无脑重跑);否定结论改为“观察/存疑、非定论”、采信前看 evidence、
  inferred 默认派复核意图且至多一次;目标未达成且无 open/running 意图必须产出(硬底线);
  “克制”降级为仅去重;深度优先于覆盖度
- worker: 否定类结论只写“观察+试探性读法”、判决权归 planner;
  跨意图线索写进 fact 的 summary 交规划者、不自己追
- terminalreason: 修正 blocked 描述(传输层故障、需查执行过程,非“此路不通”)
- reseed flag 均 bump 至 v2:存量旧库启动时把新默认追加为新版本并切过去,
  旧版本/用户自定义保留在历史可回滚
2026-09-08 10:32:43 -04:00
Autumn-27 3d71196774 feat(tools): planner 默认绑定 list_assets
新库经 PlannerTools() 并入 list_assets 绑定;老库由
seedPlannerListAssetsBinding() 一次性回填(flag 幂等,不覆盖用户解绑)。
planner 现同时具备 list_assets(DSL 全库检索)与 list_untested_assets(范围内未测)。
2026-09-08 08:53:50 -04:00