文档

说到使用文档

从安装跑起来,到把模型配到最好、看懂它的安全机制——全部在这里。完成度如实标注:现在可用 / 进行中 / 规划中。

目录

0. 怎么读这份文档

  • 只想先跑起来:读 §1(它是什么)→ §4(快速开始)→ §5.3(三种配置方案)就够;其余按需查。
  • 想知道它到底怎么做到的:§3(工作原理)→ §7(项目与 Git)→ §8(审批与安全)→ §9(记忆与账本)→ §10(验收与交付)。
  • 想配多家模型 / 多个 CLI 把效果调到最好:§5(模型与供给)全读,再看 §6(执行器)。
  • 关心数据去哪了、花不花钱:§14(隐私与数据)、§15(费用)。
  • 每节标题后若带 现在可用 / 进行中 / 规划中,表示该节描述的能力当前状态;没带的 = 该节内容整体现在可用,个别差异在正文内标注。
  • 文档口径以 macOS 桌面服务当前版本为准;移动 App 均未上架,手机相关内容以「可以这样连」而非「商店下载」为准(§13)。

1. 「说到」(SayDo)是什么

「说到」(SayDo)是一个你能对着说话的高级助手,运行在你自己的 Mac 上。你只管把事情聊清楚——甚至边聊边想清楚;它先吃透你的项目上下文,把每件事记成一本账;听懂了、火候够了,就主动提议开工,驱动你电脑上已有的 AI 工具去办;执行和检查都跑完,它主动叫你来验收;你点头,才算交付。

它的心智模型是幕僚长(chief of staff):天天和你聊、听懂就自己把事办成、做完来汇报——而不是「你说得越清楚我做得越好」的指令翻译器。核心竞争力不在用哪个模型,而在上下文工程 + 人机协作流程

1.1 三条核心承诺

  • 说了就记:按住说话(或打字),想到哪说到哪。随口一句「帮我记一下」立刻进账;答应的事、等你拍板的事、AI 正在办的事、等别人回音的事,件件有归属有去向。
  • 先吃透,再办事:第一次接触一个项目,它先做一次「奠基」——扫清项目结构与关键文件、吸收仓里已有的约定、生成持久的项目知识底座;之后每次对话都带着对你项目的理解,而不是从零开始。这是「说到」和「新开一个聊天窗口」的分水岭。(当前版本的奠基是确定性的机械管道;由沉思档模型做的深度研究是进行中的下一档,§9.2)
  • 人拍板才算数:开工前给你决策包(做什么、怎么做、哪些它做哪些要你配合、最终长什么样);办完只说「等你验收」,不说「做完了」;合并、交付,永远你点头才生效。

1.2 它不是什么

  • 不是语音输入法。它不做「语音转文字再粘贴」;语音只是入口,后面是理解上下文、立账、判断就绪、驱动执行、组织验收的完整闭环。
  • 不是云端代跑。没有「说到」的服务器,没有账号注册。重活在你自己的电脑上跑,数据存在你自己的设备上;你接入的第三方 AI(订阅 CLI 或 API key)由你的电脑直接调用,开发者不经手、不可见。
  • 不是又一个聊天客户端。语音识别、聊天、编码 agent 每一块都有成熟单点;「说到」做的是把「聊透 → 自动开工 → 办完叫你验收」治理成同一套闭环——含审批、预算、隔离、回叫、验收、沉淀。
  • 不是通用语音助手。不做闹钟、闲聊、放歌;不替代 IDE——diff、日志、长文档永远转屏幕看,语音只承载决策和摘要。

1.3 适用的事

它服务「有明确产出物的事」:代码改动 / 文档 / 调研报告 / 文章 / 方案 / 行动计划。编码开发是主场景(工程师口述需求 → AI 在隔离 worktree 里开发 → 你验收合并);但同一套上游能力(奠基、采访、就绪决断、回叫、沉淀)也服务写作与生活筹备、调研这类非代码的事。当前项目类型能力门:coding(现在可用)、writing(窄版已落地,合并链复用 coding 的 worktree + 强认证合并;引用级引证、归属合同等全量仍规划中);research / marketing / planning / general 的专属执行合同规划中——但「立一件事盯着、记义务、采访、调研」这些上游能力对任何事都可用(§9.4)。

1.4 当前状态一句话

  • macOS 桌面服务(守护进程 daemon + Web 控制台 + 可选语音管线):现在可用,开源免费(见 §18 开源与参与)。
  • 驱动你已有的 AI:推理槽位可用 Claude Code / Codex / Cursor / Grok / Gemini CLI / Qwen Code / Copilot CLI 的订阅登录态或任意 OpenAI 兼容 API(§5);执行器(真正改代码的 agent)当前为 Cursor CLI,Claude Code 执行器进行中,Codex 执行路线规划中(§6)。
  • 项目记忆与四色账本:现在可用。
  • iOS / Android / HarmonyOS App:工程壳存在,均未提审上架;手机当前可经局域网用 App 壳或手机浏览器连接桌面服务(§13)。
  • 来电式语音汇报:规划中。

1.5 费用一句话

桌面服务本身免费。AI 能力的费用直接付给你选的厂商——用你已有的 CLI 订阅(额度内零额外费用),或你自己的 API key 按量计费。「说到」不加价、不经手、不代充。细节见 §15。

2. 核心概念速查

概念一句话详见
沟通面 / 执行面手机和浏览器是沟通面(说话、看进展、拍板、审批);你的 Mac 是执行面(奠基、记忆、驱动 AI、后台办事)。沟通天然是移动的,执行天然是固定的§3.1、§13
daemon(守护进程)桌面服务的核心常驻进程:持有全部账本与状态,托管 Web 控制台,执行工具调用,派发任务,发回叫。语音会话断了它也活着§3.1
Brain(对话大脑)对话轮次背后的模型:采访、答疑、口播;它没有直接执行权,所有副作用都经 daemon§3.1
一件事(Focus)账本的主轴:一件持续关注的事(可以关联 0..N 个项目,也可以不属于任何项目);下面挂「义务」(谁欠什么)与「期待」(做成什么样)§9.4
四色账本今天页的四个色区:等你拍板(橙)/ 你欠的动作(蓝)/ AI 正在办(绿)/ 等外部回音(灰)。每件事都有归属和去向§9.4
项目 / 工作区项目 = 一类产出物的承载边界;coding 项目的工作区是你本机的一个 git 仓库文件夹;非代码项目默认用系统管理的文件夹§7.1
奠基(Foundation)第一次接触项目时的阻塞式深度研究,建立项目知识底座(M1)§9.2
M0–M3 记忆M0 跨项目用户档案层 / M1 项目知识底座 / M2 累积产物 / M3 会话转写§9.1
就绪(Readiness)「够不够开始」的判定:按项目类型的就绪清单逐项确认,由独立评估器(与对话模型不同家族)复核§3.3、§5.4
决策包就绪后端出的成果预览 + 实施计划(每步标 AI 执行 / 需你配合)+ 预计花费与封顶,外加一份轻量小样(与计划同源机械渲染的网页预览)和一句「现在开始?」§3.3
执行模式逐步确认(每个出圈动作和步骤边界都先问你;出厂默认,当前唯一生效档)/ 直达验收(一口气跑到等你验收,S2 类效果按念读签署的预授权清单放行;进行中)§8.4
S0–S3动作风险分级(按效果算,不按动作名):S0 读 / S1 写 worktree 内 / S2 出圈可逆 / S3 不可逆或外部影响。S3 永远只走已认证屏幕,语音绝不放行§8.1
Gate 0开放自主派发前的安全门禁(身份授权、幂等、独立验收 oracle、secret/egress、意图审计、删除/同意传播);代码里没有 bypass 分支§8.2
worktree 隔离每个任务一个独立 git worktree,主工作区永不被 agent 碰§7.2
ready_for_review执行和检查都跑完、产物落盘、等你验收的状态;回叫从这里触发。它不等于完成;合并/归档后才是「交付了」§10.1
推理槽位(四槽)对话 dialog / 沉思 thinking / 廉价 cheap / 评估 evaluator——各自可选 API 或订阅 CLI 供给§5.1
开发档(执行器)第五个槽位 [models.dev]:派发任务时驱动哪个 agent 去改代码(与上面「调哪个模型说话」是两回事)§6
BYOA(Bring Your Own Agent)用你本机已登录的 CLI(Codex / Claude Code / Cursor / Grok / Gemini / Qwen / Copilot)做推理供给,零 API key§5.2
cap-token控制台的本机能力令牌(~/.saydo/.cap-token),进控制台的 URL 里带它;删了会轮换§4.3、§14

3. 工作原理

3.1 整体架构:三层

人(说 / 听 / 偶尔看屏;拍板 / 审批)
   │ 语音或文字(浏览器、手机)                回叫(语音 / 桌面通知 / 手机推送)
┌──▽────────────────────────────────────────────────────────────┐
│ 沟通面:Web 控制台(桌面浏览器)/ 手机(App 壳或手机浏览器,局域网)     │
│   · 语音引擎(可选 Python 语音管线:ASR → 文本模型 → TTS)           │
│   · Brain:采访 / 就绪自省 / 决策包 / 口播;无直接执行权              │
├────────────────────────────────────────────────────────────────┤
│ 控制面:daemon(Node 22,常驻)——一切 durable 状态的唯一持有者        │
│   · 账本:一件事 / 义务 / 四色 attention / 记忆事件账本 / 审批收据     │
│   · 工具执行、Context Pack 装配、任务派发、事件对账、回叫、成本记账     │
│   · 本机 HTTP/WS(缺省 127.0.0.1:47100,能力令牌鉴权),托管控制台静态页 │
├────────────────────────────────────────────────────────────────┤
│ 执行面:本机 AI 执行器(Tier 1,当前 Cursor CLI)——在隔离 worktree 里  │
│   改代码;每条 shell 命令经审批门回连 daemon;预算/时长/回合三熔断     │
│   (另有经 Hopper 的批式执行路线,合同已定、生产绑定当前休眠,§6.3)    │
└────────────────────────────────────────────────────────────────┘

三条铁律贯穿全部设计:

  1. Brain 的模型进程可丢弃、无直接执行权——语音会话或推理进程随时可以死掉重建,任务照跑;所有副作用发生在 daemon / 执行器。
  2. 语音会话短命,任务长命——会话是事件驱动的窗口(空闲 45 秒或你说「先到这里 / 先这样 / 收工」就挂起,零成本);任务在后台持续执行,靠回叫把人拉回来。
  3. 每项状态只有一个 owner——对话域状态归 daemon,执行域状态归执行器/后端;跨边界用 durable 协议(幂等 key、事件游标、收据)连接,不共用数据库。

组件一览(全部跑在你的 Mac 上,无云端依赖):

