这份 runbook 面向的是:
Switchyard 的实现 Agent它不回答“产品为什么存在”,而回答:
今天在这台机器上,怎样把开发环境、参考运行时、验证前提和第一步实现准备到位。
本 runbook 只服务当前 V1 主线:
BYOKWeb/Login它不服务:
consumer compat 正式实现Gemini CLI完成本 runbook 后,应该达到以下状态:
Switchyard 仓本地开发环境已准备好LiteLLM 与 openclaw-zero-token 能以 lab sidecar 身份被使用Kernel Alpha,而不是继续想 abstract strategy这份 runbook 现在只负责第五层,也就是 manual / credentialed workstation。
更直白一点说:
pre-commit
pre-push
hosted
nightly
manual
如果你要看完整 5-layer 总图,先看:
这份 runbook 现在不能再按“仓库还是 docs-only、还没开工”来理解。
当前工作区现实已经是:
BYOK + Web/Login 的最小代码主干已经存在reality:gate / verify:web-login-live / verify:gemini-live 已经存在Web/Login provider 都已经进入 local-first acquisition 主线apps/service/src/web-auth-acquisition.ts 的 playwright-core 依赖接线在当前工作树里已经收口,不再单独卡住 typecheck / test / build当前更保守、也更适合接手验收的写法是:
typecheck / test / build 已经可以稳定通过test:coverage 也已经重新回到稳定通过,并回到 80% 线以上verify:service-live 当前不该继续写成 green,而是停在 Claude = account-action-requiredClaude / Grok 这组 workspace external blockersClaude / Grok 的 credentialed workstation 上继续维护 repo-local runtime hygiene,并在未来换环境时重新做 truth reset”当前 closeout 输出里的 external-blocker 还会再带一个 classification 字段,用来说明“为什么它仍然是外部尾巴”:
session-material-missing: 缺 cookie / user-agent / key 这类材料,先补材料session-incomplete: 材料在,但浏览器会话还没真正落到可用 composeruser-action-required: 需要终端用户亲自完成账号动作,例如重新登录、补 OAuth、关联账号或解锁所需 planhuman-verification-required: 命中了 CAPTCHA / anti-bot / 风控验证account-action-required: 当前账号还差一层显式账户动作,例如关联 X、补 workspace unlock、或通过所需 plan gatepermission-gated: session material 已经在,但 browser-side bootstrap 仍被 Unauthorized / permission gate 挡住transport-instability: 不是用户材料问题,而是 CDP / attached-browser / provider transport 本身不稳定probe-misclassification: 探针或 proof 语言可能把真实状态看错了,需要回到脚本与 provider runtime 继续核实provider-unavailable: 上游 provider 当下不可用,不应误报成凭证损坏所以这份 runbook 现在服务的现实阶段,不再是:
“所有 gate 都重新回到全绿的固定工作站”
而更接近:
“在 repo-side gate 已过、但 current workspace live truth 仍停在一组 workstation-bound external blockers 的 credentialed workstation 上,继续维护 repo-local runtime hygiene,并在未来环境变化时重新做 truth reset”
同时保留一个很重要的护栏:
这类 live checkpoint 天生会过期。
runbook 里的 checkpoint 不是永久真理;每次接手都应 fresh 运行:
pnpm run verify:gemini-livepnpm run verify-web-login-livepnpm run verify:service-livepnpm run reality:gate它也不覆盖更高优先级的 ADR / blueprint / task board。
这份 runbook 记录的是“当前这台机器最近一次怎么跑通”,不是正式改写阶段裁决的地方。
当前还多了一个很实用的 M2 证据脚本:
pnpm run verify:service-live这条脚本会直接启动本地 Switchyard service,并通过统一的 service-first invoke 入口验证高稳定 trio:
chatgptgeminiclaude它的作用不是替代 reality:gate,而是补一张更面向 M2 / service-first readiness 的成绩单:
reality:gate 回答的是:当前 M1 有没有关门verify:service-live 回答的是:当前 trio 能不能通过统一 service surface 真正跑通当前还多了一条很实用的 browser diagnosis 工具:
pnpm run diagnose:web-login-browser -- --provider chatgpt --reload --json
它不是另一个 aggregate gate。
它更像一把手电筒,专门照这件事:
为什么 auth store 已经显示
ready, 但 live verifier 还是说 browser session 不完整。
这条命令会输出:
current-pagecurrent-consolecurrent-network如果你本地已经把 service 跑起来了,现在还有一组更细的只读 CLI 读法:
pnpm run switchyard:cli -- provider-store-readiness --provider chatgpt
pnpm run switchyard:cli -- provider-live-readiness --provider chatgpt
pnpm run switchyard:cli -- provider-attach-target --provider chatgpt
pnpm run switchyard:cli -- provider-diagnose-ladder --provider chatgpt
pnpm run switchyard:cli -- provider-diagnose --provider chatgpt
pnpm run switchyard:cli -- surface-catalog
pnpm run switchyard:cli -- compat-targets
pnpm run switchyard:cli -- compat-target --target codex
pnpm run switchyard:cli -- mcp-status
pnpm run switchyard:cli -- mcp-tools
可以先这样理解:
provider-store-readiness = 看抽屉里的钥匙和证件在不在provider-live-readiness = 看人是不是已经站到正确的门前provider-attach-target = 看你到底连的是哪一个浏览器provider-diagnose-ladder = 看下一步先修什么provider-diagnose = 一次把整张体检单拿出来surface-catalog = 看当前 outward surface / compat / MCP 的机器可读真值表compat-targets = 看所有 thin compat 目标的机器可读目录compat-target --target codex = 定点看某一个 consumer target 的 truthmcp-status = 看当前 MCP surface 的真实级别mcp-tools = 看当前 read-only MCP server/tool surface 已经公开了哪些工具名这些命令现在只属于本地排障手册。
它们不等于 public CLI 已经升格成 today supported surface。
更直白一点说:
store-ready = 本地材料在仓里live-ready = 当前附着浏览器真的落在能发请求的工作区这条 runbook 现在还多了一个 repo-local 的磁盘治理入口:
pnpm run audit:runtime-footprint
pnpm run cleanup:runtime -- --dry-run
先把它理解成:
audit:runtime-footprint = 体检单cleanup:runtime -- --dry-run = 预演cleanup:runtime -- --apply --include-managed-browser = 高风险动作当前 .runtime-cache/ 里的东西要分 4 类看:
managed-browser-profile
.runtime-cache/switchyard-web-auth-browserdebug-evidence
.runtime-cache/browser-debug/bundlessummary.json 这类调试证据,默认只修剪旧 bundlesupport-bundles
.runtime-cache/browser-supportdisposable-generated
.runtime-cache/temp.runtime-cache/switchyard-verify-web-login-test-*、.runtime-cache/switchyard-chatgpt-ready-writeback-*、.runtime-cache/switchyard-store-preserve-*.runtime-cache/app-service*.log、.runtime-cache/reality-gate*.{out,exit}repo 外如果还需要当前仓专属的临时缓存,也只能进:
~/.cache/switchyard默认治理规则现在是:
TTL = 7 daysmaxBytes = 8 GiB.runtime-cache/~/.cache/switchyardpnpm store~/.npm~/.cache/pnpm~/Library/Caches/pnpm~/Library/Caches/ms-playwrightuv / pre-commit / Docker 全局缓存.serena/cache护栏也要说清楚:
.runtime-cache/ 和专属的 ~/.cache/switchyard<macos-temp-root>/...~/.cache 里的其他共享工具目录、Docker 全局缓存、Chrome 全局目录managed-browser-profile--include-managed-browser,并且脚本确认当前没有活跃监听或活跃 Chrome/Chromium profile 占用时,才允许删除 managed browser 工位在执行 live / browser / cleanup 类命令前,先跑:
pnpm run scan:host-process-risks
现在这仓更推荐的本地 credentialed 工作方式不是 repo-local managed browser 常开,而是:
isolated-chrome-root~/.cache/switchyard/browser/chrome-user-dataswitchyard-web-auth-browser 只保留为显式隔离 fallback推荐环境变量:
export SWITCHYARD_BROWSER_MODE=isolated-chrome-root
export SWITCHYARD_CHROME_USER_DATA_DIR="$HOME/.cache/switchyard/browser/chrome-user-data"
export SWITCHYARD_CHROME_PROFILE_NAME="switchyard"
export SWITCHYARD_EXTERNAL_CACHE_ROOT="$HOME/.cache/switchyard"
export SWITCHYARD_CACHE_TTL_DAYS=7
export SWITCHYARD_CACHE_MAX_BYTES=8589934592
export SWITCHYARD_WEB_AUTH_EXISTING_PROFILE_CDP_URL="http://127.0.0.1:9338"
这里要记住一个边界:
~/.cache/switchyard/browser/chrome-user-data是当前 repo 的永久浏览器工位。 它属于 repo 专属 steady-state browser root,不参与 TTL / cap 自动裁剪。
第一次把默认 Chrome 根目录里的 switchyard profile 搬进来,要显式跑:
pnpm run seed:isolated-chrome-root -- --json
只有你明确要重建独立根目录时,才允许:
pnpm run reseed:isolated-chrome-root -- --json
现在也明确一条 fail-closed 规则:
9338这轮还补了一条宿主机安全边界:
bootstrap-web-auth-browser现在不能再通过detached: true+.unref()偷留一个 Chrome child handle。 新实例启动必须走宿主机 launcher handoff;已在线的 repo-owned 浏览器若需要补开登录页,走 CDP/json/new。 如果宿主机不能证明这条 handoff 是安全成立的,脚本必须 fail-closed,让你改走existing-browser-session/ 手工启动,而不是偷偷回退到 detached launch。
这轮还新增了一条很关键的 coherence 纪律:
ready不再只由.runtime-cache/local-web-auth-store.json单独决定。
后续 live verify 会同时核对:
- 当前 attached browser 页面
- 当前 browser root / profile
- 当前 root 上关键持久 cookie 是否真的落盘
如果 store 还说 ready,但当前浏览器页已经掉到登录页,或者当前 root 上关键 cookie 不在,系统会把它降级成:
user-action-required
__Secure-next-auth.session-token*refreshable-but-degraded
当前仓继续只使用 GitHub Hosted Runner,不引入 self-hosted。
云端 CI 只跑:
pnpm typecheckpnpm testpnpm build下面这些仍然是 local credentialed only:
pnpm run verify:gemini-livepnpm run verify-web-login-livepnpm run verify:service-livepnpm run reality:gatepnpm run diagnose:web-login-browserpnpm run capture:web-debug-bundle如果这些 live 路径在 CI 环境中被误触发,现在应该直接 fail-closed,报出 credentialed-workstation only,而不是偷偷依赖云端没有的本地登录态或真实 Chrome Profile。
这台机器是共享实验室,不是当前 repo 一个人的桌子。
当前 repo 的默认预算是:
如果两次检查都已经说明当前 repo 自己的 canonical browser/profile 里没有有效登录态,就把它记成 blocker。不要继续靠多开浏览器、重复 clone profile、反复 attach session 碰运气。
当前 Switchyard 没有 repo-owned Docker runtime。
cleanup:runtime 误当成 Docker 清盘命令switchyard 归属的资源在跑任何命令前,先读:
README.mddocs/product/v1-brief.mddocs/product/scope-and-nongoals.mddocs/adr/0001-v1-boundary-and-lane-model.mddocs/adr/0002-external-repo-adoption-matrix.mddocs/adr/0003-upstream-relationship-openclaw-zero-token.mddocs/adr/0004-architecture-skeleton-monorepo.mddocs/contracts/provider-runtime-contract.mddocs/contracts/auth-accounts-and-credentials.mddocs/contracts/service-and-sdk-surfaces.mddocs/blueprints/v1-delivery-plan.md.agents/Tasks/TASK_BOARD-2026-03-29-switchyard-bootstrap.md如果这些没读够,就不要开工写代码。
pnpmpython3gitnode -v
pnpm -v
python3 --version
git --version
当前阶段,只要这些工具存在并能工作,就已经够开始实现 Switchyard 的 Day 1 范围。
当前主线只看这 3 个主参考:
ailitellmopenclaw-zero-token边缘/后续参考只在需要时看:
ChatALLcodexclaude-codeopenclawgemini-clils '<local-reference-root>'
不要再把已经被正式移出主线的历史小样本仓拉回当前研究主线。
即使本地未来又重新出现,也只允许作为备查,不允许进入当前主线合同。
Vercel AI SDK 准备方式pnpm 直接依赖Vercel AI SDK 不需要先独立跑成一个 sidecar。
它更像是 Switchyard 自己将来会直接依赖的核心包。
ai 的 provider-agnostic 抽象存在@ai-sdk/open-responses、@ai-sdk/openai、@ai-sdk/google-vertex 这些包的存在和语义Kernel Alpha 阶段的 contract/SDK 主骨架来源LiteLLM 准备方式根据本地 README,当前最小实验方式可以是:
pip install 'litellm[proxy]'
litellm --model gpt-4o
不是因为 Switchyard 要依赖它做核心内核,而是为了:
Switchyard 里扮演什么lab sidecar不是:
openclaw-zero-token 准备方式lab sidecar firstselective transplant本地技术母本路径按占位写法记为:
<local-reference-root>/openclaw-zero-token
其中 <local-reference-root> 表示你在本机存放第三方参考仓的根目录;公开 runbook 不写个人绝对路径。
因为它不是一个小库,而是一个完整运行时平台。
如果只看 README,不把它真正当 sidecar 研究,你很难理解:
根据本地 README,最小研究路径是:
pnpm install
pnpm build
pnpm ui:build
./start-chrome-debug.sh
./onboard.sh webauth
./server.sh
不要把精力花在它的全产品世界上。
当前只观察这些层:
如果你要继续推进 Web/Login、live-proof、acquisition、browser transport,优先看这些本地源码:
src/zero-token/providers/chatgpt-web-client-browser.tssrc/zero-token/providers/gemini-web-client-browser.tssrc/zero-token/providers/claude-web-client-browser.tssrc/zero-token/providers/grok-web-client-browser.tssrc/zero-token/providers/qwen-web-client-browser.tssrc/zero-token/streams/chatgpt-web-stream.tssrc/zero-token/streams/gemini-web-stream.tssrc/zero-token/streams/claude-web-stream.tssrc/zero-token/streams/grok-web-stream.tssrc/zero-token/streams/qwen-web-stream.ts换句话说:
当前 Web/Login lane 最值钱的学习路径,不是继续在小样本仓里横跳,而是直接深读
openclaw-zero-token本地母本。
不要把注意力消耗在:
这些是它的产品世界,不是 Switchyard V1 的施工面。
必须准备好:
ChatGPTGeminiClaudeGrokQwen当前必须确保:
Gemini API Key 可真实测试其余 provider 可以暂时停在:
而不必全部先做真实 credential 验证。
如果要跑当前仓里的 reality-gate proof,当前约定是:
Gemini BYOK:
pnpm exec node scripts/verify-gemini-live.mjsSWITCHYARD_GEMINI_API_KEY / GEMINI_API_KEY / GOOGLE_API_KEYWeb/Login:
pnpm exec node scripts/verify-web-login-live.mjspnpm exec node scripts/verify-web-login-live.mjs --provider chatgpt(gemini / claude / grok / qwen 同理)SWITCHYARD_WEB_<PROVIDER>_COOKIE_BUNDLESWITCHYARD_WEB_<PROVIDER>_USER_AGENT如果你要走 Web/Login acquisition 主路径,默认优先让 Switchyard 自己准备浏览器,而不是手工研究某个 9222 Chrome:
pnpm run bootstrap:web-login-browser -- --provider chatgpt
pnpm run bootstrap:web-login-browser -- --provider gemini
pnpm run bootstrap:web-login-browser -- --provider grok
这条脚本会尝试启动或复用 Switchyard 自己的本地 onboarding 浏览器,再打开对应 provider 登录页。
这是默认模式,也就是:
managed browser当前还存在两条高级 acquisition 路径:
use existing Chrome profileattach existing browser session它们仍然属于同一条 local-first acquisition/store 主线,但只在你明确需要复用已有 Chrome 登录态时才启用。
换句话说:
managed browserexisting profile / attach session只有当你在做 fallback/debug/proof harness 时,才需要回到 env 层面关注 SWITCHYARD_WEB_AUTH_CDP_URL 一类底层变量;产品主路径不应该要求用户先理解这些实现细节。
这里的 <PROVIDER> 当前对应:
CHATGPTGEMINICLAUDEGROKQWEN这些变量只用于 终端用户自己的本地 proof 输入,不是平台共享凭证,也不是公共账号池配置。
.env 自动加载行为当前仓里的以下入口会自动加载 repo 根目录的 .env.local 与 .env:
scripts/verify-gemini-live.mjsscripts/verify-web-login-live.mjsscripts/run-reality-gate.mjsapps/service/src/index.ts加载顺序是:
.env.local.env同时保留一条更高优先级规则:
已经存在于 shell 的环境变量优先,
.env*只补缺,不覆盖。
这里必须再强调一次:
这套 env 输入只是当前 reality gate / closeout harness 的 proof 契约。
它不是最终产品主 UX。
最终产品主路径应该是:
- 用户在
Switchyard内点击 acquisition/start,让系统启动或附着正确的本地 onboarding 浏览器- 用户在这份浏览器里完成登录 / OAuth / browser-session acquisition
- acquisition 结果进入本地 credential/session store
status / probe / reality gate优先消费这套本地产物
当且仅当下面这些条件成立,才算“可以进入 Kernel Alpha 实现”:
nodepnpmpython3Chrome都可用
LiteLLM 能按 lab sidecar 思路被启动或至少具备可运行路径openclaw-zero-token 能按研究路径被启动并观察Gemini API Key 可真实测试实现者已经明确知道:
openclaw-zero-token 是技术母本Vercel AI SDK 是 SDK/contracts 骨架LiteLLM 是 BYOK gateway 样本Codex / Claude Code / OpenClaw compatGemini CLI 拉回来进入 Kernel Alpha,从这些开始:
contractskernelcredentialsdiagnosticslanes/byoklanes/webproviders/byok/*providers/web/*surfaces/http这份 runbook 的核心不是“把所有东西都跑起来”。
而是:把实现者带到一个足够确定的起跑线。
到达这条线之后,下一步就不该继续聊抽象,而应该进入
Kernel Alpha的代码实现。