Release v0.51.543 — Release TB (stable assistant turn anchors)
Ships #4411 (franksong2702) — the capstone of the Stable Assistant Turn Anchors series. Deep-reviewed end-to-end (full gates + live browser testing) with 3 bugs found and fixed. Cherry-picked/rebased with author attribution preserved.
Added
- The Compact Worklog now renders the same ordered turn whether it's streaming live, settled, reloaded after a hard refresh, or re-opened later (#3926). A persisted
activity_scene_v1"assistant turn anchor" model captures each turn's worklog (reasoning rows, tool-call cards) + final answer as a durable scene, so the transcript no longer drifts between live and reload. Live-only rows are cleaned on both browser settlement and server hydration; the persisted scene is the source of truth on re-entry; pre-anchor sessions keep rendering via the legacy path unchanged (graceful fallback, no migration). Schema is bounded+sanitized;/api/session/anchor-sceneis auth- and profile-scoped. Culmination of #3927 RFC → #3980/#4037/#4092/#4093/#4108/#4120/#4126. Thanks @franksong2702.
Review fixes applied at the gate (each with a regression test)
- BRICK — infinite recursion in live anchor-scene window exports (
ui.js). Three top-level functions were re-exported via same-name wrappers (window.X = function(){ return X() }); in a classic script that reassigns the global to itself →RangeError: Maximum call stack size exceededon every live render / session reattach / snapshot restore. Replaced with direct assignment. Verified live in-browser (pre-fix throws, post-fix returns cleanly). This is the #2715/#2771 brick class — pytest can't catch it (no JS execution). - Cross-profile write on
/api/session/anchor-scene— the handler loaded the session by id (no profile scoping) and persisted without the active-profile visibility checkGET /api/sessionapplies. Added the guard (404 + no write). - Read-side ref-ambiguity in
_hydrate_anchor_activity_scenes— mirrored the write-side guard so a duplicate content-digest ref can't double-render a worklog.
Plus two test-correctness fixes: a stale assertion that codified the recursion wrapper, and a window-collision brick-guard that was blind to long identifiers.
Gate
- Full pytest suite: 9835 passed, 0 failed
- Codex regression gate: all findings resolved (final pass clean; the product code uses direct assignment)
- Opus advisor: SHIP (all findings applied)
- QA mock-LLM harness: core conversation loop / real streaming passed
- Live browser: 0 JS/console errors; re-entry worklog render visually verified; legacy (no-anchor) backward-compat verified (0 anchor DOM nodes, 0 errors)
Closes #3926.