组件是什么备注
daemon核心守护进程(TypeScript / Node 22):对话与任务状态的唯一持有者;托管控制台网页;审批门、账本、审计都在这缺省端口 47100;只监听本机回环
consoleWeb 控制台(Vite + React);桌面与手机(移动壳路由)共用一套由 daemon 直接托管,浏览器打开即用
pipeline语音管线(Python):桌面浏览器的云端听与说(火山豆包 ASR / TTS)可选;不起则用打字或浏览器系统语音
saydo CLIsaydo up / status / open:前台持有 daemon、探活、开控制台可选;与直接起 daemon 二选一
contracts数据契约包(zod schema、状态机、digest):各组件不分叉的类型单源开发者关心
执行器拍板后在 worktree 里真的改代码的 agent(当前 Cursor CLI)可选;没有不影响对话与记账

3.2 一次完整闭环:从聊一句到办完叫你

步骤发生什么背后机制你做什么
1 开口聊「今天」页点「开口聊」,按住说话或打字;随口一句「帮我记一下」立刻进账;它像采访一样一次问一个Context Pack(从 M0+M1+M2 挑相关切片 + 最近几轮)注入;采访纪律:一次一问、选择题优先、有问题预算
2 就绪决断它每轮自省「知识够不够 + 需求清不清」,缺哪维补哪维;够了才提议开工按项目类型的就绪清单(coding:目标 / 可验证的验收标准 / 范围 / 约束 / 代码库关键部分已理解)逐项确认;确认 = 你亲口给出 + 它复述你点头;独立评估器(异族模型)在提议前复核听提议
3 决策包端出成果预览、实施计划(每步标 AI 执行 / 需你配合)、范围内外、验收标准、风险,报预计花费与封顶;随包生成一份轻量小样(网页预览,与计划同源机械渲染)——控制台点「看小样」查看,本机对话时同轮放到你屏幕上计划落盘为可编辑产物,批准版本固化为「合同」;小样随包固化(改包即重生成);决策包有效期 24 小时
4 你拍板说「就这样」/「开始」;执行模式当前按「逐步确认」(「一口气跑完」档的语音念读签署进行中,§8.4)两把钥匙:「证据够了」≠「有权的人批准了这个包+范围+预算+有效期」;派发收据 digest 绑定、单次消费;Gate 0 未关拒派发拍板
5 后台执行在独立 git worktree 里跑,主工作区不被碰;每条 shell 命令过审批门;预算 / 活跃时长 / 回合三熔断;你可以走开,语音会话挂起命令按效果分级 S0–S3;S0/S1 自动放行,S2 上浮要你确认(45 秒无应答即拒),S3 拒绝并要求屏幕强认证可以走开
6 办完叫你执行和检查都跑完、产物落盘确认 → 它主动叫你:「执行和检查都跑完了,等你验收」settle 对账后才回叫(runner 退出不等于完成);优先级 blocked > failed > 待审批 > 待验收 > 进度(默认不叫);投递按升级链:你在控制台且语音就绪 ⇒ 在线语音开口叫你(第一句就是回叫原因,30 秒没应答再升级)→ macOS 桌面通知 + ntfy 手机推送;免打扰窗口内只发一条低打扰推送、过后补叫(§11)被叫回来
7 验收沉淀口播摘要(一句话 / 150 字走读 / 它自己做的决策清单)+ 证据视图(diff、测试、决策、未验证项);你点头 → 过强认证合并 → 「交付了」;知识与产物留存合并 = Touch ID / passkey 屏幕审批卡签单次收据,或你自己去终端合并(人工交接);会话末机械提名稳定结论为候选,你批准后进 M1验收

3.3 采访、就绪与决策包:为什么不用你写需求文档

  • 指令是有损压缩,对话是逐步展开。「说到」不要求你会下指令:你只管聊,它聊到自己懂了、准备够了,主动提议开始。规格是它的产物,不是你的输入。
  • 认知负担从「表达」转移到「判断」:不让你凭空把需求说全,而是让你看着具体的东西(成果预览 + 计划 + Demo)说「对 / 不对 / 调一下」。
  • 就绪判定是类型化的:开发缺验收标准不能开工,写作缺核心论点成不了文;所以先识别这是哪类事,再拿对应清单判就绪。清单里的 critical 项没确认覆盖,它机械地出不了包(不是靠模型自觉)。
  • 防「相关错误链」:同一个模型产事实、判缺口、做 Demo、再自评「够不够」,错误高度相关。所以「够不够开始」由独立评估器复核——与对话/沉思模型不同家族、只读证据账本、不读 Brain 的自辩(这也是 §5.4 异族规则的由来)。
  • 三个正交档位(设计原则,落地程度不一):对话车道(Quick 一两句确认直接干 / Guided 标准采访 / Explore 开放脑暴——规划中,当前只有埋点)× 执行模式(逐步确认 现在可用 / 直达验收 进行中)× 治理深度(S0–S3 由动作效果决定,现在可用)。守门句:你可以把对话调快、把确认调稀,但不能把任何动作的风险等级或 S3 门槛调低

4. 快速开始(普通用户路径)

目标:一台 Mac、一个你已登录的 AI CLI(或一个 API key),十几分钟跑起来并开口聊。

4.1 前提

要求说明
系统macOS(Apple Silicon / Intel 均可)常驻、通知、打开浏览器等链路都是 macOS 实现;其他系统未支持
Node22.x(>=22 <23)桌面服务与 CLI 的运行时;用 nvm / fnm / Homebrew 装
pnpm10.xcorepack enable 即可
git任意新版构建与任务隔离(worktree)都要
一个 AI 供给二选一:① 本机已登录任一已接线 CLI(Codex / Claude Code / Cursor / Grok / Gemini CLI / Qwen Code / Copilot CLI);② 一个 OpenAI 兼容 API key(OpenRouter / OpenAI / Anthropic / DeepSeek)只聊天、立账、调研不需要 key(走 CLI 订阅);见 §5.3
可选 · Python 3.11+ 与 uv只有桌面浏览器云端语音(火山豆包 ASR/TTS)才需要不配也能说话:浏览器系统语音兜底(§12)
可选 · cursor-agent 登录态 + jq只有派发执行任务(让 AI 真改代码)才需要没有不阻断对话,只是拍板后不会起执行器(§6)

4.2 安装

目前以源码形式分发(尚无 npm / Homebrew 包,见 §16):

git clone https://github.com/Octo-o-o-o/SayDo.git && cd SayDo
pnpm install && pnpm -r build      # build 必须:daemon 托管的控制台页来自 packages/console/dist

4.3 启动桌面服务

两种等价方式,任选其一(同一个数据目录 ~/.saydo 同时只允许一个实例):

# 方式一:直接起 daemon(开发形态;在仓库根目录执行)
mkdir -p ~/.saydo
(cd packages/daemon && SAYDO_HOME=$HOME/.saydo nohup ./node_modules/.bin/tsx src/index.ts >> ~/.saydo/daemon.log 2>&1 &)

# 方式二:用 saydo 命令行(可分发形态;先构建一次)
pnpm --filter @saydo/cli build
node packages/cli/dist/cli.mjs up        # 前台持有 daemon,Ctrl+C 优雅退出并可续接任务
node packages/cli/dist/cli.mjs status    # 探活:0=已连上 / 1=端口空闲 / 2=端口冲突
node packages/cli/dist/cli.mjs open      # 打开控制台
  • 缺省端口 47100(直起 daemon 用环境变量 SAYDO_DAEMON_PORT 覆盖;saydo 命令行只认 --port);缺省只监听本机回环地址。saydo up 缺省会自动打开浏览器,--no-open 可关。
  • 数据目录缺省 ~/.saydo(--homeSAYDO_HOME 覆盖)。首次启动会自动生成:config.toml(占位模板)、.cap-token(控制台令牌)、saydo.dbsessions/logs/projects/ 等。
  • 健康探针:curl -s http://127.0.0.1:47100/health(ok:true 即起来了;tsx 冷启动约 10–15 秒)。
  • 进控制台:open "http://localhost:47100/?token=$(cat ~/.saydo/.cap-token)"(saydo open 做的就是这件事)。注意用 localhost:为了 Touch ID 合并卡的 WebAuthn 绑定,127.0.0.1 的页面请求会被重定向到 localhost。令牌首次注入后存在浏览器本地,之后的链接不必再带。

4.4 首次使用:资源画像向导

进门先看到资源画像:它清点这台机器能用的模型来源(装了哪些 CLI、哪些已登录、.env 里有哪些 key),然后给出方案卡(§5.3 三种)。典型零 key 流程:

  1. 看到「全用 Codex(订阅内零成本)」之类的一键卡(每家已登录的 CLI 一张;列表按 已登录 > 仅安装 > 未装 排序,同档内按用过次数);
  2. 勾两条知情确认(评估档与对话同族 / 评估器笼隔离不可证,§5.4);
  3. 点「确认并启动」→ 写入待生效配置 → 自检 1/2(四槽各真调一次)→ 重启服务 → 自检 2/2(生效后再确认)→ 落到「开口聊」。全 CLI 方案每槽一次 15–25 秒,两轮自检合计约 1–3 分钟(视 CLI 而定,可能更久),界面有进度与耗时;
  4. 之后随时可在「设置」里换方案、逐槽手配(高级模式)。

没配好对话档之前,进哪一页都会先弹向导(有「先随便看看」逃生口);首次且账本为空时,它会先说一句固定开场白请你「随便说三件这周要办的事」给你立账看看。

4.5 开口聊:今天页

控制台左栏:开口聊(主入口)/ 今天(四色账本,唯一「需要你」入口)/ 全景看板 / 「正在持续的事」分组(按空间列出各件事)/ 「记录」分组:记忆库 / 产物 / 成本 / 设置;旧版 Dashboard、审批中心、通知、任务、Focus 列表(旧)、看板(旧)收在「旧版」折叠组里。

  • 「今天」页点「开口聊」:打字,或按住说话(§12);想到哪说到哪。
  • 聊成熟它会问你要不要立成一件持续关注的事;要它办的、你欠它的、等别人的,都会出现在「今天」页的四色区。
  • 开发类请求会真的走「采访 → 就绪 → 决策包 → 拍板 → 派发」全链(§3.2);拍板前它会报预计花费与封顶。
  • 已知体感(不是坏了):CLI 对话模式每轮想 15–25 秒是常态,别连点(桌面端单次调用 120 秒上限后才报错);偶尔只回应一半诉求,再问一次即可;「帮我记一下」类随口记录通常当轮提议落账,偶尔会降级先进记忆库(菜单里可看),立起事后可再挂账。

4.6 可选:桌面浏览器语音

  • 零配置:浏览器有系统语音识别(Chrome / Safari 的 SpeechRecognition)就能按住说话、朗读回复;质量一般,识别文本走文字通道。
  • 云端语音(更准更自然):在 ~/.saydo/.env 填火山豆包的 VOLC_APP_ID + VOLC_ACCESS_TOKEN(流式识别,带你项目术语的热词偏置)与 DOUBAO_TTS_API_KEY(seed-tts-2.0 合成),并起 Python 语音管线:
cd pipeline && uv sync
SAYDO_HOME=$HOME/.saydo SAYDO_DAEMON_PORT=47100 nohup uv run python -m saydo_pipeline >> ~/.saydo/pipeline.log 2>&1 &

配好后控制台自动切到云端;管线缺席时 /readyzvoiceReady=false(文本与控制面照常可用,不算启动失败)。细节见 §12。

4.7 可选:手机连接(局域网)

