Skip to content

Tick Send to Chopin by default on a new comment - #544

Merged
MaggieAppleton merged 5 commits into
mainfrom
design-comment-send-default
Oct 13, 2026
Merged

MaggieAppleton merged 5 commits into
mainfrom
design-comment-send-default

Conversation

@MaggieAppleton

@MaggieAppleton MaggieAppleton commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

A new comment in a document now starts with Send to Chopin ticked and the @Chopin chip in place, wherever a Planner runs.

Decisions

  • New top-level comments (desktop popover and phone draft sheet): ticked by default. Both go through DraftCard, so they share the default.
  • Replies: unchanged, unticked. A ticked reply would always hold the chip, which keeps the folded one-line reply field permanently open, and replies are often to the people in the thread. @chopin or the box still address Chopin.
  • AGENT=off: starts unticked. The editor's existing planner widget option (session.agent) drives it. Ticking it still works as before: the server saves the note and the thread says "Chopin isn't running". Sending never fails here, so the box stays enabled and gets no new copy.
  • Read-only viewers: no change. They never get a draft composer (comment-layer clears the draft when canEdit is false).
  • Unticking: lasts for that comment only. Nothing stored a preference before, and nothing does now. Each new comment starts ticked, and after a send the composer resets to its default.
  • HARNESS=remote with no attached Planner: starts unticked. The default uses the same attachment state as Build's plannerDetached (agent && !plannerDetached), passed as a new comment-only widget option, commentPlanner. planner={agent} is unchanged, so decisions read it as before.

Server

Under HARNESS=remote with no Planner attached, admit() now refuses a Planner-addressed comment or reply before anything is saved. It returns code: "planner-not-attached" and the message that says how to attach one, the same as chat:send and task drafts do. Before, it saved a note whose turn could never run. comment.d.ts adds the optional code to the start and reply refusals. The composer shows the message and keeps the words. Persistence-before-publication is unchanged.

Otherwise: A ticked comment sends comment:start with to: "planner". admit() asks Chat.admission, persists the note with to: "planner", and only after the commit runs send(), which is the existing explicit Planner turn. Authorization is unchanged: the same writer checks gate comment:start.

Tests

  • Server: comments-planner.test.ts checks that an unattached remote Planner refuses a new comment and a reply with planner-not-attached, saves nothing and queues no turn, and that ordinary replies still go through.

  • E2E: in planner-attachment.e2e.ts (HARNESS=remote) the box starts unticked with no Planner attached, a ticked send is refused with the attach message and the words are kept, and once a client attaches a new comment starts ticked.

  • Unit: the draft is ticked with its chip, unticked with planner={false}, and a reply is unticked.

  • E2E: harness-comments (AGENT=on) checks the box starts ticked, then unticks before the @chopin typing path. comment-send-off (AGENT=off) checks it starts unticked.

  • Design-contract: comment-layer.tsx source hash renewed in its own commit. The only change is a planner prop passed to DraftCard; the dynamic geometry and motion owners are unchanged.

Screenshots

The @Chopin chip now centres on the field's first line on phone too. Touch raises the field's text to 16px and the sheet pads its top, which left the chip sitting above the text.

Desktop Phone
Desktop draft Phone draft

🤖 Generated with Claude Code

Landing validation

Rebased onto the merged comment-card change with unchanged prepared patches and valid combined design hashes. Local CI, types, production build, 86 focused units, 40 comment browser cases, three fake-Planner cases, and the attached-Planner case passed. Prior GitHub CI was green; administrator bypass avoids repeating a full cycle for the source-preserving rebase.

@MaggieAppleton

Copy link
Copy Markdown
Collaborator Author

Review: Changes needed. One small fix: gate the default on an attached Planner. Everything else is good.

Checked on a local fake-harness server (desktop 1440×900, phone 390×844) and on a second server with HARNESS=remote and no client attached.

