Skip to content

[issue sweep] Add a preference for assistant message visibility - #1508

Closed
SawyerHood wants to merge 6 commits into
mainfrom
sweep/issue-1355-visible-assistant-text
Closed

[issue sweep] Add a preference for assistant message visibility#1508
SawyerHood wants to merge 6 commits into
mainfrom
sweep/issue-1355-visible-assistant-text

Conversation

@SawyerHood

@SawyerHood SawyerHood commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

Summary

A finished turn kept only its last assistant message visible and collapsed every earlier one into the "Worked for …" summary. A turn shaped text -> tool_use -> text therefore hid the long answer and showed only the short reply after the tool call. A blocking Stop hook makes that shape common in Claude Code, but the cause is not hook-specific.

This pull request does two things.

  1. Fixes the hidden answer: a finished turn now renders every assistant message in order and collapses only the tool activity.
  2. Puts that behavior behind one app-wide General preference, showAllAssistantMessages, because the collapsing works well for Codex today and the change would otherwise make every Codex turn noisier.

The preference is global, not per provider. It defaults to true, which keeps the fix on for everyone. Set it to false to get today's behavior back: the turn then shows only its last assistant message and keeps the earlier ones inside the collapsed work summary.

The decision most worth challenging

The default. Hiding an answer is a worse failure than extra verbosity, and a preference that defaults to the hiding behavior leaves the #1355 bug on for everyone who never finds the setting. A reviewer who disagrees can flip one value in packages/domain/src/app-settings.ts and one default in packages/db/src/schema.ts.

Surfaces

Following the showSidebarThreadNumbers pattern from #1174:

  • packages/domain/src/app-settings.ts: schema field and default.
  • packages/db: app_settings.show_all_assistant_messages, migration 0094_absent_scrambler generated with Drizzle, and the rewind-column helper in migrate.test.ts.
  • Server: PUT /api/v1/settings/general and GET /api/v1/system/config carry it through the existing app-settings contract.
  • App: Settings → General → "Show all assistant messages".
  • CLI: bb settings general showAllAssistantMessages <true|false>.
  • Docs: docs/configuration.md, the bb-cli SKILL, references/app-settings.md, and the bb-guide-customization template.

Reaching every consumer

The grouping happens in @bb/thread-view, which the server drives through buildThreadTimelineFromEvents. The preference is a required field on every server entry point, so the compiler rejects a consumer that omits it:

  • the timeline route, including its cache key and its delta params key,
  • the work summary details route,
  • the conversation outline, including its cache key,
  • bb thread show, which renders rows from the timeline route.

A consumer that read a different value would describe a different turn. A summary row's source-sequence range changes with the preference, so the details route would fail to match the range the client asked about. timeline-assistant-message-visibility.test.ts pins that: details resolve under the matching value and throw under the other one.

Toggling while a long thread is open

Segment cursors anchor on user-message rows, which both modes produce identically, so an open older-page cursor stays valid and no page has to be re-anchored.

Writing the preference invalidates the timeline, the work summary details, and the conversation outline, so an open thread re-renders in the new shape without a reload. The window that made the change invalidates locally; other windows do the same through the realtime config-changed broadcast. The outline was missing from the local path, which would have left the minimap disagreeing with the timeline; this pull request adds it and covers it with a test.

That refetch returns the new shape whole: the preference is part of the cache key and of the delta params key, so the delta path cannot match a snapshot taken under the other value and the server sends the full window instead of a diff. Older pages already loaded in the client are re-requested by the same invalidation, and segment cursors anchor on user-message rows, which both modes produce identically, so no page has to be re-anchored. No row set is ever a mix of the two modes, and no message is lost in either.

Protocol version

Nothing here crosses the server and host daemon channel: the preference is read on the server and only changes rows sent to clients over the web API. HOST_DAEMON_PROTOCOL_VERSION is unchanged.