手机 App 均未上架;当前可经局域网用手机浏览器(或自行构建的 App 壳)连到桌面服务:

  1. 启动 daemon 时加 SAYDO_MOBILE_LAN=1(监听 0.0.0.0,只接受内网 RFC1918 来源 + 能力令牌 + Host/Origin 校验三道门);
  2. 查本机内网 IP(ipconfig getifaddr en0),把 http://<内网IP>:47100/?token=<cap-token> 做成二维码(令牌不要贴进第三方在线工具)给手机扫;手机浏览器直接打开该 URL 也行(移动壳路由 #/m);
  3. 手机上从下方胶囊按住说话(iPhone 走系统语音识别,不需要 Python 管线),上滑选放进哪件事;看「今天」四色、看进展、对立账 / 记账类确认卡点头或撤回。执行中的命令审批(S2)与合并 / 删除(S3)只在本机受信屏幕出现,局域网手机面不能裁决(手机上没有设备配对身份)。

这是 dogfood 级的临时边界(局域网明文 HTTP + 长期能力令牌),不要暴露到不受信网络;设备配对 / 端到端加密 / 商店版 App 见 §13 与 §16。删 ~/.saydo/.cap-token 再重启会轮换令牌,所有已连设备一起掉线需重扫。

4.8 常驻、备份、关停与重置

  • 常驻(launchd):just daemon install | start | stop | restart | status | logs | deploy [sha]——开机自起 + 崩溃自启,运行时树与开发树分离(~/.saydo/runtime~/.saydo/releases/<sha>)。install 会一并生成并装载语音管线的常驻配置(需要 uv);没装 uv 时用 just daemon install --without-pipeline 只装 daemon(桌面浏览器云端语音不可用,系统语音与文本照常);uninstall 对称卸载两者。日常上手用 §4.3 的前台方式即可,常驻适合长期挂机。
  • 更新:git pull && pnpm install && pnpm -r build,然后重启 daemon(前台形态 Ctrl+C 再起;launchd 形态 just daemon deploy——会重启 daemon 与语音管线,挑空闲时段)。
  • 备份:daemon 每日自动快照到 ~/.saydo/backups/<时间戳>/(SQLite 在线备份 + sessions/ + 用户档案 + 各项目的知识底座与奠基产物),保留期 [params].backup_retention_days(缺省 30 天);just backup 手动触发。
  • 关停:lsof -t -iTCP:47100 -sTCP:LISTEN | xargs kill; pkill -f saydo_pipeline(saydo up 前台形态直接 Ctrl+C:会先停新派发、给活跃任务写「待续接」标记、再收口进程,下次启动接着跑)。
  • 完全重置(回到全新用户):停完后 rm -rf ~/.saydo——会轮换令牌,也会删掉全部账本与记忆;项目工作区里的 <repo>/.saydo/ 不在此目录,需单独处理。

5. 模型与供给(高级用户必读)

「说到」把模型用途拆成五个槽位,每个槽位独立选供给方式与模型。这是「一个订阅就能用」和「多家模型配合到最好」两种玩法的同一套机制。

5.1 五个槽位

槽位配置键干什么要什么示例(仓库模板 / 向导「一个 key」卡)
对话档[models].dialog每一轮对话:采访、答疑、口播低延迟、中文口语好、工具调用纪律强API(OpenRouter,openai/gpt-5.6-luna)
沉思档[models].thinking任务卡起草、决策包 / 计划生成、奠基提炼(轻量小样为机械渲染,不占模型)深推理,异步不阻塞对话API(OpenRouter,openai/gpt-5.6-terra-pro)
廉价档[models].cheap摘要叙事、热词抽取、事件打标等高频结构化调用便宜、快API(OpenRouter,google/gemini-3.1-flash-lite)
评估档[models].evaluator独立判「够不够开始」(就绪深评)与对话/沉思不同家族(§5.4)API(OpenRouter,anthropic/claude-sonnet-5)
开发档(执行器)[models.dev]派发任务时驱动哪个 agent 改代码、用它的哪个模型见 §6agent = "cursor"(与仓库模板一致;当前唯一生产执行器)

为什么分档:对话档要的是延迟(你在等它出声),沉思档要的是质量(产出是「合同」),廉价档要的是成本(高频调用),评估档要的是独立性(换一家模型做裁判)。一个模型通吃四档要么慢、要么贵、要么不独立。

5.2 两种供给方式

方式 A · API 直连({ provider = "api", via = "<端点名>", model = "..." })

  • 任意 OpenAI 兼容端点:在 [providers.api.<name>] 声明 base_url + api_key = "env:VAR"(key 只能以环境变量引用,禁止明文写进配置)。
  • 推荐网关 OpenRouter:一个 key 打通多家(缺省模板就是它);也可直连单家(OpenAI / Anthropic / DeepSeek / 月之暗面 / 阿里百炼……模板有示例)。
  • 模型名带厂商前缀时(openai/…anthropic/…google/…deepseek/…x-ai/…qwen/…)家族自动解析;单家直连端点模型名无前缀时,端点要显式写 family = "deepseek" 之类——给 §5.4 的异族校验用。
  • 对话档走 API 时是实时模式:完整多轮工具环、流式、秒级返回,语音对话就靠它。

方式 B · 订阅 CLI(BYOA)({ provider = "<x>_cli", model = "..." })

用你本机已经登录的 AI 命令行工具做推理供给,零 API key、走你的订阅额度。当前已接线的 CLI:

provider对应命令备注
codex_clicodex家族恒 GPT;可配 reasoning(none/minimal/low/medium/high/xhigh/max);model 可省
claude_cliclaude家族恒 Claude;model 可省
cursor_clicursor-agentmodel 必填(如 claude-fable-5-thinking-maxcursor-grok-4.6-high-fast),家族按模型名解析
grok_cligrok家族恒 grok;model 可省
gemini_cligemini家族来自显式 model 名或流内上报;解析不出则该槽阻断
qwen_cliqwen同上(传输型 CLI)
copilot_clicopilot同上(传输型 CLI)

(kimi_cli / opencode_cli 只在资源画像里「可识别」,不能当供给——本机实测无法在执行前可证零工具,出于安全不接线。)

登录是你与厂商之间的事:用各家官方方式登录,「说到」只探测「装没装 / 登没登录 / 能列出哪些模型」,未登录时向导给出可直接粘贴的修复命令(以向导提示为准):

CLI登录
cursor-agentcursor-agent login
codexcodex login
claudeclaude auth login
grokgrok login
gemini在终端运行 gemini 完成 Google 登录
qwen配置 OpenAI 兼容端点或 OPENAI_API_KEY(它走上游 API 计费,账本文案如实区分)
copilotcopilot login

BYOA 的工作方式与纪律(你会在界面上感到的部分):

  • 一发一收、无状态:每次调用起一个新的 CLI 子进程,不复用会话(刻意不用 resume——会话落盘与隐私开关互斥,且实测 resume 对延迟也无收益)。
  • 对话档走 CLI = 慢速文本模式(dialog_cli_oneshot):每轮约 15–25 秒,返回一段回复 + 最多 8 个结构化动作(记一笔、立任务、查状态、提议开工……),daemon 逐个执行;不进入语音实时环(语音对话请给对话档配 API)。这不是卡死,界面会显示慢速徽标与进度。
  • 真实自检后才生效:配置保存时,每个走 CLI 的槽都会真的调一次(对话档要回合法 envelope,廉价档要过 schema,评估档要过与生产同形的深评请求并上报实际模型),四槽全过才重启生效;任一失败只把该槽标红并给人话原因,不伪装成功。
  • 笼子:推理用的 CLI 调用在逐次新建的空隔离目录里跑、prompt 头部硬禁「执行命令 / 读文件」,并按 CLI 能力用最严的零工具旗标(Claude --tools ""、Codex 只读沙箱、Grok --tools ""、Gemini/Qwen/Copilot 各自的 deny 策略 + 隔离 HOME);流里一旦出现工具调用事件立即终止作废(tripwire)。Cursor CLI 没有可证零工具旗标,只有「ask 模式 + tripwire 检测」,是三档里最弱的笼。正因为 CLI 笼都「限写不限读」(读盘不可挡,评估器理论上能翻到 Brain 的自辩),评估档用任何 CLI 都需要你亲手勾两条知情确认(同族 + 隔离,§5.4)。
  • 实际模型复核:每次调用记录 requestedModel / observedModel,流内上报的模型家族与配置不符即该次作废;Codex / Claude 这类固定家族 CLI 在可执行文件身份核验(绝对路径 + 内容 digest 登记)通过时允许按登记家族放行。

5.3 三种配置方案(首跑向导里的三张卡)

首次进控制台会看到「资源画像向导」:它探测本机装了哪些 CLI、哪些已登录、.env 里已有哪些 key,然后给出可一键套用的方案卡——

方案适合谁四个推理槽怎么配体验
全用某个 CLI(如「全用 Codex」)只有一个订阅、不想申请 key对话 / 沉思 / 廉价 / 评估四槽全走该 CLI零 key 零终端;对话每轮 15–25 秒(慢速文本模式);订阅额度内零额外费用。评估档走 CLI 且与对话同族,需勾「同族知情确认」+「隔离知情确认」两条
对话走 API + 其余槽 CLI有订阅,也愿意为实时对话花一点 API 费对话档 API(秒级、可语音);沉思 / 廉价 / 评估走 CLI推荐的「又快又省」组合;评估档走 CLI 同样需勾两条知情确认
一个 key 全搞定没有任何 CLI 订阅四槽都走 OpenRouter API,各槽按规格指定模型秒级返回;按量计费,以服务商账单为准

向导的「高级模式」允许逐槽手配:每槽独立选 API 端点 / 任一已登录 CLI / 指定模型;两路都要四槽自检全绿才会重启生效。进阶玩法举例:

  • 对话档 API(如 OpenRouter 上的 google/gemini-3.1-flash 类低延迟模型,家族 gemini)+ 沉思档 cursor_cli(claude-fable-5-thinking-max,家族 claude)+ 廉价档 grok_cli + 评估档 codex_cli(reasoning = "max",家族 gpt)——对话快、沉思强、评估与对话 / 沉思都异族,且沉思与评估不共享同一家订阅时窗(评估档走 CLI 需勾两条知情确认)。
  • 全 API 但分家:对话 / 沉思走一家,评估走另一家;或用 OpenRouter 统一 key、按槽挑不同厂商的模型。
  • 项目级覆盖(控制台项目设置):某个项目把对话档 / 沉思档换成更强(或更省)的 API 模型、改开发档模型、改预算上限;项目层只允许 API binding,评估档不可覆盖(它是护栏锚点)。

5.4 异族规则:评估器必须换一家

