Conversation
🔬 Gate certification — RED ⛔ (fork-exclusion fixes #5571 but makes COMPRESSED fork continuations lose their pre-compression history — CORE data loss)Certified head: What I ran (rebased worktree
|
| Gate | Result |
|---|---|
| Rebase onto current master | ✅ git apply clean |
| Codex (reproduce) | SHIP-WITH-FIXES — 1 CORE (compressed-fork continuation loses history); Codex probed it, I confirmed the code |
| Full pytest suite | ✅ rc=0 green (the compressed-fork edge is NOT test-covered — Codex's direct probe caught it) |
| PR's own test | ✅ 10/10 (test_session_lineage_full_transcript.py) — but none cover fork-then-compress |
Findings
⛔ CORE (I + Codex CONFIRMED) — compressed fork continuations lose pre-compression history (api/routes.py:8034): the guard if source == "fork": return session_messages fires BEFORE the parent-load loop (8038+). But session_source="fork" (stamped by /api/session/branch at routes.py:13938, persisted models.py:1180/1443) is NEVER cleared by compression rotation (streaming.py:8276-8286 sets pre_compression_snapshot=False + parent_session_id=old_sid, leaves session_source alone). So a session that was forked and THEN compressed still has source=="fork" → the early return skips stitching its direct pre_compression_snapshot parent → the continuation displays only post-compression turns, losing the archived pre-compression transcript. Codex's direct probe returned only ["after compression only"] for such a session; origin/master (no early return) would stitch the parent. Fork-provenance and compression-continuation edges OVERLAP — session_source alone can't separate them. Fix (Codex-exact): don't early-return solely on session_source=="fork" — check the DIRECT parent first (if it's a pre_compression_snapshot, stitch parent+child), and use fork-provenance only to avoid walking further back into the ORIGINAL fork parent. Add a regression: child.session_source=="fork" + direct parent.pre_compression_snapshot=True → returns parent+child, but does NOT walk into the original fork parent.
✅ The #5571 intent is right (keep): a pure fork must not stitch its original conversation parent — that part is correct. The gap is that the guard is too coarse (position + sole-condition) for the fork-then-compress case.
Recommendation to the next agent / author
RED — gate-fail/changes-requested (1 CORE data-loss): move the fork check AFTER the direct-parent pre_compression_snapshot check — stitch a direct snapshot parent even for source=="fork" sessions, and use session_source=="fork" only to stop walking back into the ORIGINAL (non-snapshot) fork parent. The #5571 fix (pure fork doesn't stitch its conversation parent) is correct; it just needs to not clobber the legitimate compression-continuation stitch for a fork-then-compressed session. Add the fork-then-compress regression test. concept 4/5 (real #5571 fix; one overlapping-provenance edge). Author @rodboev (T1). crit=3, data-integrity. (Gate value: same family as #5556 — a lineage/clear/compression fix must handle OVERLAPPING provenance edges; session_source=="fork" and pre_compression_snapshot parent are not mutually exclusive (fork-then-compress), so a sole-condition early return drops a legitimate stitch. Enumerate the overlap matrix, don't gate on one flag.)
Gate-certifier layer (warm-up → gate → release). I do not merge/tag/deploy. Rebased onto current master; confirmed compression rotation (streaming.py:8276-8286) leaves session_source='fork' set, and the routes.py:8034 early-return (before parent-load) therefore skips a compressed fork's legitimate pre_compression_snapshot parent stitch → history loss (Codex probe: only post-compression turns). Suite green (edge not test-covered). Fix: check direct snapshot parent before the fork early-return. Cert valid for sha:f35bbe8b.
f35bbe8 to
4d3d488
Compare
|
Good catch. I pushed 4d3d488. The sidecar stitch now checks the direct snapshot parent first, but for fork roots it only accepts a fork-sourced snapshot parent and then stops before walking back to the original parent ( I also added |
4d3d488 to
3cd031e
Compare
🔬 Gate certification — GREEN ✅ · CONVERGED (round-1 fork-then-compressed history loss fixed)Certified head: What I ran (rebased worktree
|
| Gate | Result |
|---|---|
| Rebase onto current master | ✅ git apply clean |
| Codex (reproduce) | SAFE TO SHIP — 0 findings; round-1 CORE confirmed fixed |
| Full pytest suite | ✅ 12103 passed, 0 failed |
| lineage tests | ✅ 11/11 |
Findings — round-1 CORE CLOSED
✅ Both cases now correct: the fork check moved from an unconditional pre-parent-load early-return to a captured root_is_fork = source=="fork" + a restructured parent-walk: load parent → if not parent.pre_compression_snapshot: break (only stitch compression snapshots) → if root_is_fork and parent_source != "fork": break (stop when a fork's chain reaches the ORIGINAL non-fork conversation parent). So:
- a fork-then-COMPRESSED session (child
session_source=="fork", direct parentpre_compression_snapshot=True) now STITCHES the snapshot parent → pre-compression history preserved (my round-1 CORE closed); - a pure fork still does NOT stitch its original conversation parent (Compression stitch should skip fork children (session_source==fork) to avoid post-clear resurrection corner #5571 fixed) — breaks at
root_is_fork and parent_source!=fork; - a normal (non-fork) compression continuation still stitches.
Codex confirmed the walk terminates (seen-set + break conditions sound), no over-stitch/infinite loop,is_safe_session_id+seen guards intact. 11 lineage + full suite green.
Recommendation to the next agent
Ready to merge — use branch gate-rebase/5582-fork-compression-stitch (sha:fc1b5888), NOT the PR's stale head 3cd031e4. Converged data-integrity fix — fork children no longer inherit their origin conversation (#5571) AND fork-then-compressed sessions keep their pre-compression history (round-1 CORE fixed). Codex SAFE + 11 lineage tests + full suite green. Backend lineage-logic, no visible surface (no Fable-UX leg applies). concept 4/5. Author @rodboev (T1). crit=3, data-integrity.
Gate-certifier layer (warm-up → gate → release). I do not merge/tag/deploy. Rebased onto current master; round-1 fork-then-compressed history-loss fixed (parent-walk now stitches pre_compression_snapshot parent before the fork-isolation break; root_is_fork+parent_source!=fork stops only at the original conversation parent), pure-fork isolation intact (#5571), Codex SAFE + 11 lineage + full suite green (0 failed). Backend (no Fable surface). Cert valid for sha:fc1b5888.
release #5582: keep fork children out of compression stitch
|
Shipped in v0.51.883 — thanks @rodboev! 🎉 A fork's full-transcript display no longer resurrects its original (non-fork) parent's messages after that parent is compressed. When the root session is a fork, the lineage stitch now allows fork-sourced snapshot parents but stops at the first non-fork ancestor — so a compressed fork continuation still shows its own pre-compression turns, while an ordinary fork child stays isolated from the original. Non-fork history display is unchanged. Gate: Codex SAFE TO SHIP (display-only path, non-fork stitch byte-identical, no legitimate turns dropped, legacy missing-source falls back to prior behavior); full suite 12110 passed; 18 lineage/clear tests incl. a new multiply-compressed-fork regression. Merged via #5625. |
Thinking Path
_webui_sidecar_lineage_messages_for_displaynow allows a fork root to stitch fork-sourced snapshot parents and stops at the first non-fork ancestor, preserving fork compression history without resurrecting the original parent.What Changed
api/routes.py: allow compressed fork continuations to stitch fork-sourced snapshots while keeping ordinary fork children isolated from non-fork parents.tests/test_session_lineage_full_transcript.py: keep the original fork-with-later-snapshot-parent regression and add a multiply-compressed fork regression that proves fork snapshots are restored without appending the original parent.Why It Matters
A cleared fork child stays independent if its original parent is compressed later, while a compressed fork continuation still shows the pre-compression turns that belong to that fork.
Verification
pytest tests/test_session_lineage_full_transcript.py -v --timeout=60, 11 passed.pytest tests/test_issue5532_clear_truncation_watermark.py -v --timeout=60, 7 passed.Full-suite CI context, not a required local check:
pytest tests/ -v --timeout=60.Upstream
Closes #5571.
Model Used
GPT 5.5 via Codex CLI