在这里,ADR 是什么
一个边界决定一条记录:一个 trait 的形状、一种连线格式、一种持久化格式、一项依赖、一次
crate 拆分、一族阈值。每条上限 120 行,遵循同一个模板——Context、Decision、
Consequences、Supersedes。更长的材料去 docs/design/,并从记录里链过去。缺陷修复写在
提交正文里,不是 ADR。
它们住在仓库的 docs/adr/ 里。到目前为止三十三条。
地基
| # | 标题 | 一句话 |
|---|
| 0001 | crate 地图与依赖方向 | 四层,一个方向,五条由构建来断言的禁止边。 |
| 0002 | 一条事件流:帧、日志、reducer、意图 | 一个 Frame 类型,每个会话一份有序日志,两个纯 reducer,以及什么都不返回的写操作。 |
| 0003 | 设置:三层 JSONC,每个键由认领它的插件来合并 | 内核拥有五个键;其余每个键都属于认领它的插件,带着它自己的合并规则。 |
| 0004 | 模型事实:目录拥有模型,提供方拥有端点,服务器纠正窗口 | 三个拥有者,互不重叠,还有一个纯粹的解析器,在猜错会被拒绝的那一侧保守取值。 |
| 0005 | 会话持久化:每个会话一份 JSONL 日志、一个旁挂的锁、一份推导出来的摘要 | 会话目录是可搬走的,锁是唯一的声明,而摘要永远可以重建。 |
| 0006 | 上下文预算:内核度量并裁剪,插件摘要并记住 | 内核里一族阈值,只有真的缩小了才接受的压缩,以及失败三次之后的一个熔断器。 |
内核的那些界面
| # | 标题 | 一句话 |
|---|
| 0007 | 那条线:NDJSON 上的 JSON-RPC 2.0,方法与 HostApi 一一对应,事件原样传递 | 那条线就是 sdk 加一个信封,别无他物;schema 已提交并有漂移测试。 |
| 0008 | 命令:由会话 actor 解析和分发,结果作为 ack | 没有界面去解析一条不归它的命令;即时命令在回合中照跑,其余的排队。 |
| 0009 | 贡献来源:只有在 I/O 之后才存在的工具和命令 | 来源是同步注册的,用它此刻手上有的东西作答——答以空手从来都不算错。 |
| 0010 | 子会话:投递、重定向、树附着 | deliver 是通往另一个会话队列的唯一一扇门,而一次树附着承载每一个后代的帧。 |
| 0011 | 记录型会话、日志里的插件状态、手边的宿主 | 没有模型的会话只记录、从不跑回合;插件状态是日志里的一个事件,不是它旁边的一个文件。 |
| 0013 | UI 即数据:一套视图词汇、三条通路、动作 | 插件描述要显示什么;界面决定怎么显示,而每个节点都有一种文本折叠。 |
凭据、提供方与模型
| # | 标题 | 一句话 |
|---|
| 0012 | OAuth 凭据:一个库层级、一份存储、登录作为一次交互 | 在插件之下为共享代码设的第三个层级,一个 0600 的凭据文件,以及一次就是普通提问的登录。 |
| 0017 | 具名提供方实例与基于 key 的粘贴登录 | 每个提供方键底下的 instances 按名字注册更多端点;环境变量只喂默认的那些。 |
| 0026 | 模型目录到达模型 | 目录的那些事实骑在已有条目的元数据上,一个只读工具把它们交给模型。 |
插件与进程边界
| # | 标题 | 一句话 |
|---|
| 0015 | 跨进程插件桥 | 一份 plugin.json、一个在 stdio 上的进程,以及作为 JSON 的 sdk 自有类型——用任何语言写一个 bingo 原生插件。 |
| 0030 | 接口固定的能力跨过这座桥 | 实现 sdk 自有 trait 的代理结构体,零个新 trait,以及每一次跨越都有的期限。 |
| 0031 | 连线服务 | 进程内按类型会合;跨过一个进程时按键、方法和 schema——而且只有在它的拥有者开了一张连线的脸时才行。 |
| 0032 | 钩子跨过这座桥 | HookOutcome 没有 Allow,所以一个外部钩子只能收紧发生的事,绝不能放宽。 |
| 0033 | 额度:一项宿主能力,只为一次跨越出借 | 一个保留的 bingo.host 服务、两扇门,以及一份在它的跨越结束时就死掉的授予。 |
不属于内核的那些功能
| # | 标题 | 一句话 |
|---|
| 0014 | 经验:作为文件的程序性记忆,按排名召回 | playbook 是生成的 id 下的文件,按 BM25 排名,以权限卡片作为提案步骤。 |
| 0016 | IM 频道:一个投递器,交出自己机制的适配器 | 一项能力是一个返回该机制的访问器,所以它不可能和画它的渲染器脱节。 |
| 0018 | 后台命令,以及默认异步 | 一条长命令会脱离到一个日志文件里,只有完成或一个点名的条件才唤醒会话。 |
| 0019 | 计划任务:推迟的与重复的回合 | 一小套语法代替 cron,一次触发就是在该计划任务自己的会话上跑一个回合,而且不假装有守护进程。 |
| 0020 | 网关:一个常驻的 bingo,像服务那样管理 | 每个数据目录一个常驻宿主、一个 pidfile、一个 doctor,以及一个每用户的 launchd 或 systemd 单元。 |
会话之间的协作
| # | 标题 | 一句话 |
|---|
| 0021 | OpenRoom:代理可以开房间 | 一个代理默认召集它自己的子会话,或者用 shared 召集它的兄弟——一扇门,同一套排座代码。 |
| 0022 | 提及:一条房间发言欠下什么 | @name 开出一笔债,由该成员的下一条发言了结;债从日志推出来,并由一个有界的定时器去追。 |
| 0023 | 看板:一个房间的任务清单 | 房间就是会话,所以它的任务清单就是共享的看板;认领是在运行时打上的,而过期状态是渲染出来的,绝不写下。 |
| 0024 | 同侪消息:兄弟地址,一种投递 | 代理名字先在子会话里解析、再在兄弟里解析,而 SendMessage 一律唤醒——第二种投递模式被删掉了。 |
| 0025 | 串行的房间 | 一条发言必须跟在它作者本可看到的一切之后;过期的那条会被弹回,并带着它错过的东西。 |
| 0027 | 生成 ≠ 唤醒:待命的成员 | 一份简报可以只投递而不索要对它的回答,于是一个已入座的成员以零 token 空闲着。 |
| 0028 | 名册上的持有者 | 房间所挂靠的那个会话可以坐在它的名册上并听着它,而 @parent 欠的是一笔普通的债。 |
| 0029 | 每个席位上的耳朵 | 每个席位都有一个以秒计的耐心:零是一只活着的耳朵,三十或更多是一只有耐心的耳朵,而中间那一段会被拒绝。 |
怎么读它们
从 0001 和 0002 开始——其余每一条记录都以它们为前提。0007、0013 和 0015 是一个集成者
最先遇到的三个边界。协作那几条记录,0021 到 0029,读起来是一个序列,最好按顺序看。
它们的正文在仓库的 docs/adr/ 里,而把每一条落实下去的那些计划在 docs/plans/。