Skip to content

[整理] 静态审计 backlog 跟踪(探索 lane 剩余项) #2154

Description

@DeliciousBuding

[整理] 静态审计 backlog 跟踪(探索 lane 剩余项)——持续消化中

只读探索 lane 的全部可执行项汇总与处置状态。已消化:hub/edge/frontend/docs/mobile/contract(前 6 份报告)。

新探索 lane(2026-09-01:性能·并发 / 数据库·网络 / UIUX·产品,3 份报告)

已修复(本轮)

待消化(按优先级)

新取证前端遗留候选(2026-09-02,round-38 探索 Copernicus)

并发探索 lane(2026-09-02,第 4 份报告,Wegener)

edge/hub 并发路径锁面全量扫描;唯一 P1 级数据竞争已修,其余为资源回收与残留无锁读。

待消化(并发)

  • P1 orchestrator Adapter parentModel 共享字段竞态orchestrator.go:41 字段 + BuildCommand 无锁写 :119-121 + ParseStream 无锁读 :147;单 Adapter 服务多并发 run → 数据竞争 + 子代理继承错误父模型)→ fix(orchestrator): parentModel 改走 per-run context,消除共享态数据竞争 #2193(594d701):字段删除改 per-run context 注入(CtxModelKey,仿 CtxBudgetKey 同族);修复前 -race 复现 DATA RACE 留证,修复后干净
  • P2 SubAgentResultCollector 三个 map 永不清理(subagent_collector.go:83-85,全仓无一处 delete)→ 方案:result_aggregator.go:262-286 聚合完成两出口调用 Release(parentID)
  • P2 hub 侧 6 处无锁读 Conn 身份字段(fix(ws/cache): fanout 日志锁保护 + rate-limit INCR/EXPIRE 原子化 + 0069 迁移幂等 #2162 残留:agentcontrol/service.go:69agent/dispatch_adapters.go:31-33dispatchsvc/agent_dispatch.go:261,498agent_dispatch_target_bound.go:38app/events.go:554)→ 方案:扩 Conn.Auth() getter 覆盖
  • P3 agents.Queue run 终止后 channel 不回收
  • P3 Registry 终态 agent 实例不清除(registry 单调增长)
  • P3 Cancel 二次调用孤儿化 grace goroutine(process_executor_cancel.go:46-48,一行幂等判断可修)
  • P3 hub callback 消费者死亡 → 终态入队永久阻塞(process_executor_hub_callback.go:290-301

数据库探索 lane(2026-09-03,第 7 份报告,Ampere)

hub GORM/PG + edge SQLite 全量审计(已避开 #2176/#2178/#2181/#2182/#2179 等已修项)。

待消化(数据库)

  • P2 孤儿恢复 claim-before-redeliver → fix(dispatch): 孤儿恢复重建失败回滚认领,消除任务滞留 dispatched 静默丢失 #2198repository.RequeueClaimedOrphanTask 条件 CAS 回滚 dispatched→queued + 三处重建失败路径接入 + orphan_claim_rolled_back_total 指标;单测含缺陷回归「重建失败→回滚→下轮可重新认领」+ 真 PG16 集成 2 项;已流转任务绝不误改)
  • P2 refresh token 轮换非原子fix(auth): refresh 原子轮换 + 0072 唯一约束 + CI 退出码门禁(#2154 三连) #2197:条件写原子认领(UPDATE … WHERE token_hash=? AND revoked=false,输家计入复用指标);真 PG 并发测试修复前 4/8 双花、修复后恰 1 赢家。连带揭出并修复:0015 索引非唯一致 upsert 42P10(0072 迁移补唯一约束)
  • P2 notifications 全量列表无排序索引 + 无保留清理 → perf(notifications): 全量列表排序索引 + 已读保留清理(#2154 Ampere P2-3) #2199(0073 迁移补 (user_id, created_at DESC) 索引:0013 复合索引 read 夹中致全量列表吃不到索引序,EXPLAIN 实证内存 quicksort+OFFSET;90 天窗口清已读、未读绝不触碰,PurgeReadNotifications 单条 DELETE + 24h 后台循环 + 3 指标;0073 真机事务内 up×2+down 幂等验证后回滚不留痕)
  • P3 五张小表裸 ILIKE 繁殖(perf(messagesearch): pg_trgm GIN 索引让消息搜索 ILIKE 分支可用索引 #2178 修掉的模式):document/agent_profile/mcp_server/skill/workspace。方案:documents 复用 0071 pg_trgm 模板 + migration_audit 守卫
  • P3 ReviewDagPlan 无锁 check-then-act 双决策竞态(agentteam/agent_team_review.go:34,61,72,84,无 CAS;相邻已有 UpdateTeamRunStatusIfNotTerminal 原型)。方案:单条 UPDATE … WHERE status='pending_review' CAS
  • P3 GenerateCompeteSummary 循环内逐条查 team task N+1(agent_team_compete.go:281)。方案:IN 批量(索引已就位)
  • P3 message_reads 死表(0007):全仓零引用、0 行,读回执走 session_members.last_read_seq。方案:DROP 迁移或注释标注替代物
  • P3 热表索引迁移从不 CONCURRENTLY(golang-migrate 单事务结构限制,71 个迁移零命中;0071 上生产即 SHARE 锁阻塞写)。方案:runbook 钉 NOT VALID+VALIDATE 两段式 + migration_audit 标注检查

安全二轮探索 lane(2026-09-03,第 8 份报告,Lorentz)

hub 认证/授权面二轮审计。核查无新发现区域(均已开码确认):路由鉴权矩阵成对无缺口、无 cookie 纯 Bearer+CORS 白名单、OIDC PKCE/state/redirect_uri 合规、ID token 算法双层钉死、HS256 弱密钥启动拒绝、admin loopback-only、跨资源越权面全校验到位。

待消化(安全二轮)

  • P2 refresh 轮换 check-then-write 非原子fix(auth): refresh 原子轮换 + 0072 唯一约束 + CI 退出码门禁(#2154 三连) #2197(与数据库 lane P2-2 同根因合并消化):原子认领后输家按复用拒绝并计入 refresh_token_reuse_total,F2 信号成为可靠检测点
  • P3 logout 吊销范围由客户端可控 ?device_type= 决定,传错 → 黑名单键与 refresh 检查键不匹配,并发窗口可复活会话(handler/auth.go:60)。方案:作用域改从 JWT claim 派生
  • P3 device UUID 全局主键 + OIDC 路径 ErrDeviceOwnershipMismatch 落到 500(对比 /edge 路径映射 400)→ 抢注他人 device_id 可致登录 DoS 且不可诊断(oidc.go:209-215)。方案:映射显式错误码
  • P3 logout 只黑名单当前 access jti,同设备兄弟 access token 存活至自然过期(≤15min)。方案:SECURITY.md 登记已接受残余或引入世代键
  • P3 unknown-kid bearer 每次强制同步重取 JWKS → 对 ID 端点的放大器(jwtutil/tokendance.go:236-246)。方案:强制刷新最小间隔 + 负缓存
  • P3 refresh 滑动续期无绝对寿命上限(service.go:125oidc.go:232,CreatedAt 每次重置)。方案:保留初始签发时间 + 硬上限强制重登

round-56 双探索新 lane(2026-09-02:前端质量二轮 Averroes + 错误处理/日志诚实 Epicurus)

文档卫生(Turing)→ 已全部消化于 #2202(2026-09-02 合并)

  • 11 项全部落地:web/desktop README Source Map 重写、ADR-021 撞车改 ADR-027、Card/Pill 死引用清除、events.md owner 路径、协议映射文件名+去行号锚、02-edge-server 双路径、ui-core Toast 测试名、05-deployment 指向 v0.6.1、空壳节合并、过期 marker 批量更新
  • 遗留(非本批):孤儿 app/shared/src/ui/Pill.module.css(代码文件)、CHANGELOG.md:42 ADR-021 疑应 ADR-023

前端质量二轮(Averroes)——desktop 死代码富矿,清理优先

  • P1 Hub↔Edge 集成桥绕过统一 edgeClient:desktop/src/hooks/hubIntegrationEdgeApi.ts 手写 fetch + 重复 edgeRequestInit,错过 edgeClient 的 401 刷新重试/信封解包(createThread/startRun/cancelRun/decidePermission 已有)。方案:桥接改调 edgeClient,删重复 init
  • P2 desktop 遗留 chat/run 管线死代码簇 → chore(desktop): 删除 desktop 死代码(useSendRun 簇/死钩子/config 死常量)(#2154) #2205(42 文件 -5209 行:useSendRun 簇 18+13、死钩子 agentTeam 14/session 19/projectQueries 整文件/thread 5/useMention、config.ts 6 死常量、连带 4 个死 i18n 键;tsc x3 + vitest 437x2 + test:ci 四分区全绿)
  • P2 agentTeamQueries 16 钩子死 14 / sessionQueries 28 死 19 / projectQueries 整文件死 / threadQueries 10 死 5 / useMention 整 hook 死(350+246 行)
  • P3 config.ts 死常量与文件内重复逻辑;web/workbench「测试孤岛」导出;shared 小件死导出;mobile-rn 已实现未接线桥接面(Android 通知渠道疑功能缺口);desktop/mobile-rn 未用依赖
  • 零发现:生产代码 as any/@ts-ignore 0 处;陈旧 TODO 0 处(3 条均带 issue 有意延期)

错误处理/日志诚实(Epicurus)

  • P1 Gin 错误路径系统性静默 500:handler/response.go:29 Fail() 丢原始 err 且不打日志,160 处调用 157 处前后无 slog → 非 errcode 型 500 全不可排障。方案:FailErr(c, err) 带日志变体 + 逐步替换
  • P2 hub-relay live-push 后 markDeliverySent 裸吞错(agent_dispatch.go:321)→ outbox 重试可致双发且无痕。方案:改用已带 Warn 的 markDeliverySentPlan(S)
  • P2 edge TokenProvider refresh 失败零日志零指标(token_provider.go:189-214,LastError 无消费者)。方案:失败采样 Warn + 挂 /health(S)
  • P2 edge orchestrator 并行 dispatch worker 无 recover(orchestrator_dispatch_interceptor.go:177-182)→ panic 击穿整进程。方案:接 pkg/safego(S)
  • P2 hub 高频/后台 goroutine 批量无 recover(app/events.go:452-460,654、orphan_recovery、outbox、notification retention、ws manager pingAll)(M)
  • P2 团队 run 触发失败后回写 Failed 被吞(agent_team_run.go:78-82)(S)
  • P3 五项:run 失败事件只打 Debug(默认级别不可见)/ deploy 软失败仍报 "deployed" 假成功 / eventlog Seek 回 EOF 被吞 / WS 畸形帧静默丢弃+断连日志措辞误导 / 会话成员缓存失效被吞(踢出成员最长 5min 仍收推送)+ WS 路由回调吞 Redis 错误(误删新连接路由风险)
  • 零发现:空 if err != nil {} 块 0;成功路径打 Error 0;errcheck 22 处全为清理类 defer

网络韧性与超时卫生 lane(2026-09-02,Maxwell,第 9 份报告)

出站调用全有 Timeout+ctx、连接零泄漏、无界缓冲零发现、TLS 零发现、context 断链零发现(含排除项核读)。以下为剩余 8 项。

  • P2 edge deploy ssh/scp 子进程无超时:deploy.go:298-312exec.Command().Run() 无 ctx 无 -o ConnectTimeout/BatchMode;restTimeoutMiddleware 30s 只保客户端响应,handler goroutine+子进程继续跑到内核 TCP 重传上限 → 泄漏累积。方案:CommandContext 30-60s + ssh 硬化参数(S)
  • P2 上传 30s 超时被全局 15s Timeout 中间件吞掉:router.go:33+165 全局 Timeout(15s) 先包,attachments 组的 Timeout(30s) 派生自已带 15s deadline 的 ctx → 有效 15s,UploadRequestTimeout 形同虚设(S)
  • P2 附件下载被缓冲式 timeoutWriter 整体吃进内存 + 硬 15s 截断:middleware/timeout.go:24-58,WS 升级已有豁免先例而下载没有(S)
  • P3 出站客户端共用 DefaultTransport(MaxIdleConnsPerHost=2)连接 churn:outboundhttp.go:44-52edgehttp.go:20-31、egress 同病;Edge→Hub callback 热路径(sem=10)突发必重建 TCP+TLS。方案:Clone DefaultTransport 设 per-host 32(S)
  • P3 edge 事件 WS 写循环无写截止时间,僵尸对端拖连接 ~15min:handlers_events.go:138-176;hub 侧同型已有 10s deadline 先例(S)
  • P3 SDK 适配器 429 重试忽略 Retry-After:anthropic_sdk_request.go:70-75/openai 同款;同仓 callback.go:418-426 已有尊重 Retry-After 原型(S)
  • P3 S3 附件客户端无显式 HTTP 超时(当前巧合有界,未来后台任务拿 background ctx 即无限挂):s3_client.go:28-39(S)
  • P3 上传尺寸上限矛盾:全局 BodyLimit 10MB 盖过 attachments 配置的 20/50MB → 实际封顶 10MB(与上两条一并整改:组级 BodyLimit+Timeout)(S)

网络韧性探索 lane(2026-09-02,第 5 份报告,Fermat)

服务端主干已多轮硬化,核心链路无 P1;问题集中在客户端转发跳板、移动端与 token 轮换边缘条件。

待消化(网络)

  • P2 desktop→edge 全部 fetch 无超时(useHubIntegration.ts:386-392,443-449hubIntegrationEdgeApi.ts:16-31,37-55edgeClient.ts:123-139 全文件 0 个 AbortController)→ edge 挂死时任务静默卡死进死信。方案:4 个 fetch 加 AbortSignal.timeout(10s),既有 catch→failTask 自动闭合
  • P2 edge token 轮换固定 30s 无抖动重试(token_provider.go:57,126-131)+ 响应丢失后旧 token 已吊销 → 永久 401 锁死。方案:指数退避+±25% 抖动(复用 callback.go 模式);锁死根治(宽限/重新供凭据)为后续
  • P3 desktop 转发丢 delivery_idhubIntegrationMappers.ts:289 附近),[网络] WS 帧/重连契约审计(seq/重放/去重全量核对) #2101 G2 去重在 WS 通道绕过(有 hubTaskId 兜底层)。方案:加一行转发 + 处理 202 {deduplicated:true}推荐候选
  • P3 mobile-rn 重连风暴(hubLifecycle.ts:73-79 断线零延迟重连,无退避无上限;未上线,上线前必修)
  • P3 mobile-rn since 游标死参数(hubClient.ts:369-371 拼进 /client/ws 但 hub 从不消费;seq_id per-connection 语义错误)
  • P3 edge HTTP ReadTimeout=15s 与 REST 中间件 30s 预算矛盾(httpserver/server.go:76,173
  • P3 transport 离线队列 queueHeadAt 不随 localStorage 持久化 → 重启后 TTL 失效(transport.ts:313-323,164,184-186

CX/产品探索 lane(2026-09-02,第 6 份报告,Sagan)

五端按钮/可点元素全量 AST 扫描 + props 链路追踪;以下均为新发现死交互/不诚实内容。

待消化(CX)

  • P2 Tasks「更多」菜单 3 项全死(pages/tasks/shared.tsx:100,104,108 无 onClick,菜单也不关)。方案:删菜单或 comingSoon 置灰
  • P2 项目 Archive tab 伪造 2 个「归档包」文件且点击无反应(ProjectTabViews.tsx:131-140,与真产物行同样式)。方案:整段隐藏或 comingSoon
  • P2 联系人页组织行「管理」死按钮(ContactNav.tsx:63-65,双端常驻)
  • P2 Tasks real 模式「新建分组」死按钮 → fix(workbench): Tasks 新建分组按钮补门禁 + Settings 齿轮死按钮删除(死按钮批 1) #2192(b50a97c):{onNewGroup && ...} 门禁(对齐 onCreateTask 模式)+ TasksPage 2 条门禁断言
  • P3 设置页头部「更多」齿轮死按钮 → fix(workbench): Tasks 新建分组按钮补门禁 + Settings 齿轮死按钮删除(死按钮批 1) #2192(b50a97c):按钮 + 孤儿 aria.settingsMore key(zh/en)+ .iconAction 死样式一并删除
  • P3 SettingPath 复制按钮缺 onCopy 门禁(settings/shared.tsx:205-223;SettingValue 有同款防御注释,SettingPath 漏了)
  • P3 Agents ops 演示行 <button> 语义误用无动作(AgentOpsItemParts.tsx:40,94,270)。方案:改 <div>
  • P3 mobile-rn 死 Pressable 批(预览舱内:恢复横幅「重试」无 onPress 等;有 Demo 横幅缓解)

CI 完整性 lane(2026-09-03,round-52 实施中揭出,全部已修 → #2197

  • 后端 4 个测试 lane 退出码黑洞go test | tee 吞退出码(GHA 默认 shell 无 pipefail)+ 只数 PASS 行 → 集成 lane 带病绿数月。修复:显式 PIPESTATUS[0] 门禁
  • TestMigration0016DownRoundTrip 共享库连锁破坏:恢复与 m.Close() 竞顺序(defers 先于 Cleanup),共享集成库被困旧 schema,其后全部测试连锁失败。修复:测试改临时库(全量迁移→round-trip→DROP)
  • 0016.down 从未成功执行:占位 INSERT INTO devices(id) 必撞 user_id NOT NULL(PG 先 NOT NULL 检查后 ON CONFLICT 仲裁)。修复:占位补全 NOT NULL 列
  • TestSearchSessions 陈旧:搜索 API 已迁移 {items,page} 信封,裸数组反序列化静默失败。修复:信封解析 + 显式错误
  • TestAuthExpired* 两处 -1s TTL 落 30s leeway 内([可靠性] 时间/TTL 纪律审计(过期边界/时钟一致性/窗口矛盾) #2135 F1 设计),测的是接受非拒绝。修复:-2min
  • 已知本机环境差异(非缺陷):TestOIDCAuthorize_ReturnsAuthURL 本机加载真实 ID 配置缺客户端参数失败,CI 占位配置通过(历史日志证实)

早期 backlog(已完成,证据)

不适用/拒绝

安全探索 lane(2026-09-01,第 4 份报告)

已修复(本轮)

待消化(安全)

  • F1 P2 Redis 黑名单故障 fail-open 默认值——已取证(round-38):代码默认 AuthFailClosedDefault=false(constants.go:138-145),但生产 compose 模板已硬编码 true + 启动门禁强制显式设置;本机 start.sh 未设该变量 → dev 原生 hub 实际走 fail-open。翻默认:生产零变化,自托管裸跑全变,需翻 4 处钉默认测试 + SECURITY.md(AH-SR-052)/05-deployment 文档。决策:是否翻默认
  • F6 P2 OIDC authorize 缺 nonce(ID token 断言)
  • F3 P3 hub KeyManager 轮换完全 dormant(Sign* 零生产调用)——接线或删除,防误导
  • F14 P3 relay device-ack 走 web 产品会话 + body 自报设备——改 edge/admin 鉴权(需桌面端联动)
  • F16 P3 CloudEdgeRegister 频率限流 → fix(router): CloudEdgeRegister 接入频率限流,复用 AuthRegisterRateLimit 死常量 #2185(958d662):路由接线 middleware.RateLimitAuthRegisterRateLimit=3/min、IP 维度,死常量复活)+ 全链路路由测试 TestCloudEdgeRegisterRateLimitedByIP(前 3 次 200/第 4 次 429+Retry-After/换 IP 恢复);hub 已重建重启健康。后续项①②已消化 → fix(device): 设备注册频率限流补齐 + cloud_edge 每用户数量上限 #2191(8ce4d9b):/edge/devices/register IP 频率限流同型接线 + 每用户 cloud_edge 数量上限(新错误码 device_limit_exceeded);③本机 gosec 版本漂移致 verify-hub-lint-ratchet.py 本地误报 2 条 jwtutil G101(CI 绿,与代码无关)
  • F2 P3 refresh 复用信号(第①步)→ feat(auth): refresh token revoked 行复用信号(日志+指标) #2188(e070b26):revoked 行复用 Warn 日志 + refresh_token_reuse_total 指标,hub 已重建。遗留:第②步级联吊销属行为变更待决策;真 theft signal 需保留已轮换 hash(超最小方案,决策记录)
  • F18 P3 panic 堆栈入日志(固有风险,记录即可)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions