Skip to content

Hide decided decisions without prose from the document, and owe a review when one is answered - #548

Merged
MaggieAppleton merged 13 commits into
mainfrom
design-hide-unlinked-decided
Oct 13, 2026
Merged

MaggieAppleton merged 13 commits into
mainfrom
design-hide-unlinked-decided

Conversation

@MaggieAppleton

@MaggieAppleton MaggieAppleton commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

Maggie answered one decision in a blank document and was left with a lone "⤭ Decided: … · @MaggieAppleton / No related text" line. While the Planner writes up several answers, the document showed a stack of these lines too.

Why it said "No related text"

When the Planner asks a question in a blank document, the question has no blocks to point at. The empty anchor set gets stored while the question is open (pending: false). Any commit's rebase saves it as it reads. Once the question is answered, that set reads as reviewed and deliberately empty. So the card says "No related text", and the question never appears in anchors_pending, which means nothing asks the Planner to write or link its prose. The fake Planner's ASK-DECISIONS reproduces this exactly (screenshot below).

Fix (server): answering a decision now marks each anchor set that points at nothing as owed (pending, missing) and sends plan:anchors to the room. A decision that already points at prose is unchanged.

flowchart LR
  A[ask in blank doc<br/>blocks: none] --> B[open: anchors [] pending:false]
  B -->|answer, before| C[reads as reviewed-empty<br/>'No related text', no review owed]
  B -->|answer, now| D[pending: missing<br/>on anchors_pending, relayed]
  D -->|Planner edit_plan + anchor_plan| E[linked: marker + wash]
Loading

What the document shows now

  • Display only. A decided card shows in the document only through the prose it lives in, as the margin marker and wash. If it is pending, deliberately empty or orphaned, its decorator draws nothing. The projection node stays and records are untouched. The full card, its counts, Reopen and Discard stay in Decisions.
  • Real in-progress work only. While a Planner turn is running, or a conversation write-up job is writing, for decisions that have no prose yet, the first of them shows one quiet line: "Writing up N decisions…". Decided cards that a deck still draws are not counted. The line goes away when the prose lands.
  • Blank stays blank. When hidden decisions are all a document holds, the usual "Start writing, or ask Chopin to plan" placeholder shows in the first empty paragraph, at the same spot as in an empty document, and typing goes there. Lexical shows no placeholder next to a decorator node, so the page sets it. Backspace and Delete do nothing while the document is blank, so they can't strand the caret beside a hidden decision.
  • Decisions tab. The write-up status and Retry for a conversation decision move to its Decisions card. "Linking…" now shows only while a Planner turn runs. Otherwise it says "Not linked yet".
  • Open decisions are unchanged. Inside a deck, decided members use Fix the deck's card-to-card motion, keep decided cards full size, and bound the pager #540's full-size card. The settled line is gone: nothing draws it any more.

Before / after

Maggie's case: a blank document with one answered decision.

Before After
before one after one

It stays fully visible in Decisions:

decisions

Several decisions waiting on prose:

Before After, Planner writing After, prose landed
before five writing landed

The same flow when the Planner ends its turn without writing: the document is blank (placeholder) and Decisions says the answers are not linked yet.

Document Decisions
after five not linked

A linked decision still shows inline, as its marker:

linked

Tests

  • Unit: cardPresentation for inline, deck and list. Document visibility for each relationship state (pending, empty, orphaned, linked). The writingProse predicate. The write-up Retry on the Decisions card. Anchors.answer. A durability test that a question asked into a blank document still owes a review once answered, and that the change is relayed.
  • E2E: the harness covers a blank document with answered decisions (placeholder shows, typing works, Decisions keeps the cards). The new ASK-DECISIONS THEN-WRITE fake Planner shows "Writing up 3 decisions…" and then the linked prose. Settled-line expectations are updated in the decision-marker, icon-size, inline-deck, sidecar-card-states and decision-prose suites. I ran the harness, decision-marker, icon-size, inline-deck and sidecar-card-states suites locally against my own servers. decision-prose.e2e.ts passed all 12 cases in the manual conversation-plan configuration after synchronizing Document navigation, persisted history expansion, and the collapse/reopen test with real browser animation.