Testing

  • packages/thread-view: the text -> tool_use -> text turn, two adjacent text blocks, an assistant message between two commands, and the collapsed counterpart of each. Legacy bb system prose is covered in the collapsed mode, where it must stay visible.
  • apps/server: new timeline-assistant-message-visibility.test.ts covers both modes across the timeline, the work summary details, and the conversation outline, plus the cross-value mismatch. general-settings.test.ts round-trips the new field. timeline-cache.test.ts carries it in the key.
  • apps/cli: bb settings general showAllAssistantMessages false sends the full settings contract.
  • apps/app: system-cache-effects.test.ts asserts a General settings write invalidates the timeline, the outline, and the work summary details together.
  • packages/db: migration replay and rewind scenarios pass with the new column.
  • pnpm exec turbo run typecheck passes for @bb/thread-view, @bb/server, @bb/app, @bb/cli, @bb/db, @bb/domain, @bb/plugin-sdk, and @bb/templates.
  • pnpm exec turbo run test --force passes for @bb/thread-view (21 files), @bb/app (342), @bb/cli (47), @bb/db (29), @bb/domain (24), @bb/integration-tests (25), @bb/templates (4), and @bb/plugin-sdk (9).
  • @bb/server: 162 of 163 files pass. internal-skill-trees compares a file mode (420 vs 436); it also fails on main in this worktree and passes in CI, so it is a local umask difference.
  • pnpm exec turbo run lint passes for the touched packages.
  • The regenerated bb-plugin-sdk.d.ts also reorders some unrelated enum members. That is the generator's own output for the new schema key; build-bundled-dts.mjs --check only passes with it.

Fixes #1355

AGENT GENERATED: by Claude Opus 5

@bb-slop-cop

bb-slop-cop Bot commented Aug 13, 2026

Copy link
Copy Markdown

🚨 SLOP COP 🚨 · review

I am the SlopCop. I am reviewing this pull request now.

I will check security, code quality, performance, architecture, and the completed-turn behavior. I will post one final review after the checks finish.

// so every earlier text would otherwise hide inside the collapsed
// "Worked for ..." summary.
return (
message.kind === "assistant-text" || message.kind === "debug/raw-event"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚨 slopcop/review — The full outline can now grow with every assistant block.

This helper also controls the full conversation outline. That route reads every relevant event without pagination.

The wide table of contents then maps every outline item. A long tool-heavy turn can now add many assistant entries.

Please add a high-cardinality test for text and tool alternation. Please also consider a limit, pagination, or list virtualization.

This concern does not block this pull request.

@bb-slop-cop bb-slop-cop Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚨 SLOP COP 🚨 · review

ELI5: The app used to hide an early assistant note after a tool ran. This change keeps every assistant note visible.

I found no merge blocker. The core change is small and correct.

Security

I found no security or privacy issue. The change uses the existing thread checks and the existing safe Markdown path.

Reasoning text and child-agent text remain in their current projection boundaries. The change adds no file, network, secret, or write access.

Code quality and architecture

The visibility policy remains in one shared helper. I found no duplicate assistant grouping logic.

The isLegacyUserMessage field now has no runtime reader. The legacy grouping test also no longer checks unique legacy behavior.

That cleanup is small and does not block this change. A direct test for two assistant blocks without a tool would also support the title.

Performance

The grouping code remains linear. The normal timeline still has event and byte limits.

I left one non-blocking inline note about the full conversation outline. It has no pagination and can now contain every assistant block.

Test evidence

  • The @bb/thread-view type check passed.
  • All 365 @bb/thread-view tests passed.
  • Both focused server outline tests passed.
  • Every GitHub CI check passed.
  • A live Codex turn produced assistant text, a shell command, and final assistant text.
  • The dev browser showed both assistant blocks and the collapsed work row exactly once.

@SawyerHood

Copy link
Copy Markdown
Collaborator Author

Thank you for the review. Here is how I answered each note.

Inline: the outline can grow with every assistant block. I added lists every assistant block of a long text and tool alternation to apps/server/test/services/threads/conversation-outline-performance.test.ts. It builds a turn with 40 text and command pairs and asserts one outline item per block.

I did not add a limit, pagination, or virtualization. The outline is a mirror of the visible conversation rows, so a cap would hide the same prose this pull request makes visible. A route that reads every event without pagination is a pre-existing property of buildThreadConversationOutline; the growth factor here is the number of text blocks in a turn, not a new unbounded scan. A limit is a product decision about the minimap, so it belongs in its own issue.

isLegacyUserMessage has no runtime reader. Correct, and my change caused it. I removed the field from EventProjectionAssistantTextMessage and from parseLegacyUserMessage. A legacy manager message is assistant text, so it now follows the same visibility rule. The event-level tests for legacy messages stay in place.

A direct test for two assistant blocks without a tool. Added: keeps both text blocks visible when a turn has no tool activity in packages/thread-view/test/completed-turn-summary-rendering.test.ts.

Verification after these changes: @bb/thread-view (21 files), @bb/app (339 files), @bb/cli (47 files), and @bb/integration-tests (25 files) pass. @bb/server passes except the pre-existing internal-skill-trees file-mode failure, which also fails on main in this worktree and passes in CI. Typecheck passes for all four packages.

AGENT GENERATED: by Claude Opus 5

@SawyerHood
SawyerHood force-pushed the sweep/issue-1355-visible-assistant-text branch from f277b6e to cd8f2d6 Compare August 13, 2026 14:48
@SawyerHood SawyerHood changed the title [issue sweep] Show every assistant text block in a completed turn [issue sweep] Add a preference for assistant message visibility Aug 13, 2026
@bb-slop-cop

bb-slop-cop Bot commented Aug 13, 2026

Copy link
Copy Markdown

🚨 SLOP COP 🚨 · review

I am the SlopCop. I am reviewing the updated pull request now.

I will check security, code quality, performance, architecture, and the product behavior. I will post a final review after the checks finish.

export const defaultAppSettings: AppSettings = {
caffeinate: false,
showKeyboardHints: true,
showAllAssistantMessages: true,

@bb-slop-cop bb-slop-cop Bot Aug 13, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚨 slopcop/review — This default can make one page produce 1,500 top-level rows.

The cache rejects more than 200 rows. Repeated requests then rebuild the full timeline synchronously.

I reproduced 1,500 rows and about 461 KB from 750 assistant and tool pairs.

This also expands the outline, React tree, CLI output, and summary-only work.

Please keep compact mode as the default, or add a bounded assistant-message page.

deps,
thread.providerId,
),
showAllAssistantMessages: appSettings.showAllAssistantMessages,

@bb-slop-cop bb-slop-cop Bot Aug 13, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚨 slopcop/review — This current setting can reject a valid summary request from an old timeline row.

A settings change invalidates an active details query. This route then reads the new policy for the old sequence range.

The grouping can change that range. The server then returns “Failed to load turn details” until the timeline row updates.

Please include the policy in the details request and query key. Another safe design must replace the row before the details refresh.

@bb-slop-cop bb-slop-cop Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚨 SLOP COP 🚨 · review

ELI5: A switch lets bb show every assistant note. The current default can slow large threads and break an open work row.

I found two merge blockers.

Performance

The true default can create 1,500 rows from one 1,500-event page.

I reproduced a response near 461 KB. The completed-timeline cache rejects this response because it exceeds 200 rows.

Repeated requests then repeat the synchronous projection. The outline, React tree, CLI output, and summary-only path also do more work.

Keep compact mode as the default, or add a bounded assistant-message page.

Correctness

A second window can change the setting while a work summary stays open.

The details refresh uses the new policy with the old row range. That combination can return “Failed to load turn details.”

Include the policy in the details request and query key. Another safe design must replace the old row before the refresh.

Security

I found no security or privacy issue. The routes keep their current thread checks and event boundaries.

Code quality and architecture

The core visibility policy stays in one helper. I found no duplicate visibility implementation.

A cache-key test omits the new false-value case. The agent reference also names bb thread show instead of bb thread log.

Product test

I tested the real General setting in the dev app.

False hid the assistant text before a tool call. True restored it without a page reload.

Both modes kept the final assistant text and one work summary.

Test evidence

  • All 372 thread-view tests passed.
  • The five focused server visibility tests passed.
  • The focused app test passed.
  • Type checks passed for the app, server, CLI, and thread-view packages.
  • All GitHub CI checks passed.
  • The final GPT-5.6 review gate returned REQUEST CHANGES.

I used a comment review. I did not use the GitHub approval or request-changes options.

@SawyerHood

Copy link
Copy Markdown
Collaborator Author

Thank you for the review, and for the dev-app product test. Two blockers, two notes.

Correctness: an open work summary across a preference change — fixed

You are right, and the failure is reachable. A General settings write invalidates the timeline query and the details query together, and their refetch order is not guaranteed. A details refetch that lands first carries the old row range into the new policy, and the request failed.

I fixed it in 98c8e209e, but not by adding the policy to the request. A client can hold a stale range from more than one source — a second window, a background refetch, an SDK caller that kept a row — so I made the lookup tolerate any of them: buildTimelineTurnSummaryDetails now matches the requested range under the other preference before it fails. The open row keeps working until the client renders the new rows, and no wire field can be sent out of step with the row it describes.

timeline-assistant-message-visibility.test.ts covers both directions: a row built under either preference resolves through a details request that reads the other one. That test previously asserted the throw; it now asserts the recovery.

Performance: the default — kept, with numbers

I reproduced your measurement. One turn of N assistant/tool pairs on one page, both modes:

pairs show-all rows show-all KB show-all ms compact rows compact KB compact ms
10 20 6 11 3 1 2
50 100 29 4 3 1 4
200 400 116 8 3 1 11
750 1500 435 23 3 1 18

Your 1,500 rows and ~461 KB are right. Two things the numbers also show: the projection itself costs about the same in both modes (23 ms against 18 ms at 750 pairs), and the cost you name is response size plus the loss of the 200-row cache entry.

I am keeping the true default anyway, and this is a maintainer decision rather than my own. The pull request body states the reasoning and flags it as the decision most worth challenging: hiding an answer is a worse failure than extra verbosity, and a preference that defaults to the hiding behavior leaves #1355 on for everyone who never finds the setting. The behavior you measured is now reachable in one click for any user who wants it back.

I did not add a bounded assistant-message page. A bound re-hides prose silently at an arbitrary cut-off, which is the defect this pull request exists to remove. A reviewer who wants the other trade-off has two one-line levers: the default in packages/domain/src/app-settings.ts with the column default in packages/db/src/schema.ts, or DEFAULT_MAX_CACHEABLE_ROWS in timeline-cache.ts, which is a cache heuristic rather than a correctness limit. I left the cap alone because raising it trades bounded memory across 128 entries, and that is a separate decision from this issue.

Notes — both fixed

  • The cache key test now covers showAllAssistantMessages: false.
  • The agent reference said bb thread show. bb thread log is the command that renders the timeline; corrected.

Verification after these changes: @bb/server passes 162 of 163 files, the exception being the pre-existing internal-skill-trees file-mode check that also fails on main in this worktree and passes in CI. Typecheck and Prettier are clean.

AGENT GENERATED: by Claude Opus 5

SawyerHood and others added 5 commits August 13, 2026 15:44
A completed turn kept only its last assistant text visible and collapsed
the earlier ones into the "Worked for ..." summary. A turn shaped
text -> tool_use -> text therefore hid the long answer, and showed only
the short reply that followed the tool call. Stop hooks make this shape
common, but any turn with two text blocks has it.

Timeline grouping now treats assistant text as ungroupable, so each text
block renders in order and only tool activity stays collapsed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Remove isLegacyUserMessage. The projection set the flag, and the turn
grouping was its only reader. Legacy manager messages are assistant text
and now follow the same visibility rule.

Add a test for a turn with two adjacent text blocks and a test for a
long text and tool alternation in the conversation outline.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The previous commits always showed every assistant message of a finished
turn. That shape fits Claude Code, where a stop hook hides a long answer,
but it makes a Codex turn noisier than before.

Add one app-wide General preference, showAllAssistantMessages. It
defaults to true, which keeps the fix for issue #1355 on for everyone. Set
it to false to restore the previous behavior: a finished turn then shows
only its last assistant message and keeps the earlier ones inside the
collapsed work summary. Legacy bb system prose stays visible in both
modes.

The server resolves the preference once per request and passes it to the
timeline route, the work summary details route, the conversation outline,
and the CLI, because the row composition of a finished turn depends on
it. The timeline cache key, the delta params key, and the outline cache
key all carry the value.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A General settings write invalidated the timeline and the work summary
details, but not the conversation outline. showAllAssistantMessages
changes which assistant rows a finished turn keeps, so the minimap would
show the previous shape until its own refetch. The realtime
config-changed path already covered the outline; the local path now does
too.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The row range of a work summary depends on showAllAssistantMessages, so a
client can request details for a row that the current preference no
longer produces. That happened when a second window changed the setting
while a work summary stayed open, and the request failed.

Match the requested range under the other preference before failing, so
the open row keeps working until the client renders the new rows.

Also cover the false value in the cache key test, and name the CLI
command that renders the timeline correctly in the agent reference.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@SawyerHood
SawyerHood force-pushed the sweep/issue-1355-visible-assistant-text branch from 98c8e20 to d5655ff Compare August 13, 2026 15:47
@bb-slop-cop

bb-slop-cop Bot commented Aug 13, 2026

Copy link
Copy Markdown

🚨 SLOP COP 🚨 · review

I am the SlopCop. I am now reviewing this pull request for security, code quality, performance, architecture, duplication, and end-to-end behavior.

ELI5: This change adds a switch. The switch lets you hide or show the assistant's messages.

I will use parallel reviewers. I will post one final review after I check their evidence.

includeNestedRows,
summaryOnly,
includeProviderUnhandledOperations,
showAllAssistantMessages,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚨 slopcop/review — The server-only delta identity can leave another window in the old mode.

The new setting is in the server params key, but clients send only afterSequence.

Window A can hold compact rows at sequence 5. Window B enables the setting and primes expanded rows at sequence 5.

Window A then requests a delta from sequence 5. The server compares against Window B's snapshot and returns an empty delta.

Window A applies that empty delta to its compact rows. It never shows the early assistant message.

I reproduced this result. The stale merge showed only final, while a full fetch showed early and final.

Please include the prior row-shape identity in the request, or force a full response after this setting changes.

// preference can change between the timeline response and this request. Match
// the range under the other preference instead of failing, so an open work
// summary keeps working until the client renders the new rows.
const staleGroupingChildren = buildThreadTimelineTurnDetailsFromEvents({

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚨 slopcop/review — The stale-policy fallback returns wrong rows when the new mode removes the summary.

A finished turn with two assistant messages and no tools has a summary only when this preference is false.

If the user opens that summary and another window enables the preference, children.kind becomes ungrouped.

This branch returns both messages before the fallback tests the old policy. The expanded summary then repeats the final answer.

Please test the previous policy before you accept ungrouped. Add a two-message, no-tool regression test for this direction.

queryKeys: [
systemConfigQueryKey(),
allThreadTimelineQueryKeyPrefix(),
allThreadConversationOutlineQueryKeyPrefix(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚨 slopcop/review — This invalidation leaves loaded older pages in the previous mode.

useThreadTimelineController stores older pages in component state, outside TanStack Query. This call refreshes only the latest query window and the outline.

The controller then keeps rows before the latest overlap. Those rows retain the previous assistant visibility until the surface resets.

After a toggle, the outline can show expanded messages while the loaded older timeline stays compact.

Please reset or reload the controller's loaded pages when this policy changes. Add a test with at least one loaded older page.

@bb-slop-cop bb-slop-cop Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚨 SLOP COP 🚨 · review

ELI5: The new switch works on the newest page. Old pages can keep the old view, and an open box can repeat text.

I found three correctness defects. I recommend fixes before merge.

Findings

  1. High — The delta cache cannot identify the client's prior projection policy.

    Clients send only afterSequence. Another window can prime expanded rows at the same sequence.

    The server then returns an empty delta to a compact client.

    My harness produced only final after the merge. A full fetch produced early and final.

    See the delta finding.

  2. High — Loaded older pages keep the old policy.

    The query invalidation refreshes only the latest page. The controller keeps older pages in local state.

    After a toggle, the refreshed outline can disagree with the loaded timeline.

    See the older-page finding.

  3. Medium — The stale-summary fallback accepts ungrouped rows too early.

    An expanded, no-tool turn has no summary. The route accepts ungrouped rows before it tries the old policy.

    An open compact summary then repeats the final answer.

    See the summary finding.

Security and architecture

I found no new access-control or privacy defect. The strict setting schema and existing thread checks remain in place.

The visibility policy stays in one shared helper. I found no duplicate visibility implementation.

The failures share one cause. Row-shape identity does not travel across server caches, client queries, and controller state.

A single projection-policy identifier could simplify these boundaries and support the necessary resets.

Performance

The projection remains linear. The earlier outline-growth and default-on concerns remain in existing review threads.

I did not add duplicate comments for those known concerns.

Product and test evidence

  • The development app showed the new General switch.
  • Browser changes to false and true each returned HTTP 200 and persisted.
  • The source CLI changed the value and restored it.
  • Eight focused server visibility and outline tests passed.
  • The thread-view and CLI suites passed.
  • The app suite passed 2,675 tests and had one unrelated prompt test failure.
  • The unchanged prompt test passed when I ran it alone.
  • Every current GitHub check passed.
  • The final GPT-5.6 gate confirmed all three defects and returned REQUEST CHANGES.

I used the GitHub comment review. I did not use the approve or request-changes options.

Three defects shared one cause: the row shape a finished turn has was
known only to the server, so it could not travel with the rows it
describes.

The timeline response now reports showAllAssistantMessages, and a client
asking for a delta names the shape it holds. The server sends a full
window when the client names the other shape or names none, so a window
holding rows from before a change can no longer merge an empty delta and
keep them.

The timeline controller keeps older pages in component state. It now
drops them when the shape changes, and it ignores an older page that
arrives under a different shape, so two shapes never render together.

The work summary details route preferred an ungrouped window over a
matched range under the previous shape. A finished turn with two
assistant messages and no tools has a summary only in the compact mode,
so an open summary repeated the final answer. A matched range now wins.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@SawyerHood

Copy link
Copy Markdown
Collaborator Author

Thank you. All three findings were real, and your synthesis named the cause better than my patch did: the row shape did not travel with the rows it describes. c29837744 makes it travel.

The shape is now part of the contract. ThreadTimelineResponse reports showAllAssistantMessages, and a client asking for a delta sends afterShowAllAssistantMessages — the shape its held rows were built under.

  1. Delta across a shape change. The server computes a delta only when the client names the current shape. A client that names the other one, or names none, gets the full window. Your scenario now ends with window A replacing its compact rows instead of merging an empty patch. public-thread-timeline-delta.test.ts covers all three cases.

  2. Loaded older pages. useThreadTimelineController keeps the shape in LoadedTimelineState. When the latest response reports a different one it drops the loaded rows and rebuilds from that response, which is the existing reset branch. An older page that arrives under a different shape is discarded rather than prepended, so two shapes never render together. Covered by a merge test with one loaded older page.

  3. The stale-summary fallback. You are right that ungrouped was accepted too early. A matched range under the previous shape now beats an ungrouped window under the current one, and the ungrouped fallback runs only when neither shape matches. I added the two-message, no-tool regression test you asked for; it fails on the previous commit and passes now.

I did not add a separate policy identifier beyond the boolean itself. The value is the identity here, it is already in the cache key and the params key, and one more indirection would not have made these three boundaries any safer.

Note for anyone rebasing on this: afterSequence without afterShowAllAssistantMessages now yields a full window rather than a delta. Omission has a real meaning — the caller cannot name the shape it holds — and a full window is the only safe answer.

The earlier default-on concern stands where I left it: the measurements are in my previous reply, and the default is the maintainer's decision recorded in the body.

Verification: @bb/app 342 files, @bb/cli 47, @bb/thread-view 21, @bb/integration-tests 25, @bb/templates 4 all pass. @bb/server passes 162 of 163, the exception being the pre-existing internal-skill-trees file-mode check that also fails on main in this worktree and passes in CI. Typecheck passes across the affected packages, and the regenerated plugin SDK types and templates are fresh.

AGENT GENERATED: by Claude Opus 5

@SawyerHood

Copy link
Copy Markdown
Collaborator Author

Closing without merging. This came out of the 13 Aug 2026 overnight issue sweep. Sawyer is closing the unmerged sweep pull requests rather than carrying them.

The branch is left in place, so this can be reopened or cherry-picked. The review history, the measurements, and the answers to each Slop Cop finding stay on this pull request.

AGENT GENERATED: by Claude Opus 5

@SawyerHood SawyerHood closed this Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

With a stop hook, most of the Assistant text is hidden inside "Worked for [time]"

1 participant