# 交接说明 — 2026-10-15(接手考古 + 现状) **上一份**:[HANDOFF-2026-09-17-B.md](HANDOFF-2026-09-17-B.md)(它停在 v3.9.36 的事实,tag 行随 v3.9.40 改过一次)。本份取代它作为「现状」,并补上 09-17 以来从未落盘的:入站队列判决、冻结与门控 清单、本机独有资产、查漏补缺登记表。 方法论仍看 [AUDIT-LEDGER.md](AUDIT-LEDGER.md);发布口令看 [releases/README.md](releases/README.md)。 本份只写**现在还能接手的事实**;每条都带能复核的出处(`file:line` / commit / 命令)。 > 本份仍是活头。§0 的当前状态已按 2026-11-09 复核;2026-10-15 的原始快照原样保留在 §0 的折叠块里, > 历史结论不改写。 --- ## 0. 当前状态(2026-11-11 发布后复核 — master `7c0ca067`,产品 tag `v3.141.592661`) > 本块描述 2026-11-11 发布后的 master:`产品 tag` 行写已发布的 annotated tag 与它指向的提交 > (tag 与发布提交同一 commit,Release `441079956` 已发布);`master` 行写远端 master tip, > 它之后的提交只动文档与资产,`src/` 滞后 0;`冻结 tag` 行是那个永不发布的本地 tag 的真实指向。 ``` 产品 tag v3.141.592661 —— annotated tag(对象 `837fed0f8`)→ commit `fe98f0bc`;Release `441079956` 已发布(14 资产 / 7 个 .sigstore.json / draft=false / published 2026-11-11T00:18:15Z),tag 与发布提交同一 commit master `7c0ca067`(= origin/master;2026-11-11 复核时的 master tip,本地 `git merge --ff-only origin/master` 后同 SHA;自它起 `src/` 滞后 0,其后的提交只改文档与 `docs/assets/`。上一个改 `src/` 的提交仍是 `babafeef`,`fe98f0bc` 是 3.141.592661 发布提交,`7c0ca067` 只改 `docs/assets/star-history.svg`) 远端 master `7c0ca067`(同上;本地 `git merge --ff-only origin/master` 后与 `git ls-remote` 同 SHA,落后 0) 冻结 tag v3.141.592659 —— 本地 annotated tag(tag-object `1d63a030` → commit `d5519da3`,**未修复**:早于 JSON Schema 边界修复 `babafeef`;**永不发布**——不 push、不删除、不复用;它不是发布路径上的版本) 全量 shard 627 文件 / 7,818 测试 / 7,715 通过 / 0 失败 / 103 跳过(Path C 树:一次性 clone,只删冻结 tag、保留 `.592661` = 230 个 tag,2026-11-11 实测;本机只跑受影响集合,见发布说明 §7 与验收附录) package.json 3.141.592661 ``` ## 0. 当前状态(2026-10-30 复核) ``` 产品 tag v3.141.592658 —— annotated tag 将指向本文件的发布提交(tag 目标;SHA 见 `git rev-parse 'v3.141.592658^{commit}'`);发布提交的父提交 → commit `84a54bbb`(贡献者台账提交:`src/dashboard/data/contributors.json` 记入 PR #282;其父 `18879611` 是 combined `release/next-pr282` tip,含 PR #282 signed-thinking 与 Gemini `type[]` 修复的全部 src 变更;`c5564f9a` 是发布前的资产提交(落后 HEAD 32 个提交))。上一个已发布 tag:v3.141.592657(`a7d2e33f`);发布状态以 `gh release list` 为准 master `3816a47a`(= origin/master = HEAD,`git describe` = `v3.141.592658-8-g3816a47a`;其后 8 个提交全是发布/文档/合并,`84a54bbb..HEAD` 的 `src/` 差异 = 0。下文 `84a54bbb` 是本发布提交的父提交 = 贡献者台账提交:只改 `contributors.json` 与它的 docs 镜像;其父 `18879611` 是合并前的 `release/next-pr282` tip(PR #282 signed-thinking 回放,默认关闭 + Gemini `type[]` 降级),再前 `272429d3` 是 3.141.592657 的 sweep 记录,`c5564f9a` 是发布前的资产提交(落后 HEAD 32 个提交)。本行同时满足 docs-guard 的「master 是 HEAD 祖先、且自它起 `src/` 零滞后」——`84a54bbb` 与 `3816a47a` 两个 SHA 都过,这里取真正的分支名。D9 三支合并:`w18x-bannerlock` 把 workflow action 与 banner 生成器 锁到 commit/sha256;`w18x-dockersign` 按 digest 签名 Docker 镜像并发布 image-digest.txt; `w18x-sourceattest` 在源码 OTA 前校验 release-attestation.json。其前 `e93404f4` 是 cascade deadline flake 修复,`00aab54a` 是 docs sweep,`42846ba5` 是 D 批合并后的 src 基线) package.json 3.141.592658(= 本版版本;OTA 跟最新 annotated tag) CI 本版发布门实测(发布提交;计数见 `docs/releases/ACCEPTANCE_3.141.592658.md` §3): Windows `npm run test:release`、POSIX `gate:release`(HMC,Node 24)、docs guard、 secret scan、`git diff --check`、spec-baseline 全 PASS;wire 对 v3.141.592657 (`a7d2e33f`)270/270 字节一致、0 未声明差异。全量 mutation 沿用 `15dd8904` 的 sweep(97/97 spec,863 = 846 caught + 17 declared,0 mismatch)—— 发布侧两个提交 (贡献者台账 + 发布提交)只改数据与文档,`src/` 逻辑与 `15dd8904` 逐字节相同。 托管 CI 在 tag 后运行。 突变语料 97 份 spec / 863 条突变(2026-10-26 静态重算:`ls test/mutations/*.json | wc -l` = 97, 逐 spec 求和 863;deadline-flake 修复新增第 6 条容差突变);其中 **17 条声明为 SURVIVOR** (`expectCaught:false`:15 条既有 + `cascade-final-sweep-deadline.json` 第 2/4 条—— F2/F3 的两条冗余层,理由钉在该条 name 里)。全量 sweep 计数见验收附录 §3。 门禁数字 见 §6 末尾「门禁表」——本文件就是它的落点(CONTRIBUTING 此前指着一个不存在的表) ```
2026-10-15 快照(历史,不再代表现状) ``` 产品 tag v3.9.40 —— annotated 对象 649b1b9 → commit 25322dd;Release published 2026-10-07T04:14:37Z,draft=false,4 产物齐全;release workflow 37569886191 六 job 全 success(wire 基线选到 v3.9.39 严格祖先) master `72dc2f8` == origin/master(2026-10-16 复核:`git log v3.9.40..HEAD` = 23 提交; `git log --oneline origin/master..HEAD` 与 `HEAD..origin/master` 均为空 —— 本批已全部推送)。 v3.9.40 之后 = 7 个 star-history 机器人(只动 docs/assets/star-history.svg)+ 7 个 文档提交(`6815049`/`d9e17df`/`91d2100`/`bf1fe83`/`9031b9b`/`0ea5d38`/`72dc2f8`)+ 9 个代码提交 (`ab4e66f` windsurf.js 信任位双写、`74f319e` 考古 P0 四件、`054806a` LS 六修、 `86d5543` + `21870ae` 连接面八修、`d3f0490` 模型目录对公开成本表、`f10ade3` OTP 日志 + IMAP SEARCH、`491347d` 两个静默空转测试、`2aaeb21` GetUserJwt 15s 期限)。本行前两版分别停在 `05868a3`(当时 v3.9.40 之后只有 7 个机器人提交)与 `ab4e66f`(12 提交);此后树在 数小时内走到 `0ea5d38`(15) → `21870ae`(18) → `d3f0490`(19) → `2aaeb21`(22) → `72dc2f8`(23) —— **引用本行前先按当日树重测**,本行是这个文件里烂得最快的一处 package.json 3.9.40(= tag;OTA 跟最新 annotated tag) CI ci.yml 在 master 最新一次运行 `38771008817`(headSha `72dc2f8`)**success** —— job 全 success(Node syntax check / Unit tests shard 0-3 / Default-path request bytes / Mutation spec consistency),手工突变 job 按设计 skip(2026-10-16 `gh run view 38771008817` 复核:status=completed、conclusion=success)。 上一条完整记录 `38767160836`(headSha `d3f0490`)同为全 success。本机门(2026-10-15,`ab4e66f` 树): 4 条 `GATE_INERT_SKIP_PATHS` 声明下 `INCREMENTAL GATE: PASS`(6 checks;不声明这 4 条会判 undeclared 红——机器条件,不是回归)。 前几条记录:`38740837201` = `9031b9b`、`38729536414` = `ab4e66f`、`37569866691` = `d9e17df` v3.9.40 之后的机器人提交不触发 workflow(GITHUB_TOKEN 推送);#279/#280 的 CI 停在 action_required(首次贡献者,等维护者点批准),从未真正执行过(2026-10-16 `gh pr view` 复核: 两个 PR 仍 OPEN、`statusCheckRollup` 为空) 突变语料 85 份 spec / 767 条突变(2026-10-16 实测:`ls test/mutations/*.json | wc -l` = 85,逐 spec 求和 767; @`d3f0490` 与 @`72dc2f8`(当前 HEAD)两次重测同值。766 是 d9e17df 树的值, FIX-CLOUD-2 的 spec 2→3 随 `21870ae` 合入) 门禁数字 见 §6 末尾「门禁表」——本文件就是它的落点(CONTRIBUTING 此前指着一个不存在的表) ```
> 上一份(09-17-B 里被后续会话追加的)快照写「远端 f510539、本地落后 4、工作树 3 项脏」——已过期: > 本地 == origin/master == `72dc2f8`(2026-10-16 复核:落后 0、领先 0,本批已推送); > `.mcp.json` / `.omp/` 进了 > `.git/info/exclude`,工作树不再显示它们(2026-10-16 复核:`git status --porcelain` 只剩两个未跟踪的 > 站内文件 `AGENTS.md.before-agents15-20261015` / `SESSION-DIGEST.md`,无已跟踪文件改动)。 --- ## 1. 接手三分钟内会踩的(只写 09-17-B 之后的变化;旧 5 条仍有效) 1. 分支 → 独立评审 → `git merge --ff-only` → push。**不要直接在 `master` 上 commit**。 2. **`runtime-config.json` 是本机操作员文件**(gitignore 的活配置;`src/runtime-config.js:18` 从 `config.dataDir` 解析)。两条 2026-10-15 实测: - **文件里的 pin 会盖过 env**:`quota.spendOnDemand:false` 让 `test/devin-connect-breaker.test.js` 的 6 个用例在**裸 `node --test`** 下失败(43 pass / 6 fail)。走 `test/setup-env.mjs` 的 `npm test` 路径时 DATA_DIR 被改到临时目录、pin 读不到 → 49/49 全绿。**这是测试隔离缺陷, 不是产品缺陷**(它只会更红,不会更绿)。 - **裸 `node --test` 会改写操作员文件**:`test/breaker-tunable-hotswap.test.js`(12 测试, `_resetRuntimeConfigForTests` + 15 次 `setBreakerTunables`)裸跑一次,盘上 `quota.spendOnDemand: false → null`、`breaker.errorStreakThreshold: null → 2`。 `persist()` 写整个 `_state`,而 `DEFAULTS.credentials` 是空串 —— **真部署上等于把面板口令 哈希与 API key 抹成空**。走 `npm test` / `npm run test:release`(都 preload `setup-env.mjs`) 不会碰到操作员文件。 **规则:跑单个文件也用 `node --import ./test/setup-env.mjs --test `,并在跑测试前后 备份 `runtime-config.json`。** - 给 breaker 套件加 `beforeEach(_resetRuntimeConfigForTests())` 的候选修复(九兄弟套件的做法) **已实测、未采纳**:裸跑确实变绿(49/49),但它把 reset 后的默认状态经后续 setter 落盘 —— 把「裸跑 6 红」换成「裸跑抹掉操作员配置」,更坏。两份对照文件在 `.agent/gap-20261015/`。 (九个 reset 套件里有 **4 个**同时调会落盘的 setter:`backend-switch-hotswap`(24)、 `breaker-tunable-hotswap`(15)、`quota-tunable-hotswap`(13)、`runtime-config-hardening`(9); 四个文件的头注释都写明「隔离依赖 setup-env 的临时 DATA_DIR」。裸跑它们同样会改写操作员文件, 已实测两个:breaker-tunable-hotswap 与 quota-tunable-hotswap。) 3. `npm run mutate` 需要**受信 POSIX git**(`scripts/mutation-harness-utils.mjs:11-19` 的候选表是 Unix 绝对路径):Windows 上跑不了,突变判决去 WSL/Linux bench 做。Windows 门需要 `GATE_INERT_SKIP_PATHS` 声明(**4 条**,语义与完整清单见 CONTRIBUTING 的对应小节与 `.env.example`),Linux CI 不需要。 4. **PR 门禁工具在 `.claude/scripts/`**(`pr-gate.mjs` / `triage.mjs`,gitignore 的本机控制面): 它自带一个隔离 worktree 跑机械门。2026-10-05 之前它对「有 suite 见证的 0 测试行」会误判为说谎并 abort(`--local` 在 master 上同样死);现在按 `scripts/local-gate.mjs:37-43` 的 doctrine 记为 inert 并在门输出里点名。**PR 评审先跑它,再谈人审**——顺序在 `.claude/skills/pr-gate/SKILL.md` 里写死。 5. `.agent/` 与 `.claude/` 是本机控制面,**绝不进 git、绝不贴到 issue**(09-17-B §3 未变)。 --- ## 2. 入站队列(2026-10-15 逐条核对;这是 09-17 之后没人落盘的部分) ### 2.1 PR(4 个 OPEN) | PR | 作者 | 状态 | 内容 | 判决(对着 CONTRIBUTING 的合并条) | |---|---|---|---|---| | **#279** | felix-xqs | OPEN,**CI 从未跑**(run 37751311525 = action_required),零 review | `fix(stats)`:`importStats` 重写——merge 导入不再静默丢 model/account/hourly/token 统计;无效快照非破坏性拒绝;导入路径补上上限 | **改 2 处后可合**:① `'windsurfapi-stats-v1'` 允许值在仓库史里查无此物(RC11,无解释常量);② merge 模式把**活状态**一起校验,脏 live 值会让导入报 `'invalid snapshot'`(误导性错误,且持久化后重启仍带毒)。另:commit body 缺失、作者自报的 8 个预存失败要在干净 master 上复核(RC9) | | **#280** | felix-xqs | OPEN,**CI 从未跑**(37754506427 = action_required),零 review | `feat(logs)`:三个 opt-in 默认关的磁盘日志上限——`LOG_RETENTION_DAYS` / `LOG_MAX_FILE_MB` / `LOG_MAX_TOTAL_MB`(保留窗口、按字节轮转、总量逐出) | **改 2 处后可合**:① `test/log-files.test.js:56/:158` 用**文件符号链接**,Windows 上 EPERM(仓库惯例是 `'junction'`,见 `test/secret-scan-links.test.js:16-18`)——会在本机门里留一条红;② 功能没先开 issue(CONTRIBUTING:35 的书面规则)。保留/轮转的数学已逐条复核正确 | | **#276** | Smith-106 | OPEN,`CHANGES_REQUESTED`(dwgx,2026-10-05T20:16Z),作者自 10-02 未再推 | DEVIN_CONNECT 精确匹配应答缓存(+91/−0,仅 `chat.js`) | **等作者**:3 个 blocker(`finish_reason` 被洗成 `stop`;`_windsurf_stop_sequence` 丢失;零测试)+ 4 小项。机制方向已被维护者亲手驱动验证过(「这块做得对」),修完可合 | | **#274** | Smith-106 | OPEN,`CHANGES_REQUESTED`,head `99ad55d` **已换过一轮** | 原「repair 尾巴」的 src 实现已整体删除——现在净 diff 只剩 `test/tool-emulation-boundary.test.js` 的 +27/−0 两条测试 | **差一步**:① 守卫 2 不过 RC0(把共享层那一刀装回去它照样绿;该测试文件根本不加载 `chat.js`,物理上不可能发现共享层回归)② 标题/body 仍描述已删除的行为。作者静默 9 天 | 补充事实:**#275 已由维护者 2026-10-05 按「被取代」关闭**(与 #276 的 `chat.js` blob 逐字节相同 `0a2e6a70`,只多一笔 banner 刷新)。#279/#280 与 #274/#276 无文件重叠,彼此也无顺序约束; 两个新 PR 都过了机械门槛(零依赖、无 AI 署名、单主题),且 **0 条突变 anchor 指向它们改的文件** (85 份 spec 全扫过)。 评审计数(2026-10-15 PR 考古复核):正式 review 截至语料快照共 **9 条 / 8 个 PR** —— CONTRIBUTING 旧版 「截至 2026-10-05 的 87 个 PR 里 7 条正式 review」(#90 #142 #198 #232 #255 #256 #274)是**当日较早 时点的正确快照**,该句已在 2026-10-15 文档漂移批里改指本节;差额是 #276 在 2026-10-05 20:05Z / 20:16Z 追加的两条 CHANGES_REQUESTED。另:「无 review 对象」≠「没评审过」——2026-09 批次有详细评审**评论**但不走 review 对象,引用计数前先分清。 ### 2.2 issue(9 个 OPEN;2026-09-22 以来只关了 #277——2026-10-05,由 PR #278 修掉) | # | 一句话 | 判决 | 下一步 | |---|---|---|---| | [#273](https://github.com/dwgx/WindsurfAPI/issues/273) | 两处 wire 语义待现场校准(result 先于 call 的历史、同回合多帧 reasoning 重复) | 需现场(live) | 两个最小实验跑完再改注释或编码器 | | [#272](https://github.com/dwgx/WindsurfAPI/issues/272) | 只带图片的 assistant 回合在编码前被整条丢弃 | 需现场;reasoning 半边已修(`e0143fd`) | A/B 图片实验;若上游接受 → 改过滤 + 换掉 T4/M5 锁 | | [#262](https://github.com/dwgx/WindsurfAPI/issues/262) | feat:opt-in SWE-2 ACP 传输(client-owned tools) | **留作设计注记** —— 维护者 2026-10-05 改口:「Good to leave this open as a design note rather than let it die」(#263 撤、#266 已交付一半、第二条传输仍是边界不是缺口) | 要推进就交一个**真实失败样本**(请求体 + SWE-2 路径丢东西的原始上游输出);不再建议关 | | [#258](https://github.com/dwgx/WindsurfAPI/issues/258) | 旱灾闸挡免费模型,称 `FREE_REACHABLE_SELECTORS` 过期 | **已修(树内)** —— 维护者 2026-10-05:「already fixed in the tree」:`DROUGHT_SAFE_SELECTORS` @ `src/devin-connect-models.js:185`(`swe-1-7` / `swe-1-7-medium` / `glm-5-2`,只进旱灾门、不进免费层权益),门 @ `chat.js:3290`,v3.9.28 起未变(2026-10-15 复核:`git log -S` 单一引入提交 `6267e8a`、无后续改动) | 只差报告者一句回执(drought-on 下 `swe-1-7` / `glm-5.2` 返回 200);503 建议名单那处我方小改**已修**(`74f319e`,2026-10-15):现在把 `DROUGHT_SAFE_SELECTORS` 拼在免费名单前(`chat.js:3295` 的 `offeredModels`,同处的 `allowedModels` 一并同步;`auth.js:368` 仍是免费层的来源) | | [#250](https://github.com/dwgx/WindsurfAPI/issues/250) | reasoning 泄漏进 content 通道(不能强复现) | 需现场抓包 | `WINDSURFAPI_LEAK_TRACE=1` 跑一次真会话、贴 `leak-trace.json` | | [#245](https://github.com/dwgx/WindsurfAPI/issues/245) | Enterprise 账号响应降级,是不是配错了 | 等报告者 | 三件事:去掉 `CASCADE_REUSE_HASH_SYSTEM=0`、试 `WINDSURFAPI_NLU_RETRY=1`、贴坏回合日志 | | [#239](https://github.com/dwgx/WindsurfAPI/issues/239) | 要真实 ACU 计费 | 需现场(付费号) | 一个付费终帧的 `#22` + 同时段官方 `billed_acus` | | [#236](https://github.com/dwgx/WindsurfAPI/issues/236) | subapi → WindsurfAPI → Codex 的 GLM-5.2 工具调用停滞 | 等报告者 | 绕开 subapi 直连 + `LOG_LEVEL=debug` 抓 `ToolRoute[...]` 原文;无捕获不打补丁(维护者定的规矩) | | [#208](https://github.com/dwgx/WindsurfAPI/issues/208) | Owner 自己的公告帖 | Owner 的事 | 可按「已被 release notes 取代」关 | > issue 线程里的行号引用普遍漂了(例:#272 的 `devin-connect.js:1092` → 现 `:1218`;#245 的 > `chat.js:4731` → `:5209`)。引旧行号前先在树上 grep 一次。 --- ## 3. 冻结与门控(**不是漏做,是等裁决**) - **Owner 冻结**(2026-09-22,`ROADMAP.md`「Limits and standing decisions」):#250 / #258 / #272 / #273 标 **UNVERIFIED 且不是排队中的探针**;#262 第二条传输**维持拒绝**;不做新的 RE 获取、付费或远程任务。 - **Owner 门控(改产品语义,未获明示不得动手)**: | 项 | 一句话 | 位置 | |---|---|---| | C2 | 真实 producer 在 writable 返回 false 后继续写;背压不完整 | `src/client.js` / `handlers/chat.js`(12–24h,草案在 `.agent/audit-20260922/evidence/repairs/protocol/interrupted-c2/`) | | AAD/KDF(GPT-06) | 凭证记录未与其身份绑定(无 `setAAD`,`SCRYPT_PARAMS` 未变) | `src/devin-connect-credentials.js:44` | | G-2 | SSE registry 无准入上限(源事实,未证 OOM) | `src/sse-registry.js` | | G-4 | trace 的 `redact()` 只按 key 名,值形态的密钥不遮 | `src/trace.js` | | G-5 | wire dump 明文 token,无上限无 TTL | `src/devin-connect.js:150-180` | | LEGACY-STUB | 旧工作区不再自动重贴标(已披露的取舍) | `src/client.js` | - **四个现成仪器,只差一个活账号**(全部已合入、零代码改动): 1. `WINDSURFAPI_LEAK_TRACE=1` 一次真会话 → 关 #250(PR #249 合于 2026-08-10,**从未开过**,树里没有任何 捕获件——`test/mutations/leak-trace.json` 是突变 spec,不是捕获)。 2. `DEVIN_CONNECT_DEBUG_META=1` 抓付费终帧顶层 `#22` + 同时段官方 `billed_acus` → 关 #239/#256。 3. `CALIBRATE_REAL=1 CONNECT_SMOKE_TOKEN= npm run calibrate:devin` → 校准 `FREE_REACHABLE_SELECTORS`(口径停在 2026-07-27;失败方向是**过度拦截**,不是安全)。 4. `node scripts/cascade-survival-probe.mjs` → Cascade 后端还答不答(默认零计费,从未跑过)。 --- ## 4. 已定论 —— **不要重新推导**(省下的是这个仓库最贵的东西) - **Cascade 从来不是云服务**:`StartCascade` 及同族 RPC 在 api_server_url 上全部 404;本地 `language_server_linux_x64` 是挡在 `inference.codeium.com` 前的强制本地代理。Cognition 2026-06-02 宣布 Devin Local 取代它、桌面端 2026-09-08 移除(v3.9.19)。后端是「被掏空」不是「死了」:未迁移的 族仍服务,已迁移的**按名字**回 `403 This model is only in Devin Local`(`gpt-5.6*` / `swe-2*`)。 - **Cascade wire 层 20/20 字段正确**(对官方 language server 逐字节提取的 55 个 blob 重切后 = **126 个切片 / 57 个不同 sha256 / 56 个不同 proto 名** `FileDescriptorProto`:`Metadata` 11/11、 `StartCascadeRequest` 3/3、`SendUserCascadeMessageRequest` 6/6)。**不要再审字段号。** (**2026-10-15 第二次更正**:原写「55 份」是 blob 数;第一次更正把它改成「55 blob → 132 切片 → sha256 去重 = 62 个描述符」,那是**旧切片规则**的产物——按 protobuf 顶层自定界重切,132 里有 6 片是 垃圾(旧规则的延长步切进了提示词文本),62 里有 **5 个根本不是描述符**;proto 名数两版都是 56,变的 是切片数与 sha256 数。**基线本身还不完整**:依赖闭包显示 2 个悬空依赖(`auto_cascade_common`、 `reactive_component`)在 ELF 里存在却从未被切出 → **57 是下界**,不是 ELF LS 的完整描述符集。 目标侧(桌面 payload 内的 LS 候选,Go 1.26.6)67 切片 / 66 个 proto 名,对账 **same 40 / changed 15 / new 11 / missing 1**(每行带双侧偏移)。依据:board `LSREFRESH`, `derived/L4b-DIFF-LS.md` §2.2/§2.3/§3;第一次更正的依据(station `notes/re-methods-20261015.md` §5.2, 旧规则)已被本轮重切取代。) - **`devin acp --model X` 真的换底层模型**:由**服务端**解析,但**分两条路**(2026-10-15 第二次更正: 原写「由服务端 `AssignModel` 解析」是**归因过宽**)——router 名(`adaptive` / `arena-*` 一类)走 `AssignModel`(日志逐字 `Resolving model router '' via AssignModel RPC`、方法路径 `/exa.api_server_pb.ApiServerService/AssignModel`);普通 fuzzy 名(family slug / alias / 部分名)走 **服务端目录** `GetCliModelConfigs`——二进制里**没有**本地 name→uid 表。旧结论逐字引用的 10 条串在新版 CLI(3000.11.92)**100% 存活**(含 `ModelAssignment{model_uid, assignment_jwt, harness_uids}` 簇); 新增运行时串 `` `devin acp --model` value did not resolve … ``(`0x80051f0`)证明「解析失败 → 回退」 是真实代码路径,不是提示词。**最后一跳静态不可证**:下游推理请求实际带哪个模型,要一次 live ACP 会话。模型选择这半的迁移仍是**改路由,不是造能力**。但**工具层仍是缺口**:`special-agent` 对任何带 `tools[]` 的请求硬 400。→ `src/backend-router.js` 的同一处归因已按本条改正。 依据:board `ACPMAP`,`derived/acpmap/L-ASSIGNMODEL.md` §5.10/§6。 - **四个计费坐标不是 bug**:维护者在 #256 两次书面拒绝默认开启,v3.9.24 以 opt-in 交付; `devin-connect.js` 里的 `UNCALIBRATED` 标记是活的拒绝,不是陈年注记。 - **`ide_name` / `ide_type` 是不透明运行时字符串**,二进制里没有值表(`WINDSURF_IDE_TYPE` 枚举是死数据)。 只有抓包能定。 - **`--test-force-exit` 已于 2026-09-13(`939872b`)全面移除**:它会在跑完部分 suite 后静默以 0 退出, 自洽 TAP。**2026-09-13 之前的任何绿色结果都要重推**,不要引用。 - **`pr-gate.mjs` 的 0 测试误判已修**(见 §1.4);**死锚会被别人的合并杀死**——突变 anchor 只证明 「这一刀能被测出来」,别人改同一函数可能让它静默失效,而 spec-static/baseline 两道都不执行突变。 **唯一探测器是全量 sweep(在合并后的树上跑)**,见 `docs/AUDIT-LEDGER.md` 与 `extra-hands/RESEARCH/agent-archaeology-2026-10-05.md` §17。 - **#272 对门禁隐形是设计使然**:丢图发生在编码前,wire 字节相同,`wire-byte-identity` 照样绿—— 「既有缺陷能通过字节相等」。那条门证明的是「默认路径没动」,不是「wire 正确」。 --- ## 5. 本机独有资产(**不在 git 里**,克隆拿不到) | 位置 | 是什么 | 怎么用 | |---|---|---| | `.agent/HANDOFF.md` | **活板**(本份是它的公开版) | 每次接手先读它;它是「下一步(一件)」的唯一权威 | | `.agent/audit-20260922/` | 140 行审计登记册 + 全部证据(ROADMAP / findings.tsv / 修复证据) | 找「这条到底证过没有」 | | `.agent/gpt-*` / `.agent/reviews/` | 三轮外部(Web-GPT / Codex)评审与最终验证 | PR/发布的判决记录 | | `.claude/scripts/pr-gate.mjs` | 机械 PR 门(隔离 worktree + 定向突变) | `node .claude/scripts/pr-gate.mjs --pr ` | | `.claude/scripts/triage.mjs` | 待办与风险的机器视图 | `node .claude/scripts/triage.mjs` | | `.claude/skills/` | pr-gate / issue-reply / release / code-review / diagnose / grill / research 技能 | 动 PR 前先读对应技能 | | `.claude/CONTEXT.md` | 给 subagent 的项目背景 | 派活时带上 | | `extra-hands/RESEARCH/windsurfapi-*.md` | 2026-09-30→10-01 审计会话 + 验证台账(proven / parked / unknown)+ 3MB PR/issue 语料 | 查「当时怎么定的」 | | `extra-hands/RESEARCH/agent-archaeology-2026-10-05/` | 机队考古 + 语料(2570 文件 / 57 MiB,含 sha256 清单) | 查更早的会话证据 | | `extra-hands/RESEARCH/windsurfapi-corpus/` | **GitHub 语料库**:89 PR / 183 issue 全量(正文/评论/review/行内评论/提交/文件清单/时间线;快照 `2026-10-15T07:51:38Z`) | 离线查 `python query.py --stats`(示例与 schema 见其 `INDEX.md`;`fetch.py` 重建,gh 只读 ~2 分钟)——方法向说明见 `docs/GITHUB-CORPUS.md` | | `extra-hands/RESEARCH/windsurfapi-archaeology-20261015/` | 本轮考古产物:`pr/`(决策台账、被拒设计、贡献者矩阵、89 行分类表)+ `issues/`(183 条逐条分类、远古史、feature backlog、未决线程) | 入口 `pr/INDEX.md` 与 `issues/ISSUE-TAXONOMY.md`;引用必带编号 + 日期;「零 review」类口径先看 `pr/PR-TAXONOMY.md` §7 | --- ## 6. 查漏补缺登记表(2026-10-15 逐条对 `05868a3` 核对) ### 6.1 文档里的烂数字 / 死指针(2026-10-15 两批已修;2026-10-16 按 `d3f0490` 复核过一次) 第一批随本份提交(`d9e17df`): | 声称 | 位置 | 真值 | |---|---|---| | Claude 36 个 / GPT 65 个 | `README.md` / `README.en.md` | **73 / 118 / 22**(`src/models.js` 实测 @d3f0490:anthropic 73、openai 118、google 22;共 295 key。本行在 `d9e17df` 时点是 58 / 83 / 9、193 key —— `d3f0490` 按公开成本表加了 102 个基础 selector,README 两语已同步) | | 「十六轮追加」 | `AUDIT-LEDGER.md`、`docs/README.md`、`CHANGELOG.md` | **十七轮**(第十七轮起于 2026-09-17,`AUDIT-LEDGER.md:1730`) | | 突变 spec「25 / 44 / 82 份」 | `docs/README.md`、`.github/workflows/ci.yml` | **85 份 / 767 条**(2026-10-16 实测 @d3f0490;766 是 `d9e17df` 树的值,FIX-CLOUD-2 的 spec 2→3 随 `21870ae` 合入) | | 「image-resize 测试 import jimp(唯一运行时依赖)」 | `ci.yml:195-197` | 仓库零依赖;该测试 import `src/vendor/jpeg-js` + `src/vendor/png.js` | | 「裸 `env.FOO` 漏 70 个」 | `ENV-SWITCHES.md` 头部、`docs/README.md:47` | **漏 45 个**(2026-10-16 同口径重测 @d3f0490:脚本 157、裸 grep 112;`ab4e66f` 时点为 158/113 —— 差值仍是 45) | | `/v1/responses`(`responses.js:1415`)/ `/v1/messages`(`messages.js:1645`)/ 逐回合链(`messages.js:729-741`) | `REQUEST-TAIL-CONTRACT.md:49,57` | 现为 **1436 / 1657 / 741-753**(`messages.js` 两处可精确归因 `a2d8d07`;`responses.js` 由后续多个合并推到 1436) | | 「当前数字见最新交接文档的门禁表」 | `CONTRIBUTING.md:81`(en `:222`) | 该表**不存在**——现在指向本份 §6.2 | | 「1387 次提交、196 个版本…」 | `README.md:28` | 那是历史账本自己的冻结口径(跟到 v3.9.34);已加限定语 | | 星标数 3,046 | `README.md:18` | 3,087(该行在 banner 自动生成块内,等机器人刷新即可,**不要手改**)。2026-10-16 复核:块内仍是 3,046、`star-history.svg` 仍是 3,087 —— `star-history.yml` 只重画 svg,**banner 块只有手动 `gh workflow run banner.yml --ref master` 才会重渲染**(本车道未跑:它会往 master 推一个 bot commit,而本次文档修复有未提交的 README 改动 —— 两处会撞在集成步骤上;交给一次专门的刷新动作做) | | `RELEASE_NOTES_v3.9.22.md` 的 v 前缀 | `docs/releases/README.md` | 现行 release.yml 只查无前缀名(`:329-330`),带 v 会被静默忽略并退回自动生成——已在文中点明 | 第二批(2026-10-15 文档漂移车道,行号/计数均按当日树复核): | 声称 | 位置 | 真值 | |---|---|---| | cold stall「长输入最多给 90s」 | `README.md:642` / `README.en.md:542` | 90s 固定上限在 `b7937b0`(2026-04-20)当天就被 `maxWait` 取代;现为 30s 基数 + 5s/1500 字符,封顶 `CASCADE_MAX_WAIT_MS`(默认 600s) | | 「7 条正式 review」(zh 附带「87 个 PR」、en 写「84 PRs」——两个不同快照) | `CONTRIBUTING.md:108` / `:377` | **9 条 / 8 个 PR**(截至 2026-10-15;差额 = #276 于 2026-10-05 追加 2 条 CHANGES_REQUESTED;正文已改指本份 §2.1) | | 「git tag 201 个(截至 2026-10-05)」 | `CHANGELOG.md:23` | **202 个**(v3.9.40 的 tag 落于 2026-10-07,旧行漏了它) | | 凭证落盘 `src/auth.js:514-515` | `DEVIN-CONNECT-CUTOVER.md:71` | 现 **1495-1500**(写入时确为 514-515,函数体被后续合并推后) | | 引文里的 `chat.js:3313`(#261「走倒车」实测坐标) | `CONTRIBUTING.md:112` / `:381` | 现 **`chat.js:3384-3386`**(`74f319e` 把该调用点又推了 4 行 —— DOC-DRIFT 车道当天修到 3380-3382,随后再漂;引文按本文规则逐字保留,坐标以括注补在引文外) | | 贡献者计数「27 位贡献者、53 条记录」 | `README.md:709` / `README.en.md:609` | **36 / 68**(从 `src/dashboard/data/contributors.json` 现算:36 unique logins / 68 entries;口径用写下旧数的 `12eaac7` 反证;P0-FIX 回填 5 条落于 `74f319e`) | ### 6.2 门禁表(本文件是它的落点) | 口径 | 数字 | 出处 | |---|---|---| | 突变语料 | **85 份 spec / 767 条突变** | 2026-10-16 实测 @`72dc2f8`(当前 HEAD;@d3f0490 同值):`ls test/mutations/*.json \| wc -l` + 逐 spec 求和(766 是 `d9e17df` 树的值) | | Windows 本机 `npm run test:release` | 见下方「本机实测」 | 2026-10-15,node v24.19.0 | | Linux CI(权威口径) | 最新 `38771008817`(headSha `72dc2f8`):**success**,jobs 全 success(Node syntax check / Unit tests shard 0-3 / Default-path request bytes / Mutation spec consistency;手工突变 job 按设计 skip)。上一条 `38767160836`(`d3f0490`)同为全 success;此前 `38740837201` = `9031b9b`、`38729536414` = `ab4e66f`。分片计数看该 run 各 shard 摘要 | `gh run view 38771008817` | | wire 门 | v3.9.40 发布时对 `v3.9.39`(严格祖先)270/270 | release run `37569886191` | | Windows 本机 skip | **81**(2026-10-15 实测:POSIX git 夹具 + live 套件未 armed),需 `GATE_INERT_SKIP_PATHS` 声明 **4 条** | `CONTRIBUTING.md` 的对应小节 + 本机 run | **本机实测(2026-10-15,Windows / node v24.19.0,`npm run test:release`,树 = `d9e17df`)**: `TEST_SHARD_SUMMARY {"files":396,"measuredFiles":396,"tests":4952,"pass":4871,"fail":0,"skipped":81,"cancelled":0,"todo":0}` —— **4871 pass / 0 fail / 81 skip,396/396 文件全部实测**(跑完操作员 `runtime-config.json` 未被改动: 走 `setup-env.mjs` 的 DATA_DIR 重定向)。 > **2026-10-16 复核**:测试文件在 `d3f0490` 是 **402**、在 `72dc2f8`(当前 HEAD)是 **404** > (`git ls-tree -r HEAD test --name-only | grep '\.test\.js$' | grep -v _research | wc -l`)—— > 上面那行 JSON 是 `d9e17df` 树的实测,`tests` / `pass` / `skipped` 三个数 > 都还是那时的值(自那以后测试文件从 396 涨到 404)。**下次整跑 `npm run test:release` 时把整块刷新**; > 在那之前不要把 396 当现值。 ### 6.3 仍然开着的(按来源归档;全部对 `05868a3` 复核过) | 项 | 状态 | 证据 | 下一步 | |---|---|---|---| | 20 个「无证据关闭」的 issue 未复核 | 开 | `audit-corrections/CORRECTIONS.md` 列为 open;`HISTORY-COVERAGE.tsv` 里 0 个 NOT_PLANNED | 把 state_reason 拉进台账,逐条 symptom→commit→回归核对 | | `src/windsurf.js`(64,866 B)全量审计、`src/client.js`(74,787 B)从未完整读过 | 开 | corrections 自述「unchanged boundaries … UNVERIFIED」 | 立一个具名审计切片 | | Node 20/22/24 矩阵 + 强化的 macOS 打包烟测 | 部分 | Node22 只跑过 11 条选定测试;macOS 强化烟测未跑 | 跑完或如实标 UNVERIFIED | | Windows 上的 Unix-git 夹具 + Linux 动态突变 sweep | 开(机器门) | 本机门每次 81 skip;`mutate-verify` 需 POSIX git | 去 Linux CI/bench 跑 | | `write-baseline.mjs` 重跑 / `BASELINE.md` 再生 | 开(小) | 被撤回的 wire 声明目前是 UNVERIFIED 注记 | 单独决定 | | `spec-baseline-evidence.mjs` 的跳过白名单按 `(file, leaf-name)` 键控、无嵌套路径(M1) | 潜伏 | `scripts/spec-baseline-evidence.mjs:26,66-71`;当前无重名 leaf | 键里加嵌套路径 | | `secret-scan` 内部链接遍历是整树、无目录级 ignore(M2) | 开(性能) | 已披露边界 | 目录级 ignore | | UI-PLAN(CUT18 目录恢复、SCALE003 动画清理等) | 仅提案 | `.agent/audit-20260922/UI-PLAN.md` | Owner 定范围 | | 42 个本地分支:4 个未并入 + 38 个已并入 | 已判(**证据已修正**) | 3 支(`campaign/s4`、`test/gpt-closeout-check-20260923`、`fix/gpt-final-verification-20260923`)的每个 commit 都有 patch-id 等价物在 master(`git cherry` 全 `-`)。第 4 支 `diag/guard5-count-divergence` **不是**:`git cherry` 5 个 `+`,含 master 里没有的 `scripts/diag-guard5-count.mjs`(388 行)——它是一次性手动诊断工具,根因在它最后一笔的 3 分钟后由 `939872b` 修掉,完整存档在 `origin/diag/guard5-count-divergence`。删本地分支只丢本地副本 | `git branch -D` × 4 + 批量清 38 个;命令在 `.agent/HANDOFF.SUPERSEDED-bf1fe83.md:56`(2026-10-16 复核:`.agent/HANDOFF.md` 里已没有这段;`git branch --no-merged master \| wc -l` 仍是 4) | | **裸 `node --test` 会改写操作员 `runtime-config.json`**(抹掉 pin;真部署上会抹掉 `credentials.apiKey` / `dashboardPasswordHash`) | **已验证** | `test/breaker-tunable-hotswap.test.js` 裸跑:`quota.spendOnDemand: false → null`、`breaker.errorStreakThreshold: null → 2`;走 `setup-env.mjs` 的 runner 路径不受影响(DATA_DIR→临时目录)。`persist()` 写整个 `_state` | 二选一:给 `persist()` 加测试模式短路(由 `_resetRuntimeConfigForTests` 置位),或让套件改用 `_resetRuntimeConfigForTests({breaker:{…}})` 代替会落盘的 setter | | breaker 套件的候选隔离修复(`beforeEach(_resetRuntimeConfigForTests())`) | **实测后不采纳** | 裸跑 49/49 变绿,但把 reset 后的默认状态经 setter 落盘 → 从「裸跑 6 红」变成「裸跑抹操作员配置」。对照见 `.agent/gap-20261015/` | 与上一行同一根因,一起修 | --- ## 7. 反省:这个仓库反复出现的失败形状 1. **数字写在不是它权威来源的地方就会烂**(仓库自己写的规矩)。上面 6.1 表就是它最新的 收据:spec 数在三个文件里各写一个值,轮数在三个文件里停在上上轮。**数字只写在能重测它的地方**, 其它地方链接过去。 2. **板子快照会伪装成现状**。活板(`.agent/`)不是 git 的一部分,且它的「快照」段隔一天就成了错的 (「落后 4 个提交、3 项脏」→ 实际 7 个、1 项)。**每条状态必须带日期与它测的是哪个 SHA**, 接手时先重测再引用。 3. **门禁看不见的东西比看得见的多**:套件不跑突变 spec;突变 anchor 会被别人的合并杀死;丢图能通过 wire 字节相等;PR 的 CI 可以一次都没跑(`action_required`)而 GitHub 只显示一个灰色圆点。 **「绿」的含义永远要问一句:哪个门、在哪棵树上、测了什么。** 4. **本地证据(200MB+)不在 git 里**——一次误删就没有了。重要的结论必须同时落进 `docs/`。 5. **首次贡献者的 PR 卡在 CI 批准上**:#279/#280 自 10-08 起零 review 零 CI。维护者侧的第一动作是 **批准 workflow 运行**,否则后面所有「对着证据评」都无从谈起。 --- ## 8. 下一步(一件一件来) 1. **批准 #279 / #280 的 CI 运行**(`gh run` 两个 run id 见 §2.1),然后按 §2.1 的「改 2 处」回帖。 2. #274 / #276:作者分别静默 9 天 / 13 天(后者自 10-02 最后推送起算;自 10-05 评审起算是 10 天)。按 CONTRIBUTING:146 的取代规则,可关并自收测试(#274 的两条测试值得留,守卫 2 要按真实 handler 重写);等还是收,Owner 一句话。 3. #262:**留作设计注记**(维护者 2026-10-05 改口,见 §2.2;要推进就交一个真实失败样本);#208: 可关(公告已被 release notes 取代)。 4. 四个 live 仪器(§3)——有账号就能一次关掉 #250 / #239 两个最老的洞。 5. 分支清理(§6.3 末行)与远端过期 ref 清理(`origin/fix/gate-skip-blindspot`、`origin/fix/mut-spec-frame-assembly` 的本地领先已在 master 内)。 6. **模型目录**(board `MODELDELTA`):CLI 二进制里有一份**静态模型目录**(5 张表 → 557 个不同 id,另有 334 个 `MODEL_*` 枚举名),但**提案是 `src/models.js` 一条都不先加** —— 名字有,`enumValue` / `modelUid` / `credit` 这三个**服务端事实**二进制里没有(硬填等于把请求路由到错模型)。483 条候选分 三级:227 条可直接进 Devin 冷启动快照 `src/data/devin-catalog-snapshot.json`、169 条路由修饰族 + 87 条非纯 id **需服务端确认**;41 对是**别名**(28 分隔符 + 13 token 重排),不是新模型。 **本仓库不贴模型名清单是刻意的**(厂商数据边界)。见 `derived/modeldelta/K-PROPOSAL.md` §1/§5。 **2026-10-16 更新(`d3f0490`)**:上面那条「一条都不先加」的提案**已被一次按公开来源的批量落盘越过** —— 与 `docs.devin.ai` 的公开成本表(572 行,快照 + 逐行出处留在 `.agent/`)对账后:**44 行 credit 改正 + 102 行新增**(只加 base selector,dash 形式,provider 取自家族 token,**`enumValue 0`** —— 路由值不公开), `src/models.js` 因此从 1299 行长到 **1437 行**、目录 key 从 **193** 到 **295**;冷启动快照 `src/data/devin-catalog-snapshot.json` 的 `_count` 从 **123 → 225**。这是**另一条来源**(公开成本表, 不是 CLI 二进制),与 K-PROPOSAL 要求的 `enumValue` / `modelUid` / `credit` 三件服务端事实不冲突: 新增行的 credit 有公开出处,enumValue 留 0。另有 45 个修饰形式(-fast/-priority)、2 条 tier 待定、 8 条延后项**押后等一次 live 目录拉取**。README 两语的 provider 计数已随之更新(58/83/9 → 73/118/22)。