关于 work-sweep
work-sweep 是用于代码和系统多角度发现的 Agent 技能。它并行运行互不知情的搜索,在全部完成后统一去重、验证发现并指出覆盖缺口。
主要功能
- 01按不同角度并行盲搜
- 02通过屏障汇总结果
- 03基于持久 seen 集合去重
- 04验证新发现
- 05识别覆盖缺口
适用场景
- 01发现单一搜索策略遗漏的问题
- 02审查安全与数据暴露风险
- 03从不同维度探索代码库
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ djalmajr/ skills --skill work-sweep安装后在 Claude Code 中输入/work-sweep确认已加载。
详细介绍
/work-sweep — 多角度盲搜
实现 多模态扫描模式。
编排结构:并行执行,在合并处设置屏障
此技能采用 并行扇出 → 在去重/合并步骤设置屏障。请参阅 ../work/references/workflow-mode.md §1 中的三种结构。
- **扇出是并行的:**N 个盲搜器同时运行,每个对应一个角度,彼此完全独立。搜索器之间没有屏障。
- 合并处是一个真正的屏障:必须等待所有搜索器完成,因为去重和完整性检查是跨条目操作——“通过两条路径发现的同一问题只计一次”和“哪些内容没有被任何角度覆盖?”只有等所有角度都报告后才能计算。这正是设置屏障的跨条目依赖(workflow-mode §1:对完整结果集进行去重/合并)。这不是为了方便而设置的屏障:跨角度比较确实需要完整的结果集。
- **屏障只是简单的集合逻辑,不是 Agent 调用。**去重和完整性检查在编排器自己的上下文中针对
seen集合运行;绝不要为了“合并”而启动子 Agent。
某个角度失败时,不会阻碍屏障解除:将其过滤掉,基于剩余角度重新计算覆盖情况,并记录这次剔除(参见执行机制 → 空值处理)。
当此扫描是 work-exhaust 的一轮时,屏障的输出(新发现的问题和更新后的 seen 集合)会馈入下一轮;循环结构位于 ../work-exhaust/SKILL.md 中,而此技能负责每轮的扇出和屏障。
适用场景
- 单一搜索策略(grep 一个词、读取几个文件、让一个 Agent “查找问题”)会漏掉重要情况。
- 系统的不同模态(代码结构、运行时行为、历史变更、数据实体、用户旅程、错误状态)会揭示不同的问题。
- 你希望全面覆盖,同时避免搜索器相互影响(在本轮中,它们彼此保持盲态)。
通常与 work-exhaust 结合使用,以重复执行多轮扫描。
用法
/work-sweep "what to discover" [angles=...]
示例:
/work-sweep "可能影响作业 SLA 或状态可见性的地方"/work-sweep "注册流程中的安全和数据暴露风险" angles="authz,storage,logging,public-endpoints,third-party-calls"
编排器会在 Research 和早期 Review 阶段大量使用此技能。
工作原理
-
定义模态/角度
- 如果未提供,则使用以下默认集合:
- 结构:文件布局、模块、入口点
- 内容/语义:关键词、模式、业务规则
- 历史:git blame、近期变更、重构
- 实体/数据流:特定领域对象,如 Order、Stage、Draft
- 错误/失败路径
- 用户/外部接口路径
- 或接受调用方提供的明确角度。
- 如果未提供,则使用以下默认集合:
-
启动盲态并行搜索器
- 每个角度启动一个子 Agent。
- 每个子 Agent 只接收高层目标和自己的角度说明。
- 明确告知:“本轮中你看不到其他角度的结果。只从你的视角进行搜索。”
- 它们可以使用所有可用工具(grep、read、终端等),但须保持在各自的模态范围内。
-
屏障 — 收集并与持久化的 SEEN 集合去重(L4)
- 等待每个搜索者(或其被过滤掉的失败项)完成后再合并。
- 维护一个以稳定标识为键的持久化
seen集合(由规范化后的locations[]和 claim 的 slug 组成),在各轮之间持续保留,并且恢复时绝不重置 (它是日志的唯一事实来源)。 - 对于每个候选发现:仅当其键不在
seen中时才报告。 如果某项发现与seen中已有的键匹配——包括此前某轮已拒绝的项——则不再报告; 将其作为重复项丢弃。 - 返回更新后的集合
seen ∪ new,以及真正新增的发现列表。 如果对幸存项而非seen去重,被拒绝的项就会每轮重新出现,导致work-exhaust永远无法收敛;对seen去重才能让循环逐渐收敛。 - 为每项新发现标注发现它的角度(来源信息是有价值的信号:由两个独立角度发现的 同一项,可信度更高)。
-
验证关卡 — 不是礼节性检查,而是真正的关卡(L1、L2、L8) 对此技能输出前的每项新发现:
- L1 — 优先使用直接判定依据。 如果存在确定性判定依据(测试、类型检查、精确
grep+ 手动确认、git、运行应用),在相信该发现前先运行它。存在可用但尚未 运行的判定依据时,该发现应标为needs_review,绝不能标为confirmed。优先相信 判定依据,而不是任何 Agent 的说法。 - L2 — 重新打开并检查当前源代码中的每个
locations[]条目。 绝不直接接受搜索者 引用的evidence。如果重新读取时发现项的locations[]无法对应(行已移动、代码 已删除、找不到引用内容),则将其标为needs_review——绝不能悄悄保留 (它可能是真的,只是已过时),也绝不能悄悄丢弃(它可能是搜索者引用错误的 真实漏洞)。记录你重新读取的内容到reReadSources。 - L8 — 只有实际完成核查,驳回才算数。 因为“没问题/已经处理”而将某项发现降级
为
dropped,只有在该判断重新读取了代码并提供file:line证据时才有效 (workDone: true,reReadSources非空)。草率驳回属于弃答:该发现仍保持needs_review,并进入下一轮。一条有充分证据的反驳胜过两条空泛的“看起来没问题”。 - 将幸存的安全、身份验证/授权、多租户和数据完整性问题交给
../work-refute/SKILL.md,进行多元视角的反驳(L3 在那里, 不在这里)。
- L1 — 优先使用直接判定依据。 如果存在确定性判定依据(测试、类型检查、精确
-
完整性 — 哪些内容没有被任何角度覆盖?(L5) 合并后,不要止步于“这是我们发现的内容”。最有价值的一步是指出哪些内容 从未检查过:
- 列出
completenessGaps[]:不在任何角度覆盖范围内的模块/文件;没有任何角度 涉及的模式(例如,没有角度检查存储路径、配置/realm 维度、下游使用方、异步/ 作业路径或公共端点)。 - 至少运行一个全局判定依据,以发现角度列表之外的问题——对整个代码库执行核心
实体的
grep,或进行范围覆盖差异检查(角度检查过的文件与提及目标的文件之间的 差异)。这是发现隐藏在所有人视野之外的孤立代码路径的低成本办法。 - 将
completenessGaps[]交给../work-gaps/SKILL.md和/或将其作为下一轮work-exhaust的新角度。
- 列出
-
输出
- 结构化的
SweepResult(见下方契约):带来源信息的唯一新增发现、更新后的seen集合、completenessGaps[],以及dropped[](失败的角度 + 去重/驳回的发现, 每项都须说明原因——不得静默设限,L7)。 - 关于检查不足或成本较高的模式的备注。
- 对下一轮的建议(采用不同角度,或交由
work-exhaust处理)。
- 结构化的
结构化 I/O 契约
自由格式的严重程度字符串会破坏校准(L6),因此严重程度是基于已验证影响标准的枚举,验证状态则是由门控设置的枚举。请参阅
../work/references/workflow-mode.md §4 中的架构约定。
每个盲搜者都返回(在回复末尾附上一个 fenced ```json block):
{
"angle": "alternative-storage-path",
"findings": [
{
"title": "storage tenant derived from ?hostname, not session",
"description": "Orphan code path: the storage layer re-resolves the tenant from a request query param after auth, bypassing the session-bound tenant.",
"locations": ["src/storage/resolve.ts:88"],
"evidence": "resolve.ts:88 — `const tenant = req.query.hostname ?? session.tenant` (query wins)",
"severity": "high"
}
]
}
搜索者发现问题时的字段规则:
locations— 必填的file:line数组,不得为空(门控会重新打开每个条目)。evidence— 一段简短引文,调用方可在该位置重新找到。severity— 枚举critical | high | medium | low(搜索者的初步判断;门控可能重新校准)。标准(L6,双向):- critical / high — 确实可触达 + 造成损害 + 当前未覆盖,并提供可触达性论证。绝不能将推测性缺口判为
high。 - medium — 有一定可能但未经验证,或没有可用的判定依据。
- low — 仅影响外观、仅在开发时出现,或已得到缓解。绝不能将已证明可利用的问题判为
low。
- critical / high — 确实可触达 + 造成损害 + 当前未覆盖,并提供可触达性论证。绝不能将推测性缺口判为
该技能负责合并和门控,并返回一个 SweepResult:
{
"goal": "multi-tenant isolation risks in the upload flow",
"anglesUsed": ["forgery", "config-realm", "alternative-storage-path", "error-paths"],
"round": 1,
"findings": [
{
"id": "storage-hostname-override",
"title": "storage tenant derived from ?hostname, not session",
"description": "...",
"angles": ["alternative-storage-path"],
"locations": ["src/storage/resolve.ts:88"],
"evidence": "resolve.ts:88 — query param wins over session tenant",
"reReadSources": ["src/storage/resolve.ts:88"],
"severity": "high",
"status": "confirmed",
"workDone": true,
"oracle": "grep '\\?\\.hostname' src/ + manual re-read of resolve.ts"
}
],
"seen": ["storage-hostname-override", "auth-issuer-check", "..."],
"completenessGaps": [
"No angle traced the async thumbnail-worker path (jobs/thumbnail.ts) — same tenant resolution may be duplicated there.",
"config/realm dimension only checked for the primary realm; secondary realms untested."
],
"dropped": [
{ "kind": "angle", "ref": "git-history", "reason": "sub-agent returned empty after one retry; coverage recomputed over 4 surviving angles" },
{ "kind": "finding", "ref": "logging-pii", "reason": "duplicate of seen 'pii-in-access-log' from round 0" },
{ "kind": "finding", "ref": "csrf-upload", "reason": "dismissed — re-read route, CSRF token enforced at middleware.ts:40 (workDone:true)" }
]
}
枚举和必需的门控字段:
status— 枚举confirmed | needs_review | dropped。confirmed— 重新阅读已通过且已运行任何可用的判定依据(L1、L2)。needs_review— 重新阅读未通过,或存在判定依据但未运行,或驳回未通过 L8 工作测试。绝不能悄悄保留或悄悄丢弃——应将其暂存于此。dropped— 重复项(已在seen中)或有证据支持的驳回(workDone:true,reReadSources非空)。每个丢弃项也都必须包含在dropped[]中,并附上reason。
severity— 与上述相同的枚举和标准;最终决定权在门控。oracle— 字符串;针对已确认发现运行的 L1 命令和结果(当status==confirmed时必填,否则为 null/省略)。workDone: boolean+reReadSources: string[]— 每个经过门控的发现都必填,以便识别并降级草率判定(L8)。completenessGaps[]— 必填(L5);只有在实际运行全局判定依据后才能填[]。dropped[]— 所有被过滤的方向,以及所有去重或驳回的发现,均须附上原因(L7,不得静默设上限)。
执行机制
将每个盲搜者作为具有合适子 Agent 角色(general-purpose)的子 Agent 在后台启动。只读扫描无需隔离工作树;只有需要修改文件的角度才添加工作树。等待所有子 Agent 完成,以通过屏障,然后收集各自的结果。这些是
../work-tournament/SKILL.md 使用的相同基本操作——请保持术语一致。各工具框架对应的具体工具名称已统一列在
../work/references/workflow-mode.md 中。
- 独立性/盲视:这是价值的核心。每个搜索者只能获取目标和自己的角度,并明确告知:“本轮你看不到其他角度的结果;只从你的视角进行搜索。” 独立的子 Agent 上下文可确保这一点。
- 并发上限:按受控批次启动各角度,数量约为 min(6, cores−2);超出的排队等待。一次扫描实际最多以六个角度为宜——超过此数时,应拆分为多轮并记录延期情况(见下一条),不要悄悄减少启动数量。
- 架构验证 + 单次重试(workflow-mode §3):解析每个搜索者 fenced ```json 代码块并验证其结构。输出格式错误或为空时,重新请求同一角度一次。仍然不合格的结果视为失败角度(见下一条)——应予以剔除并记录,绝不能悄悄将其当作“没有发现”而接受。
- 空值处理(重新计算并记录,绝不计入虚假结果):失效、出错或仍不合格的角度都应过滤掉——
angles.filter(Boolean)——且不能视为“这部分内容已检查且无问题”。过滤后,根据剩余角度重新计算完整性覆盖情况(其模态现在是显式的completenessGap,而非默默视为已覆盖),并在dropped[]中记录剔除项({kind:"angle", ref, reason})。将失败角度视为“已扫描且无发现”,正是 L7 要防范的虚假安全信号。 - 零结果时提前退出:如果屏障产生的新增发现为零(所有候选项都已在
seen中),则完全跳过验证关卡,并将本轮报告为无新发现——不要在空集合上启动验证器子 Agent。(这是每轮的信号,work-exhaust会将其计入连续 K 轮无结果的终止条件。) - 不得悄悄设限(L7):任何因并发或预算而降低优先级的角度、任何延期轮次、任何达到上限而被截断的发现——都必须作为具名条目写入
dropped[],并且通过工具框架的待办/计划工具显示出来。读者必须能分辨“已检查且无问题”和“结果被截断”。 - 工作树隔离:通常不需要(只读搜索);可按角度提供。
- 日志记录/恢复:将可供机器恢复的事件写入
quality-journals/<task-id>.json(位于 Agent 的数据目录下)——{ phasesDone[], seen[], anglesUsed[], findings[], completenessGaps[], dropped[] }。恢复时,加载seen[]并且绝不重置,避免已驳回的发现重新加入,也避免重新运行已完成的角度。 - 预算与并发:由编排器设定上限;本技能遵守并记录这些上限。
- 通过工具框架的待办/计划工具记录日志/阶段:例如 “通过 4 个角度扫描(git-history 已排队,第 2 批)…”、“屏障:7 个候选项 → 去重后新增 3 个”、“关卡:2 个已确认,1 个需要审核(oracle 未运行)”、“completenessGaps:thumbnail-worker 路径尚未检查”。
示例 — 多租户孤立存储路径
目标:“上传流程中的多租户隔离风险。” 编排器选出四个不同的角度(多样性才是重点——相同提示词 ×4 是重复,不是覆盖):
| 角度 | 视角 | 追查内容 |
|---|---|---|
forgery | 欺骗 | 调用方能否伪造/重放另一个租户的身份? |
config-realm | 配置/领域混淆 | 共用 CIAM/issuer、realm 混淆、回退到默认租户 |
alternative-storage-path | 代码路径 | 是否存在绕过主防护、访问存储的第二种方式? |
error-paths | 失败模式 | 错误/catch 是否会泄漏到其他租户,或默认使用租户 0? |
其中三个角度阅读了身份验证中间件,并得出结论:“issuer 检查可以解决问题”——这是一种看似合理的单次假阴性(案例在
../work/references/anti-error-lessons.md
中记录了确切的 L2 失败)。但 alternative-storage-path 重新阅读了存储层,发现
resolve.ts:88 在身份验证之后根据 ?hostname 推导租户——其他角度的视角都没有触及这条孤立代码路径。
在屏障处:该发现的键不在 seen 中,因此会被报告(L4)。门控会运行判定程序——grep '\?\.hostname' src/ + 手动重新阅读 resolve.ts
(L1)——确认查询参数优先于会话租户;status:"confirmed"、
severity:"high"、workDone:true(L2、L8)。那三条“issuer 检查可以解决问题”的否定意见确实重新阅读了代码,因此有证据支持——但它们只检查了身份验证,因此不能推翻存储层的发现。随后,完整性检查(L5)会全局搜索租户解析器,并指出 completenessGaps: ["thumbnail-worker 在 jobs/thumbnail.ts 中重新解析租户——所有角度都未触及"],为下一轮 work-exhaust 提供线索。
结果:单个智能 Agent(或任何一个角度)都驳回了一个真实的高危漏洞;而多角度扫描 + seen 去重 + 判定程序门控 + 完整性检查则发现了它,并且指出了下一个调查方向。
与工具包其他部分的集成
- 在
../work-exhaust/SKILL.md之前使用,是极佳的第一步(扫描可为第一轮提供有力起点;循环会携带其seen集合,以达到连续 K 轮无新结果的收敛条件)。 - 经过门控的发现会传入
../work-refute/SKILL.md(视角多样化的反驳,L3),而completenessGaps[]会传入../work-gaps/SKILL.md。 - 组合这些功能的完整 Review 工具框架见
../work/references/workflow-mode.md§2。 - 编排器会针对每个阶段决定角度组合(安全扫描与边界情况扫描或数据流扫描);门控背后的经验教训见
../work/references/anti-error-lessons.md。
这种模式大幅提高了发现单个“智能 Agent”或单次 grep 可能遗漏的问题的概率,同时避免搜索者在一轮中陷入群体思维——而屏障的 seen 去重 + 判定程序门控 + 完整性检查,则能将原始命中转化为可审计、可收敛的结果。