Repository navigation
[PR] Boot contract stubbing: four-lane verifyAttachAndRecover behavior matrix + latch permanence + health glossary (#5241 Pha | 启动契约打桩:四车道 verifyAttachAndRecover 行为矩阵 + 闩锁永久性 + health 词汇表(#5241 阶段 0,只加测试) - #5242
Conversation
…#5241 phase 0) Phase-0 characterization stakes for umbrella #5241 — tests only, zero product changes. They freeze TODAY's behavior (including the inconsistencies) so the phase-1 lifecycle extraction has an explicit equivalence net: - contract-v2-stake-verify-attach: the four verifyAttachAndRecover copies (pi/omp/opencode/dsh) answer a common scenario matrix (healthy equal-version / strictly-older / dead target). Pins the S2 divergence: pi/omp/opencode attach an older resident untouched, dsh rotates+respawns (already pinned by issue3544 suite). Each lane runs in its own child process (contract-v2-stake-lane-probe.mts) — the four lanes share the host process's global fetch/env/module state and pollute each other when driven in-process, which is itself part of the characterization. - contract-v2-stake-latches: the two one-way latches. shadow stats.disabled has NO in-process recovery (healthy records after the latch are permanent no-ops — the C3 target); logger stderrDead flips once, warns once, and never touches stderr again (driven in a child process because the latch owns the whole process lifetime). - contract-v2-stake-health: /__bili/health answers exactly 503 {ok,reason:"starting"} pre-boot and an 11-field snapshot post-boot — no lifecycle/degradation vocabulary exists yet (the C1 gap, pinned so adding fields is a visible, deliberate change).
📦 Built Package ArtifactBranch: Latest build — install this exact versionnpm install -g billion-context@0.0.9202-pr.5242.5f1e2fcThis exact version is immutable and reproducible. The rolling Recent builds (commit → version)
Download artifact
tar xzf billion-context-pr5242.tgz
npm install -g packageInstall instructions are refreshed on each push. |
contract-v2-stake-latches.test.ts and contract-v2-stake-verify-attach.test.ts both spawn child processes but were never added to scripts/live-files.mjs, so run-ci-tests.mjs's SPAWN_RE tripwire (#1248) dies the test lane with "process-spawning test files missing from LIVE_FILES". Appended both entries (append-only: slot=index drives each file's zone port band, so mid-list inserts would renumber later bands). Neither suite binds a shared port — the mock bili servers are listen(0) and the spawns are stubbed — so no real zone band is needed; the entries exist for the tripwire alone, like #3890's.
…+ persist flush-waiter ref + win32 shadow db-path + issue4739 closeQuietly + inc-canonical afterNextFlush
…242-conflict # Conflicts: # scripts/live-files.mjs
… (CI fix for #5242) The phase-0 stake pinned the 3-strike self-disable latch that owner policy b9eb27a (2026-10-30, "never give up on index writes") removed from src/storage/shadow.ts hours before this branch forked from its base — the stale expectation red every CI shard after rebase onto master. Rewritten to pin the landed contract on the same fault seam: structural strikes never disable (stats.disabled stays false), one warn per distinct message (#5140 dedup), lastError carries the latest failure, healthy records resume ingesting once the fault clears, full-mode reads stay unified-first, and fork publication does not fail closed. Fixture now opens in FULL mode so readsUnified is a live gate (shadow mode made it structurally false). Tests-only; no product code touched.
[bot] (ai: vllm-qwen/qwen3.8-27b) PR #5242 的两个 blocker(与 base 分支冲突 + CI 三片红)本轮已全部处理完,head 做了什么
七问
判定:两个 blocker 均已解除,CI 全绿(head ac991de,live 验证),PR 处于可人工评审/合并状态;剩余 |
ranxianglei
left a comment
There was a problem hiding this comment.
(ai: opencode/qwen3.8-27b)
APPROVE — test-only PR(#5241 阶段 0 特征化打桩),零产品代码、不涉 kernel/、不动配置面。独立审核结论如下(非复读 issue 侧结论)。
独立验证
① 原 issue 方向:#5241 阶段 0 流程规则 = 先用特征化测试钉「现在怎样」(含不一致),老 vs 新对比经 owner 批准后才动实现。本 PR 严格照此执行,三个桩钉的都是 master 现状而非「应该怎样」。我逐条对照生产代码复核(不是只读 diff):
- 四车道矩阵:pi-native.ts:188 / omp-native.ts:294 / opencode-native.ts:335 / dsh-native.ts:775 四份
verifyAttachAndRecover拷贝各自经armNative*+singleFlight 挂到state.respawn,生产唯一入口;S1/S3 断言与代码路径吻合(健康 → 原地 attach,spawn/shutdown 均 0;死 target → spawnFallback 恰一次,env 重发布 / dsh 解 preset + 改 register)。S2「无轮换只有 dsh」成立:pi/omp/opencode 三份拷贝版本抓取成功后无条件 attach(无版本比较),仅 dsh 有isVersionNewer→rotatePinnedStaleProxy(dsh-native.ts:799-818);dsh 的 S2 分歧已有专项桩 tests/issue3544-stale-proxy-rotation.test.ts:392,此处正确地不重跑、只记录分歧事实并留给阶段 1 裁决——没有静默抹平。 - health 词汇表:src/server/admin.ts:306 boot 前恰 503
{ok:false,reason:"starting"}两键;:314 boot 后恰 11 字段快照——与桩的键集断言逐一吻合;absence 循环(lifecycle/state/mode/degraded/reason 等)正是 C1 要补的 gap,有意钉死。 - 闩锁:logger.ts 的
markStderrDead幂等、warn 恰一条、同步抛错与流 error 事件双路径都翻闩(log()先 capture 后写 stderr,capture sink 不受闩影响)——子进程桩的断言机制上全部成立;shadow.ts:245 "Nothing is ever disabled; the next save retries the write",stats.disabled恒 false、故障消失后 record() 能恢复——桩钉的是 b9eb27a 政策落地后的现状(C3 的对照基线),方向正确。
② 回归审查:diff 触碰路径 = scripts/live-files.mjs(+2 行注册)+ 4 个新测试文件。既有行为清单:产品代码零改动,不存在被触碰的既有行为。live-files.mjs 的改动是 CI tripwire 的强制要求(scripts/run-ci-tests.mjs:145-153:凡 SPAWN_RE 匹配的文件必须登记否则 CI 红),两个 spawn 子进程的新套件均已登记 ✓。无语义漂移、无 fail-fast 变吞错、无阈值/时序/输出格式变化。结论:无回归。
③④ 代码与测试有效性:hermetic 充分(mkdtemp + BILI_CONFIG_FILE 隔离、listen(0) 随机端口、NODE_TEST_CONTEXT 解除 MCP-entry 自启动守卫——claude-mcp-entry.ts:127 / zcode/mcp-entry.ts:201 有对应 if (process.env.NODE_TEST_CONTEXT !== undefined) return;,probe 的设置有据)。每车道独立子进程驱动避免共享 fetch/env/模块状态互污(PR 正文给出实测现象;生产现实也是每车道一个宿主进程),probe 末尾 PROBE 行打印后 force-exit(车道模块留后台定时器)合理。断言有牙:精确键集、精确计数(spawns==1 / shutdowns==0)、值级 deepEqual、warn 去重计数 ==1、isStreamWriteError 真值表逐格——行为任一漂移桩必红,非恒真测试。
证据:head ac991de 镜像缓存全绿(30 checks,0 failed / 0 pending,gated 车道按惯例 skip);本地定向复跑 8/8 绿(需先 build kernel dist);tsc --noEmit 干净;分支 base = 当前 master tip(c26c31a),不陈旧。PR 正文列的相邻回归(issue3544/issue5140/pi-native/opencode-native)由作者跑过,CI 全绿再覆盖一遍。
已顺手修
- 删未使用 import:tests/contract-v2-stake-health.test.ts:15
before、tests/contract-v2-stake-verify-attach.test.ts:27-29 fs/os/path + commit d18e0f5(修后本地套件复跑绿 + typecheck 干净) - PR 描述 stale 表述:stake-2 的 shadow 半段还是 CI-fix commit f922f13 之前的旧措辞(称「3 次结构性失败闩死后进程内不存在任何恢复路径……永久 no-op」),与最终代码相反(最终桩钉的是 landed never-give-up 行为:永不自我禁用、故障消失后可恢复)→ 已 PATCH PR 正文对应段对齐最终桩语义(API PATCH,无 commit)
CI 会为新 head d18e0f5 重跑一轮(仅删 import,零行为变化;旧 head 已全绿)。合并动作归人类。
八问
- 是什么问题:非缺陷修复——#5241 宿主契约 v2 治理的阶段 0:用特征化测试先钉住四车道 attach/recover 行为、两把闩锁现状、health 应答词汇表,为后续统一重构提供等价性验收网。
- 什么原因导致的:N/A(非 bug)。根因动机:四车道各有一份 verifyAttachAndRecover 拷贝且行为分歧(仅 dsh 轮换严格旧版本 target)、health 无法表达降级状态——不先钉「现在怎样」,阶段 1 统一重构就没有验收基准。
- 影响范围与严重程度:对产品行为零影响(test-only)。作用面 = 未来回归检测能力;若桩缺失,阶段 1 重构无等价性网(内部风险,无外部用户影响)。
- 怎么修复的:三个独立套件;每车道独立子进程驱动避免全局状态污染;精确键集/精确计数强断言;不一致被有意钉死(S2 跨车道分歧作为事实记录、留阶段 1 显式裁决,不抹平)。
- 是否有回归问题:无。产品代码零改动;唯一非测试文件 live-files.mjs 加两条登记(CI tripwire 强制要求)。无语义漂移、无吞错、无阈值/时序/输出格式变化。
- 是否破坏缓存:不涉及(未触碰缓存/重试/游标/去重逻辑)。
- 是否改了设计方向:无转向;这正是 #5241 声明的方向基础(阶段 0 打桩 → 阶段 1 统一),未来改行为必须显式改桩,构成可见变更账本。
- 是否引入了新的配置:无。BILI_ATTACH_EVIDENCE_GRACE_MS / BILI_ATTACH_HEALTH_DEADLINE_MS 是既有 knob(native-intercept.ts:1196 等),仅在 probe 子进程内收紧用于计时控制。
判定:可合并(APPROVE;新 head d18e0f5 的 CI 重跑预期绿,合并动作归人类)。
[bot] 🏷 PR #5242 审核完成:APPROVE / 可合并(test-only,零产品代码、不涉 kernel/)。GitHub review 已提交(review id 5866229151)。 独立验证(非复读 issue 结论)
已顺手修(2 处,均已落 PR 分支)
说明:GitHub API 不允许作者账号对自己 PR 提交 APPROVE review(422),按舰队惯例以 COMMENT review 提交、正文首行明确 APPROVE/可合并判定(同 #5681 模式);若分支保护要求正式 approve,owner 合并时点一下即可。新 head d18e0f5 的 CI 会重跑一轮(仅删 import,零行为变化)。 协调一行:#5241 阶段 0 打桩 PR #5242 审核完毕——APPROVE,2 处机械性小修已进 PR 分支(d18e0f5),CI 重跑中,待人类合并。 |
…phase 1, PR-1a) First lane migration of the approved phase-1 plan (#5241 comment): the verifyAttachAndRecover lifecycle moves from pi-native.ts into a shared native-attach.ts, parameterized by a per-lane NativeLaneSpec (publish / unpublish / onEvent / spawn seam / bootstrap). Pure transposition — the pi lane's observable behavior is unchanged, proven by the phase-0 stake matrix (tests/contract-v2-stake-verify-attach.test.ts) passing untouched. Also lands the one-lane-per-process guard (armNativeLane): the four lane implementations all assume they are alone in the process (same BILLION_CONTEXT_PROXY env var, same global fetch-intercept slot, background timers that outlive any call). Phase-0 probing (#5242) showed two armed lanes in one process overwrite each other within milliseconds. Production never does this — the guard makes the implicit contract explicit and plainly worded. Re-arming the same lane stays legal (tests/restarts); a second, different lane throws. omp/opencode/dsh keep their own copies until their migration PRs; their suites and issue3544 stay green untouched. Net: pi-native.ts -77 lines, one spec + one-line wrapper in their place.
(ai: zai/glm-5.3)
Refs #5241(阶段 0,不 Closes——umbrella 走完全部阶段才关)
这个 PR 做什么:给 #5241 综合治理的第一阶段(打桩)交第一批特征化测试。只新增测试文件,零产品代码改动。钉的是「现在怎样」——包括不一致——让后续抽取共享生命周期时有明确的等价性验收网,改行为时必须显式改桩。
三个桩(8 个测试,全绿):
四车道 verifyAttachAndRecover 矩阵(contract-v2-stake-verify-attach)
两把一次性闩锁的永久性(contract-v2-stake-latches)
stderrDead:一次失败永久跳过 stderr 腿,warn 恰一条(两条触发路径幂等),日志本身不沉默。闩无导出无 reset 且独占整个进程,所以用子进程驱动。/__bili/health 词汇表(contract-v2-stake-health)
{ok:false, reason:"starting"}两键;boot 后恰 11 字段快照(键集逐一断言)。今天没有 degraded/lifecycle 词汇——sidecar 闩死、stderr 闩死、车道降级直发在 health 里一个字都不说,C1 要补的就是这个;先钉死,阶段 1 加字段就是显式可见的变更。验证:三个套件本地全绿(重复跑稳定);tsc --noEmit 干净;相邻回归 issue3544(20)/issue5140(5)/pi-native(19)/opencode-native(65)全绿(opencode 套件须在无 BILLION_CONTEXT_NATIVE 的干净 env 下跑——本机 shell 被 bili pi 钩子标记时会误报,CI 不受影响)。
下一步(等 owner 点头):把四份 verifyAttachAndRecover 的「老方案 vs 新方案对比」写进 #5241 讨论,批准后再动阶段 1。