跳到主要内容

FASE 28 — 用户的目录

本文档是该阶段的切分:它追求什么、拒绝什么、按什么顺序。决策位于 ADR 0146 和 ADR 0147——在这里而不在那里的内容是意图,不是决策。

问题​

自 ADR 0104 起,产品有三种执行模式,而没有一种交付用户所期望的最简单的东西:打开编辑器,在他自己的目录中看到工作正在进行。

模式用户的目录代价
container不存在代码存放在一个他从不打开的卷中
mounted有,位于 BRABO_PROJECTS_BASE 之下实际上不可见:没有这个变量,该模式根本不会被提供,而产品中没有任何东西要求去配置它
runner有,真实目录二进制、手动 chmod +x、配对,以及 Docker 作为硬性前提(RN-507/508)

mounted 是最有启发性的情况。ADR 0141 构建了唯一的 base,ADR 0142 让建议一个尚不存在的路径成为可能——但这两样都没有到达界面。GET /workspaces/:workspaceId/projects-base 存在,web 中却没有人使用它,因此这个早已就绪的模式仍然在安装产品的人够不着的地方。

设计,分三层​

每一层只有一种机制,没有一层发明新的权限:

层位置机制
同意pnpm bootstrap,一次,在主机上选择 base,写入 BRABO_PROJECTS_BASE,证明 Docker Desktop 的共享
活目录base 之内按同一路径绑定(ADR 0141)——零同步
base 之外的目标可选,按项目本地 agent 的 espelho 能力:单向,从不删除

第三层的存在有一个物理原因:bind mount 不跨网络,也触及不到挂载范围之外的路径。 要写入主机上的任意目录只有三条出路——原生运行 api/engine、在主机上有一个活着的进程,或者由浏览器通过 File System Access API 写入。第二条是唯一持续的,而 brabo-runner 已经是那个进程。

配置同意 ≠ 行动审批​

两个 ADR 需要声明的要点,它决定了镜像的设计:

镜像的写入不经过 proposed_action,因为它不是 agent 请求采取行动——而是系统在用户自己创建项目时声明的路径上写入。通过终端命令同步则恰恰相反:它会落入 ADR 0055 的路径作用域,变成例行审批的队列,并恰恰侵蚀让点击有意义的那道上限。

编号——数出来,而不是继承来的​

仓库散文中的计数存在已知的漂移。CONTRIBUTING.md 说"68 个 ADR";docs/adr/index.md 的 frontmatter 说"108"。本阶段没有任何会话信任写在散文中的数字。

方法,本阶段每次会话在保留任何编号之前都要重复:

# ADRs — arquivos, não prosa
ls docs/adr/ | grep -cE '^[0-9]{4}-.*\.md$'

# RNs — cabeçalhos, nos três arquivos que compartilham a numeração
git grep -h -E '^### RN-' -- 'docs/business-rules.md' 'docs/business-rules/*.md' \
| grep -oE 'RN-[0-9]+' | sort -u | wc -l

在第 1 次会话开始时针对 dev 测得:144 个 ADR(最大 0145,0062 处有一个空缺)和 371 条 RN(最大 509,零重复锚点)。由此得出 0146 和 0147。