Notes

🤖 Generated with Claude Code

Landing verification

The author's newer caret handoff and settled-line removal are preserved. A regression fix now skips hidden accepted-comment projections when finding the editable block after a dissolving deck; the new headless test failed before the fix and passes after it. Answered empty anchors remain pending after storage restart.

Fresh validation: CI, types, production build, explicit changed-source lint, 102 focused units, and both browser caret handoff cases pass on the combined UI base. The earlier full 21-case deck suite and all 12 manual decision-prose cases passed. Assertions and committed timeouts remain enforced. Full GitHub CI is running on the final head.

Final landing: full GitHub validation, browser tests, and both CLI checks passed with the caret regression fix. The shared container size failure is repaired by #553. All twelve source patches remain identical on current main 0c525fed; fresh local project checks and types pass, and lane audit confirms the existing option-lifetime guard. Admin rebase merge skips repeating full CI after this patch-preserving base update.

@MaggieAppleton

Copy link
Copy Markdown
Collaborator Author

Review: Looks good. Two small follow-ups below, and it needs a rebase now that #540 has merged.

I checked it in the browser on a fake-Planner server (desktop 1440×900). In a blank document with three answered ASK-DECISIONS, the document stays blank and typing works. THEN-WRITE shows one "Writing up 3 decisions…" line, then the prose and markers. I also probed the keyboard: Backspace and Delete at the start, at the end and at the block cursor never remove a hidden projection, the server logged no CRDT rejection, and the projections survive a reload.

Server

  • Anchors.answer() does not break "deliberately empty". The Planner's real empty review comes from anchor_plan/relate() after the answer, and answer() runs only at submit, so that review survives. Before the answer, an empty set is either an ask-time placement or a rebase write-through, so it was never a review. A Reopen followed by a re-answer now owes a review again, which seems right because it is a new answer.
  • No loop. anchor_plan with [] clears the set (pending: false), and answer() never runs again. One side effect is new but bounded: relinkDecisions (on editing unlock under liveBuild, and when a remote Planner attaches) will now also start a relink turn for answered blank-document decisions the Planner never wrote up. That is one turn, and it clears them. It is worth knowing, not blocking.
  • Persistence comes before publication: the new anchors are part of the answered record inside publishStaged, and Service.anchors runs only in the post-finish() notify list. One nit: Service.anchors already re-announces each prose widget, so the announce just before it now sends a duplicate frame. Harmless.

Client

  1. styles.css (the [data-plan-blank] rules). The placeholder sits about 12px higher than the real empty-document placeholder: 164px against 176px at 1440×900. The first empty caret paragraph is collapsed by the existing rule .plan-content > p:has(> br:only-child):first-child:not(:last-child) { block-size: 0; margin-block: 0 }, so the ::before and the caret sit in a paragraph with zero height. Also, one Backspace in the blank document deletes that leading paragraph. The caret then becomes a Lexical block cursor before the invisible decorators, and the placeholder jumps down to the trailing paragraph (p:first-of-type) where the caret isn't. Typing recovers it. Suggested fix: under [data-plan-blank], give the first paragraph its normal size and margins back (block-size: auto; margin-block: <paragraph default>), so the placeholder and caret match the true empty state.
  2. writingEntries / useWritingUp (questionnaire.tsx). writingProse uses the "inline" presentation, so decided deck members count too, even though their deck still draws them. If the first writing entry is a deck member, its InlineCard passes writing={undefined} and no line shows anywhere. If it isn't, the count includes cards that are already visible. Suggested fix: filter out entries the deck shows, using the same state inlineMemberState uses, before counting.