「够不够开始」的判定若由同一个模型(或同一家族)自评,错误会与生成高度相关。因此:

  • 评估档的模型家族 不得 与对话档、沉思档相同(fail-closed:同族且未确认 → 评估档 unarmed,daemon 启动给提示;对话仍可用,但就绪深评不会武装)。
  • 家族按解析后的实际模型判:openai/…→gpt、anthropic/…/fable/sonnet/opus→claude、google/…→gemini、deepseek、grok、qwen、composer(Cursor 自研)……;codex_cli 恒 gpt、claude_cli 恒 claude、grok_cli 恒 grok;Cursor CLI 按你填的模型名解析。
  • 知情豁免两条(必须你亲手勾,界面不代签):evaluator_same_family_ack(接受同族评估,代价是独立性下降)、evaluator_isolation_ack(接受「限写不限读」的 CLI 笼做评估器,代价是「评估器读不到 Brain 自辩」不可证)。评估档只要走 CLI(任何一家、不论家族是否相异),两条都必须为 true;评估档走 API 且异族则一条都不需要。「全用某 CLI」方案天然需要这两条。
  • 评估档走 CLI 的武装条件 = 两条 ack 都为 true + 自检通过 + 实际模型家族可证;任一不满足就 unarmed(原因会分别显示 same_family_blocked / isolation_ack_required / cli_self_test_required / cli_self_test_failed)。
  • 相邻规则:沉思档 / 廉价档的 CLI 未登记或自检失败时,如实回落到对话档供给(状态显示 fallback_dialog 并给原因),服务不中断、不伪装成 active。

5.5 计费与记账口径

  • 订阅 CLI 调用不产生「元」:成本账本记为 source = subscription,界面显示「订阅额度内」(调用次数在周报里看)——不显示 ¥0、不显示「未知」、不预测剩余额度。只有探测到该 CLI 的认证面确属订阅(如 Gemini 个人 OAuth、Copilot GitHub 登录)才写「订阅内零成本」;若 CLI 上游其实是 API key 计费(如 Qwen 配 key),文案如实改为「按该 CLI 的上游计费方式,说到不代付」。
  • API 调用按单价表估算:[pricing] 无表项的模型成本显示「还没有确切数字」(绝不编数、不显示 0)。真正拦你的是每个任务的成本 / 时长 / 回合三熔断(§8.5),成本封顶只约束 API 计费部分,订阅调用靠墙钟 + 回合数兜底;[budget].monthly 目前只是配置项(无任何执行或展示点),不是硬闸。
  • 订阅限流不静默转计费:触发周 / 5 小时时窗限流时,该次调用返回可重试的限流错误并如实告知,绝不自动转 API 计费。「停下问你切按量计费还是等重置 + 单次 billing-switch 收据(有效期 10 分钟)」与「durable 排队自动重放」两套合同已落,生产尚未接入(进行中)。

5.6 配置文件参考

全局配置 ~/.saydo/config.toml(非密)+ ~/.saydo/.env(密钥真值;永不进 Git);仓库 templates/ 下有可复制模板。首跑向导写的就是这两个文件,手改后重启 daemon 生效(配置非法时 daemon 进入「仅恢复」模式:健康探针与设置自救页可用,对话与派发停用,见 §17)。

[models]
profile   = "default"                # default | dev(dev 还需环境变量 SAYDO_DEV=1,双开关)
dialog    = { provider = "api", via = "openrouter", model = "openai/gpt-5.6-luna" }     # 家族 gpt,实时语音环
thinking  = { provider = "codex_cli", reasoning = "high" }                            # 家族恒 gpt,走 ChatGPT 订阅
cheap     = { provider = "grok_cli" }                                                 # 家族恒 grok,model 省略=CLI 默认
evaluator = { provider = "api", via = "openrouter", model = "anthropic/claude-sonnet-5" } # 家族 claude,与上两者异族,无需 ack
# evaluator_same_family_ack = true   # 评估档走任一 CLI 时两条都必填(否则就绪深评 unarmed);评估档走 API 且同族时只需第一条
# evaluator_isolation_ack   = true

[models.dev]                         # 开发档 = 执行器(§6)
agent     = "cursor"
transport = "cli"
model     = "grok-4.6"               # 以 cursor-agent 当前可列出的模型名为准

[providers.api.openrouter]
base_url = "https://openrouter.ai/api/v1"
api_key  = "env:OPENROUTER_API_KEY"  # 恒 env 引用;多家网关不写 family
# provider_order = ["deepinfra"]     # 可选:聚合网关钉死上游路由顺序并禁自动兜底(确定性路由)
# [providers.api.deepseek]           # 单家直连示例:模型名无前缀 ⇒ family 必填
# base_url = "https://api.deepseek.com/v1"
# api_key  = "env:DEEPSEEK_API_KEY"
# family   = "deepseek"

[voice]
engine = "cascade"                   # 级联:ASR → 文本模型 → TTS
asr    = "volc"                      # 火山豆包流式识别(带热词偏置)
tts    = "volc"                      # 豆包 seed-tts-2.0 v3 双向流式

[privacy]
store_audio          = false         # 录音与转写分别同意
store_transcript     = true
audio_retention_days = 0

[budget]
monthly  = 200                       # 当前只是配置项(无执行点),不是硬闸;真正的熔断在每个任务(§8.5)
currency = "CNY"
task_max_default = 20                # 单任务成本封顶缺省(元;只约束 API 计费部分)

[dnd]
window = "23:00-08:00"               # 免打扰:窗口内不外呼,记 snooze 到窗口末后按队列补叫

[tier1]                              # 执行器(Cursor CLI)版本钉死,两键齐备才启用
cursor_agent_bin            = "/Users/<你>/.local/share/cursor-agent/versions/<ver>/cursor-agent"  # 必须绝对路径,不接受 ~
cursor_agent_pinned_version = "<ver>"

[gate0]
enabled = true
bypass  = false                      # 恒 false;为 true 反而一律拒绝派发(防误配)

[params]                             # 可调参数(节选)
foundation_budget_min  = 5           # 奠基墙钟上限(分钟)
interview_question_budget = 8        # 采访问题预算
park_aging_hours       = 72          # 停靠老化:等人超过 72h 取消并转草稿
proposed_ttl_hours     = 24          # 决策包有效期
backup_retention_days  = 30
enabled_project_types  = ["coding"]  # 类型能力门;可开 ["coding","writing"]

.env 常用键:OPENROUTER_API_KEY / OPENAI_API_KEY / ANTHROPIC_API_KEY / DEEPSEEK_API_KEY(按你建的端点填)、DOUBAO_TTS_API_KEY + VOLC_APP_ID + VOLC_ACCESS_TOKEN(桌面浏览器语音用,§12)、NTFY_TOPIC + NTFY_SERVER(手机推送,§11)。

项目层可覆盖的键白名单见 §7.1(<workspace>/.saydo/project.toml):只允许 [project]/[git]/[verify]/[setup] 与 budget / dnd / params 子集;models / providers / gate0 / hopper / privacy / voice 出现在项目层一律拒绝——仓库随附文件是不可信输入,不能把你的 key 引到别人的端点。

6. 执行器(开发档):谁来真的改代码

6.1 两套词表,别混

  • 推理槽的 CLI 供给(§5.2)= 让 Codex / Claude / Cursor / Grok / Gemini / Qwen / Copilot 的 CLI 替 Brain 说话、想事、评估——它们只做一发一收的文本推理,不碰你的仓库。
  • 执行器(开发档,[models.dev])= 拍板后在 worktree 里真的改代码、跑命令的 agent。词表 claude_code | cursor | codex,但当前只有 cursor 有生产实现;配成别的会被 daemon 拒起执行器(fail-closed,不会偷偷拿 Cursor 二进制冒充),对话不受影响。

6.2 当前可用:Cursor CLI 执行器 现在可用

  • 驱动方式:cursor-agent -p --force --trust --output-format stream-json --model <model> [--resume <chatId>] <prompt>,在任务 worktree 里跑;模型填 cursor-agent 当前可列出的任一模型名(已实测过 Grok 4.6 与 Composer 2.5;Claude 系亦可),事件流上报的实际模型家族与配置不符即该轮作废。
  • 审批门:执行器为每个 worktree 写 .cursor/hooks.json,beforeShellExecution 钩子同步阻塞回连 daemon 的本机 unix socket;daemon 按命令效果分级裁决(§8.1/§8.3);钩子超时、JSON 畸形、socket 不通一律 = 拒绝;事件流里出现 shell 调用却没有对应门请求 ⇒ 判定门被绕过,立即终止任务(canary)。
  • 版本钉死:[tier1].cursor_agent_bin 必须是锁定副本的绝对路径(…/versions/<ver>/cursor-agent)+ cursor_agent_pinned_version 精确相等;两键齐备才启用执行器——防 cursor-agent 自更新后行为漂移。升级 = 改两键 + 重跑门禁。
  • 凭据剥离:agent 进程环境只带 PATH/HOME/USER/LOGNAME/SHELL/LANG/LC_ALL/LC_CTYPE/TERM/TMPDIR 十个变量,不带任何 API key / token;它的登录态在它自己的 HOME 存储里。
  • 诚实边界:Cursor 后端只有 shell 通道过门,内建的文件读写 / 联网工具不经钩子——所以它的网络出口能力表如实标 egress = uncontrolled,隔离靠「独立 worktree + 凭据剥离 + 命令门」,不是沙箱;不信任的任务请用逐步确认档并盯紧 S2。
  • 中途改需求(steer):当前没有任何后端支持运行中即时注入;运行中的任务 = 终止本轮再带新指令续跑(cancel_resume,worktree 保留),排队 / 停靠中的任务 = 下次运行时注入(queued_delta)。它会如实告诉你是哪一种。

6.3 进行中与规划中

后端状态说明
Claude Code 执行器(agent = "claude_code")进行中方案已定:以官方 claude -p --output-format stream-json 子进程为传输,用 Claude Code 的 PreToolUse hooks 做 S1–S3 裁决(文件工具也能进门,比 Cursor 多一层),钩子由命令行注入而非 worktree 内文件;订阅只经 claude 登录态消费、零 API key;不启用 bypass 权限、不做 live steer。分三批落地:第一批(对官方 CLI 的真机能力实测 + 审批门纯函数)已收口,接线批在途
Codex 执行器规划中设计上经 Hopper 批式路线(见下);当前 agent = "codex" 会被拒起
Hopper 批式路线(重任务 drop 进独立的 Hopper 任务系统:worktree / 事件溯源 / 崩溃恢复 / 预算 / 验收闸门)合同已定,生产绑定休眠daemon 主流程不启动它;锁定版本副本与专用 vault 的约定写在配置模板里但当前不被消费;Hopper 路线的合并恒为人工交接,不经 Touch ID 卡。对用户来说今天它不是可用功能
provider-neutral 原生执行器(任意 OpenAI 兼容后端)规划中2026-08 决策推荐的方向(替代「拿 DeepSeek Harness 当默认 runner」——后者因审批缺省放行、钩子故障不阻断等与 fail-closed 红线冲突被否决)
Gemini CLI 作执行器无此计划Gemini CLI 仅作推理槽供给

7. 项目与 Git:它怎么和你的仓库打交道

