dogfood-cli

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Dogfood the vigiles CLI (expert find + fix fan-out)

内部测试vigiles CLI(专家级查找+修复分支流程)

The repeatable method for finding real bugs in vigiles by running the tool on itself and on real plugins, then FIXING them — not filing them. This is how the 2026-07 batch found and fixed 14 source-traced bugs.
通过在工具自身及真实插件上运行vigiles来查找真实漏洞并直接修复的可复用方法——而非仅提交漏洞报告。2026年7月批次就是通过这种方式找到了14个可溯源的漏洞并完成修复。

When to use

使用场景

  • "Dogfood the CLI", "find more bugs the source-traced way", "fan out agents to audit vigiles on itself", "hunt for false positives in audit/lint".
  • NOT for a single known bug (just fix it) and NOT for shipped consumer features (this is a contributor-only dev process;
    .claude/
    is not published).
  • 适用场景:“内部测试CLI”、“以溯源方式查找更多漏洞”、“分支多个Agent来审计vigiles自身”、“排查审计/ lint中的误报”。
  • 不适用场景:单个已知漏洞(直接修复即可)、已发布的消费者功能(这是仅面向贡献者的开发流程;
    .claude/
    目录不会对外发布)。

The loop

流程循环

fan out (parallel experts) → synthesize + VERIFY each finding → fix directly
   → regression test → build → targeted test → commit per theme → FULL SUITE → push
fan out (parallel experts) → synthesize + VERIFY each finding → fix directly
   → regression test → build → targeted test → commit per theme → FULL SUITE → push

1. Fan out over DISTINCT surfaces

1. 针对不同维度分支并行

