Skip to content

docs(pilot): 补 .pilot.yml + 规划层七件套(适配层),门禁 0/7 → 7/7 - #46

Merged
jhfnetboy merged 1 commit into
mainfrom
docs/pilot-planning-layer
Aug 5, 2026
Merged

docs(pilot): 补 .pilot.yml + 规划层七件套(适配层),门禁 0/7 → 7/7#46
jhfnetboy merged 1 commit into
mainfrom
docs/pilot-planning-layer

Conversation

@jhfnetboy

Copy link
Copy Markdown
Member

这是 pilot 端到端测试的第一个产物。pilot doctor 发现本地未就绪,pilot plan 补齐。

为什么是「适配层」而不是规划本身

Brood 的规划事实来源是 backlog/:4 个 milestone、49 个带验收标准的 task、2 个 ADR ——
比多数仓库完整。但 check-docs.sh --strict0/7,run 直接 fail-closed 拒跑,
因为它只认 docs_dir 下那七个固定文件名。

plan.md A.3 明写「已有规划 → 不要重复造」。两条同时遵守是不可能的。

所以七件套写成指向 backlog/ 的视图:每份开头声明「本文件是视图,不是事实来源,
改规划请改 backlog/」,内容是摘要 + 怎么读 + 怎么挑下一个,不复制任务条目

内容不是模板填空

七份都写了本仓库的真实约束,其中几条是今天用出来的教训:

  • architecture.md — 分层强制 ①GitHub 分支保护 ②hook(未建) ③git-guard ④散文,
    「越往下越不可信」;任何「这条护栏保证了 X」必须能指到 ① 或 ③ 的具体代码行,
    指不到就只是 ④。今天三个「守卫跑不起来」的教训都出在把 ③ 当成 ① 来信。
  • architecture.md放权必须先建立证据:--allow-trunk / --squash-merged
    都是先要服务端证明,不是「为了让守卫能跑就削弱它」。
  • spec.md — 每步失败必须 fail-closed,且**「查不了」与「没有」在输出上必须可区分**。
    这条踩过:子 shell 里设的状态返回后丢失,「无法核实」永远打印成「没有可清理的」。
  • spec.md — 解析外部 JSON 只取 stdout;折进 stderr 会让 shell hook 的诊断行污染 JSON。
  • acceptance.md — 单列「已知未达标项」,不掩盖:三阶段主流程从未端到端跑过、
    SKILL.md 自称的首要强制手段(PreToolUse hook / TASK-40)实现为空。

.pilot.yml

integration_branch: main —— Brood 是单主干,pilot 默认的 preview 对本仓库是错的。

