OpenRig 防御纵深调试:systematic-debugging 技能中的多层验证(Defense-in-Depth)模式全解

📅 发布时间:2026/10/9 2:26:21
OpenRig 防御纵深调试:systematic-debugging 技能中的多层验证(Defense-in-Depth)模式全解
人工智能AI Agent多智能体Agent 编排代码智能体CLI【免费下载链接】openrigBuild your own network of agents from Claude Code, Codex and Pi: persistent teams with roles, shared context and owned work.项目地址https://gitcode.com/GitHub_Trending/op/openrig点击查看免费下载本文解析 openrig 仓库systematic-debugging技能包中的 Defense-in-Depth防御纵深验证模式为什么修一个坏数据引发的 bug 时只加一处校验远远不够以及如何通过入口校验、业务逻辑校验、环境守卫、调试埋点四层防线把 bug 变成结构性不可能。读完后你将掌握该模式的四层代码写法、从真实会话沉淀的完整案例流程以及它与同目录root-cause-tracing、condition-based-waiting技术的组合关系。文档在 openrig 中的位置defense-in-depth.md 是 openrig 内置技能体系中的一个规范性文档位于skills/_canonical/process/systematic-debugging/目录下。该目录的 SKILL.md 定义了系统化调试技能的整体流程——铁律是NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST未做根因调查前禁止提出修复并按 Phase 14 推进根因调查、模式分析、假设与测试、实施修复。defense-in-depth.md在其中的角色是Phase 4实施修复之后的配套技术SKILL.md 的 Supporting Techniques 一节明确列出root-cause-tracing.md—— 沿调用栈回溯 bug 的原始触发点defense-in-depth.md—— 找到根因后在多层添加验证condition-based-waiting.md—— 用条件轮询替代任意超时。也就是说回溯到源头解决的是在哪里修的问题而防御纵深解决的是修完之后如何防止复发的问题。同目录的 root-cause-tracing.md 中的决策图也直接给出了两者的衔接Trace to original trigger 之后紧跟 BETTER: Also add defense-in-depth。值得注意的仓库级细节openrig 将这套技能逐字 vendoredSKILL.md 的 frontmatter 标注vendoring_pattern: vendored-as-is注明上游为 Obra Superpowers 技能并且在 packages/daemon/specs/agents/shared/skills/process/systematic-debugging/defense-in-depth.md 保留了一份与_canonical版本内容一致的镜像副本。从目录结构看specs/agents/shared/skills/是随 agent 规格分发给各 rig 内 agent 的技能包镜像这意味着 defense-in-depth 模式不仅写给人类开发者也是 openrig 中 agent 在调试会话中被要求遵循的流程规范。核心原则让 bug 结构性不可能文档开篇点明了单一校验的困境当你修复一个由坏数据引起的 bug 时在某处加上校验会让人觉得够了。但这个单点校验可能被不同的代码路径、重构或 mock 绕过。核心原则在数据经过的每一层都进行验证使 bug 在结构上不可能发生。文档用一个对比概括了两者的本质差异单一验证我们修好了这个 bug多层验证我们让这个 bug 不可能发生四层各自的职责划分如下这是后文所有示例的骨架层职责拦截什么Layer 1: Entry Point Validation在 API 边界拒绝明显非法的输入大多数 bugLayer 2: Business Logic Validation确保数据对当前操作是有意义的边界情况Layer 3: Environment Guards在特定上下文中阻止危险操作上下文相关的危险Layer 4: Debug Instrumentation为事后取证捕获上下文其他层全部失效时的最后线索四层验证的完整实现以下代码示例完整继承自原文档TypeScript并逐层说明设计意图。Layer 1入口点校验Entry Point Validation目的在 API 边界拒绝明显非法的输入。function createProject(name: string, workingDirectory: string) { if (!workingDirectory || workingDirectory.trim() ) { throw new Error(workingDirectory cannot be empty); } if (!existsSync(workingDirectory)) { throw new Error(workingDirectory does not exist: ${workingDirectory}); } if (!statSync(workingDirectory).isDirectory()) { throw new Error(workingDirectory is not a directory: ${workingDirectory}); } // ... proceed }注意这一层做了三个递进检查而非一个非空含 trim 后的空串、存在、是目录。错误信息里都带上了实际的workingDirectory值——这一点呼应了 Layer 4 的精神即让报错信息自带诊断上下文。从 openrig 自身源码看这种入口拒绝非法目录的风格是实际落地的模式例如 bundle-carried-project.ts 中对项目目录的前置校验throw new Error(project directory ${projectDir} does not exist);可以推断daemon 侧在消费 bundle 内项目声明时同样遵循边界即拒绝的防御思路而非把坏路径留给下游。Layer 2业务逻辑校验Business Logic Validation目的确保数据对当前操作是有意义的。function initializeWorkspace(projectDir: string, sessionId: string) { if (!projectDir) { throw new Error(projectDir required for workspace initialization); } // ... proceed }Layer 2 与 Layer 1 的区别在于同一份数据在不同操作下有不同的约束。一个路径对createProject合法对initializeWorkspace可能不合法。这一层拦截的是技术上非空、但语义上不适用于本操作的数据。它同时也是防 mock 绕过的关键层——测试替身常常只模拟了入口而不会走到业务函数。Layer 3环境守卫Environment Guards目的在特定上下文中阻止危险操作。async function gitInit(directory: string) { // In tests, refuse git init outside temp directories if (process.env.NODE_ENV test) { const normalized normalize(resolve(directory)); const tmpDir normalize(resolve(tmpdir())); if (!normalized.startsWith(tmpDir)) { throw new Error( Refusing git init outside temp dir during tests: ${directory} ); } } // ... proceed }这一层是四层中最容易被省略、也最容易被低估的。它的要点按环境切换行为只在NODE_ENV test下收紧不污染生产路径路径规范化先行normalize(resolve(...))保证..、相对路径、符号链接前缀差异不会让前缀匹配失效守卫对象是操作 × 上下文的组合git init本身无害但在测试期间于临时目录之外执行 git init会把 git 仓库初始化到源码树里属于上下文相关的危险操作。跨平台提示该守卫依赖系统tmpdir()作为安全区文档 Key Insight 一节也提到不同平台上的边界情况需要环境守卫即 Windows 等平台的临时目录解析差异正是这一层要吸收的方差。Layer 4调试埋点Debug Instrumentation目的为事后取证捕获上下文。async function gitInit(directory: string) { const stack new Error().stack; logger.debug(About to git init, { directory, cwd: process.cwd(), stack, }); // ... proceed }Layer 4 不拦截任何东西它回答的问题是当前三层都没拦住、bug 还是发生了我怎么知道是谁、在什么状态下、以什么调用链触发的示例中记录了三个字段目标directory、进程实际的cwd、完整调用栈。对于git init 跑错了目录这类 bugdirectory与cwd的差异本身就是最强的诊断信号——这正是根因回溯root-cause-tracing在取证时需要的原材料。真实案例空 projectDir 导致 git init 落在源码目录文档 Example from Session 一节记录了一次真实的调试会话完整展示了四层如何协同。这也是root-cause-tracing.md通篇引用的同一案例该文档中git init failed in .../packages/core的症状即源于此。Bug 描述空的projectDir导致git init在源代码目录中执行。数据流Data flow回溯测试 setup 传入空字符串Project.create(name, )WorkspaceManager.createWorkspace()git init在process.cwd()中执行——空串作为cwd会解析为进程当前目录也就是源码树随后添加的四层防线Layer 1Project.create()校验非空 / 存在 / 可写Layer 2WorkspaceManager校验 projectDir 非空Layer 3WorktreeManager在测试中拒绝于 tmpdir 之外执行 git initLayer 4git init 前记录调用栈日志结果全部 1847 个测试通过bug 无法复现。这个案例值得展开两点其一数据流四步中没有任何一步抛出了异常坏值一路穿透到副作用点才暴露——单靠 Layer 1 无法覆盖步骤 2→3 之间被其他路径或 mock 绕过的情形其二Layer 3 的守卫让即使前三层全被绕过测试环境也不可能把源码目录变成 git 仓库破坏半径被限制在临时目录内。应用流程从发现 bug 到落地四层文档 Applying the Pattern 一节给出了四步操作法Trace the data flow追踪数据流——坏值从哪里起源在哪里被使用Map all checkpoints绘制所有检查点——列出数据经过的每一个点Add validation at each layer在每层加校验——入口层、业务层、环境层、调试层Test each layer逐层测试——尝试绕过 Layer 1验证 Layer 2 能接住它再绕过 Layer 2验证 Layer 3 能接住依此类推第 4 步是容易被跳过的关键点防御纵深不是加了四层就完事而是要用绕过性测试证明每一层独立生效。否则四层中可能存在同构的重复检查真正的旁路路径依然畅通。为什么四层缺一不可文档 Key Insight 一节给出了来自测试实践的直接证据四层都是必需的测试期间每一层都接住了其他层漏掉的 bug不同的代码路径绕过了入口校验Layer 1 失效Layer 2 接住mock 绕过了业务逻辑检查Layer 2 失效Layer 3 接住不同平台上的边界情况需要环境守卫Layer 3 独有的职责调试日志揭示了对代码的结构性误用Layer 4 独有的取证价值。结论句直接而强硬Dont stop at one validation point. Add checks at every layer.不要止步于一个校验点在每一层都加检查。与仓库内其他机制的呼应从源码结构看defense-in-depth 的思想在 openrig 代码库中不止存在于技能文档里而是有实际的工程落点可以作为该模式在真实代码中长什么样的佐证入口拒绝式校验bundle-carried-project.ts、bundle-carried-context-pack.ts 等 bundle 消费入口都对目录类前置条件直接throw错误消息携带具体路径值符合 Layer 1 的边界拒绝 自描述报错写法技能分发链路SKILL.md 声明openrig.vendored_from与last_upstream_check配合 packages/daemon/specs/agents/shared/skills/process/systematic-debugging/defense-in-depth.md 的镜像副本构成canonical 技能 → agent 规格镜像的分发结构。也就是说rig 内由 Claude Code / Codex 等驱动的 agent 在执行系统化调试时遵循的正是本文解析的同一套四层规范同族技术组合systematic-debugging目录下还有 condition-based-waiting.md用条件轮询替代任意超时含 condition-based-waiting-example.ts 示例实现和 find-polluter.sh与 defense-in-depth 共同构成定位 → 修复 → 防复发的完整闭环上游技能体系还关联了verification-before-completion宣称成功前先验证在本仓库对应 skills/_canonical/process/verification-before-completion/SKILL.md。适用前提与限制使用本文模式时需要注意三个前提它以根因调查为前提defense-in-depth 是 Phase 4 之后的加固手段不是替代品。SKILL.md 的铁律要求先完成 Phase 13根因、模式、假设跳过根因直接堆校验只会把 bug 推得更深而不是消灭它成本与数据敏感度权衡四层校验意味着每次数据穿越都付出检查与潜在的日志成本对于热路径上的高频数据Layer 1/2 应保留、Layer 4 的完整栈捕获通常应降级为采样或 debug 级开关案例数据是文档自述文中1847 个测试通过等数字来自技能文档对历史调试会话的自述属于该会话快照不随当前仓库测试套件变化引用时应以上下文限定而非作为当前仓库的测试规模事实。总结来说openrig 的systematic-debugging技能把防御纵深从一句口号落实成了可操作的四层清单与逐层绕过测试法入口层拒绝非法输入、业务层约束操作语义、环境层限制危险上下文的破坏半径、调试层保留事后取证能力——四层各自独立生效共同把修好了这个 bug升级为让这个 bug 不可能发生。赞分享人工智能AI Agent多智能体Agent 编排代码智能体CLI【免费下载链接】openrigBuild your own network of agents from Claude Code, Codex and Pi: persistent teams with roles, shared context and owned work.项目地址https://gitcode.com/GitHub_Trending/op/openrig点击查看免费下载相关推荐openrig Systematic Debugging 技能解析以根因为先的四阶段调试方法论openrig Systematic Debugging 技能解析以根因为先的四阶段调试方法论 本文围绕 openrig 仓库中 vendored 的 sys人工智能AI Agent多智能体Agent 编排代码智能体CLIopenrig 系统化调试之纵深防御验证让数据缺陷在结构上变得不可能openrig 系统化调试之纵深防御验证让数据缺陷在结构上变得不可能 当一次修复只解决眼前这个 bug时下一次改动、重构、Mock 或新代码路径随时会让人工智能AI Agent多智能体Agent 编排代码智能体CLIOpenRig Systematic Debugging 技能深度解析Agent 根因定位的四阶段铁律与实战方案OpenRig Systematic Debugging 技能深度解析Agent 根因定位的四阶段铁律与实战方案 本文以 OpenRig 仓库中内置的 sys人工智能AI Agent多智能体Agent 编排代码智能体CLI上一篇FoliaNavidromeDockerNAS上一站式私有音乐站完整部署教程下一篇ThinkPad终极静音方案TPFanCtrl2双风扇智能控制完全指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考