关于 cs-build-audit-codebase
一项与语言和技术栈无关的代码库审计技能,指导基于证据调查问题并规划修复。它从项目状态和应用运行情况入手,结合专项审查,最终整理发现、给出重建或原地修复的判断并规划看板任务。
主要功能
- 01检测项目状态并验证功能地图
- 02检查代码库状态与交付实践
- 03运行应用并测试用户流程
- 04协调只读的专项审查
- 05整理发现并规划看板任务
适用场景
- 01诊断现有应用中的缺陷
- 02判断应重建还是原地修复
- 03将已验证的审计发现转为修复任务
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ codespringapp/ codespring-skills --skill cs-build-audit-codebase安装后在 Claude Code 中输入/cs-build-audit-codebase确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/plain-english-writeup.mdspecialist-briefs.mdscripts/check-repo.sh详细介绍
审计代码库并规划修复
适用于用户说“我的应用一团糟——告诉我出了什么问题,以及该怎么办”的情况。诊断过程不依赖特定语言,并以证据为依据。最终会输出一份通俗易懂的问题清单、仓库中的 FINDINGS.md、一项结论(重建或就地修复),以及看板任务。
请先阅读: codespring 技能的 references/project-state.md(可从任意阶段进入的流程,五个问题)、references/auditing-and-fixing.md(此处每个步骤背后的推理)、references/analyze-codebase.md、references/pitfalls.md。然后阅读此技能的 references/specialist-briefs.md(可直接复制的子 Agent 简报)和 references/plain-english-writeup.md(交付内容的结构和语气)。
脚本——运行这些脚本,而不要手动执行同等操作;检查结果必须始终一致。scripts/check-repo.sh(此技能:Git 和交付状态)以及 codespring 技能的 scripts/fetch-project.sh、state.mjs 和 check-map.mjs(状态检测和地图验证)。这些脚本均为只读。判断仍以文字说明。
以下脚本路径均相对于此技能所在目录,且这些技能并排安装——因此,../codespring/scripts/… 可访问核心技能的脚本。开始时解析一次路径(SKILL_DIR=$(dirname <this file>)),之后使用绝对路径,因为你的工作目录将是用户的仓库。
不依赖特定语言或技术栈。 此技能及其参考资料中所有具名的具体内容——如费率表、报告或状态代码——都是从本次通用化所依据的审计中摘取的带标签示例,绝不能假定它们适用于当前代码库。迁移方法模式;不要去查找示例。
防护措施: 对目标代码库保持只读,只有一个例外——仓库根目录下的 FINDINGS.md,且必须先征求同意才能写入,绝不提交。可以实时探测用户自己的运行中应用和服务,但不得造成破坏。
0. 检测项目当前所处阶段
运行状态检测脚本——每次运行的结果都相同,不要手动计数(使用与此技能并排安装的 codespring 技能中的 scripts/):
bash ../codespring/scripts/fetch-project.sh --out /tmp/cs-state # read-only snapshot; prints the projectId
node ../codespring/scripts/state.mjs /tmp/cs-state # the one-line summary + booleans and counts
node ../codespring/scripts/check-map.mjs /tmp/cs-state # the machine-checkable map faults
向用户打印单行摘要。这将决定哪些步骤可以跳过。
- 尚未关联 → 先关联(如果项目必须位于团队工作区中,则告诉用户在 Web 应用中创建项目——参见
pitfalls.md)。 - 已存在地图 → 继续之前先评估它(参见下方的阶梯式流程)。无论如何,都不要创建功能、不要“构建目标地图”,也不要在此处运行
mindmap features。打印现有核心功能及其 ID,然后开始审计。 - 已存在
FINDINGS.md→ 阅读它。你是在更新审计,而不是从头开始。 - 已存在任务 → 记录最高任务编号;继续编号,不要重新开始。
任何写入前,都要从本地 .codespring/config.json 读取 projectId 并打印。
0a. 现有地图是否可用?——判断阶梯
“地图已经存在 → 保留” 过于草率。不可用的地图会污染基于它构建的每一条笔记、PRD 和任务。完整版本(包括 CLI 命令)见 cs-build-import-codebase/references/target-map.md。
- 是否存在地图? 不存在 → 稍后由
cs-build-import-codebase(§10) 构建。不是现在。 - 地图是否可用?
check-map.mjs(上文)会核实数量、重复标题、被压平的子功能和缺失的笔记。其余部分由你判断:核心功能是否有 4–8 个,且每个都是用户能认出来的侧边栏项目;子功能是否是用户会执行的操作,而不是输出文档的章节或表单字段分组;卡片描述是否为一句话,并将具体深度留在笔记中。地图即使通过所有自动化检查,仍可能让人摸不着头脑。 - 可用 → 保留。 更新笔记,添加任务。绝不能重建。
- 可以修复(大体正确,只是有少数偏差)→ 就地修复并说明改了什么: 使用
codespring feature update <subId> --parent <coreId>更改父级,使用codespring feature delete <dupId> --yes删除重复项,使用codespring feature update <id> --title "..."重命名。 - 无法修复(错误严重,令人困惑——核心功能数量远超合理范围、把输出章节当成功能、结构毫无条理)→ 不要尝试挽救。 清楚说明原因,并建议创建一个全新的 CodeSpring 项目,使用干净的地图;旧项目保留作历史记录。创建第二个项目前必须取得明确确认,绝不能悄悄创建。
⚠️ 同一个应用有两个项目,之后会让人困惑,因此这必须是经过慎重考虑并说明理由的选择,而且必须告知用户现在以哪个项目为准。实际案例:一个包含 13 个核心功能的导入项目无法使用,于是用一张包含 6 个功能的干净地图创建了第二个项目来替代它,但两个项目都仍然存在。没有 project delete 命令,因此这项操作不可撤销。如果你接手时发现同一个应用有两个项目,请先确定哪个项目为准,再进行任何写入操作。
1. 与用户简要确定审计范围
确认:仓库路径、如何启动应用、应用的用途、它是否替代某个现有产品,以及已知的问题。询问用户最希望得到哪些答案——实际审计围绕项目所有者提出的三个问题展开(“不同地方是否都出错了?”“它是如何读取数据库的?”“为什么有些报告看起来更好?”),每个问题都得出了一个关键发现。
再问三个问题,因为它们会改变发现的含义(§2):
- 应用是否有真实用户或付费客户? 仅此一点就可能否决重建(§9)——现在就问,不要等到给出结论时再问。
- 现在是否有人也在这个仓库中工作?
- 应用的功能是否已经完备,还是仍在开发中?
一开始就说明工作方向:要让现有可用的功能正常运行,而不是增加功能。 参见 auditing-and-fixing.md §4a。
2. 侦察 + 仓库与交付审计(先由你亲自执行)
这会影响其他所有结论,所以要在分派任务前完成。命令见 specialist-briefs.md §6。确认:
- 本地克隆是否落后于远程? 执行
git fetch,然后比较本地HEAD和origin/<branch>。如果落后,说明情况并提出先更新再审计——审计过时的克隆,得出的发现可能已经修复。(实际审计时,代码比生产环境落后两个合并提交。) - 服务端源代码是否在仓库中? 还是只存在于托管平台的控制面板中?如果是后者,这是可能导致全部数据丢失的严重问题——提供准确的备份命令。
- 分支/PR 结构;部署是否受自动化检查把关,还是合并就会发布到生产环境;是否有任何 CI;
.gitignore是否充分;历史记录中是否有密钥(也要报告未发现密钥的结果);是否有预发布环境,还是每个会话都会连接生产环境。 - 现在就修正技术栈说明,避免各个子 Agent 重复推导。
2a. 代码库随时可能变化——先运行脚本
bash scripts/check-repo.sh --repo <abs repo path> [--paths <suspect files…>]
只读(git fetch 只会更新远程跟踪引用)。脚本会显示审查结果适用的提交、你的代码落后远程多少,以及那些尚未同步的提交修改了哪些文件;还会列出每个远程分支及其日期和作者、近期提交者、工作树是否有未提交的改动,以及是否存在自动化检查。退出码 2 表示本地副本落后于远程。
实际审计中的示例,说明此脚本能发现什么:存在 12 个远程分支,仓库所有者直接向 main 提交,有协作者正在并行工作,而审计所用的本地副本落后了 3 个提交——最新的提交修改的正是正在审计的文件。
然后:
- 如果落后:说明落后了多少个提交,并提出先更新再审计。 一句话即可,不要长篇说教。绝不要默默审计过期的本地副本——旧代码中的问题可能已经修复。
- 列出远程分支并说明正在进行哪些工作,以免针对已被后续工作取代的内容提出问题。
- 在
FINDINGS.md的标题中,审查日期旁记录确切的提交 SHA。 发现只适用于该提交,不适用于其他内容。 - 现在还有其他人在仓库中工作吗? 询问。如果有,建议为修复工作创建一个专用分支,并明确说明需要处理合并冲突。
- 功能已经完备,还是仍在开发中? 如果仍在开发,功能地图可能会漏掉代码中尚不存在的计划模块,因此在最终确定功能列表之前,询问所有者有哪些计划中的功能尚未实现。 真实案例:一次审计发现有四个页面没有任何链接,于是认定它们属于另一款产品;实际上,它们是同一产品中尚未完成的模块(§6a,规则 5)。
- 如果审计期间远程仓库发生变化,重新检查即将提交的具体发现,而不是从头重跑所有内容。
假设对方不了解 Git,不要就此向所有者说教。 非技术背景的所有者往往不理解分支,审计或重建工作进行期间也可能直接向 main 提交。用一句话说明你要做什么以及原因——“我会在名为 fixes 的分支上工作,这样你提交到 main 的内容就不会和我的改动冲突”——绝不要假设提交历史总是干净且线性,也不要假设 main 受到保护。
3. 运行应用并实际操作
这是收益最高的一步。不要跳过,也不要用阅读代码代替。 启动或提供应用服务,实际走一遍主要流程,观察控制台和网络面板,尝试空值、零、负数、离谱值、大小写错误的输入,并找出数据实际存储的位置。
在一次真实审计中,这一步发现清空输入后报告仍显示过期数字,证实核心计算完全没有发出网络请求(这改变了整个审计的方向),还排除了一个被怀疑存在的身份验证绕过问题——原来那只是带有明确标签的示例模式。运行应用不仅能发现问题,也同样能避免误判。
4. 并行安排专业人员审查
在同一条消息中同时启动,每位审查人员仅进行只读操作,各自收到完整独立的任务说明,且看不到其他人的内容。独立性就是证据。任务说明见 references/specialist-briefs.md:
安全/身份验证 · 数据库/模式 · 核心业务逻辑 · 前端/UX/失效控件 · 架构/可扩展性
根据应用情况增加审查领域——例如,现有产品/竞品对比、用户流程与故障地图、数据来源审查。每项发现都必须包含 file:line 或可复现的命令,以及证据标签:已确认(实际运行过/读过确切代码行)、推断(基于推理得出,未执行)、未验证(疑似问题,并说明如何检查)。没有标签、没有引用的发现一律删除。
他们审查期间,继续实际操作应用。你是第六位 Agent,负责解决意见分歧。
5. 专门排查特定缺陷类别
这些类别列于 auditing-and-fixing.md §4——要有针对性地排查,而不是寄希望于偶然发现:
- 过时的硬编码参考数据——源代码中的费率/价格/阈值字面量,却没有任何机制在它们过期时发出提醒。
- 已经出现偏差的重复逻辑——建立一份重复项清单;检查这些副本目前是否一致、过去是否曾不一致;检查主入口点实际加载的是哪一份。
- 静默失败路径——错误变成零、空对象、过时的界面或成功消息。缺失值和失败绝不能看起来一样。
- 仅存于浏览器中的数据——或者仅存于一台机器上,既没有备份,也没有警告。
- 无法验证的时效性/准确性声明——软件声称的任何无法自行核查的内容。
6. 亲自核实关键结论
不要转述子 Agent 给出的最大数字。要独立复现——使用第二种方法(将逻辑提取到临时测试框架中)和/或实际运行应用。在真实审计中,两种方法的结果精确到分,这才让向客户展示关键金额有了依据;如果确实如此,要在报告中说明。协调专家之间的矛盾;后续信息更充分的检查胜过早期检查——记录更正,而不是把两种说法都交付出去。
6a. 然后审计自己——错误实际上就出在这里
CONFIRMED/INFERRED/UNVERIFIED 标签只适用于子 Agent 的输出。在真实审计中,没人检查协调者自己的总结,所有错误都出在这里。 完整的演示示例见 auditing-and-fixing.md §3a。四条规则:
- 陈述任何测量结果时,都要在同一句中说明测量范围。 *“3 个键共 45 字节”*是在一个页面上测得的;整个应用使用了 15 个键。
- 重复子 Agent 的关键结论前,重新运行能够证明该结论的那条命令。 “两份引擎副本中的税率表已经出现偏差”——这句话是在
diff显示税率表逐字节相同、而另一个函数出现偏差时写下的;它把读者引向了错误的文件。 - 声称某应用做得更好时,要同时说明它没有做到什么。 称该应用“领先于”现有产品,掩盖了它只解决了该功能中简单的那一半。
- 每个专业术语都要在出现的句子中解释,或者换成通俗说法。 “将带版本信息的税率表写入保存的文件” → “保存报告时,也保存它使用的是哪一年的税率,这样以后修正税率时,就不会改变客户之前看到的内容。”
- 断定代码库的某个部分不在范围内。 有四个页面被称为“独立产品”,因为没有任何链接指向它们,而且它们加载了不同的脚本。证据确实如此;但结论错了——
git log显示这些文件自最初导入后就未改动过,而它们的同级文件每周都在变;所有者也已表示,那部分的工作流仍有待梳理。它们是同一产品中尚未完成的模块。规则:断定代码库的某个部分不在范围内之前,先检查其 git 历史并询问所有者。 未被引用的代码可能只是尚未完成,而非来自其他产品:逐个文件运行git log --format="%ad %s" -- <path>成本很低且能给出明确结论;对一组文件则可运行scripts/check-repo.sh --paths <files>。
必做步骤:在 §8 中写下任何内容之前,列出关键结论,并为每条结论指出具体证据——命令、file:line 或你实际操作过的界面。任何无法指出证据的内容都要删除或标注为未经验证。 把清单写下来;这是检查自己工作、而非子 Agent 工作的唯一手段。
7. 将所有内容归入三个类别
这是规则,不是建议(auditing-and-fixing.md §4a)。审计的默认做法是修复,而不是扩展——目标通常是让某项功能上线,而不是让它更丰富。
- 问题——当前存在故障或错误。这是要做的工作,也是唯一会转化为任务的类别。
- 以后可以添加——确实存在的缺口,但暂时搁置。单独列出,绝不放进任务列表。
- 不值得添加——说明原因,这样就能了结这个问题。
功能建议绝不能进入任务列表,包括“既然我们都在这里了”。“缺少这个”属于类别 2;“这个功能已经存在,但给出的答案是错的”属于类别 1。
7a. 未来想法放在哪里——目前没有其他地方
CodeSpring 有功能、笔记、PRD 和看板任务。它没有专门存放“以后可能会构建的内容”的地方,而这些内容绝不能变成任务:任务列表意味着工作已承诺,因此,搁置的想法如果出现在看板上,要么会被意外构建,要么会让看板失去可信度。
**临时约定——每次都要遵守:**未来想法放在仓库的 FINDINGS.md 中,分成两个标题明确的部分,每条占一行,并说明原因:
- “以后可以添加——现在有意暂不处理”——说明搁置原因,以及以后是否值得处理。
- “不值得添加”——说明问题为何已了结,以免反复提出。
这两个部分里的内容都不能变成任务、地图上的功能或 PRD。在文档中明确说明一次这种处理原则。向用户报告这是 FERB 的产品缺口——目前没有专门展示想法、且明确表明想法不代表承诺的界面。
8. 用通俗英语写出发现
完整结构和语气要求见 references/plain-english-writeup.md。以下要求不可妥协:
- **阅读难度大致相当于小学三年级。**使用简短的要点,每个问题配一个具体示例。
- 按现实影响排序——先写影响最大的问题,例如金钱损失或客户信任受损。
- **面向用户的文本中不得出现文件路径、行号或行话。**每条发现都要让不了解什么是数据库迁移的人也看得懂;任何专业术语都要在同一句话中解释。(*“给保存的文件加上版本化税率表的时间戳”没有通过这一标准。“保存报告时,也保存它使用的是哪一年的税率,这样即使之后修正税率,也不会改变客户之前看到的内容”*通过了。)
- 说明哪些地方做得好,并标明这些内容不可破坏。
- 用两个标题明确的部分列出未来想法(§7a): “以后可以添加——现在有意暂不处理”和“不值得添加”,每条占一行,并说明一个原因。
- 在标题中注明审计所依据的提交,以及审查日期——发现是某一时点的记录(§2a)。
- 结尾说明哪些内容未经验证,以及如何验证。
先询问,然后在仓库根目录创建 FINDINGS.md。如果该文件已存在,就在原文件中更新,并保留用户编辑过的内容。**绝不要提交该文件。**质量标准和分节结构见 references/plain-english-writeup.md。
9. 最终判断——重建还是就地修复
**默认选择就地修复。要重建,就必须说明理由。**明确向用户和自己表态:**重建应用的整个架构是一项规模大、风险高的工作,对大多数代码库来说都是错误选择。**这种做法适用于可替代逻辑很少的小型应用——极小的静态 HTML 应用可以考虑重建;几乎其他任何情况都不适合。提醒自己不要过度建议重建:用户陷入困境时会要求重写,同意是最容易的选择,但不是正确的选择。缺陷清单很长,并不能作为重建的证据。
门槛——先于表格询问这个问题,因为它本身就可能否决重建
这个应用有真实用户或付费客户吗?
- 如果有 → 强烈建议就地修复,无论代码有多糟。 重建意味着迁移、切换,以及一段新旧两个版本并存的时期——在运营中的业务可能无法承受这种风险。
- 如果有真实用户,且确实无法避免重建,就需要制定并行运行计划:旧应用继续运行,同时构建新应用,并明确切换和回滚方案。开始工作前,用户必须了解并接受这一点。
- 把陷阱明说出来:这通常意味着新建一个仓库或维护一个长期分支,而同一应用的多个版本分散在不同仓库中,很快就会变得混乱。默认在同一仓库中使用分支;只有当技术栈变化彻底到一个仓库无法容纳新旧两个版本时,才使用单独的仓库。
- “还没有用户”并不意味着应该重建。它只是消除了否决因素,让表格来决定。
| 信号 | 倾向于重建 | 倾向于就地修复 |
|---|---|---|
| 当前架构能否承载应用所需的功能? | 不能——缺失的是结构性部分(没有服务器、没有账户、没有存放数据的地方),而且无法在现有架构中添加 | 能——缺失的部分可以在现有架构中添加 |
| 有多少不可替代的领域逻辑? | 很少,且易于隔离——可以干净地提取出来并迁移过去 | 很多或分布广泛——有价值的知识遍布整个应用,无法提取出来 |
| 整体规模有多大? | 很小——页面、路由和屏幕不多;重写的工作量明确 | 很大——路由、迁移和集成众多;重写是一个范围不明的赌注 |
| 是否有测试或 CI 来保护重构? | 无关紧要——你要替换代码,而不是重构代码 | 大有帮助——能捕获回归问题的测试套件能让就地修复更安全、成本更低 |
应整体判断,不要当作评分表。**要重建,必须通过门槛,**而且第一行的答案必须是“不能”。如果架构能承载所需功能,就应该就地修复,无论代码多难看——难看不等于架构不合适。
基于真实案例,两种方案都做了推演:一个静态 HTML 应用,仓库里没有后端、没有账户、记录只存在于一个浏览器中,也没有真实客户;总计约 8,800 行代码,只有约 470 行不可替代的领域逻辑 → 重建(并有计划地迁移这 470 行)。一个 Next.js 应用,拥有真实的身份验证、133 个迁移、约 142 条授权策略和数百个路由,并存在严重的安全问题 → 就地修复,绝不重建,因为这些问题无一不能在现有架构中修复。
交付内容:建议、门槛问题的答案、决定方案的两三个信号、遵循该方案的实际成本;如果选择重建,还要说明哪些部分应该迁移而不是重写,并在应用正在运行时提供并行运行和回滚计划。同时指出无论选择哪种方案都值得优先开展的高价值工作——在真实案例中,这包括备份未纳入版本控制的后端,以及编写第一套测试;这两项都不需要重建。
10. 移交给地图构建步骤
调用 cs-build-import-codebase,传入调查结果、结论,以及现有地图在梯级上的位置(§0a)。无论结论是什么,它都会构建修正后的目标地图——也就是应用应该呈现的样子;如果已有地图,则会保留或修复,而不是重复创建。不要在此处构建地图;只有一条代码路径负责构建地图。
11. 创建看板任务
任务编写应在 cs-build-import-codebase §7 中进行,因为功能 ID 就在那里定义——不要在这里重新实现。你的工作是提供干净的输入,并检查结果。
针对每条发现,提供:仅限第 1 类发现,每条都包含其严重程度(Critical → urgent,High → high,Medium → medium,Low → low)、证据标签、文件引用,以及所属的核心功能。第 2 类和第 3 类应保留在报告中,不得出现在任务列表里。
然后确认任务形式符合判定结果:
- 重建 → 按规格构建的任务 加上一组单独的“需要避免的错误”任务,将发现的具体缺陷纳入其中,以免再次引入。这第二组任务正是先进行审计的全部意义——如果缺少它,交接就失败了。
- 原地修复 → 每个缺陷对应一个任务,注明缺陷所在位置,并在描述中包含文件引用(面向用户的文本中没有文件引用;任务需要包含,因为 Agent 必须据此采取行动)。
未验证的发现应作为调查任务,并保留其标签——绝不能将其写成确定的修复任务。
12. 验证,然后报告
运行检查,不要凭目测判断(auditing-and-fixing.md §9):
bash ../codespring/scripts/fetch-project.sh --out /tmp/cs-verify
node ../codespring/scripts/check-map.mjs /tmp/cs-verify --expect-core <the count you intended>
该检查会断言核心功能数量正确、子功能未被扁平化、没有重复功能或 PRD、每个核心功能都有一条说明,以及每个任务都关联了功能并标注严重程度。退出码非零就意味着确实失败——报告前先修复。然后直截了当地报告差异——创建 N 项、更新 N 项、跳过 N 项——并提供项目链接 https://v2.codespring.app/project/<projectId>。
做得好的表现
- 确实运行了应用,并且至少有一条发现无法仅通过阅读代码得出。
- 每条发现都引用
file:line或一条命令,并标注为 CONFIRMED / INFERRED / UNVERIFIED;标题中的数字已独立复核。 - 你自己的标题结论在写出前都已列出并附上证据,每项测量都说明了范围,而且没有任何结论比子 Agent 实际发现的更肯定。
- 审计前已将克隆版本与远程版本进行比较,注明了发现所依据的提交,并询问用户仓库中还有谁,以及应用是否已完成。
- 已审计 git/CI/部署设置,并让用户知道其后端是否有备份,以及是否有任何因素会阻止部署。
- 面向用户的发现使用平实语言,按成本排序,不包含文件路径;好处和问题都说清楚——包括某项“优于竞争对手”的功能仍然做不到什么。
- 问题、可后续添加的内容和不值得添加的内容各自分开;任务列表只包含问题,未来想法则放在两个指定的
FINDINGS.md章节中。 - 已询问并确认用户门槛条件,给出判定及理由;除非应用没有用户 且 架构确实无法承载所需内容,否则应选择“原地修复”。
- CodeSpring 中没有任何内容被重复创建——保留了已有的映射,或直接在原处修复;只有在获得明确确认后,才创建第二个项目。