#540 conflict. #540 is already merged, so this PR goes second. git merge-tree shows conflicts in questionnaire.tsx and dynamic-editor.json. Resolve it as the PR notes describe: keep where === "inline" → hidden, use #540's if (where === "deck") return "resolved", and settle on one prop shape (#540's deck boolean or this PR's presentation). Then renew the hashes. inline-decision-deck.e2e.ts and harness-decisions-deck.e2e.ts auto-merge but may still conflict in meaning, because #540 shows decided deck members at full size where this PR expects settled lines. Re-run e2e after the rebase.

The hash renewals are fine. relationNote is an explicit ReactNode prop, not part of the pointing spread, and the plan-editor and question-view class boundaries are unchanged.

CI: all 5 jobs pass on 26e264b (format/lint/types/tests, e2e, container, CLI, CLI Windows).

@MaggieAppleton
MaggieAppleton force-pushed the design-hide-unlinked-decided branch 3 times, most recently from 2752b7f to 11fc04b Compare October 13, 2026 11:42
MaggieAppleton and others added 13 commits October 13, 2026 13:07
A question asked into a blank document has no blocks to point at. Its
empty anchor set was stored as it read while open (pending: false), so
once answered it looked reviewed and deliberately empty: "No related
text", and absent from anchors_pending, so nothing asked the Planner to
write or link its prose.

Answering now marks each set that points at nothing as pending
("missing"), and relays the room's relationships so readers see the
review is owed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In the document a decided card now shows only through the prose it lives
in (margin marker and wash). Pending, deliberately empty and orphaned
decisions draw nothing inline; their projection nodes stay, and their
full cards stay in Decisions. A deck still settles its decided members
while it holds an open one.

- While a Planner turn runs, or a conversation write-up job is writing,
  for hidden decisions, the first of them shows one quiet line:
  "Writing up N decisions…".
- A document whose only blocks are hidden decisions shows the empty
  document placeholder in its first empty paragraph, where typing goes.
- A conversation write-up's progress and Retry move to its Decisions card.
- "Linking…" shows only while a Planner turn runs; otherwise "Not linked yet".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The fake Planner gains ASK-DECISIONS THEN-WRITE, which writes and links a
paragraph per answered decision after a pause, so the write-up line can
be seen and then replaced by prose. Suites that read settled lines in the
document now expect nothing there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reviewed dynamic owners keep the same data flow. question-view.tsx's
Related wrapper, title link and callout classes are unchanged; it only
gains a host relation note. plan-editor.tsx's empty and root classes are
unchanged; the placeholder text moved to a local. questionnaire.tsx keeps
decision-collapse with the presence class, and the pointing spreads
carry the same props.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Answered cards without prose no longer draw anything in the document, so
the spacing suite uses expired ones: still separate cards, never decked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t only unseen write-ups

With #540 a deck shows its decided members at full size and the document
hides the rest, so nothing draws the settled line any more: remove it.

- While a document is blank behind hidden decisions, its first empty
  paragraph keeps its normal size, so the placeholder sits where the empty
  document's does, and Backspace or Delete has nothing to remove instead of
  leaving a block cursor beside an invisible decision.
- "Writing up N decisions…" leaves out decided cards a deck still draws.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Data flow is unchanged: questionnaire.tsx keeps decision-collapse with the
presence class and the same pointing spreads into Decided and Undecided
(the removed settled line had no reviewed class); plan-editor.tsx's empty
and root classes are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ecisions

Answering a deck's last open card dissolves it, and its decided cards now
draw nothing, so focus fell to the page. The caret goes to the start of
the block after the run, or the document's first paragraph when nothing
follows, and a page-wide polite status says "Decision saved".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
questionnaire.tsx keeps decision-collapse with the presence class and the
same pointing spreads; only the deck's onLeave handler changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaggieAppleton
MaggieAppleton force-pushed the design-hide-unlinked-decided branch from 11fc04b to 0220a61 Compare October 13, 2026 12:08
@MaggieAppleton
MaggieAppleton merged commit 221d3fb into main Oct 13, 2026
4 checks passed
@MaggieAppleton
MaggieAppleton deleted the design-hide-unlinked-decided branch October 13, 2026 12:08
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