为本阶段保留的范围是 RN-511 到 RN-520,跳过 RN-510 是有意的。只数 dev 会得到 510——但 RN-510 已经被分配在一个尚未合并的工作分支上。在这里保留它,会重现 RN-505 恰恰发生过的冲突:两个 PR 相隔两分钟分配了同一个编号,锚点 {#rn-505} 重复了好几周。

值得记录那次冲突为何存活了那么久:docs:build 抓不到重复的锚点。 onBrokenAnchors: 'throw' 会让指向不存在的锚点的链接失败;有两个相同的锚点时,Docusaurus 解析第一个,第二个则静默地无法到达。只数 dev 中的内容是必要条件而非充分条件——还必须数正在进行中的。

各次会话​

每次一个可交付物,按顺序。每次会话的完整提示在上一次结束时写出,带上它所发现的东西。

#可交付物依赖
1本文档 + ADR 0146 + ADR 0147 + 保留的 RN 范围—
2bootstrap.sh/preflight.mjs 中征得同意的 base、.env.example、共享证明1
3base 存在时,向导默认提供 mounted2
4按 ADR 0146 的结论在本地 compose 中启用 broker2
5在本地 agent 协议中声明能力(尚无镜像)1
6espelho 能力:自有作用域、单向、从不删除5
7作为用户服务安装、停止/移除、服务端吊销6
8web 上的镜像状态(最后一次同步、计数、错误)6
9E2E、docs:check、docmap 和 CHANGELOG 收尾8

本阶段交付了什么,以及在哪里偏离了计划​

上表是计划。下面是实际发生之事的记录——差异放在这里,因为一个为迎合结果而重写自己的计划,就不再能教会任何东西。

#RN/ADR结果如何
1ADR 0146, ADR 0147按计划;保留了 RN-511..520 范围,跳过 RN-510(已在未合并的分支中分配)
2ADR 0146 第 1–2 点按计划——默认 base 为 $HOME/projetos-brabo,由 Node 脚本写入,因为 bootstrap.sh 的菜单项以 /dev/null 为 stdin 运行,按构造无法提问
3RN-513两半早已是规则(RN-500/RN-501),却从未到达界面;新的只有预选
4RN-512, ADR 0146 第 3 点broker 在本地 compose 中移出 profiles,并且只在那里——两个 compose 有意分歧
5RN-514, ADR 0147 第 1 点按计划;因缺少能力而拒绝在诞生时就已实现并测试,却未被触发——只有 RN-516 给了它第一次真实触发
6RN-515/RN-516, ADR 0147 第 2/3/4/8 点拆成两半(目标 × 复制),决定在会话中作出
7RN-518, RN-519/520, ADR 0147 第 5–6 点在第 8 次会话之后交付——两者都只依赖第 6 次,没有任何东西规定它们之间的顺序
8RN-517, ADR 0147 第 7 点按计划
9—收尾:缺失的 E2E、apps/runner/** 的 docmap 规则,以及本记录

有三件事与计划的假设不同,三者都在要紧之处声明了:

  • 第 7 次会话在第 8 次之后运行。 两者都依赖第 6 次而别无其他,彼此之间也没有依赖——表格的顺序是阅读顺序,不是先后约束。
  • BRB-031 没有消亡。 ADR 0147 期望作为服务安装能消灭 ADR 0118 的手动 chmod +x。它消灭不了:能运行 brabo-runner service install 的人,为了到达这条命令已经需要让二进制可执行。这个副作用依赖于安装来自 ADR 0146 的版本化引导,而本阶段没有接上它。
  • 吊销作用于 {projeto, usuário},从不作用于 {chave}。 ADR 第 6 点没有承诺按凭据的精确性,但那是它自然的解读。它不存在:runner_socket_tickets 保存 project_id/user_id/kind,而凭据的身份在 PatAuthGuard 中就消失了。代价写在 RN-520 和 security-surface.md 中,而不是被掩饰。

本阶段不触碰的内容​

两个 ADR 中都已声明,在这里重复,因为正是它赋予其余部分意义:

  • decide.ts 和绝对上限——没有任何上限获得例外,可配置的也没有
  • proposed_action 作为 agent 一切外部效果的起点
  • event log 的不可变性
  • 三种模式下的镜像关口(ADR 0135)
  • broker 的五个操作和计算出的规格(ADR 0128/0130)
  • 枚举 project_execution_mode——本阶段没有诞生新模式

本阶段触及但不解决的缺口​

  • 在 runner 模式下 docker exec 路径中被丢弃的 git 凭据——apps/runner/src/index.ts:318-320;packages/docker-port 没有 env 字段,这是 ADR 0130 的决定。在 ADR 0130/0145 中声明,这里不修正。
  • 项目内部指向外部的符号链接不会被 decide() 检测到,它是纯函数、不做 I/O——ADR 0055。apps/runner/src/guard.ts:9-31 出于同样原因声明自己是尽力而为。
  • BRB-005——已发布的工件(GHCR 镜像、runner 二进制)没有签名。没有签名的一行安装程序比当前的下载更糟,这就是第 7 次会话不提供一行安装程序的原因。
  • BRB-031——通过浏览器配置时的手动 chmod +x。如果安装改为来自版本化的引导,它会作为副作用消失。
  • {project_id, machine_id} 的排他性推迟到出现第二个真正同时工作的开发者——ADR 0137。