mcpField
B
br

br

github.com/rheinmirAgent 工作流1076 次安装2 周前更新
代码仓库

关于 br

br 是一项将原始需求逐步转为 BR、开发 frames 并通过受控循环执行的 skill,面向需要可追溯交付流程的项目。它以人工审阅为关口,使用 lint、运行护栏和状态监控,并将产物保存在项目文件中。

主要功能

  1. 01访谈并整理原始需求
  2. 02编译带条款追溯的 BR
  3. 03切分并校验开发 frames
  4. 04通过多重护栏运行循环
  5. 05生成流水线状态报告

适用场景

  1. 01将非结构化需求整理为可审阅规格
  2. 02把 BR 条款拆分为有依赖关系的 frames
  3. 03在人工批准后运行受控开发循环
  4. 04追踪失败 frame 与对应需求条款

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/rheinmir/setup --skill br

安装后在 Claude Code 中输入/br确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

assets/
defaults.yaml
design-template.md
frame-template.md
queue.example.yaml
revise-prompt.md
spec-template.md

详细介绍

Skill:br — Ralph 生产线(BR 技术编写 → frames → 带 harness 的循环)

BR = 业务需求(Business Requirements) — 已敲定的需求规格,位于 br/BR.md。Skill 以其生成的核心工件命名,而非以动词命名。每个 frame 和每条 clause 都能追溯到该文件,因此“产品缺陷 ⇔ BR 缺陷”(GH#15,2026-07-03) 是整条生产线的前提,而非口号。

单名称 Hub:用户描述范围(interview / compile / slice / run / status),无需记住多个命令。基础:council 028(thin-slice、人类参与环路)+ council 031/032(包含 6 项强制条件的 loop v1 — Taleb 均值排名第 1.0)。

内容

用途与上下文
  • **用途:**将用户的原始需求文档转化为有纪律的产品,经过 BR 技术编写 → frames → 带 harness 的循环生产线;每个 frame 和 clause 都能追溯到 br/BR.md。
  • 触发条件(何时使用):
    • 用户有需求文档(原始/非结构化),并希望将其转化为有纪律的产品。
    • 用户提到:interview / 需求访谈 / 编写 BR / slice frame / 运行 frame / 生产线状态 / ralph。
  • **非目标:**不写入 llmwiki/raw/;不重写已构建的确定性工具(frame-lint.py、loop-runner.py、build-line-status.py 等);不代替用户自行提交/合并;不在 /br run 之外手动修改 UI;不自动触发钩子。
心智模型

llmwiki/raw/ → interview(填写完整的 S1–S10 规格 + 补充问题)→ compile(包含 clause_id + “正在承担的假设” + BR.clauses.json 的 BR.md)→ slice(包含 depends_on 的 frames,由 frame-lint 把关)→ run(loop-runner 的 6 项刹车、每个 frame 单独提交、追踪日志)→ qc / find / status(从错误反向追溯到 frame → clause)。用户只需描述范围;Hub 选择模式。

输入与输出约定
字段必填?含义
输入llmwiki/raw/ 中的原始文档是(interview 模式)只读;为空时 → 请用户放入文档
输入已填写的 br/interview/NNN-answers.md是(compile 模式)用户按 field-id 提供的真实回答
输入用户描述的范围是interview · compile · slice · run · find · qc · status · sync · contract · rail
输入标志 --proactive · --lens-fill · --ack-tier · --worktree · --dry-run否可选分支(见分支)
输出br/spec-filled.md、br/interview/NNN-{questions.html,answers.md}interview 模式字段带有 status + provenance
输出br/BR.md、br/BR.clauses.json、br/DESIGN.md(如有 UI)compile 模式check-contract 通过
输出br/frames/*.md、br/frames/index.md、br/prompts.mdslice 模式frame-lint 通过
输出frame(<id>) 提交、br/frames/<id>.run.json、.checkpoints.jsonlrun 模式单行摘要 + medic
输出br/line-status.{json,html} + llmwiki/html/line-status.htmlstatus 模式3 行摘要
规则与能力
  • RULE-01(MUST):人是最终关卡 — 绝不自动提交/合并 frame 输出;采用 dry-run + 人工审核(council 028)。
  • RULE-02(MUST):刹车不可侵犯 — 绝不提高 max_iter 或关闭 guard 来“让它完成”。多一道刹车的成本低于少一道(council 031/032)。
  • RULE-03(MUST):Prompt 中的嘱咐不是安全层 — scope-jail/test-hash 是确定性代码(loop-runner guard 5/6),而非 prompt 中的嘱咐(5/5 个 council 席位)。
  • RULE-04(MUST):Lens-fill 始终为 verified: false — 不与真实回答混在一起;始终显示在“正在承担的假设”表中。
  • RULE-05(MUST):初期采用有人参与环路的 Slicer — 尚未实现全自动(Slicer 错误属于相关性错误,影响范围 = 整份 BR)。
  • RULE-06(MUST):文件优先,按需运行 — 所有工件都是可移交的文件;由 Skill 手动调用,绝不自动触发钩子(ADR-004)。
  • RULE-07(MUST):为用户生成的 HTML 必须解释术语 + 打印完整路径(R16)。
  • 能力:读取原始文档 + 代码库;在 br/ 下写入工件;在本地运行确定性工具(lint、loop、monitor);调用工具范围受限的模型适配器;仅在确认后于外部跟踪器创建 issue。
失败边界
  • llmwiki/raw/ 为空 → clarify:询问用户是否放入了文档。
  • br-fill.py check-contract 显示红色 → 编译失败,修复 BR,直到通过。
  • frame-lint.py check 显示红色,或工作树不干净 → /br run blocked(拒绝运行)。
  • Frame 的 tier: compensable/irreversible 尚未提供 --ack-tier → blocked(TIER-GATE)。
  • 触发 KILL 条件(例如 diff-jail 触发 ≥2 次 / test-hash 触发 1 次)→ 整个 run cancelled,不挽救,不解除刹车。
  • Frame 显示红色 → 下游分支标记为 status: blocked(partial),无关分支仍继续运行。
  • UI 检查没有真实图片文件 + MANIFEST.json → 视为失败(等同于从未做过)。

HOW

Main workflow
StepTypeInputsActionOutputs/exitFailure/next
W01判断用户的话根据用户描述的范围选择模式(单名称 hub)mode模糊 → 询问
W02判断llmwiki/raw/ + spec-templateMode 1 interview:将 raw 拆解到 S1–S10,进行 gap-diff,生成 questions.html + answers.md2 个文件 NNNraw 为空 → clarify;--proactive → B01
W03判断—STOP — 用户打开 HTML + 填写 answers.md已填写的 answers--lens-fill → B02
W04判断已填好的 spec + answersMode 2 compile:BR.md + BR.clauses.json(如果有 UI,还包括 DESIGN.md)BR—
W05确定性BRGate br-fill.py check-contract通过显示红色 → 修复 BR,重复 W05
W06判断BR.mdMode 3 slice:提出切片,STOP,等待用户逐个批准,按模板记录 frameframes + index—
W07确定性frames运行 frame-lint.py check + br-prompts.py sync 检查lint 通过显示红色 → 修复 frame,重复 W07
W08执行frameMode 4 run:br-run.py run(tier-gate、lint、干净的工作树、loop-runner、commit、run_log_ref、trace 日志)frame commit + run log阻止下游分支;KILL → 丢弃 run
W09确定性frames + run log + BRMode 5 status:build-line-status.py build + 3 行摘要line-status.html错误落入 assumed → 下一轮返回 W02

各步骤详情(W01–W09 和所有辅助模式的事实来源):

确定性工具(已构建 + 自测 — 请勿重写)
Tool用途selftest
skills/br/assets/spec-template.md标准 specs 套件 S1–S10(所有项目的参考框架)—
skills/br/assets/frame-template.md所有 frame 的确定性模板(frontmatter + 4 个易读的正文部分)—
skills/br/assets/design-template.md可复用的设计模板(Google design-doc 框架 + 从 /high-end-visual-design 加载的 design system)→ 复制为 br/DESIGN.md—
fdk/tools/frame-lint.py检查 frame 的 7 条规则(schema · scope · test-first · freshness · DAG · exclusive-scope 含 lease · content)frame-lint.py selftest
harness/scripts/loop-runner.py6 道刹车的 loop(max_iter·budget·no_progress·escalate·diff-jail·test-hash)loop-runner.py selftest
fdk/tools/build-line-status.py确定性监控工具(frame·run-log·BR → json+html,--check)build-line-status.py selftest

运行时产物存放在项目根目录的 br/ 中(不在 skill 内):br/spec-filled.md、 br/interview/NNN-{questions.html,answers.md}、br/BR.md、br/BR.clauses.json、br/frames/*.md、 br/frames/index.md、br/frames/<id>.run.json、br/line-status.{json,html}。

模式 1 — /br interview
  1. 读取 llmwiki/raw/ 中的所有文件(只读——规则禁止写入 raw/)。如果为空 → 请用户放入文档。
  2. 对照标准 specs 模板 skills/br/assets/spec-template.md:从 raw 提取信息并映射到各个字段 S1–S10 → 写入 br/spec-filled.md。每个字段都要记录 status(filled|missing|conflict|assumed)+ provenance(raw:<file>)。
  3. 差异分析:对于 missing/conflict 字段 → 生成一组问题。**每个字段对应一个明确的 spec(rigor /orca-workflow):**问题要说明字段的作用 + “怎样回答才算充分”(字段的验收标准),不能问得含糊。写入 2 个文件(使用相同的序号 NNN):
    • br/interview/NNN-questions.html — 按 section 查看,包含术语解释 + 每个字段的充分标准,显示完整路径(R16),支持深色模式。只询问缺失部分。
    • br/interview/NNN-answers.md — 按字段 ID 提供填写区块(例如 ## S4.2 …留空),供用户输入答案。 3b. --proactive(T-260714-01,简称 /br auto) — 用户希望由机器填写缺失部分,而不是把问题全部交给用户:运行 python3 fdk/tools/br-fill.py fill --root .(必须执行,不使用模型)。工具查询 registry defaults(skills/br/assets/defaults.yaml — 26 个 loop 条件的表格 + github/spec-kit 约定;若字段重复,项目 override br/defaults.yaml 优先),并输出 2 组内容:
    • 机器填写建议 → 粘贴到 NNN-answers.md,每项都保留原样的 filled_by: <source>:<refs> + verified: false(lens-fill 规则适用于所有机器填写层级)。
    • 真实问题(carve-out 字段——认证/权限、信任边界、资金——以及没有默认值的字段):按 Impact × Uncertainty 选择 ≤5 个问题,放入 questions.html(carve-out 已优先排序,优先占用提问名额);超出上限的部分则使用 lens-fill(步骤 5)。绝不允许为 carve-out 字段赋予机器生成的值——即使 registry 中有条目,即使使用 lens 也不行。
  4. 停止 — 告知用户打开 HTML 查看并填写 answers.md。
  5. 如果用户启用 --lens-fill(或表示“让专家填写不确定的项目”):通过 python3 harness/scripts/council.py roster --case product --json 获取 lens,为用户标记为“不确定”的 missing 字段填写内容 → 每个字段都标记 filled_by: lens:<tên> + verified: false。不要与用户的真实回答混在一起。
模式 2 — /br compile
  1. 读取 br/spec-filled.md + 已填写的 br/interview/*-answers.md。
  2. 生成 br/BR.md:每个条款都包含 clause_id(继承字段 ID,例如 S4.2)+ provenance(raw|user|lens:<tên>)。文件开头放置 “正在承担的假设” 表格,列出所有 lens/assumed 条款(fail-fast:一眼看出正在押注什么)。
    • 带 UI 的产品(S7.5):确定一个指向 br/DESIGN.md 的 NFR 条款(例如 N01 giao-diện),不要把 design 规则复制到 BR 中。同时将 skills/br/assets/design-template.md 复制到 br/DESIGN.md,并为产品填写 §1/§2/§4/§6/§7(§3/§5 保持继承内容不变)。BR = 必须有主题/设计;DESIGN.md = 设计看起来是什么样。
  3. 生成 br/BR.clauses.json:{clause_id: {provenance, assumed: bool, fields: ["S4.2", …]}} — fields 声明该条款落实了哪些 S1–S10 spec 字段(这是合同 checksum 的键);monitor(/br status)读取此文件,为 assumed 条款标为橙色。“正在承担的假设”表格按填入来源(default / spec-kit / lens)分组,让审核者看清正在从何处接受哪些风险。
  4. 合同 checksum 门禁(G1 修复 — council c9dc13d): python3 fdk/tools/br-fill.py check-contract --root . — 所有必填 S1–S10 字段都必须有对应条款;显示红色即表示编译失败,必须修复 BR,直到检查通过。不能出现“编译完成但合同有漏洞”的情况。
模式 3 — /br slice
  1. 阅读 br/BR.md。提出切片列表:每个切片 = {clause_ids、预期 scope_code(≤3 个文件)、scope_test、acceptance_test、depends_on}。暂停,让用户逐个审核/修改/合并/拆分切片(人在回路中——防止 slicer 相关性错误的关卡)。首批 ≤ 3–5 个 frame。
    • depends_on 必须考虑,但不要求必须有值(GH#75,提炼自 Atomic Task Graph):依赖链是图,不是列表。若 B 在 A 尚未通过时无法通过(B 调用 A 构建的 API/store/schema),则在 frame B 中声明 depends_on: [frame-A]。如果没有依赖 → depends_on: []。正确声明后,模式 4 会自动获得三项好处:自动确定正确的执行顺序、frame 失败时自动阻断下游分支,以及修改某个 frame 时只需重新运行其对应分支。随意声明(为了「看起来合理」而连线)会损失并行性并造成不必要的等待——只在存在真实依赖时连线。
  2. 按照模板 skills/br/assets/frame-template.md 编写 br/frames/frame-NNN-<slug>.md(schema v0 + 5 个必需正文部分:业务 · 输入/输出 · Spec(FR/SC) · 验收标准 · 范围之外——内容应便于后续读者理解,frame-lint R7 会严格把关:frame_id 必须包含业务 slug,muc_tieu 不能是通用描述,每个 frame 必须有明确的 FR-id/SC-id,各部分不能为空)+ parent_br_hash = sha256(br/BR.md)。
  3. 根据各 frame 的 frontmatter 生成 registry br/frames/index.md(表格列:frame_id · clause_ids · scope_code · status · run_log_ref)。
  4. 检查:python3 fdk/tools/frame-lint.py check br/frames --root . — 全部通过后才算切片完成(包括 R6 exclusive-scope:2 个未完成的 frame 不得占用同一个文件)。
    • **R6 是租约,不是产权证:**已完成的 frame(run-log verdict: SUCCESS)会释放文件占用权。因此,新 frame 可以接入曾由旧 frame 占用的启动点(main.ts、state.ts、server.ts……)。否则,即使新代码通过,用户也看不到(walleye 2026-09-10:4 个 frame 均已通过,但玩家什么也看不到)。两个未完成的 frame 仍不得同时占用同一个文件——除非 depends_on 已将它们排成前后依赖(其中一个 frame 是另一个的祖先):这样它们就不会同时修改文件,也可以让多个功能依次接入同一个 main.ts。_manifest.json 会将文件交给最后一个租用者(后代)。
    • 每项功能都必须有一个接入启动点的切片;UI frame 必须通过实际界面测试(e2e/route-shots)验收,而不能只用独立模块的单元测试验收。
  5. python3 fdk/tools/br-prompts.py sync — 将新 frame 的提示词条目添加到 br/prompts.md,以便用户立即手动编辑。
模式 4 — /br run <frame>

确定性调用方式(已接入 — 默认 IN-PLACE,仅一个工作树):

python3 fdk/tools/br-run.py run br/frames/<frame>.md --root .
# xem prompt sẽ gửi mà không chạy: thêm --print-prompt
# chạy cả hàng đợi resumable: python3 fdk/tools/br-queue.py run --queue br/queue.yaml
# sửa 1 frame → chạy lại ĐÚNG nhánh của nó, không cả dây chuyền:
#   python3 fdk/tools/br-queue.py affected <frame_id> --queue br/queue.yaml --reset
#   python3 fdk/tools/br-queue.py run --queue br/queue.yaml
# cần cô lập thư mục thật sự (hiếm): thêm --worktree

队列按图运行,而非按手动输入顺序(GH#75 — 提炼自 Atomic Task Graph,arXiv 2607.01942):

  • 拓扑顺序:br-queue 读取每个 frame 的 depends_on 并自动排序(没有依赖时保持声明顺序 — 旧队列的运行方式不变)。
  • 红色 frame 会阻断其下游整个分支(status: blocked,记录 blocked_by):该分支的输入已损坏,继续运行只会浪费模型调用次数,因为它必定失败。不相关的分支仍会正常运行 — 一个 frame 出错不再阻断整个流水线。
  • 局部修复(affected):修复一个 frame → 仅该 frame 及其下游分支重置为 pending,其他所有绿色 frame 保持不变。这正是节省成本的关键:以前,链中间一个 frame 出错,就会迫使你重跑超出必要范围的内容。
  • 不实现子图复用缓存(论文有,我们有意省略):status: done 已会跳过绿色 frame;在几十个 frame 的规模下再加哈希缓存,只会产生陈旧缓存 bug。论文自身的限制在此同样适用 — 图较小且 acceptance_test 确定时,收益依然存在;图非常大,或测试/工具返回结果不稳定时,这种运行调度就会失效。 br-run.py 会自动执行:(0) TIER-GATE — frontmatter 中声明了 tier: compensable|irreversible 的 frame(不可逆副作用:调用外部 API/发送邮件/写入 DB)会被阻断,直到运行者使用 --ack-tier 重新运行(SHEPHERD 在物化前进行门控);(1) frame-lint;(2) 检查工作树是否干净;(3) 在当前工作树中立即运行 loop-runner,且 revise 已指向 fdk/tools/br-revise.py(渲染 skills/br/assets/revise-prompt.md → 使用受限工具的 claude -p);(4) frame 通过 → 提交到当前分支,提交信息附带 frame_id(用于回滚/追责);(5) 打印一行摘要;(6) 将 run_log_ref 写入 frame;(7) 在 TRACE LOG .checkpoints.jsonl 中记录检查点(checkpoint-trace/SHEPHERD — 记录直接指向已有提交,不重复提交)→ 查看整个流水线:python3 fdk/tools/checkpoint.py list;按名称将整个流水线回滚到任意 frame:checkpoint.py rollback <frame_id>(保留历史,并警告检查点之后发生的不可逆 tier 副作用)。 **为什么默认使用 in-place(用户反馈 05/07):**N 个 frame = N 个工作树 = N 个没人会去翻找的文件夹;普通用户的流程是打开应用查看,修改必须立即显示在当前运行应用的工作树中。范围外修改的控制由 HARNESS 负责(每轮 diff-jail 回退 + FINAL SCOPE SWEEP + test-hash + scope_clean + R6 exclusive-scope),而非目录隔离。不满意结果 → git revert <commit frame>。

等效的手动步骤(如需手动微调):

  1. 使用 frame-lint check 确认该 frame 通过。检查工作树干净(git status --porcelain 为空)— 不干净则拒绝。
  2. 从该 frame 的 baseline_ref 创建独立的 git worktree(文件系统 jail — 第一个 frame 不会触碰 harness/hook/CI)。
  3. 运行 loop — 逐 frame 提交到 WORKTREE BRANCH(不是 main);仍由用户手动合并:
    python3 harness/scripts/loop-runner.py run \
      --verify "<acceptance_test>" --revise "<adapter claude -p>" \
      --state "<scope_code>" --scope "<scope_code>" --protect "<scope_test>" \
      --baseline "<baseline_ref>" --commit-on-success \
      --commit-message "frame(<frame_id>): <muc_tieu> [<clause_ids>]" \
      --max-iter <g> --budget-seconds <g> --no-progress-k <g> --escalate-after <g> \
      --log br/frames/<id>.run.json --cwd <worktree>
    
    Revise 适配器 = 使用受限工具的 claude -p(--allowedTools Edit,Write,Read,Grep,Glob — 不允许自由使用 Bash,也不允许网络访问),提示词根据 muc_tieu + scope_code + 最近一次 verify 失败的输出生成。 追踪 frame→代码(前提条件 — 确认哪个 frame 生成了哪些代码,且不超出范围):
    • Run-log 记录 changed_files = frame 实际修改的文件(≠ 预期范围);当所有文件 ⊆ scope_code 时,scope_clean=true;attempted_out_of_scope = frame 试图写入范围外、但已被回退的文件。
    • FINAL SCOPE SWEEP:每次 loop 停止时(包括 PROTECT_VIOLATION),loop-runner 都会干净地回退所有 scope_code 范围外的文件 → worktree 始终保持范围干净,changed_files 始终 ⊆ scope_code。这是完全控制,而非仅依赖提示词提醒。
    • 只有 verdict=SUCCESS 且 scope_clean 时,--commit-on-success 才会提交;提交信息附带 frame_id → git blame 可准确追溯到对应 frame。--baseline = 用于计算 diff 的原始提交(通常是 worktree 开始时的 HEAD)。
提示词与队列(运行多个 frame,可恢复)
  • 📒 提示词总账(优先级最高的来源,用户可手动修改,无需模型):br/prompts.md——一个文件,每个 frame 一个 ## <frame_id> 条目。打开文件,找到 frame 后可随意修改/添加内容(保留 {{...}} 占位符,由机器在运行时填入)。python3 fdk/tools/br-prompts.py sync 会自动为新 frame 添加条目,绝不会覆盖手动修改过的条目(每次 /br slice 后运行);使用 list/get <frame_id> 查询。运行时优先级:提示词总账 > 队列内联内容 > prompt_file > 默认模板。
  • 原始模板(总账的种子):skills/br/assets/revise-prompt.md。Adapter fdk/tools/br-revise.py 会渲染胜出的来源 → 调用 claude -p(工具范围受限)。查看将发送的提示词:br-revise.py run --frame <f> --verify "<cmd>" --print。
  • QUEUE 文件(br/queue.yaml,示例 skills/br/assets/queue.example.yaml):按顺序运行的 frame 列表;每项使用 prompt_file:(指向模板文件)或 prompt:(直接填写文本,仍支持占位符)。Driver fdk/tools/br-queue.py run --queue br/queue.yaml 会逐项运行,并在每项运行后回写 status → 重新运行队列时会跳过 done,从中断处继续(恢复)。使用 --dry-run 查看每项使用的提示词;使用 list 查看状态。
  • Adapter claude -p 是 verified:false(BNAL)的边界——模板、队列和渲染均为确定性操作,并带有 selftest(br-revise.py selftest、br-queue.py selftest)。
  1. 预先写明 KILL 条件(via negativa):例如 diff-jail 触发 ≥2 次/test-hash 触发 1 次 → 丢弃整个 run,不挽救,不松开刹车。
  2. 循环停止 → 输出一行摘要(判定 · 循环次数 · diffstat · 最后一次 verify 命令)+ 运行 python3 fdk/tools/medic.py --ci。STOP — 由读者在 worktree 中查看 diff,自行决定合并/继续运行/丢弃。
  3. 将 run_log_ref + outcome 填入 frame 和 registry。记录经验(包括没有发生的事——哪些刹车从未触发)。
Mode 4b — /br find <file或关键词> — 指向出错位置,找出负责的 frame/提示词

常见用户流程:打开应用 → 看到错误 → 指向出错区域:

python3 fdk/tools/br-find.py "src/auth/login.py"     # theo file
python3 fdk/tools/br-find.py "đăng nhập"              # theo từ khoá / clause

输出:负责的 frame(按实际变更的文件 > scope_code > 关键词匹配)· BR 条款 · 提示词位置(内联于 queue.yaml/prompt_file/默认模板)· 修改提示词后准确重跑该 frame 的命令。此功能依赖 R6 exclusive-scope(frame-lint)强制每个文件在任何时刻只属于一个 frame——如果文件通过 lease 更换了归属,负责的 frame 就是最后一个租用它的 frame(_manifest.json);历史归属则通过 git blame 按 frame(<id>) 提交追溯。

Mode 4c — /br qc [frame] — 对 mockup/frame 进行高级 QC 审计(LLM 四项)

mockup/frame 通过后,运行高级人工审查(成本较高=LLM,手动调用——低成本的确定性检查已在每次 /br run 后自动运行):

  • **代码:**调用 /qc-code(Skill tool → qc-code)检查 frame 的 diff——涵盖安全性/性能/命名/逻辑四项,并生成复现问题的 qc-* 测试。
  • **UI/UX:**调用 /qc-uiux(Skill tool → qc-uiux)审计 mockup——涵盖 a11y/层级/一致性/反模式四项;可测量的部分(对比度/点击目标/重叠/错位/缺少标签)通过 visual-qa headless engine 运行:
    node skills/visual-qa/assets/route-shots.mjs <base-url-mockup> --audit
    
  • 判定为需要修改 → 定稿 frame 前先修改。仅供参考——LLM 判定只是意见;只有 engine 测量结果 + qc-* 测试才是强制门槛(已在 /br run 和 verify-before-commit 的步骤 3b 中自动运行)。未指定 frame → 审计现有 mockup 路由。
Mode 5 — /br status
  1. python3 fdk/tools/build-line-status.py build --root . → br/line-status.json + llmwiki/html/line-status.html。
  2. 输出 3 行摘要(总体状态 · 最值得关注的 frame · HTML 路径)。页面支持从错误追溯至 frame → 条款;假设条款以橙色标示 → 如果错误落在假设条款上,请在下一轮执行 /br interview。
模式 6 — /br sync(frame ↔ GitHub 子议题)

提炼自 automazeio/ccpm:每个 frame 对应一个 GitHub 子议题,让团队查看进度并交接。不要重新实现溯源(clause_id/manifest 已比 ccpm 更深入);只在 gh 上添加一层轻量同步。

  1. python3 fdk/tools/br-sync.py sync br/frames --root . --repo <owner/repo> --dry-run——始终先执行 dry-run(不调用 gh,不写入映射)。
  2. 确认无误后移除 --dry-run → 为尚未映射的 frame 创建子议题,并写入 br/frames/issue-mapping.json。支持幂等操作。--epic 可创建 epic 议题。status/selftest 可用。
  3. 创建 issue 会产生仓库外部操作 → 移除 --dry-run 前必须先确认。
模式 7 — /br contract(用于最终实现的 UI Contract,md+html)

将 CODE 轴(frame)与 DISPLAY 轴(screen/route)分开。所有项目采用以下标准:

  1. Frame 声明 ui_role: none|screen|panel|widget|form|action + ui_screen(frame-template)+ 章节「## UI 如何运作」。
  2. br/ui-layout.yaml:包含 nav_style + screens[](id·title·实际 route·frames[])。集中修改屏幕时无需触碰 frame。
  3. python3 fdk/tools/br-contract.py build br/frames --layout br/ui-layout.yaml --root . → br/UI-CONTRACT.md + .html。包含 frame·功能·ui_role·屏幕·route·clause·acceptance 表格 + frame/屏幕/route 计数 + 偏差警告。selftest 可用。
分支
ID类型条件行为跳过 / 失败汇合点
B01用户可选interview 中使用 --proactive(简写为 /br auto)br-fill.py fill 提供机器填充建议(verified: false)+ 最多 5 个真实问题,按 Impact × Uncertainty 排序;例外项不接受机器填充值超出上限 → lens-fillW03
B02用户可选使用 --lens-fill 或「让专家填写尚不确定的字段」council.py roster --case product --json,填写用户标记为不确定的缺失字段,添加标记 filled_by: lens:<名称> + verified: false不与真实回答混合W04
B03条件必需产品带有 UI(S7.5)NFR clause 指向 br/DESIGN.md;将 design-template.md 复制到 br/DESIGN.md,填写 §1/§2/§4/§6/§7没有 UI → 跳过W05
B04条件必需frame 的 ui_role 不为 none编码前运行 /design-twice;acceptance_test 为 visual-qa route-shots.mjs --assert缺少 ## 设计(design-twice) 章节 → frame 尚未完成W08
B05条件必需frame 声明 tier: compensable 或 irreversible阻止执行,直到使用 --ack-tier 重新运行未确认 → 不运行W08
B06能力可选需要真正隔离目录(少见)添加 --worktree,或使用等效手动步骤(从 baseline_ref 创建独立 worktree)—W08
B07用户可选运行多个 frame / 修改一个 frame按拓扑顺序执行 br-queue.py run --queue br/queue.yaml;affected <frame_id> --reset 可重新运行正确分支frame 标红会阻止下游分支W09
B08用户可选/br find <文件或关键词>模式 4b:br-find.py 输出负责的 frame + clause + prompt 位置 + 重运行命令—W08(修改 prompt 后重新运行)
B09用户可选/br qc [frame]模式 4c:/qc-code + /qc-uiux(建议性检查);判定为需要修改 → 定稿 frame 前先修改—W08
B10用户可选/br sync模式 6:先运行 br-sync.py sync --dry-run,确认后再移除 --dry-run未确认 → 停在 dry-run结束
B11用户可选/br contract模式 7:br-contract.py build → br/UI-CONTRACT.md + .html—结束
B12用户可选/br rail off 或 skip通过 frame-lint … --soft-off 关闭软门控(R7 content · visual-qa UI · assumption-gate);硬性制动保持不变skip 仅生效一次,之后自动重新启用W08
验证与停止

必须执行:frame-lint.py check(7 条规则)、br-fill.py check-contract、loop-runner 的 6 个制动条件 + FINAL SCOPE SWEEP、每轮 loop 后运行 medic.py --ci、每个工具的自测(frame-lint.py selftest、loop-runner.py selftest、build-line-status.py selftest、br-revise.py selftest、br-queue.py selftest)。必须进行 review(人是最后一道关卡):审核 answers、在 slice 中审核每一片、阅读 frame diff,然后自行决定合并/继续运行/丢弃。Mode 在已记录的 STOP 点停止;loop 按制动条件停止,不得提升制动条件。

示例
  • **正向:**用户将 3 个需求文件放入 llmwiki/raw/,并说“起草 BR” → interview 生成 br/interview/001-questions.html,询问缺失的 7 个 field → 用户填写 → compile 生成 br/BR.md + check-contract 通过 → slice 提出 4 片,用户审核通过 → frame-lint.py check br/frames --root . 通过 → br-run.py run br/frames/frame-001-dang-nhap.md --root . → SUCCESS,提交 frame(frame-001-dang-nhap): …,用一行总结 + medic。
  • **边界/失败:**当 git status --porcelain 不为空时运行 /br run → 拒绝运行。Frame 声明发送邮件的 tier: irreversible → TIER-GATE 阻止运行,直到指定 --ack-tier。Frame-003 未通过 → frame-004(depends_on: [frame-003])变为 status: blocked,无关的 frame-005 仍然运行。
参考 — 统一的 Stream UI + 明确的 Spec(提炼 hallmark + orca-workflow)

多 frame 流程存在两个缺口,通过两个提炼机制来弥补:

A. 跨 FRAME 统一 UI/UX(提炼自 hallmark)。 每个 frame 通过 loop-runner 独立运行 → 容易导致每个 frame 风格各异、mockup 拼凑。hallmark 机制:br/DESIGN.md = 锁定的 TOKEN 系统,必须先阅读,并覆盖所有选择;反向规则 — frame 必须彼此相同(共享系统),不得追求多样化;locked-token — 所有颜色/字体/间距都必须指向具名 token(var(--…)),禁止 inline。应用到 /br:

  • /br compile 将 design-template.md 复制到 br/DESIGN.md,其中的 §4 + §4.1 token 表(锁定 token)是唯一真实来源。
  • ## UI hoạt động ra sao 中的 Frame UI 只能使用 DESIGN.md 中的 token;新增值 = 将 token 添加到 DESIGN.md 并引用,不得在 frame 中自行创造。
  • /qc-uiux(一致性)+ engine visual-qa 会捕获 token 漂移 → “stream” 由确定性 gate 驱动,而非靠口头提醒。结果:frame-01 和 frame-09 看起来像同一个产品。

B. 每个 frame + interview 屏幕都需要明确的 SPEC(参考 /orca-workflow)。 Propose 生成稳定的 FR/SC id + acceptance;/br 将这种严谨性带入每个环节:

  • **Frame:**frame-template 包含 ## Spec (FR/SC) section(frame-lint R7 严格把关)— 每个 frame 声明 FR-id(系统必须……)+ SC-id(面向人的衡量标准),acceptance_test 是 SC 的证据,每条验收标准都能追溯到一个 FR。Frame 缺少明确的 FR/SC = 尚未完成,就像 interview 缺少 field 一样。
  • **Interview:**每个被询问的 field S1–S10 都必须是一条明确的 spec — 问题要说明 field 的用途 + “怎样的回答才算足够”的标准(不得含糊提问)。仍为 missing/assumed 的 field = spec 尚不完整,显示在“正在承担的假设”表格中,避免遗漏。
参考 — UI frame 的设计轮次(skill /design-twice)— 编码前运行

**所有 ui_role≠none 的 frame 都必须执行:**在编写任何 UI 代码之前,运行 /design-twice 以获得 2–3 个根本不同的方案,进行比较,选择 1 个,然后在 frame 本身添加 ## Thiết kế (design-twice) 部分(3 个方案 + 选定方案 + 理由 + 从落选方案中借鉴的点)。

  • 原因:第一个想法是最容易想到的,不是最好的。没有方案可供比较时, agent 只会不断修补唯一的方案 — 每轮修补都会产生一个新问题(Lume 主题:修补 5 轮)。
  • 需要回到设计轮次的信号:同一位置正在进行第 2 次修补,或用户表示 “难看/糟糕/不喜欢”,却没有指出具体问题 ⇒ 形态错了,继续修补只会浪费时间。
  • 缺少 ## Thiết kế (design-twice) 部分的 UI frame = 尚未完成(R7 content 会视为缺少内容)。
  • 设计完成后才能进入 ## UI hoạt động ra sao → 编码 → 下方的 /visual-qa gate。
参考 — UI frame 的视觉自检循环(技能 /visual-qa)

**原则(不是单独的重新检查规则):**修改 UI = 编辑该 frame 的 spec + 代码,然后再次运行 /br run。若想实现“重新运行 frame 时自动重新验证 UI”,那么 UI frame 的 acceptance_test 必须就是 visual-qa — 测试必须命中 UI,而不是旁边的单元测试。这是高杠杆做法:无需提醒 Agent“记得重新检查”,因为 frame 自身的验证循环已经包含了 UI 检查。

  • 设置 ui_role≠none 的 frame:acceptance_test: "node skills/visual-qa/assets/route-shots.mjs --base <url> --route <route> --assert --user <u> --pass <p> --out <dir>" → 若路由不是 200 / 内容为空,则退出码为 1 → 直到 UI 正确渲染,frame 才会变绿。每次修改后重新运行 /br run = 自动重新验证。
  • 变绿后,Agent Read 图像(技能 /visual-qa)→ FINDINGS.md(路由·级别·修复方法)→ 每条发现都对应 frame 的一次 spec+代码修改 → 再次运行 /br run。可捕获主题/品牌/空状态问题,这些是单元测试发现不了的;在 MCP 扩展 localhost 出错时使用。
  • 禁止在 /br run 之外手动修改 UI(欠账 p28 05/07):手动修改 = 失去门禁 + 不会重新验证。所有 UI 修改都必须通过 frame。
参考 — Rail — 流水线的 harness 开关(/br rail on|off|skip)

“On the rails” = 正处于监管范围内。默认开启 — 使用 /br 时,整个会话自动开启。

  • python3 fdk/tools/br-rail.py status --root . → 状态 + 始终提醒可以开启/关闭。
  • on(全面监管)· off(关闭软门禁,直到再次开启)· skip(恰好跳过一次软门禁,然后自动重新开启 + 警告)。
  • 安全性(不变量):off / skip 只会关闭软门禁 — R7 content · visual-qa UI · assumption-gate。硬制动机制(diff-jail · test-hash · scope-clean)+ R1–R6 结构 + 安全 hook 永远不会通过此方式关闭。
  • **接线:**在 /br run 开始时,读取 br-rail.py consume → 若为 off / skip,则调用 frame-lint … --soft-off(跳过 R7+assumption),loop-runner 的硬制动机制仍保持不变;每次运行时输出 Rail 状态 + 提醒行。
参考 — 证据胜过说法(UI 检查规则 — 反馈 2026-07-13)

UI / 视觉检查只有在存在真实图片文件 + 列出 route→图片→字节数的 MANIFEST.json 时才有效(技能 /visual-qa)。没有文件 = 从未做过 = 失败,无论模型怎么说。修改 UI 后必须重新截图 + 重新查看,然后才能变绿。禁止靠推理“判定通过”。(这也是 /fdk 的规则。)

评论

支持 Markdown