Autumn-27
|
9b82b02fe2
|
docs: 采用 AGPL-3.0 开源协议
|
2026-09-18 07:47:13 -04:00 |
|
Autumn-27
|
2951e10a4d
|
docs(readme): 完善许可与免责声明
|
2026-09-18 07:43:58 -04:00 |
|
Autumn-27
|
0ec51e3799
|
docs(changelog): 定版 0.3.12
|
2026-09-17 13:17:39 -04:00 |
|
Autumn
|
ec0ae108c4
|
Merge pull request #150 from Autumn-27/feat/broadcast-search-node-id
feat(web): 播报板搜索支持按节点 id 筛选
|
2026-09-18 01:09:30 +08:00 |
|
Autumn
|
8a3f40b6f8
|
Merge pull request #149 from Autumn-27/feat/intent-delete-modes
feat(intent): 意图删除支持假删除/真删除两种模式
|
2026-09-18 01:05:03 +08:00 |
|
Autumn-27
|
4756bb1c45
|
feat(intent): 意图删除支持假删除/真删除两种模式
删除入口区分两种模式(待领/运行中/已暂停的意图均可删除):
- 假删除(默认):意图置 state='deleted'、删除原因记入新字段 delete_reason,
保留节点与全部产出/血缘,不再在图上另挂 fact。
- 真删除:物理删除意图及「仅由它支撑」的独占子孙(沿 yields/derived_from
级联到叶子),避免孤立数据;共享节点、目标、任务根事实保留。被删意图先做
token rollup 并清理 activity/副会话,被删 finding 先删 findings 行。
两种模式都照常用 cancelled 触发通知 planner(带删除前捕获的意图摘要 + 原因),
planner 文案不再声称原因挂为事实。
- DB: 新增 SoftDeleteIntent、重写 CancelIntent 为深度独占级联;schema 加
delete_reason 列与 intent 的 deleted 状态(含旧库迁移)。
- 前端: 删除对话框加模式切换与动态说明,状态徽章/图标新增「已删除」,
播报板展开展示删除原因。
|
2026-09-17 12:52:57 -04:00 |
|
Autumn-27
|
6e3dbf6452
|
fix(web): 修复新对话未创建时上传文件报「缺少上传文件」
Composer 的 file input onChange 里同步执行 e.target.value = "" 清空了与
input 活绑定的 FileList。DraftChat 的 pickFiles 要先 await 建会话才取文件,
恢复执行时 FileList 已空,FormData 里没有 file 字段,后端返回 400。
改为在清空 value 之前把 FileList 快照成 File[] 再回调,onPickFiles 签名
随之改为 (files: File[]),调用方去掉各自的 Array.from。
|
2026-09-17 12:40:38 -04:00 |
|
Autumn-27
|
e2ada7e494
|
feat(web): 播报板搜索支持按节点 id 筛选
搜索框在内容/来源之外,新增节点 id 匹配:纯数字或 UI 展示的「#41」形式
都会精确命中该节点。服务端 NodesPage 在 payload/origin ILIKE 的 OR 组里
追加 id 精确匹配;mock 同步;补 NodesPage id 搜索测试。
|
2026-09-17 11:31:27 -04:00 |
|
Autumn
|
c6c5329a18
|
Merge pull request #147 from Autumn-27/feat/broadcast-node-detail
feat(web): 播报板节点详情展示上游节点信息与锚定资产
|
2026-09-17 23:28:03 +08:00 |
|
Autumn-27
|
d95f0d002d
|
feat(web): 播报板节点详情展示上游节点信息与锚定资产
上游/下游节点从只显示 id 改为悬停弹出节点名片(类型/状态/来源/时间/摘要/payload);
展开时顺带展示该节点锚定的资产(类型标签 + 可辨识文本)。
服务端 /exploration/nodes 新增 assets 字段(节点id→资产),读 exploration_anchors
并复用发现列表的资产打标逻辑;同页节点互引时用本页 items 兜底 refs 查找表。
|
2026-09-17 11:23:53 -04:00 |
|
Autumn-27
|
3b60191e86
|
refactor(engine): 移除从不执行的全局 planner/worker 空壳,就绪信号改用谓词
权威解析器(SetAuthoritativeAgentResolver)落地后,引擎每轮规划/worker 都走
per-task 的 agentsForTask 路由;applyLLM 经 buildPlannerWorker 构建、UseLLM 装入
的全局 planner/worker 从不被执行,仅充当 Ready() 的'已配置'探针。这层空壳是
功能容易被错误接线的温床(冷节点压缩此前就误接在它上面)。
改动:
- 删除 buildPlannerWorker、providerForAgent(仅前者调用)、Engine.UseLLM/snapshot/
Mode、Engine.planner/worker/mu 字段。
- Ready() 改为读 SetReadiness 注入的谓词(基于 s.llmOn);snapshotFor 去掉全局
兜底,权威解析器返回 nil 即表示该任务不可用(语义不变)。
- applyLLM 不再构建全局 pair;NewServer 注入就绪谓词。
- 相应更新 3 处依赖旧注入方式的测试(改用权威解析器注入)。
生产行为不变(全局 pair 本就从不执行);go build/vet 通过,server 测试失败集合
与基线一致(均为需 DB 的既有用例),无新增失败。
|
2026-09-17 09:40:06 -04:00 |
|
Autumn
|
cd5e779a24
|
Merge pull request #145 from Autumn-27/feat/broadcast-node-id
feat(web): 播报板每行显示节点 id
|
2026-09-17 21:19:50 +08:00 |
|
Autumn-27
|
3cde43f64f
|
feat(web): 播报板每行显示节点 id
|
2026-09-17 09:17:30 -04:00 |
|
Autumn-27
|
e78b35869c
|
chore(server): 删除已死的全局 mainAgent 与 agentsForProfile 等冗余构建
per-task 路由(agentsForTask)落地后,这些全局副本已无人使用:
- 全局 mainAgent(字段 + applyLLM 里的构造 + mainAgentRef getter):真正在跑的是
agentsForTask(t).main,全局那份从不被读取,mainAgentRef 无调用者。
- agentsForProfile:旧的任务 pin 路径,已被 agentsForTask 取代,无调用者。
- 随之失活的 profBundle 类型与 profAgents 缓存(仅初始化/清空、再无存取)一并移除。
均为编译器可确认的死代码,不改变任何执行路径;chat 的全局兜底(chatAgent/
chatAgentForProfile)、provider 缓存(provByProfile)等仍在用,保留不动。
全局 planner/worker 空壳与 Ready()/Mode() 改造留待第二步。
|
2026-09-17 09:07:40 -04:00 |
|
Autumn-27
|
564096c063
|
fix(web): 修复静态导出版任务列表页丢失全局头部
判断任务详情页的前缀 "/function/tasks/" 在 trailingSlash 静态导出下
会把列表页自身(pathname 为 "/function/tasks/")也匹配进去,导致发布
二进制里的列表页走了 full-bleed 分支,侧边栏折叠、搜索、版本号、主题
与账号入口整条 header 都不渲染;dev 与 mock demo 未开 trailingSlash
故看不出问题。判前缀前先剥掉尾部斜杠。
|
2026-09-17 08:55:04 -04:00 |
|
Autumn-27
|
55869705ad
|
Merge fix/cold-digest-wire-per-task-planner: 给 per-task planner 接上 Compactor,修复冷节点压缩从不触发
|
2026-09-17 08:53:30 -04:00 |
|
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
|
357ef6a5ab
|
Merge pull request #144 from Autumn-27/feat/exploration-broadcast-board
feat(web): 任务详情页新增探索链路播报板
|
2026-09-17 20:50:17 +08: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 |
|
Autumn-27
|
a15285a7ae
|
Merge remote-tracking branch 'origin/main'
|
2026-09-16 11:07:02 -04:00 |
|
Autumn-27
|
6d0614ae79
|
Merge branch 'fix/demo-finding-traffic-mock':修 demo 漏洞详情页关联流量白屏
|
2026-09-16 11:06:12 -04:00 |
|
Autumn-27
|
5fbeb35b8c
|
fix(web): 补齐 demo 漏洞详情页关联流量 mock,修白屏
PR #102 给详情页加了 FindingTrafficPanel 并请求
GET /exploration/findings/{id}/traffic,但 demo mock handler 没有
对应路由,请求落到读兜底返回 {},前端读 data.bindings.length 时
因 undefined 崩掉整个概览 Tab —— 漏洞详情页白屏、展示不出信息。
补齐关联流量的全套 mock 路由(列表/绑定/编辑/解绑/排序/报文详情/
正文分页),返回与后端 db.FindingTraffic 一致的结构并维护内存态;
为 5 条代表性漏洞预置语义匹配的流量证据,其余走空状态;列表与详情
接口补上 traffic_count。
|
2026-09-16 11:05:21 -04:00 |
|
Autumn-27
|
7f71f77d16
|
fix(changelog): 移除历史遗留的裸 NUL 字节,恢复文本格式
0.3.10 的 /btw 条目把 NUL 字符本身字面写进了反引号,导致整个
CHANGELOG.md 被 git 和编辑器判为二进制/显示乱码。改为可读的 \u0000。
|
2026-09-15 12:39:49 -04:00 |
|
Autumn-27
|
8ee890771f
|
docs(changelog): 定版 0.3.11
|
2026-09-15 12:37:19 -04:00 |
|
Autumn-27
|
95bcd4ef9c
|
Merge branch 'feat/noa-experimental':noa 实验性上下文压缩
|
2026-09-15 12:09:24 -04:00 |
|
Autumn-27
|
c4579637dc
|
refactor(noa): 归档集中到 <workDir>/noa 下,不再分散在任务目录
各 agent 的 noa 归档基目录由本 run 的工作目录改为全局 workDir,
统一落在 <workDir>/noa/<SessionID>/。SessionID 全局唯一,同一基目录
内互不冲突。
|
2026-09-15 12:01:38 -04: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 |
|
Autumn-27
|
4ae319feca
|
chore(deps): 升级 norma 至 v0.4.0(引入 noa 上下文压缩能力)
|
2026-09-15 09:11:55 -04:00 |
|
Autumn
|
0d6fa880b8
|
fix(intercept): 模型裁决被代码块包裹时不再静默放行 (#126)
ParseVerdict 要求裸 JSON,而模型把 JSON 套进 markdown 围栏是常见偏差。
围栏导致解析失败后,reviewer 返回错误、Judge 走 FailAction,其默认值是
allow —— 模型判定的 DENY 会被静默降级为放行,审批记录只显示“模型输出
无法解析”,看不到模型其实给了拒绝。
解析入口前置一次围栏解包。这是确定性解包而非修复:载荷仍交由原
ParseVerdict 严格校验,重复字段、多余字段、多个对象、尾部残留的判定
全部不变。
要求开围栏与闭围栏同时存在。回复在 MaxTokens 处被截断时的形态正是
“有开围栏、无闭围栏”,对其补全会造出模型从未给出的裁决,因此这种输入
继续视为无法解析。
测试:原先断言“围栏必须拒绝”的用例改为接受,另补未闭合围栏、围栏后
带尾随文本、散文夹 JSON 三条必拒用例。
|
2026-09-15 20:40:41 +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 |
|
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 |
|
Autumn-27
|
f2589ad47c
|
fix(web): 修复 demo 任务详情页旁路提问历史缺失导致的整页崩溃
mock 模式下 GET /api/tasks/<id>/side-questions 无路由,被读兜底当集合返回
[],data.items 为 undefined,旁路 hook 的 merge() 迭代抛 TypeError: t is not
iterable,异常在 setState updater 中经 render 重抛、catch 接不住,整页被错误
边界接管。mock handler 显式返回空旁路历史,sideAPI.history 同时归一化返回值。
|
2026-09-14 09:37:08 -04:00 |
|
Autumn-27
|
90f31577f2
|
docs(changelog): 定版 0.3.10
|
2026-09-13 12:37:37 -04:00 |
|
Autumn-27
|
9eefeb3f32
|
docs(changelog): 补齐 Unreleased —— worker 回看工具/node_detail/add_hint 播报、回看工具补绑修复、/btw NUL 修复、合并触发去重
|
2026-09-13 12:22:21 -04:00 |
|
Autumn-27
|
a5abe8ec3c
|
style(agent): 清理 compaction.go 静态检查提示
- generationFor 移除未使用的 genBySig 参数(连同只写不读的 map 构造)
- 两处 WriteString(x+"\n") 改为 WriteString + WriteByte,避免多余拼接
- 一处 WriteString(fmt.Sprintf(...)) 改为 fmt.Fprintf
|
2026-09-13 12:05:11 -04:00 |
|
Autumn-27
|
3480760d4e
|
chore(bench): 补 .dockerignore 忽略项,bench 容器不再挂持久化卷
|
2026-09-13 11:39:05 -04: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
|
0b9341ac8b
|
refactor(agent): 精简 worker 边界#2 措辞,聚焦"绕过手段走完再下结论"
|
2026-09-13 10:08:34 -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
|
d531ea9850
|
feat(agent): worker 增加跨 work 回看工具 search_all_worker_traces / get_worker_trace
worker 也可复用其他 work 的观察、避免重复劳动:search_all 无需先知 intent_id 按关键字全局捞命中步骤,get_worker_trace 锁定某条 work 后列步骤/就地搜/取完整内容。list_worker_traces 仍归 planner/main。
|
2026-09-12 13:05:01 -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
|
abf701e03c
|
refactor(agent): 全局态势提示改松绑口吻,鼓励发散与跨意图线索上报
原措辞连用 4 个"绝不",且把上报写成"最多写进 fact"的退让,易让
worker 为自保而不敢深想、漏报跨意图关键线索。改为:唯一红线收窄到
"别真去执行别的意图",明确"发散是好事",上报改为"务必写进 fact"。
|
2026-09-12 06:12:55 -04:00 |
|
Autumn-27
|
159c587c2e
|
fix(script): start.bat 改用 CRLF 并切 UTF-8 代码页
start.bat 之前是 LF 换行。cmd.exe 解析批处理按字节偏移边读边执行,
只认 \r\n,全 LF 时会读串行,表现为 goto loop 被截断成 'oop'、
"75"( 不是内部或外部命令、: 运算符不存在等一连串报错,脚本根本跑不起来。
同时文件是 UTF-8 无 BOM,中文控制台默认 GBK(936),注释和 echo 全是乱码。
- 顶部加 chcp 65001,中文提示正常显示(artex 本身输出也是 UTF-8)
- 新增 .gitattributes:*.bat 钉 eol=crlf、*.sh 钉 eol=lf,
避免在 Linux 上编辑或重新 checkout 后又被打回 LF
|
2026-09-12 05:32:09 -04:00 |
|
Autumn-27
|
4ccb8f4ff2
|
fix(agent): list_assets 按任务范围过滤,修复任务间资产互串 (#59)
list_assets 此前把任务 id 写死为 0、裸查整个共享资产库,模型又无从写出
范围过滤条件,于是把别的任务的资产(尤其 IP)当成本任务目标,测试方向
被带偏。
- 新增 QueryDSLInScope / GetByIDsInScope:只返回落在【本任务及直接关联
任务】task_scope 内的资产,按归属匹配而非字面值(根域范围含其全部子域/
服务/接口,网段范围含段内主机及服务);越权 id 静默丢弃
- 新增 scopeTargetCTE(纯 scope 归属判定,不含 anchor/tested);whereBuilder
加占位符偏移,$1 留给 taskID
- 修复 IP 直连主机(http://1.2.3.4/api)无法被网段范围命中的盲区:谓词加
OR ts.net >>= try_inet(a.domain)
- 非任务上下文(Auto/pentest, taskID<=0)无范围可依,回退全库
- QueryDSL/CountDSL 原样未动,UI 的「测试资产」视图(按生产者过滤)不受影响
|
2026-09-12 03:25:47 -04:00 |
|
Autumn-27
|
16e87b48c2
|
fix(db): side_question checkpoint 入库前剥除 jsonb 不支持的 NUL 转义
HTTP/工具响应含裸 NUL 字节时,json.Marshal 将其编码为 \u0000 转义,
PostgreSQL jsonb 列拒绝并抛 SQLSTATE 22P05,导致 SaveSideSnapshot 的
INSERT 每秒失败数十次刷屏。新增 jsonbClean 在 marshal 后剥除真正的
\u0000 转义(按前置反斜杠奇偶判断,避免误伤字面 \\u0000),并订正
exploration.go 中 "json.Marshal already sanitizes" 的错误注释。
Closes #111, Closes #112
|
2026-09-12 03:00:28 -04:00 |
|
Autumn-27
|
42f0ff97d3
|
refactor(agent): 测试范围与资产覆盖度开关解耦,移除 insert_assets 的 related 入参
task_scope 是任务的授权边界、资产查询的过滤基准,覆盖度开关只该决定要不要
拿它当分母算指标,不该决定要不要累积范围本身。此前关闭覆盖度会让 auto 与
agent 两条写入路径同时失效,task_scope 只剩界面手工添加的行。
- insert_assets 的自动入范围(source='auto')无条件执行,不再判 coverageDisabled
- add_task_scope 移出 coverageOnlyTools,planner / 任务内主 Agent / 目标拆解
Agent 在覆盖度关闭时照样持有;list_untested_assets 仍随开关隐藏(纯覆盖度视角)
- 移除 insert_assets 每条资产的 related 入参:唯一作用是决定要不要入范围,值又
不落库(同一资产再次登记即作废、界面上也看不出谁被判为无关),连带删除
StripCoverageParams 及其专用的 deepCopyJSONMap / nestedMap
- add_task_scope 与 goalsScopeTail 的描述改为「授权边界」优先、「覆盖度分母」其次
|
2026-09-11 13:33:44 -04:00 |
|
Autumn-27
|
33d3d00c4b
|
docs(changelog): 定版 0.3.9
|
2026-09-11 12:59:32 -04:00 |
|
Autumn-27
|
aa3ef63121
|
docs(changelog): 补齐 0.3.8 以来的变更条目
|
2026-09-11 12:45:23 -04:00 |
|
Autumn-27
|
f5c38da8dc
|
Merge feat/one-click-update: 页面一键更新 + 守护启动脚本
|
2026-09-11 12:41:31 -04:00 |
|
Autumn-27
|
d69ab3b0f8
|
Merge remote-tracking branch 'origin/main' into feat/one-click-update
|
2026-09-11 12:41:02 -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
|
3f8f072202
|
Merge pull request #110 from Autumn-27/feat/task-assets-dsl-search
feat(assets): 任务测试资产支持 DSL 搜索
|
2026-09-12 00:04:19 +08: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
|
1f258837f5
|
Merge pull request #109 from Autumn-27/fix/mcp-insecure-tls
fix(mcp): http 传输支持跳过 TLS 证书校验(自签证书)
|
2026-09-11 23:38:36 +08: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
|
cde3ce9b25
|
fix(btw): 非安全上下文降级生成旁路请求 ID
crypto.randomUUID 仅在 https/localhost 可用,经 IP+http 访问 Web UI 时
为 undefined,导致 /btw 提问抛 "crypto.randomUUID is not a function"。
改用与 sessions-tab / tasks 页面一致的降级写法。
|
2026-09-11 11:13:21 -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
|
5a92e0089e
|
Merge fix/llm-test-session-header: 测试连接补发自定义会话头,修 opencode zen 400
|
2026-09-11 10:47:25 -04: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 |
|
Autumn
|
d86dd152c3
|
Merge pull request #105 from Autumn-27/feat/spawn-task-source-ids
feat(orchestration): spawn_task 支持 source_task_ids 只读继承来源任务
|
2026-09-11 01:43:53 +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
|
98f2a28f25
|
Merge fix/main-session-interactive-live: 主 Agent 任一会话可交互 + 实时徽章修复
|
2026-09-10 13:16:26 -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
|
b4bbe612df
|
Merge feat/main-agent-multi-session: 任务内主 Agent 支持多会话可切换
|
2026-09-10 12:57:59 -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 |
|
Autumn-27
|
9ad88d5ce8
|
fix(guard): 拦截文案标明为平台管控而非目标防御
拦截 deny/ask 回给 agent 的 tool_result 原文案(禁止执行/用户拒绝)
读起来与目标侧 WAF/403 无异,渗透 agent 会当成目标防御去改写命令、
换 payload 尝试绕过。统一经 systemBlockMessage 加平台权威框架,说明
此为平台管控、操作被禁止,引导换方向而非规避。
|
2026-09-10 11:30:28 -04:00 |
|
Autumn-27
|
01760aa345
|
refactor(agent): 精简 worker 默认提示词
- 边界①收敛为「只做领到的这一条意图」,去掉指纹意图的冗长举例
- report_finding 去掉流量绑定的细节段落(traffic_refs 用法另在 [B] 段)
- 删除可选流量绑定说明与结尾的措辞冗余,收尾一句话总结保留
|
2026-09-10 11:08:06 -04:00 |
|
Autumn-27
|
066681a71d
|
Merge feat/chat-session-grouping: 会话列表按 Agent 分组
|
2026-09-10 11:04:58 -04:00 |
|
Autumn-27
|
97e67df158
|
feat(chat): 会话列表按 Agent 分组,支持展开收起与置顶独立
左侧会话列表原先所有 Agent 的会话混在一起平铺,现按 Agent 分组:
- 分组头可点击展开/收起,收起状态存 localStorage 刷新后保持
- 分组顺序按会话活跃度排(后端已 updated_at DESC,首次出现即最近活跃)
- 置顶会话仍独立平铺在所有分组之上
- 分组头吸顶,带运行中标记与会话数;收起时若当前会话在组内提示圆点
- 分组内行不再重复显示 Agent 名
|
2026-09-10 11:02:36 -04:00 |
|
Autumn-27
|
a90f6e67a3
|
feat(web): 攻击链路图渲染压缩(digest)节点并收缩其成员
- ExploreKind/ExploreRel 增加 digest/covers 类型
- digest 节点独立样式(青色 Layers)、图例与摘要(body)
- collapseDigestGraph:active digest 覆盖的 fact/intent 成员从图中隐藏,
触及成员的边端点改接到 digest,成员内部边丢弃并去重,covers 边不渲染
- 详情抽屉展示压缩结论与被压缩成员列表,成员可点击下钻
|
2026-09-10 11:02:33 -04: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
|
eb5290039a
|
refactor: 升级 norma v0.3.7 并精简 insert_assets/list_assets 描述
- go.mod/go.sum: norma v0.3.6 -> v0.3.7(含 shell_* 工具描述精简)。
- insert_assets: 顶层描述去掉与字段 schema 重复的逐类型字段罗列,
仅保留各类型条件必填字段、非 HTTP service 的 ip/domain 约束、
append 合并语义与返回结构。
- list_assets: 字段清单合并、示例保留 2 条覆盖全部语法,去掉多处
重复的 dsl 必填约束与示例。语义不变。
|
2026-09-10 10:46:47 -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
|
ae22e456ce
|
refactor(tools): get_worker_output 移除 terminated 与 worker_name 字段
terminated 仅凭有无 result 记录推断,会把运行中(尚无最终结论)的 work
误报为 terminated=true,语义不可靠;worker_name 对调用方也无实际用途。
两字段一并从返回中删除,并同步更新工具描述。
|
2026-09-10 10:19:19 -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 |
|
Autumn-27
|
29fa64cdbe
|
Merge PR #101: feat(intercept): 增加审批记录详情与执行审计
|
2026-09-10 10:02:29 -04:00 |
|
Autumn-27
|
8dae851b9b
|
docs(changelog): 发布 0.3.8
|
2026-09-09 14:10:07 -04:00 |
|
Autumn-27
|
c585b196b5
|
docs(changelog): 补全 v0.3.7 以来的未记录变更到 [Unreleased]
把 v0.3.7 之后除五层重试外的 25 个 commit 归类补入 [Unreleased]:
cold-digest 冷节点压缩、全局出口代理、自定义会话头、墙钟就地收尾、
worker/planner 提示词与工具集调整、graph_overview 改动、意图状态标签
语义修正等。新增「探索图」「网络」两个章节。
|
2026-09-09 14:08:48 -04: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
|
64b08f518f
|
feat(agent): 墙钟超时改为就地收尾,移除外部硬 ctx 兜底
依赖 norma v0.3.6:MaxDuration 到点会打断在跑工具并就地进收尾(在活 ctx
上按收尾轮数续跑落库+总结,终态 timeout),不再依赖 worker/planner 各自
的 maxDur+90s 外部硬 ctx 把卡住的 run 直接杀成 aborted_tools。
- worker/planner: 删除 WithTimeoutCause 硬 ctx 与 settleHardGrace 常量,
run 直接用 ctx(仅承载 pause/kill/shutdown)。
- chat 走同一 harness 自动获得同样行为;mainagent 无 MaxDuration 不受影响。
- terminalreason: 更新 ReasonTimeout 文案。
|
2026-09-09 13:49:59 -04:00 |
|
Autumn-27
|
aa12706ed1
|
docs(llm): 重试配置每层写清「什么错误会走到这层」
原来每层只有一句泛泛的说明,用户填了旋钮看不到效果时无从判断是配错了还是
这类错误压根不落在这层。现在每层固定给两句:
触发 具体到状态码——建连是 408/429/5xx 与网络层错误,空响应是 200+
正常 stop 却无内容块,安全窗口是拿到 200 之后的断流/overloaded/
流内 429,熔断区分瞬时(429/5xx)与确定性(401/402/403/404),
意图重跑是前面几层都没兜住的 model_error
不走这层 长得像但走别处的:max_tokens 截断、额度耗尽(402)、上下文过长
(413)、4xx 确定性拒绝
模型配置抽屉里的紧凑版只显示「触发」这一句,全局页两句都给。纯文案,无逻辑改动。
|
2026-09-09 13:39:44 -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
|
377ccc7e5a
|
fix(web): 修正意图状态标签 exhausted/blocked 语义错误
- exhausted「已穷尽」→「预算耗尽」:实为达步数/时间预算被中途掐断、只写回部分结果,
并非该方向已探尽(易被误读为无需再探)。
- blocked「被拦截」→「执行出错」:实为模型/API/网络故障重试用尽、意图基本没真正探成,
并非目标/WAF 拦截。
- 补上缺失的 stopped「已停止」(用户手动停止的 work)。
|
2026-09-09 12:59:48 -04:00 |
|
Autumn-27
|
ae29b6714e
|
Merge feat/cold-digest: 探索图冷节点压缩(cold-digest)
冷节点折叠成 digest 进 graph_overview,原节点保留、按 id 可还原(无损、可逆)。
含 §3.1 同父归组、后台 minor/major 压缩、按资产索引、related_tasks 只读折叠、
expand_digest/expand_index 工具(仅 planner/main agent)。经 20 项对抗式评审修正。
|
2026-09-09 12:54:27 -04:00 |
|
Autumn-27
|
67787b5be8
|
chore(digest): expand_digest/expand_index 只给 planner 与 main agent,不给 worker
worker 不读 graph_overview、不需要按 digest 列成员;命中折叠成员 id 时用 node_detail
(直接取原节点、非折叠感知)即可还原。故从 WorkerTools 移除这两个工具,只保留在
PlannerTools 与 MainAgentTools。
|
2026-09-09 12:28:39 -04:00 |
|
Autumn-27
|
775189d916
|
feat(digest): related_tasks 只读折叠(§2 跨任务)
关联/继承任务的概览现在复用其【自身的折叠视图】,与当前任务同逻辑:
- relatedTaskOverviews 按 source 任务自己的 covered/hot 折出已折成员(recent_facts /
recent_intent_results 跳过已折且仍冷的成员),并把该任务的 cold_digests(body)只读带出,
统一 inherited=true / source_task_id 标记。
- expand_digest 支持跨任务:先查本任务,再查直接关联任务(read-only),返回成员紧凑列表并
标继承;node_detail 已有的 GetNodeWithSources 负责成员完整还原。
- 复活检查同样生效:source 任务里已复活(转热)的被覆盖成员照常显示,不被折出。
至此设计文档 §2 跨任务折叠全部落地;仅 §2.3 墙钟兜底(任务停摆判稳)按既定作为后续。
|
2026-09-09 12:09:01 -04:00 |
|
Autumn-27
|
eefd5ee2f2
|
fix(digest): 多智能体评审修正 — 资产索引收敛 + 60cap 保 hot + 文档同步
对照 cold-digest-spec 的对抗式评审(20 项发现)逐条核对实现,两处真实代码问题已修:
- 资产索引膨胀(评审 §6.2 高危):早前把一个 digest 落进它成员命中的【每个】asset 桶,
跨资产 digest 会复制进几十个桶、顶层条目不降反升(真实图 asset_ids 约 144 个)。改为
每个 digest 只归一个【代表资产】桶(成员锚定众数、并列取最小 id;无锚定 → 0 号兜底桶),
条目数 ≤ digest 数。
- 60 兜底截断误砍活跃上下文(评审 §6.3 高危):hot(live 前沿祖先链 / live 意图下新事实)
是活跃推理上下文,绝不能截。改为 hot 全保、60-cap 只约束【冷但未折】残余;冷区两侧
均衡保留。graph_overview 每轮计算 render 期 hot 集(兼用于复活检查)。
其余 16 项评审发现经核对,本实现已由设计选择规避/处理:全量扫描维护(静默变冷/传递翻转
盖章)、签名含锚节点、minor+major 统一走同一 group()(§3.1 在两处都生效、major 不会拆散
同父组)、提交时活跃度复核(不折入复活成员)、content_version 列+状态变更 bump、渲染期索引
(无 KindIndex 陈旧)、cold_digests 与索引并列(body 仍在顶层)、singleton 只进 recent。
文档 §6.2 同步上述解决口径(body 归属、一 digest 一桶、singleton 归 recent)。
|
2026-09-09 12:04:17 -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
|
801160930b
|
feat(planner): 心跳唤醒时若无 open/running 意图则强制补出新意图
停摆兜底:心跳/无变动唤醒且全图已无任何 open 或 running 意图时,
开场白改为停摆告警,明确告知 planner 无 worker 在跑、无排队方向,
本轮必须产出一个或多个与既有意图互不重复的新意图(不得产出 0 意图)。
|
2026-09-09 10:45:20 -04:00 |
|
Autumn-27
|
d728e509dc
|
feat(overview): graph_overview 全量输出 finding_list
findings 是任务最高价值产物且单任务通常不多,改为在 graph_overview
里全量带出 finding_list(不像 facts 只给最近窗口),planner/worker 每轮
即可一眼看全所有确认漏洞,无需再调 list_findings。
每条精简为 {id, summary, evidence?, from_intent?, assets?}:
- evidence 取 finding payload 的 evidence.poc
- from_intent 为产生该漏洞的意图(yields 边)
- assets 直接给受影响资产的可读内容(url/域名/ip:port 等,不再是裸 id),
经 FindingMetaByNodeID 反查锚定资产、批量 GetByIDs 解析
- vulnclass/severity/state 等仍走 list_findings / node_detail
新增 AssetStore.FindingMetaByNodeID 薄封装,让只持有 AssetStore 的
ToolSet 能拿到 node_id→资产映射(读 anchors 表,覆盖新旧漏洞)。
|
2026-09-09 09:24:13 -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
|
4fba36b73d
|
refactor(worker): 意图/启动指令/锚定资产移入 system prompt,user 只留全局态势
意图是 worker 贯穿整个 run 的唯一职责,放 system 每 run 重拼、绝不被
compaction 压掉,续跑也不依赖 transcript 首消息留存;意图锚定资产原始
JSON 与启动指令一并随意图进 system。启动 user 消息瘦身为仅全局态势
overview(可降级、容忍 stale),空时回退一句启动词避免空首轮。
代价:system 混入 per-intent 数据、失去跨意图缓存复用,为不丢意图的
刻意取舍;与 planner 态势块放 user turn 有意分叉(planner 无单一 mandate)。
|
2026-09-08 13:51:24 -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 |
|