Skip to content

fix(feed): agent questions post as answerable choices, named for their agent - #28846

Open
azooz2003-bit wants to merge 3 commits into
feat-cmux-nextfrom
feat-cmux-next-feed-question-choice
Open

azooz2003-bit wants to merge 3 commits into
feat-cmux-nextfrom
feat-cmux-next-feed-question-choice

Conversation

@azooz2003-bit

@azooz2003-bit azooz2003-bit commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

What

The Mac's feed bridge posted every question an agent asks in its chat (Claude Code's AskUserQuestion, a Codex request_user_input) as a bare notice: "Agent asks: <first question, cut to 160 characters>", with no options, no body and the poster "Agent". Only a Chief subagent's report (a message of its own in the reports basket) showed what an agent actually said, which is why only optchat-* agents' events looked complete in the Feed.

Now:

  • A question that fits a feed choice (1 to 4 questions, 2 to 8 options each, the owner's bounds in feed-kinds.ts) posts as a choice request. Its body lists every question in full with its options and descriptions. Its prompt uses positional ids (q0, o0), because Claude keys answers by question text and the owner caps ids at 40 characters. The person answers it inline in the Feed.
  • The person's choice answer maps back by position onto the same request. The bridge re-reads that request and checks it is still pending with the same digest, then sends it to acpmux as the question's own answer (AgentQuestion.reply, _acpmux/permission_respond, with answeredBy).
  • Trust: an answer the person gives in this Mac's own Feed goes to acpmux on the bridge's person-proven connection (FeedModel.onAnswer → answeredHere), as an answer typed in the chat would. Answers relayed by the owner from another device are admitted only from another install, the same rule a Deny already follows: never a session: answer, and never this Mac's own install. A question is not a permission (Leo 2026-10-21), so no phone presence proof is required. Approvals are unchanged.
  • Every item the bridge posts is named for its agent: the session's name from _acpmux/info ("claude", "codex", "Fix login"), not "Agent".
  • A question that does not fit a choice stays a notice, now also named for its agent.
  • The pure post builders moved out of the App into CmuxNextAgentPane/Approvals/AcpmuxFeedPost.swift, together with their 6 strings, which were moved byte-for-byte between catalogs. The question-to-choice mapping is new in CmuxNextAgentQuestion/AgentQuestionFeedChoice.swift. Net App lines: −3.

The phone half (every finished turn's card shows the agent's whole reply, not a 160-character flattened preview) went straight to feat-cmux-next as iOS work: db183fa..c78a916 .

Tests

CmuxNextAppTests/AcpmuxFeedBridgeQuestionTests (fleet package-test-lane.sh suite, Xcode 26.6): passed at 8b3a043 (cmux-ci step 6e65559206f0faea6d6ef847, aws-m4pro-8)

  • aQuestionPostsAsAnAnswerableChoice: choice kind, options, body, agent poster.
  • aChoiceAnswerAnswersTheQuestion: a feed answer maps back to permission_respond params; unknown question or option ids answer nothing.
  • aSessionAnswerNeverAnswersAQuestion: a session or this Mac's own install, relayed through the owner, never answers.
  • aQuestionThatDoesNotFitAChoiceStaysANotice
  • aToolPermissionStillPostsAnApproveItem, plus the 2 existing question-title tests.

Observed / Not run

  • Observed: the suite above on the fleet; the prepush gate (no new violations, App −3 lines); and the tagged dev build feed-event-details (fleet job 106cb1fb41c1fd6fb2884966), built and published.
  • Not run: a live end-to-end answer from the Mac Feed into a real Claude Code session. That needs a signed-in cloud Feed and a live acpmux question; no capture scene seeds either.

No capture: the visible change is the content of a feed item (a choice card instead of an "Agent asks:" line). The choice card UI itself (FeedChoiceControls) is unchanged. No capture scene can post a bridge item without a signed-in cloud Feed and a live acpmux question. The before/after post bodies are in the report.

Changelog

  • Fixed: Feed questions from Claude Code and Codex chats show every question and option and can be answered right in the Feed, and every Feed event names the agent that posted it.

🤖 Generated with Claude Code

azooz2003-bit and others added 3 commits October 30, 2026 18:56
…or its agent

The Mac's feed bridge posted every acpmux question (Claude Code's
AskUserQuestion, a Codex request_user_input) as a bare notice: "Agent asks:
<the first question cut to 160 characters>", no options, poster "Agent".
Only a Chief subagent's report, which arrives as a message of its own, showed
what an agent said; every other agent's events read as one thin line.

