BaaRai
07d272727d
fix: emit safe skill frontmatter YAML and verify it round-trips
...
Descriptions written through the API were interpolated raw into the SKILL.md
frontmatter, so a value containing a colon+space made the whole frontmatter
unparseable: every field silently stayed empty, the skill loaded under its
directory name, and a skill-gated MCP server was silently skipped. The same
applied to updates through the meta rewrite, and the shipped scopesentry skill
had a malformed name line all along.
- yamlScalar: plain-safe tokens stay bare, everything else single-quoted
- fsCreateSkill/fsUpdateSkillMeta emit safe values and re-verify the written
file with the real skill parser (name + mcps must survive), rejecting the
write otherwise
- warnBrokenSkills at startup logs skills whose name fell back to the
directory (the signature of broken frontmatter)
- fix skills/scopesentry/SKILL.md name line
Closes #39
2026-10-11 22:26:22 +02:00
BaaRai
d8f47d4359
Traffic ingest: capture operator browsing via a browser extension
...
Closes #33 . The MITM proxy only sees the agent's own actions, so
anything behind a human gate (signup captcha, email OTP, 2FA, SSO)
left the authenticated surface dark. The operator's browser becomes a
capture source instead:
- traffic: exported RecordExternal storing an externally captured
exchange through the same spill/blob/FTS path as proxy traffic
(insert logic shared with record()); rejects unparsable URLs and
empty methods
- server: POST /api/traffic/ingest inside the authenticated API group,
batch capped at 50 entries, bodies truncated at 256 KiB, per-entry
ingested/failed counts
- extension/: Manifest V3 Chrome/Edge extension driving the
chrome.debugger Network domain on the chosen tab, batching text
exchanges to the ingest endpoint with the operator's URL + JWT in
chrome.storage.local; binary bodies skipped; flush on batch/stop
- tests for both layers, README section
2026-10-11 14:53:08 +02:00
BaaRai
c177ab9d86
feat(tasks): per-task test-account credentials
...
Task credentials (#3 ): declare test accounts at task creation, and never
lose the accounts the agent registers on its own.
- task_credentials table (unique per task+domain+username; upsert
overwrites the password in place), idempotent schema migration
- POST /api/tasks accepts credentials; GET/POST/DELETE
/api/tasks/{id}/credentials serve the UI (manual add, e.g. relaying an
OTP-verified account; delete)
- empty password = the "agent generates" mode: the entry surfaces in the
worker's graph overview with an explicit instruction to register that
account with a strong password and record it
- new tools save_task_credential / list_task_credentials for worker and
pentest; the graph overview injects the task's credentials each round
with a standing note: reuse matching entries, always record accounts
you register
- New Task dialog: optional credentials section (domain, username,
password, note) with a dedicated-test-accounts hint
- task detail: Credentials tab, passwords masked with explicit
reveal/copy, agent-recorded badge, light polling so mid-run recordings
appear
One-shot binding migration (settings-flag-guarded, same pattern as the
other seeds) grants the two tools to worker+pentest on databases seeded
before this change; fresh DBs get them via WorkerTools()/the pentest
catalog.
Closes #3
2026-10-09 14:28:08 +02:00
BaaRai
e233c02314
Translate all Chinese text to English
...
Comments, doc comments, UI labels, log and error messages, LLM prompt
strings, markdown docs, test data and assertions. Identifiers, enum
keys, routes, placeholders and code structure are unchanged.
Notes:
- docs/漏洞流量证据.md renamed to docs/vulnerability-traffic-evidence.md
- tests that exercised CJK specific handling (GBK zip names, Chinese
full text search) now use ASCII equivalents; go build passes and the
test suite matches the pre translation baseline (remaining failures
need a PostgreSQL DSN and fail identically on the original)
- frontend mention syntax now uses English kinds (finding, asset, ...)
matching the backend, chat mentions tests pass
2026-10-08 23:14:34 +02:00
Autumn-27
8bc4d58c85
feat(intercept): 模型兜底审批单独计量 token 并在配置页展示
...
兜底审批(LLM judge)调模型判定漏网命令,其 token 消耗此前无法单独查看:
usage 行要么无 worker 归属、要么被并进复用的模型 profile 桶里。
- llmrec 增加 WithWorker 上下文覆盖,reviewer 调用前标注 worker='judge',
让审批调用的计量行可被单独筛出(复用现有 llm_usage.worker 列,无需迁移)。
- db.JudgeUsageStats 返回累计总量 + 近 N 天每日序列(WHERE worker='judge')。
- 新增 GET /api/intercept/judge/usage。
- 配置页「模型兜底审批」开关下方新增用量卡片:调用次数 / 输入 / 输出 /
缓存读写 五项统计 + 近 30 天每日消耗迷你柱图 + 刷新。
2026-10-04 02:43:26 -04:00
luckone and Claude Code
4eb5311998
feat(notify): 漏洞发现支持推送到钉钉/飞书/企业微信等六种渠道
...
新增「系统 → 通知推送」页,把扫描发现的漏洞推送到钉钉、飞书、企业微信、
通用 Webhook、Telegram、邮件。同一类型可配任意多个机器人实例,每个实例独立
设启停、限流与过滤规则(最低级别 / 任务资产范围 / 漏洞类型关键词 / 是否接收
处置状态变更)。推送时机分实时与汇总两种模式,「高危实时、其余汇总」建两个
渠道即可表达,策略不写死在代码里。带投递历史与失败重发。
三个关键设计:
1. 写漏洞的事务只做一次盲 INSERT。notification_events 由 RecordFindingTx
在同一事务内写入,保证「漏洞落库」与「推送任务存在」原子一致;这条 INSERT
刻意不读渠道表、不跑用户的过滤规则,否则一条配错的过滤条件就能污染甚至
中止事务,让高危漏洞存不进库。为把失败隔离在这一条语句上(PostgreSQL 中
事务内任一语句报错会让整个事务作废、连 COMMIT 都失败),它被 SAVEPOINT
包住,失败时只记日志。
2. 投递用租约领取而非长事务。FOR UPDATE SKIP LOCKED 领取后把行置为 sending、
把 next_attempt_at 推到未来作为租约,提交后再做网络投递,因此投递期间不
持有数据库锁;崩溃留下的 sending 行会被下一轮重新领取,自愈且不会无限重试。
3. 限流不消耗重试预算。先按渠道令牌桶算出本轮还能发几条,再按这个数量领取;
顺序反过来会让被限流挡下的投递白计一次尝试,三次预算被等待耗光后落入失败。
审计并修复的四个问题:
- 推送凭据经错误信息外泄:http.Client.Do 返回的 *url.Error 会把完整 URL 打进
错误文本,而钉钉 access_token、企业微信 key、飞书 hook id、Telegram
/bot<token>/ 都就在 URL 里。该串流入 last_error(明文落库)、投递历史接口
(绕过渠道掩码)、服务端日志与前端错误提示。现统一脱敏为 scheme://host
+ 底层原因,并拒绝跨主机重定向。
- 最低级别门槛打错字会让过滤器静默失效:未知级别序数为 0,判定退化成
rank >= 0 恒真,用户以为限制「仅高危」实际全推。现于写入路径校验取值。
- 汇总批次无上限:一次领取把全部待发行读进内存、消息被渠道长度上限截掉大半
且静默丢失。现单批上限 500 条,超出部分留库成为下一批。
- 邮件渠道把 SMTP 4xx(灰名单等临时失败)判成永久失败,导致这类最该重试的
场景从不重试。现按应答码首位区分 4xx/5xx。
测试:notify 包 82% 覆盖(含用自建最小 SMTP 服务器驱动的完整邮件协议会话、
两种签名算法对 OpenSSL 基准值的比对、UTF-8 边界截断、以及模板能力边界的
反射断言);db 与 server 侧共 29 个用例跑真实 PostgreSQL,其中端到端用例
真发 HTTP 到假接收端并断言消息内容与投递状态。
Co-Authored-By: Claude Code <noreply@anthropic.com >
2026-09-30 16:25:06 +08:00
Autumn-27
eb347d5965
feat(traffic): 流量列表新增「清空全部」,并借空库时机压实索引
...
一次删除全部流量记录,忽略当前筛选条件。与按 host 删除的两条路径相比多做
两件事:
- 清理索引已不再记录的历史 host 目录。按 host 删除只能从索引反查目录,
行已消失的孤立目录会一直留着;「清空全部」既然语义是不留残余,就直接
扫顶层目录(跳过 _index/_blobs/_ca/_delete_staging)。
- 收尾做一次全量压实(optimize + VACUUM + wal_checkpoint(TRUNCATE)),把
索引占用的磁盘空间还给系统,并把实际释放量返回给前端提示。
VACUUM 的耗时与临时空间只和它保留的内容成正比,所以空库是做全量压实唯一
免费的时机——也正因如此,这一步顺带成为已有实例的转换途径:auto_vacuum
只能通过 VACUUM 生效,清空一次之后旧库即转为增量回收模式,此后日常按
host 删除就能自行回收空间(TestDeleteAllConvertsLegacyIndex 覆盖)。
已绑定到漏洞的流量证据保存在独立的证据库中,不受影响——绑定时已拷出独立
副本,正是为了让热流量可以随时清空而不带走证据。确认弹窗里明确写了这点。
前端把「清空全部」做成 outline 样式而非第二个 destructive 按钮:它忽略一切
筛选条件,不该看起来和「删除该目标」只差一次误点;无流量时禁用。
测试:新增 TestDeleteAllPurgesAndCompacts(清空后索引、正文、blob 引用与
孤立目录全清,空间回收到 1/8 以下,清空后仍可继续录制)与
TestDeleteAllConvertsLegacyIndex(旧库经清空后转为增量回收,随后普通删除
即可回收)。
2026-09-30 02:50:49 -04:00
Autumn-27
6d8c50a12e
feat(traffic): 流量列表支持内容检索、路径/状态码/长度筛选与列排序 ( #177 )
...
- 后端 traffic.Page 改为 PageQuery:新增响应内容(FTS)、路径(url_template)、
状态码(精确/Nxx 分桶)、响应长度范围筛选,并支持按 ts/status/resp_len 排序
(尾随 id DESC 保证分页稳定);补 status/resp_len 两个索引(IF NOT EXISTS,旧库自动生效)
- server getTraffic 解析 body/path/status/resp_min/resp_max/sort/order 参数
- 前端流量页新增高级筛选行(响应内容/路径/状态码/长度范围)与可排序表头,
排序偏好持久化到 localStorage;抽出公共组件 ui/sortable-head
- 仅改动前端页走的 Page,不动 Agent 工具的 query 契约
2026-09-29 21:58:17 -04:00
Autumn-27
1a10c153b0
feat(tasks): 漏洞列改为按严重度分档显示 严/高/中/低
...
- TaskListMetricsAll 用 COUNT(*) FILTER 按 severity 分四档统计(同一条查询)
- TaskListMetrics.Findings 及 TaskDTO.findings 由数字改为 {critical,high,medium,low}
- 列表页「漏洞」列渲染 x/x/x/x,配色沿用 severity 语义、为 0 的档位弱化
- severity 为空/白名单外的记录不计入任一档;mock 同步为对象结构
2026-09-24 13:32:45 -04:00
Autumn-27
ee33f91bc1
feat(tasks): 任务列表新增漏洞数量列,描述/目标列收窄
...
- 任务列表接口 TaskListMetricsAll 批量统计每任务的漏洞数(findings 表,
按 task_id),经 TaskDTO.findings 下发;列表页新增「漏洞」列,>0 高亮
- 描述/目标列宽 max-w-xs → max-w-40,目标列补 title 悬浮全文
- mock data/handler 同步补 findings 字段
2026-09-24 13:26:22 -04:00
Autumn-27
bd1772c62f
feat: 资产拦截接入执行链,新增任务级拦截/允许规则
...
在 agent 下发意图(add_intent)与插入资产(insert_assets)两处接入资产闸门;
并新增任务级规则(拦截 block + 允许 allow 白名单),创建任务时录入、任务详情
总览里可编辑。
- 匹配/执行(db/asset_intercept_match.go):MatchAssetInterceptRules 纯匹配
(exact/fuzzy 的 域名·IP·URL + CIDR,URL host 会拆出归类);EvaluateAssetGate
「先拦截后允许」闸门——命中拦截即禁止;未命中但存在启用的允许规则且都不命中→
不允许测试;无启用允许规则则不启用白名单。附单元测试。
- 执行点:add_intent 命中即不下发意图;insert_assets 命中即跳过 Upsert 及
AddAutoScope 副作用。均合并 全局∪任务级 规则。
- 任务级规则:表 task_intercept_rules(task_id FK CASCADE + action block/allow,
幂等 ALTER 补旧库);db/task_intercept.go 提供 List/Split/CRUD/事务插入;
创建任务随 intercept_rules 提交;CRUD 路由 /api/tasks/{id}/intercept-rules。
- 前端:新建任务抽屉多行录入(拦截/允许 + 类型,用 NativeSelect 避免 Sheet 内
下拉 portal 导致误关抽屉);任务详情总览新增规则管理卡片(增删改+启用开关)。
2026-09-19 09:06:22 -04:00
Autumn-27
228674a2ce
feat: 新增资产拦截规则(全局黑名单)增删改查
...
新增独立于命令拦截(intercept_rules)的资产拦截功能,仅提供规则的
存储与管理;具体匹配/拦截逻辑另行实现。
- db: 新增 asset_intercept_rules 表(schema.sql,幂等)与 CRUD 层
(db/asset_intercept.go);kind 支持全等/模糊的 域名·IP·URL 及 CIDR
- db: 首启动 seed 内置模糊拦截政府(.gov/.gov.cn)与教育(.edu/.edu.cn)
网站,settings 标记位门控,可禁用/删除且重启不复活
- server: /api/asset-intercept/rules 的 list/create/update/delete/toggle;
cidr、exact_ip 做格式校验
- web: 新增「资产拦截」页(/system/intercept/assets)与侧边栏入口、
api 与类型定义
2026-09-19 07:58:23 -04:00
Autumn-27
6f295f48f8
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
0848eb6a0a
feat(web): 播报板节点详情展示上游节点信息与锚定资产
...
上游/下游节点从只显示 id 改为悬停弹出节点名片(类型/状态/来源/时间/摘要/payload);
展开时顺带展示该节点锚定的资产(类型标签 + 可辨识文本)。
服务端 /exploration/nodes 新增 assets 字段(节点id→资产),读 exploration_anchors
并复用发现列表的资产打标逻辑;同页节点互引时用本页 items 兜底 refs 查找表。
2026-09-17 11:23:53 -04:00
Autumn-27
6c6311ff63
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-27
79cd8d6d9d
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
b932888b49
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
RuoJi6
48b26be980
feat(chat): 支持多类型记录 @ 引用及滚动分页 ( #135 )
2026-09-16 22:36:07 +08:00
Autumn-27
a6515e6f0d
Merge branch 'feat/noa-experimental':noa 实验性上下文压缩
2026-09-15 12:09:24 -04:00
RuoJi6
eee40408ee
精简动作审查输入并支持审批来源定位 ( #125 )
...
* fix: 精简审查背景并区分人工消息与调度输入
* fix: 模型审查仅提交当前调用与选定背景
* feat: 审批来源定位原会话并移除 Worker 审查背景
2026-09-15 23:51:37 +08:00
Autumn-27
59ae1ebc8d
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
0cf50fa2ab
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
88198f3134
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
c4297854c6
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
b42ec8aeed
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
05de881812
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
8f4f54dbce
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
7604c763f5
Merge upstream/main into codex/btw-side-question
...
同步官方 main 的任务会话与 spawn_task 更新,保留 /btw 旁路上下文能力。
2026-09-11 08:47:57 +08:00
Autumn-27
98b0193a11
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
2954781cb7
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
f62f1cc1a4
Merge origin/main into codex/btw-side-question
...
合入 main 的 norma v0.3.7、会话分组与流量证据更新,保留 /btw 快照和输入布局。同步自动放行、关闭流量绑定的测试断言,并等待归档测试夹具的旁路后台退出。
2026-09-11 00:54:51 +08:00
Autumn-27
2d93f07ac8
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
028d9bd25c
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
e237d3c9f3
Merge PR #103 : feat: 支持会话级漏洞复测与运行状态展示
2026-09-10 10:02:39 -04:00
ji ruo
aacc303706
feat(agent): 支持持久化 /btw 旁路提问
2026-09-10 21:42:25 +08:00
ji ruo
1c77195e79
feat: 支持会话级漏洞复测与运行状态展示
2026-09-10 16:06:08 +08:00
ji ruo
009799e160
feat(intercept): 增加审批记录详情与执行审计
2026-09-10 15:10:50 +08:00
ji ruo
e820cfcb86
feat: 增加 Agent 流量绑定开关并补齐证据交接
2026-09-10 14:08:40 +08:00
ji ruo
e6f8195500
feat: 支持漏洞关联多条流量证据
2026-09-10 13:03:20 +08:00
Autumn-27
76bdf4c3d2
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
2faee6ed99
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
57fa1dba3a
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
12b63ab671
feat(llm): 每个 LLM 配置支持自定义会话头
...
新增 session_header_key:非空时每次 LLM 请求带上该 HTTP 头,头值为当前
运行的 session id(chat 会话=conv-<id>,worker=exp<x>-worker-i<intent>
等)。用于某些按 session-id 头做提示缓存/粘性路由的网关。
实现:在已有的 quotaAwareTransport 里从请求 context 读取 session id
(transcript.WithSessionID 挂上的)并注入,无需改 norma;同一共享 provider
也能按会话发出不同头值。DB 加 session_header_key 列(带旧库迁移),前端
LLM 配置弹窗新增输入框。
2026-09-07 11:21:50 -04:00
Autumn-27
87375979af
feat(proxy): 新增全局出口代理配置
...
所有目标流量可经统一的全局代理出网(http/https/socks5,支持 user:pass):
- 开启流量捕获时,作为 MITM 记录代理的上游(流量照录再经代理出网);
拦截与透传两条路径都走上游,不泄露源 IP。
- 关闭捕获时,直接注入 agent 的 bash 环境与 WebFetch;proxyEnv 增加
ALL_PROXY 以支持 socks5。
配置存于 settings KV 表(无需迁移),前端系统配置页新增「全局代理」卡片。
与网络搜索代理、LLM 代理相互独立。
2026-09-07 10:43:38 -04:00
Autumn-27
a0c17701c2
feat(llm): 模型配置新增输出上限,支持 max_completion_tokens 字段名
...
llm_profiles 加两列:max_tokens(单次回复输出上限,0=不发送该字段,由服务端
默认值决定)与 max_tokens_field(上限发哪个键)。后者仅对 format=openai 生效:
空(默认)= max_tokens;'max_completion_tokens' = 新键。OpenAI 推理模型
(o 系列/GPT-5)拒收 max_tokens、只认新键,而多数兼容网关反过来只认旧键,
故做成显式开关而非自动推断。anthropic 与 openai-responses 自带字段名,
存下来只会误导,保存时一并清空。
顺带补上一处从未接通的链路:planner/worker/chat/mainagent/goals 五个
agentcore.Options 都没设过 MaxTokens,恒为 0——openai 系因 omitempty 压根
不发上限,anthropic 走 norma 的 8192 兜底。光加配置项而不接这条线,用户在
后台填了数字也不会生效,故本次一并接通,取值与 streaming 一样按 profile
每轮解析,故障转移切换后下一轮即生效。
task_llm.go 里 nonStreaming() 的来源优先级(agent 绑定 → 任务链激活 profile
→ 全局)抽成共用的 activeCfg(),避免 maxTokens() 再抄一份同样的三级回退。
norma 升到 v0.3.3(该版本提供 Config.MaxTokensField)。go.mod 只动 norma 这
一行:仓库此前未 tidy 过,跑 go mod tidy 会顺带升 x/crypto、x/net 等一批无关
依赖,不混进本次改动。
迁移:新列走 ADD COLUMN IF NOT EXISTS + 默认 0/'',旧库升级后行为完全不变;
CHECK 约束限定取值,每次启动先删后建保持幂等。
2026-08-31 12:20:31 -04:00
Autumn-27
1f90ba13e7
feat(findings): 发现页新增「按资产」视图
...
左侧资产树 + 右侧该子树下的发现,与另外两个视图共用同一张表和同一批筛选。
后端
- db/finding_assets.go:按当前筛选构建资产树。只收有发现的资产,祖先链逐层
补齐(endpoint→service→subdomain/ip→root_domain),父子优先级与
BuildCoverageGraph 同源;计数沿祖先链去重累加,一条发现挂多个资产不会让
父节点重复计数
- FindingFilter 加 AssetScope:选中节点=选中整棵子树,解析成资产 id 集合后
下推 SQL,列表 / 分组 / 导出三个入口共用,导出「当前筛选」自动带上
- 「未关联资产」同时收 asset_ids 为空与指向已删资产的发现,与树上桶的口径
一致(只判空数组会让桶上的数字大于点开后的条数)
- findingFilterFromQuery 统一四处的筛选解析;新增 GIN 索引
idx_findings_asset_ids,按资产反查发现不再全表扫
前端
- 树默认展开一层,支持过滤(匹配项自动展开)、面包屑下钻、手动刷新
- 每层只显示相对上一层的增量:子域名去根域名后缀、服务显示 `https :443`、
接口只留路径。完整值在 title 与面包屑,搜索仍按完整值匹配
- 不轮询:进入视图 / 改筛选 / 页内改动发现 / 点刷新时才查
- 节点超上限时整层丢弃接口/服务并提示,计数已在上层不会丢
2026-08-31 10:58:32 -04:00
Autumn-27
cc7c56f138
feat(llm): 任务 LLM 配置链改为任何状态都可修改
...
任务结束(done/failed/timeout)后主 Agent 对话仍走任务配置链,链上模型出问题时
既不能改配置链、也就没法继续交互。去掉 HTTP 与 DB 事务两处终态拦截,前端弹窗
对终态任务同样开放编辑与保存(顺带修掉 queued 状态也不能编辑的口子)。
终态任务保存时不再重开额度阻塞意图:那些意图会从 blocked 挪到 open,既没有
worker 执行、也不再满足「重跑意图」的可重跑条件,反而变成死状态。终态任务想
继续跑仍走重跑意图/新增目标,由它们把任务重新 admit 回运行态。
2026-08-31 09:26:33 -04:00
Autumn-27
54eba57c0a
重构 worker 对话:复用 resume 机制,改专属 goroutine 运行
...
把「给运行中 Worker 发消息调方向」从自建的介入持久化协议,改为复用
已有的暂停/恢复 + transcript resume 能力,实现与主 Agent chat 一致。
- 拆 runWorkerStep:抽出 runIntent(执行+善后),池子与消息路径共用一份
善后逻辑;新增 runDetachedIntent,把意图 paused→running(不经 frontier)
并在专属 goroutine 里直接跑,用户消息不受 3 槽池限制、随发随跑。
- 精简 sendWorkerMessage handler:校验 + emit 用户活动 + 专属运行;消息经
ExecuteWithMessage 作为下一轮输入注入,request_id 仅做 transcript 去重。
- 删除介入 DB 协议与 15 处 activity 查询过滤(回退 exploration.go)、
directedClaims 调度屏障、RecoverWorkerMessages 恢复、workerWake/waitWorker、
AbortWorkIntervenedByUser。无 DB schema 改动。
- 前端:保留消息框,恢复「直接继续」(resume)按钮;发送改由 SSE 承载,
去掉乐观插入。
- 取舍(低频可接受):消息仅存内存,不做崩溃恢复;发消息时该任务可能瞬时
超并发 1 个 worker。
净改动 9 文件 +583/-46(原 PR 15 文件 +1940/-72)。
2026-08-31 09:00:21 -04:00
pphua
e22c34f893
新增worker直接对话
2026-08-29 21:55:27 +08:00
pphua
fa7b3cd4ec
merge: sync official main into PR branch
2026-08-28 14:14:41 +08:00