7.1 项目与工作区

  • 一个 coding 项目 = 你本机的一个文件夹(git 仓),以绝对路径登记(~/ 可;符号链接会被解析;记录文件系统身份防漂移)。硬约束:必须在你的用户目录内、不能与 ~/.saydo 重叠、不能与其他现役项目互为父子目录。
  • 不支持「给我一个远端仓库 URL 我来 clone」:全部实现都以本地文件夹为前提;想用远端仓先自己 clone 下来。
  • 登记方式:对话里点名本地路径(它只从你当前这句原话里的唯一路径字面量解析,只读核验目录存在,复述「这个本地项目、类型 X」请你封闭确认后才采用——否认、歧义、路径不存在、路径不是你亲口说的,一律零写入,绝不由模型编路径自动挂靠);或在控制台受信终端选择已有项目。非代码的事(写作、调研、生活筹备)默认用系统管理目录 ~/.saydo/projects/<id>,不会拦着你「先选文件夹」。
  • 项目内目录 <workspace>/.saydo/:knowledge/(M1 知识底座,Markdown,人可读可改,自带独立 git 历史)/ foundation/(奠基产物与 manifest)/ worktrees/<taskId>/(任务隔离树)/ project.toml(项目层配置)。产物库、源快照、就绪深评记录与会话转写都在全局 ~/.saydo/{artifacts,snapshots,assessments,sessions},不在项目目录。建议把 .saydo/ 加进项目 .gitignore(daemon 不会替你改 .gitignore;知识库想团队共享可显式提交 knowledge/)。
  • project.toml(仓库随附、视为不可信输入):只认 [project](type / exec_mode_default)、[git].protected(保护分支,与缺省 ["main","master"] 取并集,只能加不能减)、[[verify.entries]](验收命令登记,§7.4)、[setup].command(装依赖命令)、以及 budget / dnd / params 子集;models / providers / gate0 / hopper / privacy / voice / pricing / tier1 出现即拒收(拒键不拒文件,拒收项落审计)。文件坏了 = 该项目的任务认领转 blocked 叫人,不带宽松缺省硬跑。
  • AGENTS.md 互通:奠基时反向吸收仓里已有的 AGENTS.md / CLAUDE.md / .cursor/rules;输出侧在 AGENTS.md 放一段幂等指针块指向知识底座(<!-- saydo:knowledge:begin/end -->),换工具时知识库价值不归零。

7.2 每个任务一个 worktree

  • 拍板派发后,执行器在 <repo>/.saydo/worktrees/<taskId>/git worktree add -b saydo/<taskId> … HEAD——分支名 saydo/<taskId>,从主仓当前 HEAD 切出;同一任务返工 / 恢复复用同一 worktree。你的主工作区在执行期不会被碰(agent cwd 锁死在 worktree;圈外命令按 S2/S3 上浮或拒)。
  • 装依赖:[setup].command 只接受 pnpm / npm / yarninstall / i / ci 形态,旗标白名单,且强制追加 --ignore-scripts(postinstall 属供应链执行面,确需时按 S2 上浮)。
  • agent 的 prompt 里明写:只在当前工作目录内改动、不要 git push、改动不需要你合并。
  • 同仓任务串行、跨仓并行;重型仓库可单 worktree 串行。
  • worktree 不会被自动删除(取消也保留,方便捡回);磁盘上会累积 <repo>/.saydo/worktrees/,定期自己 git worktree remove / 清理。

7.3 完成、验收与合并:它不会替你 push,也不会开 PR

  1. 执行跑完 → daemon(不是 agent)对 worktree 拍树快照(git add -A 排除 .cursor/write-tree 得到 treeSha)→ 在 worktree 里重跑冻结的验收命令(§7.4)→ 产 settle 证明(任务 / 轮次 / 决策包版本 / treeSha / verify digest / 转写游标)→ 任务进入 ready_for_review → 回叫你。之后任何漂移都会被发现。
  2. 你在验收面三选一:通过(记录批准的 treeSha,进入「等合并」)/ 要改(同任务新一轮,复用 worktree,意见进下次 prompt)/ 作废(取消本轮)。
  3. 合并两条路,都是「人触发」:
    • Touch ID / passkey 审批卡(Tier1 缺省):屏幕上完成一次 WebAuthn 强认证,签一张绑定 任务 / 轮次 / 决策包版本 / 预期树 的单次收据;daemon 凭收据执行:复核 worktree 现树 == 收据树(漂移拒)→ 隔离环境再跑一遍冻结 verify(不过 ⇒ merge_failed 转人工)→ 断言主仓未动(merge-base == HEAD)且主仓已跟踪文件干净(有未提交改动 ⇒ 转人工)→ git commit-tree + git merge --ff-only 到主仓当前分支(只快进、不改写历史;提交信息形如 saydo: merge <taskId> (S3 approved))→ 再断言 HEAD 树 → 「交付了」。首次使用要先在本机「注册批准指纹」(一次性)。
    • 人工合并交接(没注册 passkey、或你想自己来):它给你一个交接入口,你在终端自己 merge;之后点「核验」,daemon 现读主仓 HEAD 的树与批准时落库的 treeSha 对账,一致才推进到「交付了」,不一致拒绝并留痕(防「已回滚却显示完成」)。
  4. 它不 push、不开 PR:全部实现里没有推送远端或创建 Pull Request 的路径;agent 若自己敲 git push,按 S2(feature 分支)/ S3(保护分支或 force)上浮或拒。推远端、开 PR 是你验收合并后自己做的事。
  5. 语音面永不渲染合并按钮;局域网 / tailnet 手机面调用合并动作会被拒并审计。

7.4 验收命令只认登记模板(防命令注入与「自证通过」)

  • project.toml 登记:[[verify.entries]] name="test" source="package_script" ref="test"(source 只有 package_script / justfile 两种);Brain 只能登记项,任何拼接串拒绝。
  • 内容冻结:派发 / 认领时冻结每条 verify 的 argv + 脚本内容 digest + 相关框架配置文件(vitest / vite / playwright / jest / tsc / eslint / pytest / ruff / mocha 等已知 config)的 digest;执行前重读重算,不符 ⇒ fail-closed。agent 合法改了测试脚本 ⇒ 拦下转 blocked 回叫「要改验证命令,需要你重新拍板」(Plan Delta),不静默放行也不静默死。
  • 没登记任何 verify 的 coding 任务不 settle,转 blocked 叫人——独立验收 oracle 是门禁,不是可选项。
  • verify 跑在比 agent 更窄的环境(HOME 换成一次性空目录)。诚实边界:绝对路径直读与出网仍不可挡,完整隔离 = 后续容器 / sandbox。
  • 合并前会再跑一次冻结 verify。

8. 审批与安全

8.1 风险按效果分级 S0–S3

语音是弱认证通道(在场任何人都能说话、识别有误听率),所以审批权按风险分级;分级由效果计算,不按动作名:效果 × 目标(圈内 / 圈外)× 触及数据敏感度 × 身份凭据 × 触发的下游(CI / 部署)× 成本

级别典型(缺省,可被效果升级)审批方式
S0 读读代码、只读命令自动放行
S1 写(worktree 内)改代码、跑登记的 verify、本地 commit自动放行
S2 出圈但可逆装依赖、push 到 feature 分支、未识别的命令逐步确认档:屏幕 / 语音确认(缺省 45 秒窗,超时即拒);直达验收档:命中念读签署的预授权清单则放行(当前未在语音链启用,见 §8.4)
S3 不可逆 / 外部影响合并到保护分支、force push、部署、花钱、删数据、对外发消息必须已认证屏幕(Touch ID / passkey);语音绝不放行——同一麦克风的复述不构成独立认证因子

升级规则:触及 .env / 凭据 / 客户数据 ⇒ 至少 S2;依赖带 postinstall ⇒ 至少 S2 且必须出清单;push 触发预览部署 ⇒ S3;push 到保护分支 ⇒ S3。

8.2 Gate 0:能不能开工的总闸

Gate 0 不是运行期的命令门,而是开放自主派发前必须关闭的六项安全门禁,每次派发前都检查 [gate0] enabled = true && bypass = false,代码里没有 bypass 分支(配置文件损坏时按「未关」处理,拒派发而不是带宽松缺省继续):

内容
G1 身份 / 授权单用户假设显式化;S3 只走屏幕;控制台能力令牌 + Host/Origin 白名单 + DNS rebinding 防护;审批门完整性(socket 裁决、canary)
G2 跨边界事务幂等回叫 outbox 唯一、事件游标 + 崩溃重放
G3 独立 acceptance oracleverify 白名单 + 内容冻结 + Plan Delta;生成方不自评
G4 secret / egress 隔离agent 环境剥离凭据;出口能力按适配器如实声明(Cursor = uncontrolled,不假绿);setup 缺省 --ignore-scripts;TTS 脱敏
G5 意图审计转写 → 收据 → 任务三方留痕贯通;审计表不可变(触发器)
G6 删除 / 同意传播「忘掉这个」硬删通路;录音 / 转写分别同意;备份按保留期整份过期

8.3 每条 shell 命令怎么过门

  • 物理链:worktree 内 .cursor/hooks.json → daemon 供给、放在 worktree 之外 ~/.saydo/tier1/ 的 gate 脚本(与 agent 同用户,当前不保证 agent 不可写——诚实口径)→ unix socket → daemon 裁决;补偿控制 = 每次门请求都重算脚本完整性,漂移 ⇒ 取消全部活跃任务。
  • 分类器把命令保守推导成效果:识别不出的一律按 S2 上浮;词面含 .env / credential / secret / .pem / .key / id_rsa / id_ed25519 / .npmrc / .netrc / keychain / token ⇒ 敏感升级;force push / 绝对路径删除 / 管道执行远端脚本 ⇒ S3;复合命令(&& / ; / | / 子 shell)按最高风险段归类,任一段不可判 ⇒ 整条不可判。node / python / tsx / just 等任意代码执行入口也按 S2(node -e "fetch(…)"node build.js 词面无法区分);已登记的 verify(如 just test)在门里先于分类表匹配,仍自动放行。
  • 裁决:S0/S1 放行;S2 上浮(45 秒,超时 = 拒);S3 直接拒;风险计算异常 = 拒。每条命令独立审批,一次放行不得长期有效
  • 第四个动作「修改后批准」:你可以把命令改一改再批,agent 收到编辑后的命令原样重试即命中这张单次收据。
  • 每条 S2 一张收据,绑定父决策包 digest 与拍板轮次,接受即消费。

8.4 执行模式两档

语义现状
逐步确认(出厂默认,口语「每步问我 / 盯着点」)每个出圈动作(S2)前置确认 + 计划步骤边界确认;agent 提问即时上浮;S0/S1 任何档都不问(worktree 已兜底)现在可用——当前全部任务都按此姿态执行
直达验收(口语「一口气跑完」)拍板即授权整包:决策包逐项声明并念出本任务预计的 S2 效果类(带约束参数:装哪些包 / 推哪个分支模式),随包 digest 签署;运行中命中清单自动放行(落预授权收据,执行点复验有效期),未命中或被升级的拒绝并反馈 agent 换路进行中——预授权清单的合同与匹配逻辑已落,但语音拍板环尚未接入念读签署,组包恒为逐步确认;拍板时选「一口气」会被如实告知走屏幕或改逐步确认

