这是「GSD 全景代码解析」专题的第 27 篇。
代码修复与安全 Agent
在 GSD 的 Agent 生态中,33 个专业 Agent 各司其职。如果说 gsd-executor 是"创造者"、gsd-debugger 是"诊断者"、gsd-code-reviewer 是"审查者",那么 gsd-code-fixer 和 gsd-security-auditor 则是**"修复者"和"守卫者"**。前者负责在审查发现问题后实施精准修复,后者负责在代码进入主分支前拦截安全威胁。
本文将深入解析这两个 Agent 的定义文件——agents/gsd-code-fixer.md(约 19KB)和 agents/gsd-security-auditor.md,揭示它们的修复策略、安全审计流程、威胁模型分析,以及它们如何与 GSD 的其他组件协同工作。
一、gsd-code-fixer 深度解析:精准外科医生
gsd-code-fixer.md(19KB)是 GSD 中定义代码修复 Agent 的核心文件。它的设计哲学可以用一句话概括:
修复不是重写,而是精准、最小化、可验证的变更。
1.1 Agent 角色定义与工作方式
gsd-code-fixer 的 Agent 定义遵循 GSD 的标准 YAML frontmatter 格式:
---
name: gsd-code-fixer
description: |
精准修复代码审查和调试过程中发现的问题。
专注于最小化变更范围,只修改被明确标记为问题的代码行或函数。
保持原有代码风格和架构一致性,修复后必须运行相关测试验证。
tools: Read, Write, Edit, Bash, Grep
---核心定位:gsd-code-fixer 不是通用编码助手,而是问题绑定的修复器。它的上下文被严格限制在"被审查标记的问题"范围内——只读取 REVIEW.md 或调试会话中明确指出的问题,不越权重构无关代码。
与 gsd-executor 的关键区别:
| 维度 | gsd-executor | gsd-code-fixer |
|---|---|---|
| 输入 | PLAN.md(完整计划) | REVIEW.md(问题列表)或调试会话(根因分析) |
| 目标 | 从零实现功能 | 修复已发现的具体问题 |
| 变更范围 | 按 Plan 覆盖多个文件 | 仅限被标记的问题代码 |
| 自由度 | 高(设计 + 实现) | 低(修复 + 验证) |
| 提交策略 | 每个任务原子提交 | 每个问题独立提交或批量提交 |
| 上下文预算 | ~200K tokens | ~150K tokens |
这种区分不是冗余,而是职责分离的体现。让同一个 Agent 既写新代码又修旧问题,容易导致"顺手重构"——修复一个 Bug 时顺便改了三个文件的架构,引入新的回归风险。
1.2 代码修复策略:四层决策框架
gsd-code-fixer 的修复策略不是简单的"看到问题就改",而是一个结构化的四层决策框架:
flowchart TD
subgraph A["① 问题解析"]
A1[读取 REVIEW.md
提取问题列表] --> A2[按优先级排序
Critical → Major → Minor] --> A3[识别问题类型
逻辑错误 / 安全漏洞 / 风格问题]
end
subgraph B["② 影响分析"]
B1[定位问题代码位置] --> B2[分析依赖关系
谁调用了这段代码?] --> B3[评估修复副作用
是否会破坏现有行为?]
end
subgraph C["③ 修复实施"]
C1[制定最小化修复方案] --> C2[实施变更
Write / Edit] --> C3[运行相关测试]
C3 --> C4{测试通过?}
C4 -->|否| C5[调整修复方案]
C5 --> C1
C4 -->|是| D1
end
subgraph D["④ 验证与记录"]
D1[生成修复摘要] --> D2[更新 REVIEW.md
标记已修复项] --> D3[提交修复 commit]
end
A --> B --> C --> D层 ①:问题解析
Code-Fixer 首先解析输入的问题报告(REVIEW.md 或调试会话的 Resolution 部分),提取结构化的问题列表。每个问题必须包含:
- 位置:文件路径 + 行号范围
- 类型:security / logic / style / performance
- 等级:Critical / Major / Minor
- 描述:问题的具体表现
- 建议(可选):Code-Reviewer 或 Debugger 给出的修复方向
层 ②:影响分析
这是 Code-Fixer 最容易被忽视但最关键的步骤。在实施修复前,它会:
- 读取问题代码所在的完整函数或类,理解上下文
- 使用 Grep 搜索该函数/变量的所有调用点,评估变更的波及范围
- 判断修复是否会引入行为变更(behavioral change)——如果是,需要更谨慎的处理
层 ③:修复实施
修复实施遵循最小变更原则。Code-Fixer 的提示词中内嵌了严格的修复约束:
## 修复约束清单
- [ ] 仅修改被问题报告明确标记的代码区域
- [ ] 不得重构未涉及的问题代码,即使它"看起来不好"
- [ ] 保持原始命名风格、缩进风格和注释语言
- [ ] 如果修复需要引入新依赖,必须在修复摘要中说明理由
- [ ] 如果修复涉及 API 变更,必须同步更新调用方
- [ ] 如果问题原因是设计缺陷而非实现错误,标记为 "needs-design-change"层 ④:验证与记录
修复完成后,Code-Fixer 会生成结构化的修复摘要,格式如下:
## Fix Report
### 修复项 #1
- **问题 ID**: review-042
- **文件**: src/auth.js:45
- **原问题**: 密码以明文形式存储到 localStorage
- **修复方案**: 使用 Web Crypto API 的 encrypt() 方法加密存储
- **变更范围**: +8/-3 行(仅 auth.js)
- **测试验证**: ✅ auth.test.js 通过
- **副作用评估**: 无(调用方已正确处理字符串返回值)
### 修复项 #2
- **问题 ID**: review-043
- **文件**: src/utils.ts:23
- **原问题**: 递归函数缺少终止条件检测
- **修复方案**: 添加 depth 参数,超过 1000 时抛出 Error
- **变更范围**: +5/-1 行
- **测试验证**: ✅ utils.test.ts 通过
- **副作用评估**: 无(新增参数有默认值,不影响现有调用)1.3 修复范围控制:最小化变更的工程实践
gsd-code-fixer 最核心的设计是修复范围控制。GSD 认为,"过度修复"比"不修复"更危险——因为不修复只会保留已知问题,而过度修复可能引入未知问题。
范围控制的三个机制:
机制 1:行级锁定(Line-Level Locking)
Code-Fixer 的输入中包含精确的行号范围,修复时只能修改这个范围内的代码:
# REVIEW.md 中的问题标记格式
- id: review-042
file: src/auth.js
lines: [45, 47] # 只能修改第 45-47 行
severity: critical
type: security如果需要修改范围外的代码(如新增辅助函数),Code-Fixer 必须:
- 在原范围内添加调用
- 在文件末尾或合适位置新增函数
- 在修复摘要中明确说明"变更超出了原始标记范围"
机制 2:行为等价检查(Behavioral Equivalence Check)
对于非安全类修复(如性能优化、风格调整),Code-Fixer 会评估修复前后的行为等价性:
| 修复类型 | 行为等价要求 | 示例 |
|---|---|---|
| 安全修复 | 允许行为变更(更安全) | 添加输入校验 → 原本非法输入通过,现在抛出错误 |
| 逻辑修复 | 必须行为等价(修复 Bug) | 修复边界条件 → 原本错误输出,现在正确输出 |
| 性能修复 | 必须行为等价(优化) | 替换算法 → 输出相同,速度更快 |
| 风格修复 | 必须行为等价(格式化) | 重命名变量 → 所有引用同步更新 |
机制 3:依赖冻结(Dependency Freeze)
Code-Fixer 的提示词中明确禁止以下操作:
- 升级依赖版本(除非问题明确由依赖 Bug 导致)
- 引入新的外部依赖(除非安全修复必需且已有项目依赖)
- 修改数据库 Schema(除非问题明确由 Schema 不匹配导致)
- 修改 CI/CD 配置
这些约束确保 Code-Fixer 不会"越权"——它的职责是修复代码问题,不是做架构升级。
flowchart TD
A[接收修复任务] --> B{变更范围?}
B -->|行内修复| C[直接修改标记行]
B -->|需要新增函数| D[在文件内合适位置添加]
B -->|需要跨文件修改| E[评估是否超出权限]
E -->|超出权限| F[标记为 "needs-executor"
转交 gsd-executor]
E -->|在权限内| G[实施跨文件修复]
C --> H[运行测试验证]
D --> H
G --> H
F --> I[记录到修复摘要]
H --> J{测试通过?}
J -->|是| K[提交修复]
J -->|否| L[回滚并重新分析]
L --> B1.4 与 gsd-debugger 的协作:诊断到修复的闭环
在第 24 篇中,我们详细解析了 gsd-debugger 的科学方法调试流程。当 Debugger 定位到根因后,修复工作往往由 gsd-code-fixer 承接,而非 Debugger 自己实施。这种分离的设计遵循 GSD 的"调查与修复分离"原则:
sequenceDiagram
participant O as Orchestrator
participant D as gsd-debugger
participant F as gsd-code-fixer
participant T as 测试套件
O->>D: Spawn 调试任务
D->>D: 科学方法调查
D-->>O: 返回 ROOT CAUSE + specialist_hint
alt specialist_hint = "code-fix"
O->>F: Spawn 修复任务 + 调试会话上下文
F->>F: 读取调试会话中的根因分析
F->>F: 制定最小化修复方案
F->>T: 运行相关测试
T-->>F: 通过 / 失败
F-->>O: 返回修复摘要 + 测试报告
else specialist_hint = "executor"
O->>E: 转交 gsd-executor(复杂重构)
end协作的关键协议点:
- 信息传递:Debugger 的会话文件(
.planning/debug/{slug}.md)中的Resolution部分,是 Code-Fixer 的输入之一。它包含根因描述、建议修复方向和涉及的文件。 - 修复边界:Debugger 只负责"找出问题在哪",Code-Fixer 负责"怎么修"。Debugger 不会给 Code-Fixer 施加具体的实现约束(如"必须用某种设计模式"),只提供根因分析。
- 失败回退:如果 Code-Fixer 的修复导致测试失败,且 3 次尝试后仍未解决,任务会回退到 Orchestrator,可能重新 spawn Debugger 进行更深入的调查。
1.5 修复验证机制:测试驱动的修复闭环
gsd-code-fixer 的修复验证不是可选步骤,而是强制步骤。每个修复都必须通过以下三层验证:
第一层:单元测试验证
运行被修改文件对应的单元测试:
# Code-Fixer 内部自动执行
npm test -- src/auth.test.js
# 或
pytest tests/test_auth.py如果单元测试失败,Code-Fixer 必须分析失败原因并调整修复方案。
第二层:集成测试验证
如果修复涉及接口变更或跨模块调用,运行相关集成测试:
npm test -- tests/integration/第三层:回归测试验证
运行全量回归测试,确保修复没有破坏其他功能:
npm testflowchart TD
subgraph Fix["修复实施"]
F1[应用代码变更]
end
subgraph L1["第一层:单元测试"]
U1[运行被修改文件的单元测试] --> U2{通过?}
U2 -->|否| U3[分析失败原因]
U3 --> U4[调整修复方案]
U4 --> F1
end
subgraph L2["第二层:集成测试"]
I1[运行受影响模块的集成测试] --> I2{通过?}
I2 -->|否| I3[分析接口兼容性]
I3 --> I4[调整修复方案]
I4 --> F1
end
subgraph L3["第三层:回归测试"]
R1[运行全量回归测试] --> R2{通过?}
R2 -->|否| R3[定位回归来源]
R3 --> R4[回滚或调整]
R4 --> F1
end
F1 --> U1
U2 -->|是| I1
I2 -->|是| R1
R2 -->|是| Done[修复验证完成]特殊情况处理:
| 场景 | 处理策略 |
|---|---|
| 测试不存在 | 在修复摘要中标记 "tests-missing",建议补充测试 |
| 测试不相关 | 如果现有测试无法覆盖修复场景,标记 "coverage-gap" |
| ** flaky 测试** | 重试 3 次,若仍不稳定,标记 "flaky-test" 并继续 |
| 修复导致测试需要更新 | 同步更新测试,但必须在修复摘要中说明 |
二、gsd-security-auditor 深度解析:安全哨兵
gsd-security-auditor.md 是 GSD 中定义安全审计 Agent 的核心文件。与其他 Agent 最大的不同是:它是一个只读 Agent。
---
name: gsd-security-auditor
description: |
对代码变更进行安全审计,聚焦 OWASP Top 10 和运行时漏洞。
使用只读工具集,确保审计过程不会意外修改代码。
输出结构化的安全审计报告 SECURITY_AUDIT.md。
tools: Read, Grep, Bash, Glob
model: claude-sonnet-4-20250514
temperature: 0.2
---2.1 为什么安全审计必须是只读的?
gsd-security-auditor 的工具白名单中没有 Write 和 Edit。这个设计不是疏忽,而是刻意的安全设计:
审计者不能修改被审计的代码。这是信息安全的基本原则之一。
如果安全审计 Agent 拥有写权限,存在以下风险:
- 审计偏差:为了"通过"审计,Agent 可能"顺手"修复问题,导致审计报告与代码实际状态不一致
- 审计痕迹缺失:修改后的代码如果没有独立提交,安全审计的原始发现将无法追溯
- 权限混淆:审计者同时拥有裁判和运动员身份,破坏了职责分离原则
因此,Security-Auditor 的发现必须通过报告形式输出,由 Orchestrator 决策后,再派发给 gsd-code-fixer 或 gsd-executor 执行修复。
2.2 安全检查流程:五层深度扫描
gsd-security-auditor 的安全检查流程分为五个层次,从表面到深层递进:
flowchart TD
subgraph A["① 表面扫描"]
A1[硬编码密钥检测] --> A2[敏感文件模式匹配
.env, .key, .pem] --> A3[注释中的 TODO/FIXME
含敏感信息]
end
subgraph B["② 输入验证扫描"]
B1[SQL 拼接检测] --> B2[XSS 输出点检测] --> B3[命令注入风险] --> B4[路径遍历风险]
end
subgraph C["③ 认证授权扫描"]
C1[JWT 实现审查] --> C2[会话管理检查] --> C3[CORS 配置审查] --> C4[权限绕过风险]
end
subgraph D["④ 依赖与供应链扫描"]
D1[已知漏洞检测
CVE 数据库] --> D2[依赖许可证冲突] --> D3[恶意包检测]
end
subgraph E["⑤ 运行时行为分析"]
E1[动态分析建议] --> E2[模糊测试建议] --> E3[渗透测试建议]
end
A --> B --> C --> D --> E层 ①:表面扫描(Surface Scan)
最快的一层,通过正则表达式和模式匹配完成,通常在 30 秒内完成:
- 硬编码的 API Key、密码、Token(如
password = "123456"、api_key = "sk-...") - 敏感文件是否被意外提交(
.env、*.key、*.pem、id_rsa) - 注释中是否包含敏感信息(如内部 IP、数据库连接字符串)
层 ②:输入验证扫描(Input Validation Scan)
检查所有用户输入的处理路径:
| 漏洞类型 | 检测模式 | 示例 |
|---|---|---|
| SQL 注入 | 字符串拼接 SQL / 未参数化查询 | query("SELECT * FROM users WHERE id = " + userId) |
| XSS | 未转义的 HTML 输出 | innerHTML = userInput |
| 命令注入 | 用户输入传入 shell/exec | exec("ls " + userInput) |
| 路径遍历 | 用户输入拼接文件路径 | readFile("./uploads/" + filename) |
| 反序列化 | 不可信数据的反序列化 | JSON.parse(userInput) 无 schema 验证 |
层 ③:认证授权扫描(AuthN/AuthZ Scan)
审查身份验证和授权逻辑:
- JWT 实现:密钥管理、过期时间、算法选择(禁止
none算法) - 会话管理:Cookie 的
Secure、HttpOnly、SameSite属性 - CORS 配置:是否允许通配符
*来源 - 权限检查:敏感接口是否缺少鉴权中间件
层 ④:依赖与供应链扫描(Dependency Scan)
通过 security-scan.sh 脚本和外部数据库检查依赖安全性:
# security-scan.sh 的典型操作
npm audit --audit-level=moderate # Node.js
pip-audit # Python
safety check # Python (alternative)
trivy fs --scanners vuln . # 通用扫描层 ⑤:运行时行为分析(Runtime Analysis)
静态分析无法覆盖的场景,Security-Auditor 会生成建议而非直接发现:
- 建议对关键接口进行模糊测试(fuzzing)
- 建议对认证流程进行渗透测试
- 建议启用运行时安全监控(如 RASP)
2.3 威胁模型分析:STRIDE 框架的应用
gsd-security-auditor 的审计不是无头苍蝇式的扫描,而是基于 STRIDE 威胁模型 的系统性分析:
flowchart LR
subgraph S["S - Spoofing
伪装"]
S1[身份伪造] --> S2[会话劫持]
end
subgraph T["T - Tampering
篡改"]
T1[数据篡改] --> T2[代码篡改]
end
subgraph R["R - Repudiation
抵赖"]
R1[缺少审计日志] --> R2[日志不可信]
end
subgraph I["I - Information Disclosure
信息泄露"]
I1[敏感数据泄露] --> I2[错误信息泄露内部信息]
end
subgraph D["D - Denial of Service
拒绝服务"]
D1[资源耗尽] --> D2[无限循环/递归]
end
subgraph E["E - Elevation of Privilege
权限提升"]
E1[垂直越权] --> E2[水平越权]
end
S --> T --> R --> I --> D --> ESTRIDE 在 Security-Auditor 中的应用:
| 威胁类别 | 审计焦点 | 典型发现 |
|---|---|---|
| Spoofing | 认证机制 | JWT 签名验证缺失、密码哈希强度不足 |
| Tampering | 数据完整性 | 缺少请求签名、传输层未加密 |
| Repudiation | 审计日志 | 关键操作无日志、日志可被篡改 |
| Information Disclosure | 数据保护 | 错误堆栈暴露、敏感字段未脱敏 |
| Denial of Service | 资源控制 | 无速率限制、大文件上传无限制 |
| Elevation of Privilege | 授权检查 | 管理员接口缺少权限校验、IDOR 漏洞 |
Security-Auditor 在审计时会为每个发现的威胁标注对应的 STRIDE 类别,帮助开发者理解威胁的本质。
2.4 安全门控集成:与 gates.md 的联动
gsd-security-auditor 的审计结果不是独立的报告,而是与 GSD 的质量门控系统深度集成:
# gates.md 中的安全门控配置
security:
audit_depth: standard # quick / standard / deep
critical_vuln_threshold: 0 # Critical 漏洞必须为零
high_vuln_threshold: 0 # High 漏洞必须为零
medium_vuln_threshold: 3 # Medium 漏洞最多 3 个
dependency_scan: true # 启用依赖扫描
secrets_scan: true # 启用密钥扫描
owasp_coverage: all # 覆盖全部 OWASP Top 10门控判定流程:
flowchart TD
A[gsd-security-auditor 完成审计] --> B[生成 SECURITY_AUDIT.md]
B --> C[Orchestrator 读取审计结果]
C --> D{Critical = 0?}
D -->|否| E[阻塞合并
必须修复]
D -->|是| F{High = 0?}
F -->|否| G[阻塞合并
必须修复]
F -->|是| H{Medium ≤ 阈值?}
H -->|否| I[条件通过
需人工确认]
H -->|是| J[安全门控通过]
E --> K[派发 gsd-code-fixer 修复]
G --> K
I --> L[生成安全风险说明
等待用户决策]三种安全审计结果状态:
| 状态 | 含义 | 后续动作 |
|---|---|---|
secure | 无 Critical/High,Medium 在阈值内 | 允许进入下一阶段 |
conditional | 无 Critical/High,Medium 超标 | 需人工确认风险后方可继续 |
blocked | 存在 Critical 或 High | 必须修复后方可继续 |
2.5 与 security-scan.sh 的协作:自动化与智能化的结合
security-scan.sh 是 GSD 仓库中提供的一个自动化安全扫描脚本,它与 gsd-security-auditor 形成互补关系:
flowchart TB
subgraph Script["security-scan.sh
(自动化工具层)"]
S1[npm audit / pip-audit] --> S2[truffleHog 密钥扫描]
S2 --> S3[semgrep 规则扫描]
S3 --> S4[生成 RAW 扫描报告]
end
subgraph Auditor["gsd-security-auditor
(智能分析层)"]
A1[读取 RAW 报告] --> A2[去重和降噪]
A2 --> A3[上下文分析
"这个漏洞是否可 exploited?"]
A3 --> A4[威胁建模]
A4 --> A5[生成 SECURITY_AUDIT.md]
end
S4 --> A1两者的职责分工:
| 维度 | security-scan.sh | gsd-security-auditor |
|---|---|---|
| 定位 | 自动化工具编排 | 智能分析与判断 |
| 速度 | 快(1-5 分钟) | 慢(5-15 分钟) |
| 误报率 | 较高(规则匹配) | 较低(上下文理解) |
| 输出 | 原始漏洞列表(JSON) | 结构化审计报告(Markdown) |
| 深度 | 已知漏洞(CVE) | 未知漏洞模式、业务逻辑漏洞 |
| 可解释性 | 低(只有规则 ID) | 高(含 exploit 场景分析) |
典型协作流程:
# 1. 先运行自动化扫描
./scripts/security-scan.sh --format=json > .planning/raw-security-scan.json
# 2. Orchestrator spawn Security-Auditor
# 传入扫描结果作为上下文Security-Auditor 在收到 RAW 报告后会做以下处理:
- 去重:将同一漏洞在不同工具中的重复发现合并
- 降噪:排除已知的 false positive(如测试文件中的假密钥)
- 上下文分析:判断漏洞是否可被利用(如 SQL 注入点是否实际接收用户输入)
- 风险评级调整:根据业务上下文上调或下调风险等级
- 修复建议生成:为每个确认的问题提供具体的修复方向
三、安全最佳实践在 Agent 中的体现
GSD 的安全设计不仅体现在 gsd-security-auditor 的审计能力上,更体现在整个 Agent 系统的安全内建(Security by Design)理念中。
3.1 最小权限原则在 Agent 工具中的体现
回顾第 22 篇中的工具权限矩阵,Security-Auditor 的只读设计是 GSD 最小权限原则的典型体现:
| Agent | Write 权限 | 安全考量 |
|---|---|---|
gsd-executor | ✅ | 需要写代码,但受原子提交约束 |
gsd-code-fixer | ✅ | 需要修复代码,但受最小变更约束 |
gsd-security-auditor | ❌ | 审计者不得修改被审计对象 |
gsd-code-reviewer | ❌ | 审查者不得修改被审查代码 |
gsd-verifier | ❌ | 验证者不得修改被验证产物 |
3.2 职责分离原则的体现
GSD 的 Agent 设计遵循经典的职责分离(Separation of Duties)安全原则:
flowchart LR
subgraph Write["写入者"]
W1[gsd-executor]
W2[gsd-code-fixer]
end
subgraph Audit["审计者"]
A1[gsd-code-reviewer]
A2[gsd-security-auditor]
A3[gsd-verifier]
end
subgraph Approve["批准者"]
O1[Orchestrator / 用户]
end
W1 --> A1
W2 --> A1
W1 --> A2
W2 --> A2
A1 --> O1
A2 --> O1
O1 --> W2在这个模型中:
- 写入者负责生产代码
- 审计者负责发现问题(但无权修改)
- 批准者负责决策(是否合并、是否修复)
没有任何一个 Agent 同时拥有"写代码"和"批准代码"的权力,这防止了恶意或错误的代码未经审查就进入主分支。
3.3 审计痕迹的完整性
GSD 的所有安全相关操作都被完整记录在文件系统中:
| 文件 | 记录内容 | 保留时长 |
|---|---|---|
SECURITY_AUDIT.md | 每次安全审计的完整报告 | 永久(Git 历史) |
REVIEW.md | 代码审查发现的安全问题 | 永久(Git 历史) |
.planning/security/ | 历史审计报告归档 | 项目生命周期 |
security-scan.sh 输出 | 自动化扫描原始结果 | 可选(CI artifact) |
这种设计使得安全审计具有可追溯性(Traceability)和可审计性(Auditability),满足合规要求。
四、修复与安全的协作关系
gsd-code-fixer 和 gsd-security-auditor 虽然职责不同,但在 GSD 的执行管道中紧密协作,形成**"发现 → 审计 → 修复 → 验证"**的完整闭环。
4.1 协作流程全景
flowchart TD
subgraph Review["代码审查阶段"]
R1[gsd-code-reviewer 审查] --> R2{发现安全问题?}
R2 -->|是| R3[REVIEW.md 标记 Critical]
R2 -->|否| R4[继续常规审查]
end
subgraph Audit["安全审计阶段"]
A1[gsd-security-auditor 审计] --> A2{发现漏洞?}
A2 -->|是| A3[SECURITY_AUDIT.md 标记风险]
A2 -->|否| A4[安全门控通过]
end
subgraph Fix["修复阶段"]
F1[Orchestrator 汇总问题] --> F2[派发 gsd-code-fixer]
F2 --> F3[按优先级修复]
F3 --> F4[运行测试验证]
end
subgraph Verify["验证阶段"]
V1[重新审查 + 重新审计] --> V2{全部通过?}
V2 -->|否| F1
V2 -->|是| V3[允许合并]
end
R3 --> F1
A3 --> F1
R4 --> Audit
A4 --> Fix
F4 --> Verify4.2 优先级冲突的处理
当 Code-Reviewer 和 Security-Auditor 对同一问题给出不同优先级时,GSD 的处理策略是:
Security-Auditor 的判定优先于 Code-Reviewer 的判定。
具体规则:
| 场景 | 处理策略 |
|---|---|
| Code-Reviewer 标记为 Minor,Security-Auditor 标记为 High | 按 High 处理,优先修复 |
| Code-Reviewer 未发现,Security-Auditor 发现 Critical | 立即阻塞流程,紧急修复 |
| Code-Reviewer 标记为 Critical(安全问题),Security-Auditor 标记为 Low | 按 Critical 处理(Reviewer 的业务上下文判断优先) |
| 两者标记不一致但都在阈值内 | 取较高等级处理 |
4.3 修复循环的安全强化
在标准的 code-review-fix 工作流中,当 Security-Auditor 发现问题时,修复循环会被安全强化:
flowchart TD
A[Security-Auditor 发现漏洞] --> B{漏洞等级?}
B -->|Critical| C[立即暂停当前 Wave]
B -->|High| D[标记阻塞,当前 Wave 完成后修复]
B -->|Medium| E[进入常规修复队列]
B -->|Low| F[记录为技术债务,后续迭代处理]
C --> G[spawn gsd-code-fixer
最高优先级]
D --> H[Wave 完成后 spawn
高优先级]
E --> I[常规优先级修复]
G --> J[修复完成 + 重新审计]
H --> J
I --> J
J --> K{Security-Auditor 确认修复?}
K -->|否| L[分析修复不足原因]
L --> G
K -->|是| M[安全门控通过]关键设计:安全修复完成后,必须重新经过 Security-Auditor 的审计,不能仅由 Code-Fixer 自行验证。这确保了修复没有引入新的安全问题,且原始漏洞确实被消除。
4.4 与 gsd-debugger 的三方协作
当安全问题涉及复杂的运行时行为(如 race condition 导致的安全令牌泄露),gsd-code-fixer、gsd-security-auditor 和 gsd-debugger 会形成三方协作:
sequenceDiagram
participant SA as gsd-security-auditor
participant O as Orchestrator
participant D as gsd-debugger
participant F as gsd-code-fixer
participant T as 测试套件
SA->>O: 发现疑似运行时漏洞
"JWT 验证存在 race condition"
O->>D: Spawn 调试任务
调查 race condition 根因
D->>D: 科学方法调查
D-->>O: 返回根因:
并发请求共享同一个 token 验证实例
O->>F: Spawn 修复任务
修复 race condition
F->>F: 实施最小化修复
添加互斥锁
F->>T: 运行并发测试
T-->>F: 通过
F-->>O: 返回修复摘要
O->>SA: 重新审计修复后的代码
SA-->>O: 确认漏洞已消除
O->>O: 安全门控通过这种协作模式的价值在于:
- Security-Auditor 发现"有什么不对劲"
- Debugger 找出"为什么会这样"
- Code-Fixer 实施"怎么修好它"
三者各司其职,没有功能重叠,也没有职责真空。
五、关键设计洞察
通过深入分析 gsd-code-fixer.md 和 gsd-security-auditor.md,可以提炼出几个贯穿 GSD Agent 设计的核心洞察。
5.1 "修复专业化"的价值
GSD 没有让 gsd-executor 兼任修复工作,而是设计了专门的 gsd-code-fixer。这种专业化的价值:
- 上下文聚焦:Code-Fixer 只关注问题代码,不受 Plan 中其他任务的干扰
- 约束明确:最小变更原则、行级锁定、依赖冻结等约束,在 Code-Fixer 的提示词中被强化
- 可度量性:修复摘要的结构化格式,使得修复质量可以被追踪和审计
5.2 "只读审计"的安全哲学
Security-Auditor 的只读设计是 GSD 安全哲学的集中体现:审计的客观性比审计的效率更重要。一个只能发现问题、不能修改代码的 Agent,虽然"不那么方便",但它确保了:
- 审计报告的真实性和完整性
- 审计与修复的职责分离
- 审计结果的人类可审查性
5.3 "报告即协议"的协作模式
Code-Fixer 和 Security-Auditor 之间的协作不依赖内存状态或 RPC 调用,而是通过结构化报告实现:
| 协议文件 | 生产者 | 消费者 | 作用 |
|---|---|---|---|
REVIEW.md | Code-Reviewer | Code-Fixer | 代码问题列表 |
SECURITY_AUDIT.md | Security-Auditor | Orchestrator | 安全审计结果 |
.planning/debug/*.md | Debugger | Code-Fixer | 根因分析与修复方向 |
| 修复摘要 | Code-Fixer | Orchestrator | 修复结果与验证报告 |
这种设计使得 Agent 之间的协作人类可读、机器可解析、版本可追踪。
总结
本文深入解析了 GSD 修复层和安全层的两个核心 Agent:
| Agent | 核心职责 | 关键设计 |
|---|---|---|
| gsd-code-fixer | 精准修复审查和调试中发现的问题 | 四层决策框架、最小变更原则、行级锁定、测试驱动验证 |
| gsd-security-auditor | 安全审计与威胁建模 | 五层深度扫描、STRIDE 威胁模型、只读设计、与 gates.md 门控联动 |
两者的协作关系:Security-Auditor 发现"哪里不安全",Code-Fixer 修复"怎么变安全"。Debugger 在需要时提供根因分析,形成完整的安全修复闭环。
安全最佳实践的内建:最小权限原则(Security-Auditor 只读)、职责分离(写入者/审计者/批准者分离)、审计痕迹完整性(所有报告纳入 Git 历史)。
GSD 的修复与安全体系设计体现了一个核心理念:
安全不是事后补丁,而是内建在 Agent DNA 中的约束。
Code-Fixer 的最小变更原则防止了"修一个 Bug 引入三个 Bug";Security-Auditor 的只读设计确保了审计的客观性;两者的协作闭环使得安全问题能够被发现、审计、修复、验证——而不是被忽视或敷衍。
下一篇预告:第 28 篇《UI 与假设分析 Agent》
在解析了修复层和安全层的核心 Agent 之后,我们将继续探索 GSD Agent 系统的另外两个独特维度——
gsd-ui-auditor和gsd-assumptions-analyzer。UI Auditor 如何确保前端实现与设计稿的一致性?假设分析 Agent 如何在规划阶段识别需求中的隐含假设和认知盲区?它们如何与 Planner、Executor 形成从"需求理解"到"视觉交付"的完整闭环?敬请期待!