Spawn several agents (Sonnet — cheap parallel reads/traces; no synthesis needed per agent), each owning ONE surface so they don't overlap. The surface map that has paid off:
  • compile / eject — round-trip correctness, frontmatter/data loss, integrity.
  • audit / lint false-positives — a real plugin must stay CLEAN (don't cry wolf); phantom paths; glob/quote tokens misread; comment-only matches.
  • init / scaffold edge cases — no
    package.json
    , config-driven
    harness
    , malformed frontmatter,
    --target
    , the scaffolded CI workflow,
    --test
    /
    --lint
    .
  • config parse-don't-validate
    .vigilesrc.json
    severities (
    "off"
    /0/1/2), string-or-array keys, unknown values.
  • CLI error UX — an unknown flag/harness must print a clean message + exit 2, never a raw Node stack trace.
  • cross-harness (CC + Codex) + browser/disk parity
    scanFiles
    must match
    scanPlugin
    byte-for-byte; a Codex-shaped repo must not be scanned as CC.
Tell each agent: SOURCE-TRACE every bug to
file:line
+ a proposed fix.
A finding without a trace is a lead, not a bug.
启动多个Agent(推荐Sonnet——低成本并行读取/溯源;无需每个Agent单独进行整合),每个Agent负责一个独立维度,避免工作重叠。已验证有效的维度划分如下:
  • 编译 / 导出——往返正确性、前置数据/内容丢失、完整性。
  • 审计 / lint误报——真实插件必须保持“清洁”(不能误报);虚假路径;通配符/引号解析错误;仅注释匹配。
  • 初始化 / 脚手架边缘案例——无
    package.json
    、配置驱动的
    harness
    、格式错误的前置内容、
    --target
    参数、脚手架生成的CI工作流、
    --test
    /
    --lint
    参数。
  • 配置解析(不验证)——
    .vigilesrc.json
    中的严重程度(
    "off"
    /0/1/2)、字符串或数组类型的键、未知值。
  • CLI错误体验——未知标志/harness必须输出清晰的错误信息并以状态码2退出,绝不能显示原始Node栈追踪。
  • 跨harness(CC + Codex)+ 浏览器/磁盘一致性——
    scanFiles
    必须与
    scanPlugin
    逐字节匹配;Codex结构的仓库不能被当作CC扫描。
告知每个Agent:将每个漏洞溯源至
file:line
并提出修复方案
。没有溯源信息的发现只能算作线索,不能视为漏洞。

2. Synthesize + VERIFY yourself

2. 自行整合并验证

Agents over-report. Before touching anything, reproduce each finding yourself (run the real built CLI on a tmp fixture or a vendored
test/dogfood/*
plugin). Discard what doesn't repro. Confirm the exact
file:line
.
Agent的报告可能存在过度上报。在动手修复前,需自行复现每个发现(在临时测试环境或
test/dogfood/*
目录下的供应商插件上运行已构建的真实CLI)。丢弃无法复现的内容,确认准确的
file:line
位置。

3. FIX directly — don't file

3. 直接修复——而非提交漏洞报告

A deterministic, source-traced bug needs no issue: fix it. File an issue ONLY when the fix is genuinely ambiguous (several valid interpretations, or an architecturally significant change the founder should weigh in on). "Fix, not file" is the founder's standing call for this loop.
Per fix:
  • Repro → fix → regression test →
    npm run build
    → targeted
    vitest
    → commit.
  • One theme per commit. Conventional Commit subject; end the body with the
    Co-Authored-By: Claude …
    trailer. NEVER a session URL or a raw model id (public repo — see the
    no-session-links
    / model-identity rules).
  • The fix must be high-precision — a false-positive fix must not silently UNDER-detect (don't trade crying wolf for missing the real thing).
  • Honor the architecture: a shared detector has ONE home (
    one-detector-no-drift
    );
    core ⊄ adapter
    ; no CC literal in
    src/core/**
    or the agnostic detectors.
可确定且可溯源的漏洞无需创建Issue:直接修复。仅当修复方案存在真正的歧义(多种有效解读,或涉及架构层面的重大变更需创始人权衡)时,才需创建Issue。“修复而非上报”是创始人对此流程的明确要求。
每个修复需遵循:
  • 复现→修复→回归测试→
    npm run build
    →针对性
    vitest
    测试→提交代码
  • 每个提交对应一个主题。使用约定式提交的主题;提交说明末尾添加
    Co-Authored-By: Claude …
    标记。禁止提交会话URL或原始模型ID(公共仓库——需遵守
    no-session-links
    /模型身份规则)。
  • 修复必须高精度——误报修复不能导致检测不足(不能以漏报真实漏洞为代价解决误报问题)。
  • 遵循架构规范:共享检测器只能有一个归属地(
    one-detector-no-drift
    );
    core
    不能包含在
    adapter
    中;
    src/core/**
    目录或通用检测器中不能出现CC字面量。

Hard-won discipline (the lessons)

经验总结(教训)

  • Serialize/merge fixes that touch SHARED files (
    src/cli.ts
    ,
    src/scan-core.ts
    ). Parallel edits to the same file conflict — do those sequentially, or give each agent its own git worktree (
    isolation: "worktree"
    ).
  • RUN THE FULL SUITE before declaring done. A strict assertion in an unrelated test file can only surface in the whole run — the I2 fix changed an install command and a strict regex in a different e2e file broke; per-file runs were all green, the full
    vitest run
    caught it.
  • Rebuild after every source edit — the e2e tests run
    dist/cli.js
    , so a stale
    dist/
    silently tests the old code.
  • Watch the parity gate. Any change to a scan detector must keep
    scanFiles ↔ scanPlugin
    byte-identical (
    src/scan-files.test.ts
    ); if the disk side gains a field, the browser side needs it too.
  • Prettier +
    fmt:check
    before commit
    — markdown code spans need surrounding spaces; CI runs
    fmt:check
    .
  • Coverage gate is an allowlist (
    vitest.config.mjs
    coverage.include
    ) — a new file under it needs 100%; scan/cli files are NOT in it today.
  • 序列化/合并涉及共享文件的修复(如
    src/cli.ts
    src/scan-core.ts
    )。对同一文件的并行编辑会导致冲突——需按顺序处理,或为每个Agent分配独立的git工作树(
    isolation: "worktree"
    )。
  • 完成前必须运行全量测试套件。无关测试文件中的严格断言只有在全量运行时才会暴露——I2修复修改了安装命令,导致另一个e2e文件中的严格正则表达式失效;单文件测试全部通过,但全量
    vitest run
    检测到了问题。
  • 每次源码编辑后重新构建——e2e测试运行的是
    dist/cli.js
    ,过时的
    dist/
    目录会导致测试的仍是旧代码。
  • 关注一致性校验。扫描检测器的任何变更必须保持
    scanFiles ↔ scanPlugin
    逐字节一致(
    src/scan-files.test.ts
    );如果磁盘端新增了字段,浏览器端也需要同步添加。
  • 提交前运行Prettier +
    fmt:check
    ——Markdown代码块需要前后空格;CI会运行
    fmt:check
  • 覆盖率校验是白名单机制
    vitest.config.mjs
    中的
    coverage.include
    )——白名单下的新文件需要达到100%覆盖率;目前扫描/CLI文件不在白名单中。

The two recurring bug classes — hunt for them, then PREVENT the class

两类常见漏洞——查找并预防此类问题

Almost every bug this repo has produced is one of two shapes. When you find one instance, GREP for its siblings, and add a GATE so the class can't come back.
本仓库中出现的几乎所有漏洞都属于以下两类。当发现一个实例时,需搜索同类问题,并添加校验机制防止此类问题再次发生。

1. An unverified assumption about an EXTERNAL contract

1. 对外部契约的未验证假设

Code that guesses how an external thing behaves without checking: a CLI flag's format (the
skills
-s
was assumed comma-separated, is space-separated → the install exited 1), a harness's frontmatter key (skills use
allowed-tools
, not
tools:
), git's behavior (
git config origin
in a subdir walks UP to the parent repo), module resolution (
vigiles
can't resolve without a package.json), a linter's enabled-state (a checkstyle
severity=ignore
module is disabled).
  • PARSE, DON'T VALIDATE the boundary. Read the REAL contract before coding — the tool's
    --help
    , its arg parser in
    node_modules
    ,
    git rev-parse
    , the linter's own status logic. Don't guess; verify.
  • Add a UNIT assertion of the command/format's SHAPE, not just a network/binary-gated e2e. The e2e that runs the real command SKIPS in dev (no network / no
    claude
    / no linter binary), so it's not a reliable guard — CI is the only place it runs. A unit test that parses the constructed command the SAME way the external tool does (e.g. the
    -s
    space-split assertion in
    setup-plan.test.ts
    ) fails fast, offline, on a regression.
代码在未验证的情况下猜测外部事物的行为:CLI标志的格式(
skills
-s
参数被假设为逗号分隔,实际是空格分隔→安装失败,状态码1)、harness的前置内容键(skills使用
allowed-tools
而非
tools:
)、git的行为(子目录中执行
git config origin
会向上遍历至父仓库)、模块解析(无
package.json
时vigiles无法解析)、linter的启用状态(checkstyle中
severity=ignore
的模块会被禁用)。
  • 解析而非验证边界。编码前先查阅真实契约——工具的
    --help
    信息、
    node_modules
    中的参数解析器、
    git rev-parse
    、linter自身的状态逻辑。不要猜测,要验证。
  • 添加对命令/格式结构的单元断言,而不仅仅是依赖网络/二进制限制的e2e测试。运行真实命令的e2e测试在开发环境中会跳过(无网络/无
    claude
    /无linter二进制),因此无法作为可靠的防护——仅在CI环境中运行。单元测试以与外部工具相同的方式解析构造的命令(例如
    setup-plan.test.ts
    中对
    -s
    空格分隔的断言),可以在回归时快速离线失败。

2. An incomplete fix — SOME call-sites of a pattern, not all

2. 不完整的修复——仅修复了部分调用点

A pattern fixed in one place but left live elsewhere:
audit
/
init
honoured
config.harness
but
test
/
eval
/
generate harness
didn't;
E1
fixed
ScanAgent.path
but not the frontmatter-family findings; comment-stripping was added to one detector but not the next.
  • GREP for every instance of the pattern the moment you fix one.
  • MAKE-INVALID-STATES-IRREPRESENTABLE — one choke-point. Route every caller through a single helper (e.g.
    resolveCommandHarness
    ) so a new call-site can't bypass it, and add a gate test that FAILS if the old path reappears (
    cli-harness-resolution.test.ts
    asserts
    cli.ts
    never calls the raw detector).
  • Detectors that scan raw text share a hazard (matching inside comments / examples / illustrative prose) — check the shared text-context helpers exist and are REUSED, not re-copied per detector, and keep the FP-guard fixtures green.
仅在一处修复了模式,但其他地方仍存在问题:
audit
/
init
遵循了
config.harness
test
/
eval
/
generate harness
未遵循;
E1
修复了
ScanAgent.path
但未修复前置内容相关的发现;仅为一个检测器添加了注释剥离功能,其他检测器未添加。
  • 修复一个实例后立即搜索所有同类模式
  • 使无效状态无法表示——单一入口。将所有调用者路由至单个辅助函数(例如
    resolveCommandHarness
    ),确保新的调用点无法绕过,并添加校验测试,若旧路径重新出现则失败(
    cli-harness-resolution.test.ts
    断言
    cli.ts
    从不直接调用原始检测器)。
  • 扫描原始文本的检测器存在共同风险(匹配注释/示例/说明性文本)——检查共享文本上下文辅助函数是否存在并被复用,而非每个检测器重复编写,同时保持误报防护测试用例通过。

NOT this skill

不属于本技能范畴

The blind-agent onboarding dogfood (a fresh agent runs
npx vigiles init
on a real repo across an OS matrix in GHA + a subscription eval) is a SEPARATE, roadmapped e2e — do not fold its OS-matrix here. This skill is the in-repo find+fix loop; that one measures the cold onboarding experience end-to-end.
新Agent入门内部测试(新Agent在GHA的OS矩阵中对真实仓库运行
npx vigiles init
并进行订阅评估)是一个独立的、已规划的e2e测试——请勿将其纳入本流程。本技能是仓库内的查找+修复循环;而前者是端到端衡量首次体验的流程。