Skip to content

fix(chat): keep the answer visible when a recycle notice trails it - #15120

Merged
bolichen97 merged 1 commit into
kirodotdev:mainfrom
drakeo338:claude/15115-fix
Sep 30, 2026
Merged

bolichen97 merged 1 commit into
kirodotdev:mainfrom
drakeo338:claude/15115-fix

Conversation

@drakeo338

Copy link
Copy Markdown
Contributor

Problem / Motivation

Goal: Keep a finished turn's answer visible when the watchdog recycle notice lands after it.

findConclusionIdx picked the last substantive item, so the recycle notice won and the answer folded into the collapsed steps pane.

Why it matters

The answer looks missing until the pane is expanded.

Not a goal

  • Notice storage and wording.

What changed (motivation → approach → change)

The conclusion choice now skips system notice rows (compaction, session reload, recycle), so the answer stays the final message and the banner follows it. Added a test for both collapseAll settings.

Backwards compatibility

Compatible: only which item is chosen as the conclusion changes.

Tests

website/src/test/TurnBlock.test.tsx: 39 passed. The new test failed before the fix. Full suite not run.

Manual verification

N/A: unit coverage sufficient.

Screenshots / video

no-visual-delta. Why no screenshot: only item selection changes, covered by the test.

Related Issues

Fixes #15115.

Pattern harvest

Not generalizable: one-off ordering assumption in a single helper.

Checklist

  • At most two commits (one is the norm), with a Conventional Commits title (feat|fix|docs|style|refactor|perf|test|chore|ci|build|revert: ...)
  • Existing tests pass and new tests added for new functionality (new test added and its file passes; full suite not run)
  • Self-review completed; code follows project style guidelines
  • Documentation updated (if applicable)
  • No secrets, credentials, or internal references in the diff

Contribution License Agreement

N/A: the template says the CLA wording is still a placeholder.

findConclusionIdx picked the last substantive conclusion item, so the
assistant-role watchdog recycle notice won over the real answer and the
answer folded into the collapsed steps pane. Skip system notice rows
(compaction, session reload) when choosing the conclusion.

Fixes kirodotdev#15115
@drakeo338
drakeo338 requested a review from a team September 29, 2026 20:22
@drakeo338
drakeo338 requested a review from a team as a code owner September 29, 2026 20:22
@github-actions github-actions Bot added readiness: checking Automated validation is still running fork Pull request from a fork (external contributor) labels Sep 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

GPT 5.6 Review (fork) — ✅ no blocking findings

Reviewed 868b02849cc8ea77d97a326302edaa4c885481c8 via the fork AI-review pipeline; updated in place on each push.

Review details

No findings.
[GPT-REVIEWED] 868b028

@github-actions

Copy link
Copy Markdown
Contributor

First Principles Review (Fable 5, fork) — ✅ PASS

Premise-level review of 868b02849cc8ea77d97a326302edaa4c885481c8 via the fork AI-review pipeline — why this exists and whether the shipped surface is the smallest honest version. Updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

First-Principles-Verdict: PASS

Verify a turn whose only assistant row IS the notice: findConclusionIdx now returns -1 there, so the whole turn renders flat, uncollapsed.

What this change ships

Inventory (3 items) — 3 justified

Intent: FIX — keep a finished turn's answer visible when a trailing watchdog recycle notice would otherwise be picked as the conclusion (#15115, test fails on base).

  1. In collapse-all mode, the answer stays the visible conclusion when a recycle/compaction notice trails it — justified
  2. Search auto-expand mirrors the same choice, so a match in the answer no longer wrongly expands reasoning — justified
  3. The skip covers all system-notice kinds (compaction, session reload), not just recycle — justified

Evidence: the fix reuses the existing shared predicate isSystemNoticeRow (CompactionCard.tsx:100), whose own doc says it is "one predicate shared with the last-real-message scans." Grepped isSystemNoticeRow: the four existing last-real-message scans (ChatPage.tsx:4806, 4860, 6605; messageRenderers.tsx:411) already skip these rows; findConclusionIdx was the remaining unfixed sibling, so this sits at mechanism level with zero siblings left. Notice storage (the assistant-role tagging that is the deeper cause) is declared out of goal, consistent with the predicate ecosystem already built around it.

[FIRST-PRINCIPLES-REVIEWED] 868b028

Description read

[DESCRIPTION-READ] f451874c34aa411e1e1ae26eef5ea37504efe59b8a432d821f6cdb97fccd2b1f

That sha256 names the PR description this verdict read. Recompute it with .github/scripts/pr-description-capture.sh; if it differs, the description changed after this verdict was formed and any finding drawn from the description is unproven.

@github-actions

Copy link
Copy Markdown
Contributor

Design Review (Fable 5, fork) — ✅ PASS

Design-level review of 868b02849cc8ea77d97a326302edaa4c885481c8 via the fork AI-review pipeline — updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