不变量(任何档位不得触碰):效果分级、S3 屏幕强认证、三熔断、verify 白名单、Plan Delta 重授权、回叫优先级、状态词纪律、两把钥匙、Gate 0。预授权范围永远属于决策包、由你听到并签署;模式只是这份清单的启用开关——否则「切到全自动」就成了一句话扩权通道。默认收紧(逐步确认)是对冲自动化偏信;「信任毕业制」被明确否决。

8.5 三熔断与停靠老化

  • 三熔断(任一触发 ⇒ cancel ⇒ 带上下文进 blocked 叫你):活跃墙钟(缺省 45 分钟,审批 / 提问停靠期停表)+ 回合数(缺省 80)+ API 成本(来自决策包封顶,缺省 20 元;只约束 API 计费部分,订阅调用靠前两者兜底)。项目级可覆盖三者。「15 分钟无事件」只能抓挂死,抓不住「活跃地兜圈烧钱」,所以三者缺一不可。
  • 停靠老化:等你验收 / 等你解 blocked 超过 park_aging_hours(缺省 72 小时)⇒ 取消并转草稿卡(停靠占着 worktree 与同仓队列,不能无限悬挂);长停靠恢复时强制复验收据有效期。
  • 决策包有效期 proposed_ttl_hours(缺省 24 小时),过期作废;同项目新提议 supersede 旧的。

8.6 其他安全纪律

  • TTS 脱敏:token、密钥、客户数据、完整本机路径永不进语音(路径说「某个配置文件」,密钥说「一处凭据」)。
  • 控制台调用方身份:每次请求 / WS 握手校验能力令牌,Host / Origin 白名单,防恶意网页绕过语音授权直调 daemon;缺省只监听本机回环。
  • 记忆写路径:第三方内容(仓库 / 网页 / 资料)永远不能定义「你喜欢什么 / 允许什么 / 凭据在哪」;候选 → 受信需人批(§9.3)。
  • 审计与日志分流:日志可轮转,审计表不可变;敏感 payload 只记 digest 不记原文。

9. 记忆与账本

9.1 四层记忆(M0–M3)

名称存储生命周期内容
M0用户档案记忆账本中的跨项目层(~/.saydo/saydo.db;~/.saydo/profile.md 已纳入备份保护范围,作为人可读投影规划中)跨项目、长期偏好、技术栈、沟通风格、术语热词(顺带提升识别准确率)
M1项目知识底座<workspace>/.saydo/knowledge/(Markdown,人可读;m1-notes.md 为账本投影)项目级、长期稳定项目目标 / 约束、代码库理解(架构 / 模块 / 术语)、关键决策、领域知识
M2累积对话知识产物库(~/.saydo/artifacts/ + 主库索引,按项目归属)项目级、随对话增长每次对话新生成的方案 / 决策、调研资料(版本化、可召回)
M3会话工作记忆上下文窗口 + 转写(~/.saydo/sessions/<id>.jsonl)单次会话最近 N 轮、当前任务

Context Pack = 每轮从 M0 + M1 + M2 挑相关切片 + M3 最近几轮拼进窗口(带版本,失配则重取);检索用 SQLite FTS5(trigram,BM25)答「我们决定过什么」,代码事实永远现场 rg 现读、不进知识库(无陈旧税;短于 3 字符的词靠 rg 兜底)。

真相源:记忆域以 append-only 记忆事件账本为真相,Markdown 文件与 SQLite 索引都是可重建投影;源码与 Git 永远是代码事实的最终权威。m1-notes.md 是单向投影——直接改文件不会回写记忆,要改就对它说(P0 没有文件监听)。

9.2 奠基(Foundation)现在可用 · 机械管道

第一次接触一个项目时触发,阻塞式(「学习中」是一等会话状态,会说清在学什么、进度、还要多久):

  • 扫文件清单与语言分布;按白名单读关键文件(README / AGENTS.md / CLAUDE.md / package.json / pyproject.toml / justfile / Makefile / Cargo.toml / go.mod 等,单文件摘录上限 6000 字符);
  • 反向吸收你仓里已有的 AGENTS.md / CLAUDE.md / .cursor/rules;
  • 生成四份知识文档:core.md / inventory.md / build-test-run.md(标注「未运行验证」)/ conventions.md;
  • 预算:缺省 5 分钟墙钟 + 200k token,超限产出 partial 并如实写「还没读完,按已读部分回答」;
  • 按 generation 原子切换(knowledge/gen-N/ + current 链接;失败保留旧代),knowledge/ 目录自带独立 git 历史;奠基换代后,依赖旧代知识的就绪绑定自动失效(不拿过期理解开工);
  • 在你的 AGENTS.md 里放一段幂等指针块(<!-- saydo:knowledge:begin … end -->)指向知识底座,写失败(只读仓 / 权限)静默降级不翻转已发布的 generation。
  • 会话预热(每次,轻):按 git diff 四组种子(已提交 / 暂存 / 未暂存 / 未跟踪)增量刷新;rebase / force-push 不会被误判为「全删」。

诚实标注:当前奠基是确定性的机械管道(清单 + 摘录 + 文档生成),不含由沉思档模型做的 LLM 深度研究——后者是进行中的下一档。

9.3 记忆写路径:候选 → 受信(安全边界)

持久记忆的头号风险不是陈旧,而是来源污染与跨项目泄漏。写路径是:

raw evidence(不可信)→ candidate(带来源 / 引文 / 信任级 / 有效期)→ 冲突 / taint / policy 检查
→ 低影响的项目本地事实可自动入库;偏好 / 决策 / 外部事实需你批准 → trusted
  • 直入 trusted 的只有你亲口说的(user_stated)与低影响机械事实(git 跟踪的仓内文件 / 你的编辑,且是事实性陈述);命中指令 / 副作用词(curl | shrm -rfsudogit push、「部署 / 上线 / 删库 / 迁移」…)一律降为候选;来自网页 / agent 输出 / 导入的一律候选。
  • M0 红线:第三方内容永远不能定义「你喜欢什么 / 允许什么 / 凭据在哪」;M0 只接受你亲述或你批准的。
  • 会后提炼 = 机械提名 + 你批准(不是自动沉淀):会话挂起时按决策性词表(「决定 / 定了 / 就用 / 以后都 / 统一用 / 拍板」…)提名最多 5 条候选,你在记忆库页逐条批准 / 拒绝(拒绝 = 软遗忘,否定不复活)。
  • 遗忘:失效标记(不删行,投影排除)/ 软遗忘 / 硬删(「忘掉这个」:tombstone + 历史正文就地覆写为 [forgotten] + 从全文索引、投影、源快照正文与评估记录里清除)。诚实边界:自动快照备份是不可变整体文件,硬删不逐条清备份,靠保留期(缺省 30 天)到期整份删除闭合。

9.4 一件事、义务与四色账本 现在可用

控制台主轴是「一件事」(Focus):一件持续关注的事,生命周期 captured / active / dormant / closed / abandoned / archived;可以关联 0..N 个项目,也可以不属于任何项目(生活筹备、调研都行);下面挂义务(谁欠什么:owner = 你 / AI / 外部,状态 open / in_progress / waiting / deferred / blocked → resolved / superseded)与期待(做成什么样的验收标准,改了要 AI 复述影响再确认)。

四色账本(今天页)不是独立的表,而是从账本现算出来的「球在谁」视图:

含义来源
橙 · 等你拍板需要你回答 / 决定待确认卡、等你验收的任务、owner=你且需要决策 / 补充的义务、任何被前置终止(blocked)的事
蓝 · 你欠的动作需要你动手owner=你、需要行动的义务
绿 · AI 正在办球在 AI排队 / 运行中的任务、owner=AI 的未结义务
灰 · 等外部回音球在别人owner=外部的未结义务
  • 「帮我记一下 / 记一条 / 别忘了」⇒ 当轮立即提议落账(决定 = decision,待办按归属,要查证 = check),经确认卡(你点头或倒计时)写入;同一句里多条可一卡确认、全有或全无。若当前对话工具面没有落账工具,会降级先记进记忆库并告诉你「立起来后可以再挂到账上」。
  • 销账:义务由 AI 提议 resolve(done / abandoned / 不再适用)经你确认;AI 自己的义务标 done 必须带可验证证据(产物 / 任务 / 事件三查);叙事性修订不销账。绿 / 灰条目可「知道了」让它从收件箱消失,橙 / 蓝不能 ack、只能靠源数据变化消失;条目升级(绿 → 橙)时无视历史 ack 必然重现。
  • 确认卡过期不蒸发:屏幕档确认卡超时(10 分钟)会按归属降格落到对应色区(「待你补一句」形态);语音档 5 秒倒计时自动执行属设计内;防风暴:同会话同事日限 5 条,超限聚合。
  • 多步接续:你确认一步后 AI 自动续走下一步,连续自动最多 3 步,到上限就停下来挂账(防失控)。

10. 验收与交付

10.1 状态词纪律(硬约束)

状态含义它怎么说
run.completedagent 进程退出(闸门 / 产物可能还没 settle)不播报「完成」
ready_for_review验收闸门跑完、产物落盘确认,等你验收「执行和检查都跑完了,等你验收」
task.done你验收 + 合并 / 归档后「这件事交付了」

执行任务不预估剩余时长,只说已发生(「跑了 18 分钟」);成本 unknown 说「还没有确切数字」,不说 0。

任务状态机(coding 类,节选主干;另有 confirmed / paused_step_boundary / merge_failed / cancel_settled / superseded 等状态):

queued → running → ready_for_review → review_approved_waiting_merge → merging → task_done
              ↑            │ 要改:同任务新一轮(复用 worktree)
              └────────────┘
  任一阶段:blocked(等你:S2 超时 / 提问 / 熔断 / verify 缺失)· failed(可重试)· cancel_requested(作废,worktree 保留)

10.2 证据视图

任务验收面按验收标准组织:左边标准、右边证据(diff、测试结果、它自己做的决策清单、未验证项)。纪律:agent 自报的证据用空心标记以示降权、可推翻;没绑上证据的项诚实标 unknown,不显示伪精确;决策清单与口播同源(落库的 decisions),口播与上屏一致。

10.3 口播摘要三层

  1. 一句话(≤40 字,纯规则):「改了 5 个文件,测试 12/12 过,1 个待确认决策」——文件数来自 git、测试数来自独立闸门,未知标 unknown 不写 0;
  2. 走读(150 字口语稿,你说「讲讲」时);
  3. 决策清单(每条 = 决策 + 理由 + 可推翻动作,≤5 条;从事件流机械抽取 → 廉价档惰性提炼一次 → 落库)。

原始事件流永不直接进对话模型;叙事模型只做措辞,不得产生规则层没有的数字。

10.4 验收三态与合并

通过 / 要改(同任务新一轮,复用 worktree,意见进下次 prompt)/ 作废;通过后按 §7.3 的两条路合并。写作类另有「逐节裁决」屏障:settle 不等于全绿,未逐条裁决不能通过。