A question that fits a feed choice (1-4 questions, 2-8 options) now posts as a
choice request: every question and option whole in its body, positional ids
(q0/o0) in its prompt, the session's name as poster. The person's choice
answer maps back onto the same request (re-read, same digest) and goes to
acpmux as the question's own answer (CmuxAgentQuestion reply). Session answers
are refused; a question is not a permission, so no presence proof is needed,
as on the chat pane and the dialog socket. Other questions stay notices, now
named for the agent; approvals name the agent too.

Tests: CmuxNextAppTests/AcpmuxFeedBridgeQuestionTests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ces as the owner counts

Review follow-ups:
- An answer the person gives in this Mac's own feed goes to acpmux through the
  bridge's person-proven connection (FeedModel.onAnswer -> answeredHere), as an
  answer in the chat would; the Mac feed's own answers reach the owner as a
  session and would be refused. Owner answers are admitted only from another
  install, as a deny (never a session, never this Mac's own install).
- Choice text is cut by UTF-16 units (the owner counts JS string length), and a
  choice whose cleaned question or label is empty posts as the notice.
- _acpmux/info for the agent's name does not wait for the session log.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…from the bridge's nonisolated statics)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@azooz2003-bit azooz2003-bit added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 31, 2026
@github-actions

github-actions Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 8b3a043: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr28846 -f ref=feat-cmux-next-feed-question-choice -f platform=macos -f backend_mode=local

red: cmux-next checks (god files, concurrency, crash safety, l10n); base red: the same failure on the base db183fa; does not block

Default changes

This pull request changes 2 defaults at 8b3a043182e8 (what everyone gets without configuring anything):

  • tunable-source.CmuxNextAgentPane/Approvals/AcpmuxFeedPost.swift:shown: (none) -> "dcfce72c14947590edd351deb9bd49e36b3df577f900ec6ec80afa31b6d065da"
  • tunable-source.CmuxNextApp/Feed/AcpmuxPermissionFeedBridge.swift:postBody: (none) -> "5d901d331fa457cb96b56b0fa8d0b180ece054bbe7e6af5e49c12631b680f95e"

Needs a review. It passes with an independent review receipt on this commit: a comment or review whose first line is Review (<reviewer>): SHIP at 8b3a043182e81d35df6aefe62f518619931744bb, from a member, not a self-review (the newest verdict naming the head decides; a later BLOCK beats an earlier SHIP), or with an approving review on this commit from @lawrencecchen or @austinywang or @teamleaderleo (the call owners in .github/defaults-call-owners.json, never the author). A receipt posted as a review re-runs this check; after a plain comment, re-run it. The needs a call label alone does not pass, and a new push needs a new receipt.

Regenerate the snapshot with python3 scripts/ci/defaults_guard.py snapshot.

@azooz2003-bit

Copy link
Copy Markdown
Collaborator Author

Correctness review (subagent), and how each finding was resolved

Head reviewed: f17fd36 (and, for iOS, the commits that went straight to feat-cmux-next). Current head: 8b3a043. Verdict: no blockers.

