You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
storage-render golden suite is not hermetic: locally regenerated digests cannot be reproduced on CI runners #5402
The only difference is one environment variable at regen time.
Why
tests/preload-test-env.mjs:53 pins it unconditionally:
process.env.BILI_MESSAGE_TIMESTAMPS="0";
and scripts/run-ci-tests.mjs:185's PRELOAD_ARGS loads that preload into every per-file child process. So the suite always hashes with message timestamps off.
scripts/update-storage-render-goldens.ts already documents two parity pins for exactly this class of bug:
// Parity with tests/golden-storage-render.test.ts (#3400): ...process.env.BILI_IMAGE_RESCALE="0";// Parity #2: the test suite also disarms the shadow observability lane (#3756) ...process.env.BILI_SNAPSHOT_SHADOW="0";
There is no Parity #3 for BILI_MESSAGE_TIMESTAMPS. A bare node --import tsx has no preload, so the timestamp flag resolves through the production default (ON), and every nudge / tsStamps digest is computed against a different render mode than the test hashes. The regenerated golden is stale by construction — exactly your symptom.
This also explains why the divergence lands precisely on those keys rather than on blockContents / blocks, which do not depend on the timestamp flag.
Consequence: master itself is red from this right now
#5415 (c91ef1a81, "kernel: abort-heavy sessions stop starving the nudge cadence") added nudge.absorbedDebt? / nudge.absorbCount? to kernel/src/types.ts (+14) and booked them in src/session.ts (+17), but did not regenerate the goldens — its 9-file diff contains no tests/golden/ file.
tree
golden-storage-render.test.ts
tests/storage-engine-proofs.test.ts
7578e8184 (#5415's direct parent)
5 / 0
12 / 0
c78ecb4b5 (master tip, after #5415)
1 / 4
8 / 4
CI on master c78ecb4b5 fails 4 of 11 test shards on exactly these two families (ubuntu-latest,22,3, ubuntu-latest,24,3, windows-latest,22,2, windows-latest,22,4). Failure text matches the state-shape change:
state-key divergence: nudge=75d1956dd2bc409a (golden 1875424e64e16bc5)
sections: {"state":"6a3fe0d7d15b45c1",...} vs golden {"state":"8d09f6115ebffb9d",...}
Suggested fix (5 files, verified bidirectionally)
Add the missing parity pin to the regen script:
// Parity #3: the suite runs under the CI preload chain, whose// tests/preload-test-env.mjs pins BILI_MESSAGE_TIMESTAMPS=0. A bare// `node --import tsx` regen has no preload and renders with the production// default (timestamps ON), so every nudge/tsStamps digest differs from what// the suite hashes and a freshly regenerated golden reds immediately.process.env.BILI_MESSAGE_TIMESTAMPS??="0";
Regenerate tests/golden/storage-render/{chat,anthropic,responses,google}.json with the now-hermetic documented command.
Then the diff is the real #5415 state-shape drift only: 16 changed lines across the four files, versus 208 when regen runs under the wrong mode.
Negative control: git checkout -- scripts/update-storage-render-goldens.ts (drop the pin), regenerate with the documented command again → back to 1 / 4 fail and a 208-line golden diff. Re-adding the pin restores 5 / 0.
Note on the hypothesis in the issue body
Token estimation / calibration reading environment-dependent inputs (locale, ICU, model-window fallback) is ruled out by the matrix above: the divergence is fully explained by a boolean render flag, and it reproduces byte-identically on repeated runs on the same machine exactly as observed — the determinism comes from the env being fixed per process, not from machine identity. The conclusion that "the runner is deterministic and the delta is purely container-vs-runner environment diff" stands, and the delta is now identified.
I have not opened a PR for this because it touches the golden contract; say the word and I will.
Resolved the merge conflict and pushed a clean fast-forward (no force-push). The dirty conflict is cleared — the PR is now mergeable; state advanced dirty → blocked, i.e. it is no longer a conflict, just waiting on the normal pre-merge gates (CI / approval).
Conflicts found (5 files) and how each was resolved:
src/plugin.ts — import line: union of both sides' session.js imports (this branch adds isCompressionDisabled; master adds noteTruncatedUpstream). Both symbols verified present in the merged src/session.ts.
src/server/admin.ts — master refactored notices to the one-registry model (announcements.js / remote-notices.js); kept master's notice imports and added this branch's isCompressionDisabled / markDirty session symbols. Dropped PCK_NOTICE_ID / pckNoticeActive (0 references remain in the merged body after the refactor).
Master had advanced ~2454 commits and touched several of these files, so I re-synced to the newest master after the first resolution: it auto-merged cleanly.
Local verification (targeted, on the final tree): npm run typecheck clean; the PR's own tests/issue5300-session-compress-optout.test.ts passes 7/7. Full-suite verdict is left to remote CI on the pushed head — I did not confirm the fresh CI outcome yet (the mirror check cache still shows the pre-push sha; CI is re-running on the new head 91ee0543ad).
Verified live before touching anything: the dirty/conflict the trigger reported did not exist this run — the PR was mergeable: True, state behind (up-to-date lag), never an actual conflict.
Root cause of the drift: the branch sat on an older base while master kept moving. Two waves landed since the last sync — (1) the compressAtFoldPoint removal (#6132), then (2) a further ~26-commit busy window (blockOps gate #5765 [default off], snapshot-write-lifecycle #6186, anthropic trailing-system-tails #5441, …).
What I did:
Merged current master into the branch twice (both non-force; dry-run predicted 0 conflict hunks each time, and both real merges were clean).
Effective PR diff stays exactly the 8 #5300 files (src/plugin.ts, src/session.ts, src/server/admin.ts, src/server/handle.ts, src/incremental-lane.ts, docs/configuration.md, docs/configuration.zh-CN.md, tests/issue5300-session-compress-optout.test.ts). All kernel / fold-point / guard changes converge to match base, so they add nothing to this PR's own diff (no kernel-guard surface introduced).
Local verification after both syncs: npm run typecheck exit 0 + tests/issue5300-session-compress-optout.test.ts 7/7 pass. Full-suite verdict left to remote CI.
Result: branch is now fully up-to-date with master tip 31684f368e (ancestry-confirmed), so the behind gate cleared; merge-state advanced behind → blocked. blocked here is the normal pre-merge gate (checks running / approval), not a conflict.
Mirror check cache: failed: 0, only in-progress/pending (test shards were running on the prior head 46544a94a4; they re-run on the new head). No red-CI lane is actionable right now.
Final head: 9fe8c21344. Note: master is in a fast-moving window, so behind can reappear transiently if more commits land before merge — that is expected up-to-date lag, not a conflict, and needs no design decision; a final trivial sync at merge time suffices if the repo enforces up-to-date-before-merge.
Activity
test: pin storage-render goldens to post-retire persist contract (#3849)
Louie0806 commentedon Nov 1, 2026
(ai: deepseek/deepseek-v4-flash)
Root cause found — it is not "machine-specific estimation input". It is a missing #3 parity pin in the regeneration script, and it is deterministic.
The decisive experiment
All on
upstream/masterc78ecb4b5, containernode v22.23.4, same machine, same commit.tests/golden-storage-render.test.tsunder the CI preload chainnode --import tsx scripts/update-storage-render-goldens.ts(the committed golden's own expected command, no env)BILI_MESSAGE_TIMESTAMPS=0 node --import tsx scripts/update-storage-render-goldens.tsThe only difference is one environment variable at regen time.
Why
tests/preload-test-env.mjs:53pins it unconditionally:and
scripts/run-ci-tests.mjs:185'sPRELOAD_ARGSloads that preload into every per-file child process. So the suite always hashes with message timestamps off.scripts/update-storage-render-goldens.tsalready documents two parity pins for exactly this class of bug:There is no Parity #3 for
BILI_MESSAGE_TIMESTAMPS. A barenode --import tsxhas no preload, so the timestamp flag resolves through the production default (ON), and everynudge/tsStampsdigest is computed against a different render mode than the test hashes. The regenerated golden is stale by construction — exactly your symptom.This also explains why the divergence lands precisely on those keys rather than on
blockContents/blocks, which do not depend on the timestamp flag.Consequence: master itself is red from this right now
#5415(c91ef1a81, "kernel: abort-heavy sessions stop starving the nudge cadence") addednudge.absorbedDebt?/nudge.absorbCount?tokernel/src/types.ts(+14) and booked them insrc/session.ts(+17), but did not regenerate the goldens — its 9-file diff contains notests/golden/file.golden-storage-render.test.tstests/storage-engine-proofs.test.ts7578e8184(#5415's direct parent)c78ecb4b5(master tip, after#5415)CI on master
c78ecb4b5fails 4 of 11 test shards on exactly these two families (ubuntu-latest,22,3,ubuntu-latest,24,3,windows-latest,22,2,windows-latest,22,4). Failure text matches the state-shape change:Suggested fix (5 files, verified bidirectionally)
tests/golden/storage-render/{chat,anthropic,responses,google}.jsonwith the now-hermetic documented command.Then the diff is the real
#5415state-shape drift only: 16 changed lines across the four files, versus 208 when regen runs under the wrong mode.$ node --import tsx scripts/update-storage-render-goldens.ts $ node --import ./tests/preload-storage-baseline.mjs \ --import ./tests/preload-test-env.mjs \ --import ./tests/preload-zone-slot.mjs \ --import tsx --test tests/golden-storage-render.test.ts # pass 5 # fail 0 $ ... --test tests/storage-engine-proofs.test.ts # pass 12 # fail 0Negative control:
git checkout -- scripts/update-storage-render-goldens.ts(drop the pin), regenerate with the documented command again → back to 1 / 4 fail and a 208-line golden diff. Re-adding the pin restores 5 / 0.Note on the hypothesis in the issue body
Token estimation / calibration reading environment-dependent inputs (locale, ICU, model-window fallback) is ruled out by the matrix above: the divergence is fully explained by a boolean render flag, and it reproduces byte-identically on repeated runs on the same machine exactly as observed — the determinism comes from the env being fixed per process, not from machine identity. The conclusion that "the runner is deterministic and the delta is purely container-vs-runner environment diff" stands, and the delta is now identified.
I have not opened a PR for this because it touches the golden contract; say the word and I will.
test: self-pin BILI_MESSAGE_TIMESTAMPS in both storage-render suites (r…
fix(test): pin BILI_MESSAGE_TIMESTAMPS in the storage goldens' own te…
fix(test): pin BILI_MESSAGE_TIMESTAMPS in the storage goldens' own te…
fix(test): pin BILI_MESSAGE_TIMESTAMPS in the storage goldens' own te…
Merge upstream/master (848f59b): adopt the CI test-signal batch (guar…
ranxianglei commentedon Nov 10, 2026
(ai: vllm-qwen/qwen3.8-27b)
Resolved the merge conflict and pushed a clean fast-forward (no force-push). The
dirtyconflict is cleared — the PR is nowmergeable; state advanceddirty → blocked, i.e. it is no longer a conflict, just waiting on the normal pre-merge gates (CI / approval).Conflicts found (5 files) and how each was resolved:
src/plugin.ts— import line: union of both sides'session.jsimports (this branch addsisCompressionDisabled; master addsnoteTruncatedUpstream). Both symbols verified present in the mergedsrc/session.ts.src/server/admin.ts— master refactored notices to the one-registry model (announcements.js/remote-notices.js); kept master's notice imports and added this branch'sisCompressionDisabled/markDirtysession symbols. DroppedPCK_NOTICE_ID/pckNoticeActive(0 references remain in the merged body after the refactor).src/server/handle.ts— two independent blocks landed at the same anchor; kept both: the [Feature] Per-session opt-out from compression (scope today is only global → provider → model) #5300 verbatim early-return first, then master'sWorkBuddy tier aliases (fast-model / balanced-model) are absent from bili's built-in window table, so the window silently falls back to 200000 and the effective wall collapses to 152000 — mid-session, after a model switch#5490 unresolved-model warn.CONFIGURATION.md/CONFIGURATION.zh-CN.md— master moved these underdocs/, leaving redirect stubs. Took master's stubs and re-homed this branch's new “per-session opt-out ([Feature] Per-session opt-out from compression (scope today is only global → provider → model) #5300)” section intodocs/configuration.md+docs/configuration.zh-CN.mdat the matching anchor.Master had advanced ~2454 commits and touched several of these files, so I re-synced to the newest master after the first resolution: it auto-merged cleanly.
Local verification (targeted, on the final tree):
npm run typecheckclean; the PR's owntests/issue5300-session-compress-optout.test.tspasses 7/7. Full-suite verdict is left to remote CI on the pushed head — I did not confirm the fresh CI outcome yet (the mirror check cache still shows the pre-push sha; CI is re-running on the new head91ee0543ad).八问(中文结构化结论)
mergeable_state=dirty),无法合入。plugin.ts/admin.ts/handle.ts/session.ts/CONFIGURATION*);且 master 把CONFIGURATION.*迁到了docs/下、又把通知系统重构成单一注册表模型,与 PR 的改动撞在同一区域。dirty(完全无法合并)。不影响任何已发布/线上行为。PCK_NOTICE_ID/pckNoticeActive在合并后正文中 0 引用,非回归;(b)handle.ts交叉点:[Feature] Per-session opt-out from compression (scope today is only global → provider → model) #5300 早退放在WorkBuddy tier aliases (fast-model / balanced-model) are absent from bili's built-in window table, so the window silently falls back to 200000 and the effective wall collapses to 152000 — mid-session, after a model switch#5490 告警之前,意味着「已关闭压缩的会话」不会再触发WorkBuddy tier aliases (fast-model / balanced-model) are absent from bili's built-in window table, so the window silently falls back to 200000 and the effective wall collapses to 152000 — mid-session, after a model switch#5490 的未解析模型告警——这是两个新特性的组合语义,符合 [Feature] Per-session opt-out from compression (scope today is only global → provider → model) #5300「关闭即纯透传、不做额外记账」的设计意图,不是既有功能的回归(两个特性此前从未共存)。typecheck + [Feature] Per-session opt-out from compression (scope today is only global → provider → model) #5300 回归套件 7/7 通过佐证。行为变更披露:旧=两特性各自独立存在;新=二者共存且关闭压缩的会话跳过WorkBuddy tier aliases (fast-model / balanced-model) are absent from bili's built-in window table, so the window silently falls back to 200000 and the effective wall collapses to 152000 — mid-session, after a model switch#5490 告警。docs/configuration*.md)。收工判定:冲突已全部解决并推送(head=
91ee0543ad,non-force fast-forward),PR 现为mergeable(dirty→blocked,剩余是 CI/审批门禁而非冲突)。自动修复 lane attempt 1/3 的目标(接冲突)已完成;后续 CI 结果以远程为准。ranxianglei commentedon Nov 11, 2026
(ai: vllm-qwen/qwen3.8-27b)
Verified live before touching anything: the
dirty/conflict the trigger reported did not exist this run — the PR wasmergeable: True, statebehind(up-to-date lag), never an actual conflict.Root cause of the drift: the branch sat on an older base while master kept moving. Two waves landed since the last sync — (1) the
compressAtFoldPointremoval (#6132), then (2) a further ~26-commit busy window (blockOps gate #5765 [default off], snapshot-write-lifecycle #6186, anthropic trailing-system-tails #5441, …).What I did:
#5300files (src/plugin.ts,src/session.ts,src/server/admin.ts,src/server/handle.ts,src/incremental-lane.ts,docs/configuration.md,docs/configuration.zh-CN.md,tests/issue5300-session-compress-optout.test.ts). All kernel / fold-point / guard changes converge to match base, so they add nothing to this PR's own diff (no kernel-guard surface introduced).npm run typecheckexit 0 +tests/issue5300-session-compress-optout.test.ts7/7 pass. Full-suite verdict left to remote CI.31684f368e(ancestry-confirmed), so thebehindgate cleared; merge-state advancedbehind → blocked.blockedhere is the normal pre-merge gate (checks running / approval), not a conflict.failed: 0, only in-progress/pending (test shards were running on the prior head46544a94a4; they re-run on the new head). No red-CI lane is actionable right now.Final head:
9fe8c21344. Note: master is in a fast-moving window, sobehindcan reappear transiently if more commits land before merge — that is expected up-to-date lag, not a conflict, and needs no design decision; a final trivial sync at merge time suffices if the repo enforces up-to-date-before-merge.八问(中文结构化结论)
behind(落后于 master),不是冲突。compressAtFoldPoint特性移除(Remove the compressAtFoldPoint feature — it reorders resent history and caused an authorship-misattribution incident in a live session #6132);②随后约 26 个提交的合并高峰(blockOps 门控 Request two capabilities: compressed block "retirement" and summary "external rewrite". | 请求两个能力:压缩块「退役」与摘要「外部重写」 #5765、snapshot-write-lifecycle [PR] fix: await unified snapshot writes and reset each debounce batch #6186、anthropic trailing-system-tails [PR] fix: insert Anthropic ephemeral tails before trailing client systems (#5432) #5441 等)。本质是「上游在动、分支没跟上」的落后,而非双方改到同一处的冲突。behind会被「合入前须最新」的保护规则挡住合并按钮。不影响任何已发布/线上行为。WorkBuddy tier aliases (fast-model / balanced-model) are absent from bili's built-in window table, so the window silently falls back to 200000 and the effective wall collapses to 152000 — mid-session, after a model switch#5490 告警的组合(上一轮已披露)保持不变。typecheck + 7/7 通过佐证。收工判定:冲突不存在(触发器的 dirty 为过期信息);分支已同步到当前 master 尖端并本地验证绿,head=
9fe8c21344;状态由behind→blocked,剩余blocked属正常合入门禁(CI 检查运行中 / 待审批),非冲突。镜像检查缓存failed=0,当前无可修的红灯车道。自动修复 lane attempt 1/3 的目标(接冲突 + 修红 CI)已达成;若新 head 上 CI 转红,将作为独立的红 CI 触发处理。