11. 回叫与通知

  • 触发:只由 settle 后的状态触发(ready_for_review / blocked / failed 等),runner 退出不算;durable outbox,重放幂等,daemon 重启只叫一次。
  • 优先级:blocked(等人)> failed > 待审批 > ready_for_review > 进度(默认不通知)。
  • 升级链 现在可用:L0 在线语音回叫——控制台在线、语音管线健康且你没在说话时,它直接开口,第一句就是回叫原因;30 秒没应答升级。L1 macOS 桌面通知(系统通知中心)+ ntfy 手机推送——任一送达即算已通知(桌面通知首次弹出可能需要在系统设置里允许通知);「今天」页橙区始终常亮。L2 电话与移动端来电式汇报规划中。sweep 每 15 秒扫 outbox,投递失败留队重试。
  • ntfy:.envNTFY_TOPIC(随机串,手机 ntfy App 订阅同名主题)与 NTFY_SERVER(缺省 https://ntfy.sh,可自托管);消息 JSON POST(中文标题走 body),优先级 blocked / failed = 4,待验收 = 3;深链只带路由、绝不带能力令牌;标题经与 TTS 同一套脱敏(公网 topic 明文可订阅)。这两个键当前不在向导白名单内,需手改 .env
  • PagerDuty 式状态机:pending → notified → acked → resolved;ack 只停止升级,不等于解决、更不等于授权任何动作;ack 后 30 分钟(callback_resolution_timeout_min)未解决重新升级。ack 的途径:「通知」页点「知道了」,或你直接开口回话(语音回叫后的开口即视为已应答);任务离开待验收 / blocked 被解决时自动销账。
  • 免打扰 [dnd].window(缺省 23:00-08:00,支持跨午夜):窗口内不出声、不弹桌面,只发一条低优先级 ntfy(注明免打扰时段)并 snooze 到窗口末;窗口结束后按队列顺序补叫;设备不可达不算 DND,走短周期重试。
  • 拦截不等于叫人:危险动作先把原因反馈给 agent 让它换路,同一意图被拦 ≥ 2 次才进回叫链。
  • 输出仲裁 现在可用:你这轮话还没说完时不插播语音,该条降级走桌面 + 推送;「会议软件占麦」检测暂无数据源,恒按未占处理(如实)。

12. 语音

12.1 三档语音能力

条件说明
打字(始终可用)任何时候都能打字;键盘自带的系统听写也能用
浏览器系统语音(零配置)浏览器支持 SpeechRecognition(Chrome / Safari)按住说话 → 浏览器识别 → 文字通道进对话;朗读用 speechSynthesis。质量一般
云端级联语音(更准更自然).env 填火山豆包三键 + 起 Python 语音管线ASR = 火山豆包 sauc 流式(带热词偏置:你纠正过的术语、项目符号自动注入,实测术语召回 +10 点);TTS = 豆包 seed-tts-2.0 v3 双向流式(首句先播、可随时打断);当前识别形态 = 按住说话松手后整段识别(实时字幕进行中)
手机原生语音iOS / Android 壳走系统语音识别与合成(设备端),不需要 Python 管线

12.2 采集与轮次

  • 桌面三种触发:点击 - 再点击(toggle)/ 键盘长按(按住空格)/ 免手 VAD(能量 RMS + hangover 状态机 + 语义「说完了没」词表 + 显式「说完了」按钮兜底;中英混说默认延长静音阈值 900ms);嘈杂环境走按住说话。
  • 录完二选一:「发送」(语音气泡先进对话,转写异步补挂,AI 即刻开跑)/「转文字改一改」(转写只进输入框,改字后发送);「取消」彻底丢弃。转写在途必有显式「转写中」状态;空转写 / 超时给「没听清」。
  • 打断:TTS 立停;未播完的文本标 heard=false、不进对话事实;被打断的授权类播报(S2 / 预授权清单)立即作废当前确认,随后的裸肯定「好 / 可以」不消费旧收据。
  • 重听上一问:原文重放,不重新生成。
  • 误听纠错:说「不是 X,是 Y」 ⇒ 纠正进 M0 热词(热词:X->Y),下次识别带偏置;连续误听降级打字。
  • 会话空闲 45 秒或你说「先到这里 / 先这样 / 收工」即挂起(零成本),收尾语必含状态:「任务在跑,到验收点我叫你」。

12.3 口播纪律

人格 = 幕僚长:简短、口语、中文、不念代码、先结论后细节;口播 ≤ 30 秒;清单 > 3 项转屏幕;选项一次最多念 3 个。TTS 脱敏红线:token / 密钥 / 客户数据 / 完整本机路径永不进语音;PEM 块、sha256:、Bearer、sk-/ghp_ 等前缀、云访问密钥、绝对路径、11–19 位数字串、≥20 位裸密钥串自动替换。

13. 手机与远程

13.1 今天能做什么

  • 局域网直连(SAYDO_MOBILE_LAN=1,§4.7):手机浏览器或自行构建的 App 壳打开 http://<内网IP>:47100/?token=…(桌面控制台可出二维码;只对 RFC1918 私网地址出码,公网 / CGNAT 不出)。手机面是移动壳路由(#/m):今天四色、一件事详情、最近对话回放、最近记忆;发文字 / 原生语音转文字进对话;对立账 / 记账类确认卡点头 / 撤回。LAN 面 HTTP 路由白名单极窄(只读投影 + 首跑开场白),写口、设置写口、S3、全文屏幕文本一律拒。
  • tailnet(Tailscale)面:config.toml [t2].tailnet_hosts = [...](纯主机名 / IP 显式白名单,禁通配,含任一非法项整面不开)+ [t2].listen;just t2-pair 出配对 URL(一次性注入手机本地会话,深链之后不带令牌)。tailnet 面可看任务、批 S2 级审批(review / decide / 记忆候选批准),合并链动作与 /dev/* 注入通道 403 引导回桌面。
  • S3 永远不在手机:四重断言(socket 必须本机回环、Origin 精确 http://localhost:<port>、来源面 local、rpId 固定 localhost),拒绝文案「S3 操作只在本机受信终端完成——回到桌面屏幕操作」;S3 工具也不进对话模型的工具面。
  • 诚实边界:当前 LAN 面是「局域网明文 HTTP + 长期能力令牌」的 dogfood 临时边界,没有设备配对 / 逐设备身份 / 端到端加密;删令牌重启即全员掉线。不要暴露到不受信网络。

13.2 App 状态

状态说明
iOS未提审原生 SwiftUI 壳(扫码配对、原生语音识别 / 合成、Web 容器)工程存在;App Store 记录已建(中文店名「说到」),无可提审包
Android未提审Kotlin 壳可构建;Play 应用记录已建(com.octoooo.saydo),无可提审包
HarmonyOS未提审HarmonyOS NEXT ArkTS 壳;AppGallery 记录与发布证书已就绪,Profile 未建

三端共同的不可提审原因:无生产配对 / 信任层、明文 LAN、审核夹具未执行。上架前要做的:设备配对(一次性票据 + Noise XX 互认证 + 桌面人工确认 + 信任设备免确认重连)、推送隐私合同(payload 只带 opaque id)、来电式汇报(PushKit 唤醒 + CallKit 来电 UI)。这些都是规划中。

13.3 设计原则

沟通天然是移动的,执行天然是固定的:手机只做沟通面(说话、看进展、拍板、审批封顶 S2),重活留在你的 Mac;手机断连不影响后端执行。远程通道默认只读;电话 DTMF(规划中)只做 ack / snooze / 拒绝,不做任何审批。

14. 隐私与数据

  • 没有服务器、没有账号、没有埋点:代码里没有任何遥测 / 统计 / 广告 SDK;开发者无法访问、也不收集你的数据。
  • 数据在哪:
    • ~/.saydo/saydo.db(任务 / 审批 / 成本 / 记忆事件 / 审计等主库)、~/.saydo/sessions/*.jsonl(转写,目录权限 0700)、~/.saydo/.cap-token(控制台令牌,0600)、~/.saydo/logs/~/.saydo/backups/;
    • <workspace>/.saydo/(知识底座 / 奠基 / worktrees / project.toml);~/.saydo/{artifacts,snapshots,assessments}(产物 / 源快照 / 就绪深评记录);
    • 第三方 AI 由你的电脑直接调用(CLI 订阅或 API key),适用你与服务商的协议。
  • 语音的数据去向(两端不同,请分清):手机端与浏览器系统语音在设备 / 浏览器侧识别;桌面端配了火山豆包 key 时,音频经 WebSocket 发到火山引擎云端识别与合成——这是你自己配置、你的电脑直连的第三方服务。缺省 store_audio = false(当前版本根本没有写录音文件的代码路径)、store_transcript = true(可关;关了轮内流程照常、只是不落盘,并如实标注)。
  • 什么流量会出网(只有两类,且都是你自己配置的上游):① 你接入的 AI 上游——CLI 订阅工具走它们各自的官方通道,API key 直连你配置的端点;② 语音识别与合成(火山豆包,仅在你启用桌面云端语音时)。可选的 ntfy 推送是第三类(你配置的 topic,标题经脱敏)。
  • 审计不可变:审计表有数据库触发器禁 UPDATE / DELETE;敏感 payload 只记 digest 不记原文;每条带 actor。日志可轮转,审计不可变。
  • 调用方身份:控制台能力令牌 + Host / Origin 白名单 + DNS rebinding 防护;缺省只监听本机回环;LAN / tailnet 面另有来源门(§13)。
  • 备份:每日自动快照(SQLite 在线备份 + sessions + 各项目 foundation / knowledge),保留期缺省 30 天;just backup 手动。
  • 删除:「忘掉这个」硬删传播到索引 / 投影 / 源快照 / 评估记录;备份按保留期整份过期(如实告知);完全重置 = 删 ~/.saydo(令牌轮换、设备掉线)。
  • 迁移:新机装好后把 ~/.saydo/(或某份备份)拷回即可;令牌与执行器锁定副本需重新登记;各项目的 <workspace>/.saydo/(知识底座 / 奠基 / worktrees)随项目目录走。
  • 完整隐私政策见 /privacy/

15. 费用

  • 软件:桌面服务开源免费;App 免费、无内购(规划中)。
  • AI 费用去向:
    • 订阅 CLI(BYOA):走你已有的 Codex / Claude / Cursor / Grok / Gemini / Qwen / Copilot 订阅额度,零额外费用;账本显示「订阅额度内」;撞限流该次调用如实报错,不偷偷转计费。
    • API key:按各家账单;账本按 [pricing] 单价表估算(缺省不填 = 显示「还没有确切数字」,不编数);每个任务有成本封顶(缺省 20 元)+ 活跃 45 分钟 + 80 回合三熔断。
    • 语音(可选):火山豆包 ASR / TTS 按你的火山账号计费;浏览器系统语音免费。
    • 推送(可选):ntfy 公共服务器免费 / 自托管。
  • 「说到」不加价、不经手、不代充。放外人用之前先确认额度:开发类请求会真实派发执行任务、消耗订阅或 API 额度。

16. 路线图与完成度总表

能力状态备注
macOS 桌面服务(daemon + 控制台)现在可用源码分发;npm / Homebrew 包与桌面 App 壳规划中
四推理槽 API 供给(OpenAI 兼容 / OpenRouter)现在可用
四推理槽 CLI 订阅供给(Codex / Claude / Cursor / Grok / Gemini / Qwen / Copilot)现在可用对话档走 CLI 为慢速文本模式
首跑资源画像向导(三种方案卡 + 高级逐槽)现在可用
一件事 / 义务 / 期待 / 四色账本 / 确认卡降格 / 多步接续现在可用
奠基(机械管道)+ M1 知识底座 + AGENTS.md 互通 + 会后提名批准 + 遗忘现在可用LLM 深研档规划中(方案在拟)
类型就绪清单 + 规则层 + 异族深评 + 复述确认绑定现在可用
决策包(预览 / 计划 / 成本 / 风险 / 验收标准 / 轻量小样)现在可用小样与计划同源机械渲染;控制台「看小样」+ 本机同轮上屏
Cursor CLI 执行器 + worktree 隔离 + 命令效果门 + 三熔断 + verify 冻结现在可用
验收证据视图 + 三层口播 + Touch ID 合并卡 + 人工合并核验现在可用Touch ID 卡真人过卡待 owner 触点
逐步确认档现在可用
直达验收档(预授权清单念读签署)进行中合同与匹配逻辑已落,语音拍板环未接
回叫升级链:在线语音回叫 → macOS 桌面通知 + ntfy 手机推送;免打扰;应答(ack)现在可用语音回叫需控制台在线 + 语音管线健康;30 秒未应答升级;输出仲裁同批落地
云端级联语音(豆包 ASR/TTS)+ 浏览器系统语音 + 热词纠错现在可用实时字幕、Silero VAD 进行中
coding 类型现在可用
writing 类型(窄版)现在可用(需开能力门)引证 / 归属合同等全量规划中;真人全链待验
research / marketing / planning / general 执行合同规划中上游采访 / 立账 / 调研可用
局域网手机面(浏览器 / 壳)现在可用(dogfood 边界)无配对 / 无 E2E
tailnet 薄版现在可用(需手工配)
Claude Code 执行器进行中分三批:第一批(对官方 CLI 的真机能力实测 + 审批门纯函数)已收口,接线批在途
Codex 执行器 / Hopper 批式路线规划中 / 休眠
provider-neutral 原生执行器规划中
设备配对 / E2E 加密 / 推送隐私合同规划中
iOS / Android / HarmonyOS App 上架规划中商店记录已建,壳工程存在
来电式语音汇报(PushKit + CallKit)规划中
电话回叫 / S2S 语音引擎 / 本地全栈语音 / 唤醒词规划中
对话车道 Quick / Guided / Explore规划中只有埋点
主动巡检 / 多人会议旁听规划中

17. 常见问题与故障排查

这是语音输入法吗? 不是。语音只是入口;后面是理解上下文、立账、判断就绪、驱动执行、组织验收的闭环。

是把我的项目上传到云端代跑吗? 不是。没有云端服务器;重活在你的电脑上跑;你接入的第三方 AI 由你的电脑直接调用。

需要什么前提? macOS + Node 22 + 一个已登录的 AI CLI(或一个 API key)。语音和执行都是可选增量(§4)。

不配任何 key 能用吗? 能:本机有任一已登录 CLI 即可零 key 开聊(对话每轮 15–25 秒的慢速文本模式);语音走浏览器系统语音或打字。

它怎么知道「办完了」? 执行和检查都跑完、产物落盘,它说「等你验收」——不说「做完了」;你点头、过强认证合并,才是「交付了」。

它会不会偷偷花钱? 订阅调用不产生费用、撞限流只会如实报错不会转计费;API 调用有每任务成本封顶 + 活跃时长 + 回合三熔断;S3(花钱 / 部署 / 删数据 / 对外发消息)必须你在屏幕上强认证。

它会 push 到 GitHub 或开 PR 吗? 不会。它在 saydo/<taskId> 分支的 worktree 里改代码;合并到你当前分支要你 Touch ID 或自己 merge;push / PR 是你之后自己做的。

对话每轮要等十几二十秒,是卡了吗? 不是。对话档走 CLI 订阅就是慢速文本模式(15–25 秒);界面有慢速徽标;桌面端单次 CLI 调用 120 秒上限后明确报错(手机页 90 秒提示重发)。想要秒级对话给对话档配一个 API key(§5.3 方案二)。

界面说「仅恢复模式 / recovery-only」。 活动配置非法(TOML 坏了、参数越界、项目覆盖冲突等):daemon 不退,只留健康探针、控制台静态页与设置自救写口;对话、派发、合并、恢复任务全停。去设置页按提示重建安全配置或清理非法项目覆盖,再重启。

向导说某个 CLI「可识别,暂不能当模型供给」。 该 CLI(如 kimi / opencode)无法在执行前可证零工具,出于安全不接线;换一家或用 API。

评估档一直 unarmed。 看原因:同族未确认(勾 evaluator_same_family_ack 或换家族)/ CLI 评估器缺隔离确认(勾 evaluator_isolation_ack)/ 自检失败 / 实际模型家族上报 unknown。unarmed 不影响对话,只是就绪深评不武装。

打开控制台白页 / 没反应。curl -s http://127.0.0.1:47100/health;不是 ok:true 就看 ~/.saydo/daemon.log(tsx 冷启动 10–15 秒);确认 URL 带了 ?token=、用的是 localhost

支持 Windows / Linux 吗? 暂不支持,当前面向 macOS(常驻、通知、打开浏览器等链路为 macOS 实现);没有明确时间表,不承诺。

端口冲突。 saydo status 退出码 2 = 47100 被别的服务或另一个数据目录的 daemon 占着;不会自动换端口或杀进程,用 --port 换或停掉对方。

手机扫码连不上 / 全部掉线。 确认 daemon 带 SAYDO_MOBILE_LAN=1、手机与电脑同一私网;删过 .cap-token 会轮换令牌,重新扫码。

拍板后没有起执行器。 [models.dev]agent 须为 cursor(或留空,缺省即 cursor)且 model 非空;[tier1] 两键(锁定二进制绝对路径,不接受 ~ + 版本)齐备;jqcurl 在 PATH(gate 脚本硬依赖,缺 jq 时连拒绝回执都产不出,一律视为拒绝);cursor-agent 已登录。否则队列里的任务停在 queued 并给处方化日志,对话不受影响。

任务停在 blocked。 看原因:S2 等你确认超时 / 没有登记 verify / project.toml 坏了 / 工作区或 .git 不见了 / agent 提问 / 熔断触发。解了在任务页「重试 / 回答」。

worktree 越来越多。 设计上不自动删(便于捡回);自己 git worktree remove <repo>/.saydo/worktrees/<taskId> 清理。

常驻(launchd)装不上。 just daemon install 需要 uv 才能一并装语音管线常驻;报「未找到 uv」时按提示用 just daemon install --without-pipeline 只装 daemon(云端语音不可用,系统语音与文本照常),或先装 uv 再重跑(§4.8)。

18. 开源与参与

  • 仓库:https://github.com/Octo-o-o-o/SayDo(桌面服务:contracts / daemon / console / cli / pipeline 与全部设计文档、证据、过程档案同仓);执行后端候选 Hopper 为同作者独立仓。公开仓为快照仓(自 2026-08-20 起):逐提交过程史保存在私有归档,文档中引用的历史 commit SHA 在归档中解析(仓库 README「过程史与归档」有说明)。
  • 许可证:Apache License 2.0(含专利授权);「说到」/「SayDo」名称、印章 logo 与 assets/ 品牌资产不在许可范围(Apache 2.0 第 6 条),衍生作品不得以原项目名义呈现;详见仓库 LICENSE / NOTICE
  • 工程约定:全仓零 emoji;状态词纪律;Gate 0 无 bypass;契约不分叉(类型只从 @saydo/contracts import);审计与日志分流;两提交法(代码提交 + 证据提交)。
  • 本地开发:pnpm install && pnpm -r build,just dev(daemon + pipeline + console 热更),just ci(node + python 双矩阵 + emoji / 颜色 / 迁移门禁);发行验收 pnpm --filter @saydo/cli verify:distribution
  • 设计文档地图:docs/01–11(愿景 / 产品定义 / 架构 / 关键机制 / 路线 / 参考 / 选型 / 模块 / 数据契约 / 话术 / UI)+ docs/adr/
  • 反馈与支持:[email protected](请说明系统版本、是否已完成扫码配对;不要粘贴 API key、配对令牌或完整日志)。安全问题按仓库 SECURITY.md 私下披露(邮件标题注明 SECURITY),勿公开细节。

19. 术语与状态词对照(中英)

中文English说明
说到SayDo产品名
沟通面 / 执行面communication surface / execution surface
一件事Focus账本主轴
义务obligation谁欠什么
期待expectation验收标准的管理层
四色账本four-color ledger等你拍板 awaiting your call / 你欠的动作 owed by you / AI 正在办 AI working / 等外部回音 waiting externally
奠基grounding / foundation项目知识底座建立
知识底座knowledge base(M1)
就绪readiness
决策包decision pack
拍板sign-off
逐步确认 / 直达验收step-confirm / direct-to-review执行模式
等你验收ready for your review状态词,不说 done
交付了delivered合并 / 归档后
回叫callback
停靠parked等人期间
熔断circuit breaker
推理槽位 / 开发档reasoning slots / dev slot (executor)
订阅 CLI 供给BYOA (bring your own agent)
异族different model family评估器规则
能力令牌capability token

附录 · 速查表

daemon 端口47100(直起 daemon:SAYDO_DAEMON_PORT;saydo CLI:--port)
控制台入口http://localhost:47100/?token=$(cat ~/.saydo/.cap-token)(saydo open)
健康 / 就绪探针GET /healthGET /readyz(voiceReady=false 不算启动失败)
数据目录~/.saydo(--home / SAYDO_HOME,绝对路径)
配置 / 密钥~/.saydo/config.toml / ~/.saydo/.env(模板在仓库 templates/)
项目内目录<workspace>/.saydo/{knowledge,foundation,worktrees,project.toml};产物 / 快照 / 深评记录 / 转写在 ~/.saydo/{artifacts,snapshots,assessments,sessions}
环境变量SAYDO_HOMESAYDO_DAEMON_PORTSAYDO_MOBILE_LAN=1(局域网手机面)、SAYDO_DEV=1(dev profile 双开关)
.env 常用键模型:OPENROUTER_API_KEY / OPENAI_API_KEY / ANTHROPIC_API_KEY / DEEPSEEK_API_KEY;语音:VOLC_APP_ID / VOLC_ACCESS_TOKEN / DOUBAO_TTS_API_KEY;推送:NTFY_TOPIC / NTFY_SERVER
常驻just daemon install / start / stop / restart / status / logs / deploy [sha](install 一并生成语音管线常驻配置;无 uv 用 --without-pipeline,§4.8)
备份just backup~/.saydo/backups/<时间戳>/;自动每日;保留 30 天
关停lsof -t -iTCP:47100 -sTCP:LISTEN | xargs kill; pkill -f saydo_pipeline
熔断缺省活跃 45 分钟 / 80 回合 / 20 元;停靠老化 72 小时;决策包有效期 24 小时;S2 确认窗 45 秒
分支 / 目录saydo/<taskId> @ <repo>/.saydo/worktrees/<taskId>
回到顶部 ↑