fix(session): skip runtime handoffs when deriving the auto title - #6012
Open
SparkofSpike wants to merge 3 commits into
Open
fix(session): skip runtime handoffs when deriving the auto title#6012SparkofSpike wants to merge 3 commits into
SparkofSpike wants to merge 3 commits into
Conversation
Chat-template compatibility forces runtime-owned control traffic (sub-agent handoffs, the Operate contract, restore checkpoints) through role = user. The auto-generated session title was derived from the first such message, so Operate/automation sessions whose transcript opened with an internal envelope got titles like '<codewhale:runtime_event kind=...' instead of the real prompt. Reuse the runtime_handoff::is_internal_runtime_handoff recognizer the session peek already uses, so title derivation and preview agree about what counts as conversation. When no real user message exists yet the placeholder DEFAULT_SESSION_TITLE is kept. Adds two regression tests: an Operate-contract-first session titles from the following real prompt, and a runtime-traffic-only session keeps the placeholder.
Review follow-up: SavedSession::import_foreign re-derived the title with the old first-role-user logic (no runtime-handoff filter and no <turn_meta> stripping), so importing a session whose transcript opened with an internal envelope re-introduced the exact title bug the main derivation path just fixed. Extract conversation_derived_title() shared by both callers — it skips is_internal_runtime_handoff messages and strips a leading <turn_meta> envelope — so auto-snapshot, session creation, and foreign import all agree on what counts as a real user message. Extends the runtime-traffic-only regression test to cover every handoff shape the session peek filters (Operate contract, waiting/restored checkpoint, shell completion) and adds two import_foreign regression tests.
macOS Test hit the 90-minute job timeout after all 14547 tests passed (cold sccache on first run); npm wrapper smoke was killed by a runner shutdown signal. Both are infrastructure failures, not test failures.
SparkofSpike
marked this pull request as ready for review
September 8, 2026 17:08
Contributor
Author
|
Ugh, I'm so confused by this CI. It's either a Test timeout or the Smoke failing. No idea what to do, but it doesn't seem like my problem. Just gonna wait for a manual merge. |
Hmbown
pushed a commit
that referenced
this pull request
Sep 9, 2026
… live UI Harvested from PR #6012 by @SparkofSpike Preserve the contributor's shared save/import title derivation and four regression tests from eeee8b9 and 14147f6. Resolve the test-helper insertion against current source without removing the existing session tests. Use the existing user-turn classifier for prompt eligibility and share raw prompt selection with the live title fallback. This also excludes generic runtime and legacy non-authoritative metadata while retaining the first image-only user boundary. Existing formatting, sanitization and rename priority remain in place; previously persisted bad titles are not migrated. Local validation: - Exact source-fragment probe: 21 passed, 0 failed; rustc -D warnings exit 0. - Baseline runtime-first preservation invariant: expected failure, exit 101. - cargo fmt --all -- --check and git diff --check: exit 0. - npm test and npm run check:web: each exit 1, missing package scripts. - Production crate compilation/tests: not run in this lane; integrator owns the coordinated full-link window. Four maintainer regressions added. Hosted PR-head CI is separate evidence: three OS test jobs passed; wrapper binary build ended with exit 143 and runner shutdown, smoke skipped. That failed gate is not a pass for this integrated donor. Co-authored-by: Sh1Zuku <125943630+SparkofSpike@users.noreply.github.com>
Hmbown
pushed a commit
that referenced
this pull request
Sep 9, 2026
Record the adapted #6012 contribution and retain #6011/#6013 as open broader requests. Describe local candidate dispatch ordering and request diagnostics without claiming reporter reproduction or provider billing proof. Validation: changelog sync and sync --check passed; git diff --check passed. No new product tests for documentation. npm test and npm run check:web each exit 1 because the Core root defines neither package script. Final candidate product gates remain separate.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Session titles auto-generated from the conversation were showing internal runtime envelopes such as
<codewhale:runtime_event kind="operate_contract" ...>instead of the real prompt. Chat-template compatibility forces runtime-owned control traffic (sub-agent handoffs and completions, the Operate contract, restore checkpoints) throughrole = "user", andcreate_saved_session_with_id_and_modederived the title from the firstrole == "user"message with only a<turn_meta>prefix stripped. In Operate/automation sessions whose transcript opens with an internal envelope, the envelope text became the title (truncated to 50 chars with...), and once such a title was persisted the snapshot priority rules kept it pinned until a manual/rename.SavedSession::import_foreigncarried the same stale logic, so importing such an exported session re-derived the envelope as its title.Changes
fix(session): skip internal runtime handoffs during title derivation (
session_manager.rs): the auto-title now comes from the first message that is bothrole = "user"and notis_internal_runtime_handoff(m), reusing the exact recognizer the session peek already uses (runtime_handoff.rs), so title generation and preview agree about what counts as conversation. When no real user message exists yet, theDEFAULT_SESSION_TITLEplaceholder is kept and the existing snapshot healing logic promotes a real prompt title once one arrives.fix(session): apply the same derivation on foreign import (
session_manager.rs): the logic is extracted into a sharedconversation_derived_title()used by bothcreate_saved_session_with_id_and_modeandSavedSession::import_foreign, closing the import-side copy of the bug (review follow-up).test(session): regression coverage (
session_manager.rstests):create_saved_session_skips_runtime_handoffs_when_deriving_title— an Operate-contract-first session titles from the real prompt that follows it;create_saved_session_with_only_runtime_traffic_keeps_placeholder_title— covers every handoff shape the peek filters (Operate contract, waiting/restored checkpoint, shell completion) and asserts the placeholder is kept; plus twoimport_foreigntests for the same guarantees on the import path. All fail on the old code.Type of Change
Testing
cargo fmt --all -- --checkcargo clippy --workspace --all-targets --all-features --locked(not run: full-workspace gate; the change is a shared title-derivation helper plus unit tests, and the crate compiles cleanly through the test build)cargo test -p codewhale-tui --lib create_saved_session— 3 passed (regression tests + existing turn_meta title test)cargo test -p codewhale-tui --lib "session_manager::"— 72 passed (incl. new import_foreign tests)cargo test -p codewhale-tui --lib import_foreign— 2 passedcargo test -p codewhale-tui --lib "import"(RUST_MIN_STACK=16MB) — 52 passed (contract import integration surface unaffected)cargo test -p codewhale-tui --lib "runtime_handoff::"— 14 passedcargo test -p codewhale-tui --lib "session_peek::"— 15 passedcargo test --no-fail-fast -p codewhale-tui --lib(RUST_MIN_STACK=16MB) — 11651 passed; 9 failures verified unrelated on the unmodified baseline viagit stash(missingsh/bashon this Windows host, live-network Anthropic SSE test, one rendering-surface baseline, one zai-stream thread test). One additional acp_server test overflows the default Windows test-thread stack and passes withRUST_MIN_STACK=16MB— also reproduced on the unmodified baseline.Independent review: a reviewer sub-agent returned APPROVE-WITH-NITS; its single MAJOR finding (stale duplicate logic in
SavedSession::import_foreign) was fixed in the follow-up commit above, and its suggested test-coverage extension (all peek-filtered handoff shapes) was folded into the runtime-traffic regression test.Checklist
Related Issues
No-Issue: auto-generated session titles leak
<codewhale:runtime_...>internal envelopes when runtime control traffic is the first user-role message (reported in-session 2026-09-08; no matching GitHub issue or PR found at report time; branchcodex/fix-title-runtime-envelope, commits eeee8b9 and 14147f6).