不设 preflight: —— preflight.sh 已自动发现 scripts/ci/*.{sh,py} 与 build,
显式再写一条只会让同一个检查跑两遍(初稿写了,自查时删掉)。

账本新增两条 —— 测试挖出来的 pilot 缺陷

内容
FU-5 B 门禁应支持可配置规划源,否则每个用 backlog/ / issues / Jira 管规划的仓库都会被判「未就绪」
FU-6 C doctor 在单主干仓库会把人往「去建 preview」引,而正确答案是 integration_branch: main + --allow-trunk;doctor 不知道这两件事是连着的

这两条读代码都看不出来 —— 和今天那三个守卫一样,只有真跑才现形。

验证

check-docs.sh --docs-dir docs/agent --strict
→ PILOT_DOCS: mode=strict dir=docs/agent min_bytes=120 ok=7/7
→ PILOT_DOCS: ready — planning layer complete, safe to run unattended.
→ rc=0

preflight.sh 4/4 通过。

自审

等级 B(344 净变更行),3 轮:①内容真实性(每条断言都能指到仓库里的具体文件/行,
不写模板套话)②内部一致性(七份之间、与 backlog/ 之间无矛盾;.pilot.yml
preflight: 冗余在这一轮删掉)③门禁真跑(不是读代码判断,是 rc=0 实测)。

端到端测试 pilot 的产物。跑 `pilot doctor` 发现本地未就绪,`pilot plan` 补齐。

## 为什么是「适配层」而不是规划本身

Brood 的规划事实来源是 `backlog/`:4 个 milestone、49 个带验收标准的 task、2 个 ADR ——
比多数仓库完整。但 `check-docs.sh --strict` 报 **0/7**,`run` 直接 fail-closed 拒跑,
因为它只认 `docs_dir` 下那七个固定文件名。

而 `plan.md` A.3 明写「已有规划 → 不要重复造」。**两条同时遵守是不可能的。**

所以七件套写成**指向 backlog/ 的视图**:每份开头声明「本文件是视图,不是事实来源,
改规划请改 backlog/」,内容是摘要 + 怎么读 + 怎么挑下一个,不复制任务条目。

## 内容不是模板填空

七份都写了本仓库的真实约束,其中几条是今天用出来的教训:

- `architecture.md`:分层强制 ①GitHub 分支保护 ②hook(未建) ③git-guard ④散文,
  「越往下越不可信」;任何『这条护栏保证了 X』必须能指到 ① 或 ③ 的具体行
- `architecture.md`:**放权必须先建立证据** —— `--allow-trunk` / `--squash-merged`
  都是先要服务端证明,不是「为了让守卫能跑就削弱它」
- `spec.md`:每步失败必须 fail-closed,且「查不了」与「没有」在输出上**必须可区分**
  (这条踩过:子 shell 里设的状态返回后丢失,「无法核实」永远打印成「没有可清理的」)
- `spec.md`:解析外部 JSON **只取 stdout** —— 折进 stderr 会让 shell hook 的诊断行污染 JSON
- `acceptance.md`:单列「已知未达标项」,包括三阶段主流程从未端到端跑过、
  以及 SKILL.md 自称的首要强制手段(PreToolUse hook)实现为空

## .pilot.yml

`integration_branch: main` —— Brood 是单主干,pilot 默认的 `preview` 对本仓库是错的。
不设 `preflight:`,因为 preflight.sh 已自动发现 `scripts/ci/*.{sh,py}` 与 build,
显式再写一条只会让同一个检查跑两遍。

## 账本新增两条(测试挖出来的 pilot 缺陷)

- FU-5(B):门禁应支持可配置规划源,否则每个用 backlog/issues/Jira 管规划的仓库
  都会被判「未就绪」
- FU-6(C):doctor 在单主干仓库会把人往「去建 preview」引,而正确答案是
  `integration_branch: main` + `--allow-trunk`;doctor 不知道这两件事是连着的

验证:`check-docs.sh --docs-dir docs/agent --strict` → `ok=7/7`、
`PILOT_DOCS: ready — planning layer complete, safe to run unattended.`、rc=0

Claude-Session: https://claude.ai/code/session_01CmAW1q62bBtjT99inZeyLk
@jhfnetboy
jhfnetboy requested a review from clestons as a code owner August 5, 2026 08:17

@clestons clestons left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APPROVE — 头条主张实测成立,且这是少见的「不掺水」的规划层 PR

两条核心断言都实跑验过:

check-docs.sh --docs-dir docs/agent --strict
→ PILOT_DOCS: mode=strict dir=docs/agent min_bytes=120 ok=7/7
→ ready — planning layer complete, safe to run unattended.     rc=0

preflight.sh run
→ PREFLIGHT: ok — 4/4 passed. Stamped HEAD d6fdb21 (grade A)

「不设 preflight:」这个删减也复算过是对的 —— 自动发现确实覆盖了 scripts/ci/ 下全部三个脚本(check-docs-gate.sh / check-task-yaml.py / check-version-sync.sh)加 build,显式再写一条只会让同一检查跑两遍。

七件套里可查的断言逐条核过,全部成立:49 tasks / 4 milestones / 2 ADRs;To Do 27 / In Progress 15 / Done 7;按里程碑的 In-Progress 拆分 m-1=5 / m-r=5 / m-3=3 / m-2=2 与 roadmap.md 逐位对得上;TASK-40 确实是 status: To Doplugin.json 确实没有 hooks 段,所以「PreToolUse hook 实现为空」是准确的;SKILL.md:41 的引述一字不差;13 处引用路径全部 resolve,零悬空引用task-schema.md 确实是五态;git-guard.sh 的退出码(2=用法错 / 3=die)与 spec.md 的约定一致;七份都以 12-20 倍余量越过 120 字节门槛,不是卡边过。

.pilot.yml 在真解析器下是干净的protect_patterns: [release, hotfix, cla-signatures] 用的 inline flow 形式被 git-guard.sh:39 正确解析(PROTECTED=…,release,hotfix,cla-signatures),实测 git-guard.sh push origin cla-signatures → BLOCKED。而 .github/workflows/cla.yml:36cla-signatures 走的是服务端 Action、不经 git-guard,所以保护这个名字只拦本地误推、不会打断 CLA 流水线 —— 这个取舍是对的。

已知未达标项 主动写了「三阶段主流程从未端到端跑过」和「SKILL.md 自称的首要强制手段实现为空」;FU-5 / FU-6 指的是根因(固定文件名的门禁 vs 真实规划源)而不是给自己打补丁。这是本 PR 最有价值的部分。

以下全部 非阻塞


⚠️ 一条需要在合并动作上注意的(不是代码问题)

docs/agent/followups.md:22 —— 和在途的 #45 在同一个 append-only 账本上有真冲突。

#45 把 FU-1~FU-4 改成 [x] … done=PR#45 并在第 14 行后插入「⚠️ 再更正」块;本 PR 在同段尾部追加 FU-5/FU-6。两者基线同为 4ee077e。实测三方合并:

git merge-file -p pr46.md base.md pr45.md   →  rc=1,2 个冲突标记,冲突块覆盖 FU-1..FU-6
gh pr view 45 --json mergeable → MERGEABLE      gh pr view 46 --json mergeable → MERGEABLE

GitHub 两边都报 MERGEABLE,因为它只拿每个 PR 和 main 两两比、不比彼此 —— 冲突要等其中一个合进 main 之后才现形。而这个账本的契约是 append-only / 永不删行,用 --ours/--theirs 随手取一边就会静默丢掉四条 done 标记、或者丢掉 FU-5/FU-6。

建议:#45 先合,#46 rebase 时手工解,两边都留。


🟡 建议(非阻塞)

  • [Low] acceptance.md:37 —— 「现在真正兜底的只有 GitHub 分支保护,它管 PR 合并,管不到 git add -A 和直推」这句话对了一半。实读线上规则:required_approving_review_count=1enforce_admins=trueallow_force_pushes=falseallow_deletions=false —— 这条规则下 GitHub 会拒绝直推 main。本 PR 自己在 architecture.md 里立的标准是「任何『护栏保证了 X』必须能指到 ① 或 ③ 的具体行」,反过来的「护栏管不到 X」应该受同一把尺子约束。建议改成「管不到 git add -A(本地暂存),直推 main 已被①拦住」。(说反的方向是保守的,所以不阻塞。)

  • [Low] spec.md:12 + tasks.md:36 —— milestone 字段有三种形态,而「坑」那一列是空的。 这是我在全量复扫里唯一觉得可能真的误导无人值守运行的一条:实际数据里 26 条用 m-N11 条用带引号的阶段全名'Phase 1: Genesis Launch'"Phase 3: Ecosystem Maturity")、12 条根本没有 milestone: 字段。于是 tasks.md:36 那条自动化选取规则(「优先 M1 的 To Do」)如果按字面过滤 milestone: m-1只能选出 1 条 To Do;而那 12 条无字段的恰好是本仓库自己的 pilot/CI 任务 —— 包括 TASK-40,也就是 acceptance.md:36 / architecture.md:31 / research.md:45 / tasks.md:45 四处都点名为最重要缺口的那一条。文档化的挑活规则在结构上永远够不到它。 这和同一张表里 status 那行已经写了Done vs "Done" 坑是完全同一类。建议补上:「milestone 有三种形态:m-N、引号包裹的阶段全名、以及缺失(本仓库自己的 pilot/CI 任务全部无 milestone)—— 按 m-1 过滤会漏掉 23/49」,并给 tasks.md 一条「什么时候该挑无字段的本仓库任务」的规则。

  • [Low] progress.md:9 本地分支清单(main + cla-signatures + feat/pilot-auto-commit)漏了本提交所在的分支 docs/pilot-planning-layer#45 的分支,而同文件下一节就写着「在途 PR #45」—— 这份清单在写下的那一刻就不可能为真。

  • [Low] progress.md:36 「两个已知缺口记在 followups.md」,但同一个 commit 里的账本有六条,全是 - [ ]。就算把 #45 在途的 FU-1/2/4 记在它头上,也还剩三条(FU-3/5/6)。

  • [Low] .pilot.yml:9-12 —— 六个 key 里只有一半是脚本机械读的,但外观上完全一样。 base_branch / integration_branch / protect_patternsgit-guard.shgrade-change.sh 读;preflightpreflight.sh 读;而 remote / docs_dir / allow_remote_cleanup 没有任何 .sh/.pycheck-docs.sh:22 是硬编码 docs_dir="docs/agent",从不打开 .pilot.yml)。allow_remote_cleanup 只活在 phases/status.md / phases/run.md / reference/git-safety.md 的散文里 —— 正是本 PR 自己 architecture.md 分层里的 ④「靠模型自觉」,却和 ③ 的机械 key 混排在同一个文件里、没有任何视觉区分。建议在 .pilot.yml 注释里标出哪几个 key 是脚本读的、哪几个是 skill 读的。

  • [Low, 不在本 diff 内,建议记成 FU-7] templates/pilot.example.yml:6-8protect_patterns 写法照抄会静默失效,而且比预想的更糟。 官方模板文档的是块状写法(protect_patterns: 换行后 - release),而 git-guard.sh:39sed … | head -1 | tr -d " \"'[]" 对块状形式解析不出任何东西。实跑该 sed 对模板原文的结果是:

    base_branch        → [main#主干,受保护,禁止直推/直合]
    integration_branch → [preview#PR合并进这里;若该分支不存在则回退到base_branch]
    protect_patterns   → [#额外保护的分支前缀(如release/1.2会被release护住)]
    

    照模板抄的仓库会拿到三条垃圾条目 + 零额外保护,且没有任何告警。本 PR 之所以安全,是因为它把注释单独放行、并用了 inline flow —— 是撞对的,不是被保证的。「配置看起来生效了其实没有」正是本仓库连着修掉三个「守卫跑不起来」的同一家族。建议要么让 parser 也认块状形式并剥 # 注释,要么把模板改成 inline。


反向验证(这些不是 bug,已排除)

  • R1a 唯一那条 finding(「FU-5 应建议可配置 planning_source」)不成立:FU-5 本身就是这条建议,是一条正确归档的账本条目,不是 diff 里的缺陷。
  • followups.shnext_id 算出来是 6 → 下一个 FU-7,编号无冲突
  • scripts/ci/check-docs-gate.sh 只在 mktemp 出来的 fixture 目录上跑,不读仓库真实的 docs/agent,所以新增七件套不会影响这个必需检查。
  • acceptance.md 里三个 CI check 名与 verify.yml 逐字一致。

2-round(post-R2 全 Low,按闸门跳过 Codex R3)· R1a/R1b=deepseek-v4-flash · R2/R4=opus · head d6fdb21 · 所有实测均在 PR head 的独立 worktree 里跑,未修改任何仓库文件,未执行任何写操作

@jhfnetboy
jhfnetboy merged commit 5549b8b into main Aug 5, 2026
5 checks passed
@jhfnetboy
jhfnetboy deleted the docs/pilot-planning-layer branch August 5, 2026 09:05
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 5, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants