Skip to content

fix(chat): a structured agent's question can always be answered from the chat - #186

Draft
Stener1 wants to merge 4 commits into
cosscom:mainfrom
Stener1:structured-ask-card
Draft

Stener1 wants to merge 4 commits into
cosscom:mainfrom
Stener1:structured-ask-card

Conversation

@Stener1

@Stener1 Stener1 commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

Summary

A structured Claude session (driver: "claude", the chat's header says "stdio") that asked an AskUserQuestion while helpers it had left in the background kept working showed a bare "Claude asks you" card with no options. The reply box said "Pick an answer above first", Send was disabled, and the terminal can't be opened while the agent waits. There was nothing the person could do.

Root cause: its agent-host log keeps the helpers' lines beside the conversation. A chat read afresh (a box restart, a chat nobody had open for a while) reads the log's last 4 MB, and there the helpers had written megabytes after the question. The window held no conversation and no question, so the pane fell back to the permission-style card, which locked the reply box.

 conv.read (a long file, opened afresh)
-  read its last 4 MB
+  read its last 4 MB
+  fewer than 20 items? read again from 16 MB back, then 64 MB (as Before pages)

 addMessage (another agent's message or ping)
   closeArtifacts()
-  closeQuestions()          # a helper back counted as the person's answer
 atMenu (lib/questions.ts): the reply box waits for a pick above
-  any ask the box reports → locked
+  structured: only something to pick here locks it (a form the box fills in,
+    options read, options still being read); with nothing, the reply is the
+    answer (claudeDriver.Send: no, and the words)
+  in its terminal: as before (its own screen opens as the way out)

 <Permission> card with no options
-  "Its options aren't on its screen: answer it in the terminal."
+  structured: "Reply below to answer it."

The pane also skips the stand-in card for a form it just showed and the record has answered, while the box catches up (keyed to that form's call in that wait). conv gets one constructor (newConv/restart) in place of five hand-written copies, two of which had already drifted.

verify-berthd: a new chat-structured-ask-live scenario (a real structured Claude, four background helpers, a box restart). dev-box.sh gains VERIFY_DRIVER=claude and restart [berthd], and features/chat-ask-card.md gains structured-form and structured-reply.

Evidence

A real structured Claude Code on a dev box of this checkout (chat-structured-ask-live). Four background helpers read 100 files while the question waited, and they reported back with the question 6.2 MB before the log's end. Then the box restarted, so the chat read the log afresh.

  • Before (main's berthd and app): only a bare card; "answer it in the terminal"; Send disabled.
    before
  • After, nothing to pick (this app, main's berthd, so the window still has no form): "Reply below to answer it"; Send works. Claude's log gets the words as the answer (control_response) and it goes on.
    reply below
    replied
  • After (this berthd and app): the whole conversation, the form with its options, and Crew "All back". Picks 2.5 and Customers are submitted, Claude's log has both answers and Claude replies "Release 2.5, for customers.", and no stand-in card appears meanwhile.
    form
    answered

Tests:

TestAQuestionStaysOpenWhileItsHelpersWorkOn   host log: question, 5 MB of a helper's lines, its notification
  main: read afresh → no items                                  FAIL
  here: read afresh → prompt first, open question last          PASS
TestAHelpersWordDoesntAnswerTheAgentsQuestion  question, helper ping, hand-back → still open; a prompt → settled
  main: FAIL   here: PASS
questions.test.ts   lastQuestion / atMenu, structured vs terminal          PASS
e2e/ask-card.spec.ts (+4): structured form after helper pings; no-options card takes a reply;
  a next question after an answered one keeps its card; a terminal permission still holds the box   11/11 PASS

A fresh read of a real 21 MB log of this shape takes 140 ms, against 0 items before. Checks: go vet, go test -race ./internal/transcript, the app's checks, pnpm test (581), pnpm build, tsc -p e2e, the docs build, and e2e/ask-card + e2e/chat (24).

  • In the full go test -race ./..., TestTheCatalogIsCapped fails on this machine on main too: it counts this machine's real command list.
  • TestGitHubLooks… and TestServicesAreCounted failed only under the full run's load; both pass alone.
  • cargo check can't build glib-sys here (no GTK dev libraries). No Rust changed.

Merge Danger

Door: two-way

App and transcript-reading only. No stored data or API changes. A revert restores the old behaviour.

Blast Radius: chat

  • A fresh read of a long log whose last 4 MB hold fewer than 20 items now parses up to 64 MB once (about 0.1–0.3 s, under the reader's lock). It runs only on the first read, never on a poll.
  • Another agent's message no longer closes an open question; its tool result or the person's next prompt still does.
  • In structured sessions the reply box no longer locks at a card with nothing to pick. Typed text answers with a no plus the words, as claudeDriver.Send already did when sent with force.

This touches the same pane as #184 (the hourglass for a turn that ended while its work runs on), in nearby lines: #184 changes state/mode=, this one openQ/atMenu/blocked. Whichever merges second rebases with a small conflict at most.

🤖 Generated with Claude Code

@vercel

vercel Bot commented Oct 23, 2026

Copy link
Copy Markdown

@Stener1 is attempting to deploy a commit to the seanbrydonio's projects Team on Vercel.

A member of the Team first needs to authorize it.

@Stener1

Stener1 commented Oct 23, 2026

Copy link
Copy Markdown
Contributor Author

This is a draft only because of GitHub's open-PR limit for my account. It's ready for review and will be marked ready automatically when a slot frees. I can't add run-ci here, so could a maintainer add it? The checks are listed under Evidence, and all of them pass locally.

@keithwillcode

Copy link
Copy Markdown

@cubic-dev-ai review this pull request

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 23, 2026

Copy link
Copy Markdown

@cubic-dev-ai review this pull request

@keithwillcode I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 19 files

Reply to a comment to ask cubic a question or push back. It learns from your replies.

View guided diff | Re-trigger cubic

Comment thread .claude/skills/verify-berthd/features/chat-questions.md Outdated
Comment thread internal/transcript/host_test.go Outdated
Comment thread app/src/lib/questions.ts
Comment thread app/src/components/conversation/conversation-pane.tsx Outdated
Comment thread .claude/skills/verify-berthd/scripts/dev-box.sh Outdated
Comment thread .claude/skills/verify-berthd/scripts/dev-box.sh Outdated
Comment thread .claude/skills/verify-berthd/scripts/scenarios/chat-structured-ask-live.mjs Outdated
Comment thread internal/transcript/peer_test.go Outdated
Comment thread .claude/skills/verify-berthd/features/chat-ask-card.md Outdated
Stener1 and others added 4 commits October 23, 2026 22:50
…the chat

A structured Claude session whose helpers kept working in the background
after it asked a question showed a bare "Claude asks you" card with no
options, and a reply box that took nothing. Its log keeps the helpers'
lines beside the conversation, so a chat read afresh (a box restart, a
chat nobody had open) read a 4 MB window with none of the conversation in
it, and the question with it.

- transcript: a window read afresh reaches further back (up to 64 MB, as
  a page of older items does) when it holds next to none of the
  conversation; one constructor for a reading of a file.
- transcript: another agent's message no longer settles a question the
  agent asked the person.
- app: a structured agent's card with nothing to pick says "Reply below
  to answer it", and the reply box takes the answer; an agent in its
  terminal keeps the old hold. A form just answered leaves no stand-in
  card while the box catches up.
- verify-berthd: chat-structured-ask-live drives it on a real structured
  agent; dev-box.sh gains VERIFY_DRIVER=claude and restart.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sion's card

The pane can change session; the form it remembers showing is now that
session's, by its key, as well as by its wait and its call.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… prompt closes it unanswered

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e structured-ask scenario reads a growing log

- serve stops when berthd exits or isn't serving after a minute, saying
  where its log is.
- restart checks the build is there before it stops the running one, and
  waits for the old process to exit, not just for its port.
- chat-structured-ask-live skips the log's half-written last line and
  counts helpers back from the prompt, so one back before the question
  counts.
- The notes give dev-box.sh's full path and label the array block bash.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Stener1
Stener1 force-pushed the structured-ask-card branch from bb685b9 to 1387798 Compare October 23, 2026 23:10

This branch has not been deployed

No deployments
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.

2 participants