What works

  • Desktop popover and phone draft sheet both open with Send to Chopin ticked and the @Chopin chip in place.
  • Unticking applies to one comment only. The next new comment opens ticked again, both after a send and after Escape.
  • A ticked comment starts exactly one Planner turn, after the save: one "Comment on … sent to Chopin" notice, one turn, and a reply in the thread. An unticked comment adds nothing to Chat.
  • Replies stay unticked. AGENT=off starts unticked (comment-send-off covers it).
  • Data flow is fine: comment-layer.tsx only passes planner={options.planner !== false} to DraftCard. The server path is unchanged: admit() → persist → send(). The hash renewal is safe.
  • Chip alignment on phone (4086660): the chip's centre is at 747.0px and the field's first line centres at 747.0px (16px text, 24px line). It looks right. Desktop is unchanged.

Needs a change: HARNESS=remote with no attached Planner
With this PR, every new comment there is sent to Chopin by default. I reproduced it:

  • Chat gets a "Comment on … sent to Chopin" notice, then a system line: "This channel's Copilot owner is unavailable." That copy is wrong for this harness, and the person didn't ask for any of it.
  • The thread shows @Chopin Can you shorten this? and then nothing. No reply arrives, and no clear state says why.
  • The composer already shows "Planner: none attached. @chopin needs an attached Planner." So we tick a box that we know will fail.

That means an error on every comment, so the default is a bad experience here.

Suggested fix: tick by default only when a turn can actually run. room-workspace.tsx already tracks plannerAttachment. It is the same state that useBuildPlan gets as plannerDetached (around L636). So:

  • Tick by default when: agent && !(plannerAttachment.wire === wire && plannerAttachment.planner && plannerAttachment.planner.state !== "attached"). That covers both "none attached" and "held".
  • Pass it through a dedicated widget option, for example commentToPlanner, used only by DraftCard. Don't change planner={agent}: decisions.tsx and questionnaire.tsx also read options.planner.
  • Ticking the box by hand keeps working as it does today.

Follow-up (existing gap, not this PR)
comments/service.ts admit() doesn't ask plannerNotAttached, unlike Chat.send and draftTasks. So even a hand-ticked comment under remote ends in the misleading "Copilot owner is unavailable" line. It should refuse, or save and announce, with the planner-not-attached message.

Minor

  • comments.test.tsx: /<input[^>]*type="checkbox" checked/ depends on attribute order. /<input[^>]*\bchecked\b/ is sturdier.

MaggieAppleton and others added 5 commits October 13, 2026 12:19
A new top-level comment starts addressed to Chopin, with its @chopin chip,
wherever a Planner runs; unticking it, or Backspace at the start, sends an
ordinary comment as before. Each new comment starts ticked again: nothing
remembers an untick. Replies keep their unticked default, so the reply
field stays one quiet line until it is used. Where AGENT=off the box starts
unticked, since nothing would act on the note.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reviewed dynamic owners in comment-layer.tsx keep the same data flow:
the change only passes the widget options' planner flag to DraftCard; the
measured overlay geometry and motion-contract classes are untouched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Touch raises the field's text to the 16px floor and the sheet pads the
field's top, while the chip kept its small size at the very top, so on a
phone it sat above the text. The chip now centres on the first line from
the field's own text size and top padding; desktop is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Under HARNESS=remote a document with no attached Planner now starts a new
comment unticked, from the same attachment state Build uses, passed as a
comment-only widget option so decisions keep reading planner as before.

A comment sent to Chopin there is refused before anything is saved with
the planner-not-attached code and the message that says how to attach one,
as chat:send and task drafts are, instead of saving a note whose turn could
never run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reviewed dynamic owners in comment-layer.tsx and plan-editor.tsx keep
the same data flow: plan-editor passes one more boolean into the widget
options and comment-layer reads it for DraftCard; overlay geometry and
motion-contract classes are untouched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaggieAppleton
MaggieAppleton force-pushed the design-comment-send-default branch from 9799b28 to 4516d03 Compare October 13, 2026 11:21
@MaggieAppleton
MaggieAppleton merged commit 8d29a9b into main Oct 13, 2026
3 of 4 checks passed
@MaggieAppleton
MaggieAppleton deleted the design-comment-send-default branch October 13, 2026 11:21
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.

1 participant