Design-Verdict: PASS

Verify a turn whose only assistant row is the notice (recycle with no answer) still renders acceptably — it now takes the no-conclusion flat path in collapseAll.

[DESIGN-REVIEWED] 868b028

Description read

[DESCRIPTION-READ] c701d07cfd2dfe23e201c2fa10614560ba1fabfc18269454ebfc0d1108941dda

That sha256 names everything this verdict read: the PR description, plus the 1 evidence file(s) the workflow collected from it and handed this review. It covers that evidence because the media strip replaces every attachment URL with the same placeholder, so an edit swapping one attachment for another would leave the description's captured text identical while what this review judged changed. Recompute it with .github/scripts/pr-description-capture.sh over the same inputs; if it differs, the description or that evidence changed after this verdict was formed and any finding drawn from either is unproven.

@github-actions

Copy link
Copy Markdown
Contributor

UX Review (Fable 5, fork) — ✅ PASS

UX-level review of 868b02849cc8ea77d97a326302edaa4c885481c8 via the fork AI-review pipeline — updated in place on each push. A BLOCK verdict blocks PR readiness; PASS/CONCERNS are advisory.

UX-Verdict: PASS

Verify once in a live recycled session that the answer renders above the ♻️ banner, both outside the "Worked through N steps" fold.

The diff adds or changes no user-visible control, label, or string — it only fixes which existing item is picked as the always-visible conclusion, restoring the product's standard turn layout (answer visible, notice trailing it, per the after.forEach render path in TurnBlock.tsx:490). The recycle-notice wording is explicitly out of goal and unchanged, so there is nothing new for a first-time user to comprehend and no screenshot obligation.

[UX-REVIEWED] 868b028

Description read

[DESCRIPTION-READ] abb97a9917ff47a093af60162bc8ff17b7f2401930519e5d4d0db37bd14fb990

That sha256 names everything this verdict read: the PR description, plus the 3 evidence file(s) the workflow collected from it and handed this review. It covers that evidence because the media strip replaces every attachment URL with the same placeholder, so an edit swapping one attachment for another would leave the description's captured text identical while what this review judged changed. Recompute it with .github/scripts/pr-description-capture.sh over the same inputs; if it differs, the description or that evidence changed after this verdict was formed and any finding drawn from either is unproven.

@github-actions

Copy link
Copy Markdown
Contributor

Opus 5 Review (fork) — ✅ no blocking findings

Reviewed 868b02849cc8ea77d97a326302edaa4c885481c8 via the fork AI-review pipeline; updated in place on each push.

Review details

A trailing system notice was the only isConclusion row of some completed turns, so excluding it drops the collapseAll fold entirely.

FINDING — website/src/pages/chat/TurnBlock.tsx:218 — !(it.kind === 'single' && isSystemNoticeRow(it.msg)) makes findConclusionIdx return -1 for a completed turn whose only assistant-role row is the notice (a turn cut short with no answer row — _note_dead_runtime/RSS recycle fire _SESSION_RECYCLED_NOTICE into the same turn batch, since only a user/nudge/subagent row starts a new turn), so beforeItems = [] → stepCount === 0 → the flat early return renders every 🔧 row inline with no CollapseToggle, and when the scan instead falls back to an earlier short assistant row the toggle claims "Worked through 1 step" while the later tool rows sit visible in after → Fix: when no non-notice conclusion exists, keep the fold by splitting at the first row of the trailing notice run instead of collapsing to -1 (beforeItems = items.slice(0, conclusionIdx >= 0 ? conclusionIdx : noticeStart)), leaving the notice rows in after.

[OPUS-REVIEWED] 868b028

@github-actions github-actions Bot added readiness: passed Eligible automated validation passed for the current revision and removed readiness: checking Automated validation is still running labels Sep 29, 2026

@bolichen97 bolichen97 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed on behalf of the maintainers (sweep 2026-09-30): readiness passed, required checks green on 868b028, no blocking review threads, security posture unchanged. Approving and merging.

@bolichen97
bolichen97 merged commit ea8af27 into kirodotdev:main Sep 30, 2026
98 of 99 checks passed
@github-actions github-actions Bot removed the readiness: passed Eligible automated validation passed for the current revision label Sep 30, 2026
bolichen97 added a commit that referenced this pull request Sep 30, 2026
…15120) (#15578)

findConclusionIdx picked the last substantive conclusion item, so the
assistant-role watchdog recycle notice won over the real answer and the
answer folded into the collapsed steps pane. Skip system notice rows
(compaction, session reload) when choosing the conclusion.

Fixes #15115

(cherry picked from commit ea8af27)

Co-authored-by: Y.B. <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fork Pull request from a fork (external contributor)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dashboard folds a finished turn's answer into the steps pane when a watchdog recycle notice lands after it

2 participants