Mac findings

  1. Major. Lengths were cut by Character count while the owner counts UTF-16 units. A question or label could also come out empty after cleaning. Either way the owner rejects the post and nothing is posted.
    • Fixed: AgentQuestionFeedChoice.cut now counts UTF-16 units. parts(clean:) returns nil when a cleaned question or label is empty, and the question then posts as the notice.
  2. Major (policy). The first version admitted this Mac's own install with no proof, so a local process holding that install could steer an agent through "Other" text.
    • Fixed: the owner path now uses the existing Deny rule (admits(by:ownInstall:)). Session answers and this Mac's own install are refused.
    • The person's answers in the Mac Feed go through answeredHere on the bridge's person-proven acpmux connection, the same authority as typing the answer in the chat.
    • This also fixes the "Mac feed answers arrive as session: and are refused" case.
  3. Minor. A refused answer still closes the card silently.
    • Not changed here: approvals behave the same way today. Follow-up.
  4. Minor. _acpmux/info waited for the session's logs to load.
    • Fixed: it now passes waitLogs: false.

Verified correct by the reviewer

  • The approve body is moved byte-for-byte, so shownSHA256 gets the same input.
  • Positional id mapping is bounds-checked.
  • The digest is re-checked before answering.
  • withdrawResolved cancels choice cards too.
  • FeedChoiceControls produces .choice, which itemsChanged handles.

iOS findings (landed on feat-cmux-next as c78a916)

  • The complete test was wrong. Fixed: it now uses hasMore plus maxBytes.
  • A card could take the next turn's reply. Fixed: the read stops at the card's own turn_result.
  • Long turns fell back to the preview. Fixed: a tool call, thought or plan marks where the last message starts.
  • A failed read was retried on every refresh. Fixed: the negative result is cached.
  • fullReplies grew without bound. Fixed: it is pruned to the cards still in the Feed.

Tests

  • Mac: AcpmuxFeedBridgeQuestionTests green at 8b3a043.
  • iOS: FeedFullReplyTests was red on the base behaviour (step 7382fc0f), then green at 38/38 and 40/40 after the review fixes.

@blacksmith-sh

blacksmith-sh Bot commented Oct 31, 2026

Copy link
Copy Markdown

Found 2 test failures on Blacksmith runners:

Failures

Test View Logs
test_a_picked_signing_label_has_a_rerun_alternative (main.RunsOnFallbackTests.test_
a_picked_signing_label_has_a_rerun_alternative)/
test_a_picked_signing_label_has_a_rerun_alternative (main.RunsOnFallbackTests.test_
a_picked_signing_label_has_a_rerun_alternative)
View Logs
test_no_runs_on_chain_ends_on_the_reserved_side_label (main.RunsOnFallbackTests.tes
t_no_runs_on_chain_ends_on_the_reserved_side_label)/
test_no_runs_on_chain_ends_on_the_reserved_side_label (main.RunsOnFallbackTests.tes
t_no_runs_on_chain_ends_on_the_reserved_side_label)
View Logs

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@teamleaderleo

Copy link
Copy Markdown
Collaborator

For awareness: this PR has a SHIP review at its head, but GitHub reports it as conflicting with feat-cmux-next, so the lander's update-branch can't merge it and it can't land as is. Files that conflict in a test merge against the current base: Packages/macOS/CmuxNext/Sources/CmuxNextAgentPane/Resources/Localizable.xcstrings. Once feat-cmux-next is merged into the branch and the conflicts resolved, it needs only a quick review of the resolution before it can land. (From the conflict sweep; no push was made to this PR.)

@teamleaderleo

Copy link
Copy Markdown
Collaborator

Awareness note from an agent lane that does not own this PR; it is not a review or a request to take the PR over.


Awareness from #33562: a dropped ACP answer receiver now returns agent_gone rather than success. The caller audit found AcpmuxPermissionFeedBridge.swift:424 only logs a refused permission_respond; it does not reflect failed delivery on the Feed item or phone. This belongs with the Feed owner; no Feed code was changed. Tracked with reproduction and related caller findings in #33565. Please preserve a visible not-sent result when the underlying agent is gone.

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 8b3a0431 Deployed Oct 31, 2026 by azooz2003-bit via namespace autofix #8933
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants