Skip to content

board: ask the reviewer about a review finding - #940

Open
edroch wants to merge 6 commits into
mainfrom
board-finding-questions
Open

edroch wants to merge 6 commits into
mainfrom
board-finding-questions

Conversation

@edroch

@edroch edroch commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator

Lets you ask the reviewer about one finding before you post it: is it real, is it overstated, what does the data say. The question goes to the reviewer's own Claude session, which already has the code and the review loaded. You talk it through in its pane, and if the finding changes, the reviewer re-raises its gate with the revision. You finish the review on the board as usual.

This replaces the PR's first design (a separate question agent in its own questions workspace). Reusing the reviewer's session saves a cold start, and needs no new workspace and no Flock change.

Spec: docs/superpowers/specs/2026-10-27-review-finding-question-design.md.

What changed

Review sheet (apps/board/src/client/board)

  • Every finding, ticked or not, gets an "ask a question" link in its card header. It opens a textarea under the header; "send to the review pane" (or cmd/ctrl+enter, which never posts the review from there) sends the question. One question at a time.
  • On an open gate the link is disabled while the review pane is gone. On a parked gate it stays live: asking resumes the reviewer's session with the question.
  • When the reviewer re-raises the gate, an open sheet moves onto the new gate by itself, with no page refresh. /data.json now carries gateReplacements (old gate to the newest gate in its chain), and the decision queue swaps the replaced gate for its successor in place, without counting it as answered.
  • A revised card says "Revised in the review pane", then what changed (severity, lines, wording, fix, comment), with "show original". The board works this out by comparing the new gate with the one it replaced in the same run (kept in memory), with nothing stored.
  • Your picks, notes and comment edits carry over to the re-raised gate: its form seeds from gate-kit's per-gate draft on the gate it replaced, then drops that draft. A revised finding takes the reviewer's new comment instead of your edit.

Board server (apps/board/src)

  • POST /review/finding-question types /board:review-finding-question <gate> <finding> "<question>" into the reviewer's pane through pane:send, then brings Flock forward on that pane.
    • It asks rt which pane runs the review's Claude session (paneSelf) and types nothing when none does, so a stale pane on file never gets the line.
    • On a parked gate with no pane running, it resumes the session with the line as its prompt, under the same tab label as the parked-gate resume, so an answer later focuses that tab instead of starting a second pane.
    • If the pane shows the gate's question form, it presses Escape first. Any other prompt is refused: "the review pane is waiting on a prompt; answer it there first".
    • It refuses when the gate isn't the MR's open or parked review gate, or the finding isn't in it.
  • No schema change and no new route for drafts.

rt daemon (lib/daemon/gates-store.ts)

  • Opening a gate now supersedes a parked gate of the same subject and kind, not only an open one, so a session resumed off a park can re-raise its gate.

Skill

  • New board:review-finding-question (apps/board/skills-src/review-finding-question/). Inside the review session it:
    1. restates the finding and the question;
    2. sends a read-only Explore agent (code, logs, New Relic, QA databases through sdm's read-only resources; prod only when you name it);
    3. reports a verdict, the evidence, what it couldn't check, and a proposed change;
    4. asks for the outcome with a mattstack:wrap-up form: revise and re-raise the gate, leave it as is, or keep asking.
  • On revise, it confirms the wording in another form, rewrites that finding in the report, and rebuilds the gate exactly as the first one was built. Only if the old gate is still pending does it stop the old wait and re-raise, then hold at the new gate.
  • Written test-first with superpowers:writing-skills. Agents without the skill dug through code and data inside the reviewer's session, reported in a different shape each time, offered prod unasked, and risked ending the run when the old gate closed. Agents with it did none of that.

Design files: B48 and B48b in docs/apps/design/board/board.pen (renamed from B23/B23b, which main now uses for another frame).

Verification

  • Rebuilt on main at 870166b20 as one commit, plus the review fixes in their own commit.
  • bun run board:test: 4125 pass. bun run board:typecheck: green. The gate store and handler tests: 155 pass. The board skills drift guard passes. bun run check is green apart from the console app's tests (getClientRects is not a function locally; this PR changes nothing in the console, and main's CI is green).
  • Ran it live on a real review, from the board into the pane and back.

Notes

  • The board keeps the last few replaced gates in memory only. After a board restart, the revised notice, the draft carry-over and the sheet's move to the new gate skip one re-raise (a manual refresh picks the new gate up).
  • The parked supersede takes effect once the dev daemon runs this code.

🤖 Generated with Claude Code

Note

Add board flow for asking the reviewer about a review finding

  • Adds a question UI on finding cards in the review gate sheet. Questions go to a new local POST /review/finding-question route, which validates the gate and finding, then sends the question to the review agent's existing pane via herdr. If the pane shows a prompt that is not the Claude Code question form, it sends Escape and retries (finding-question.ts, ReviewGateSheet.tsx).
  • Adds the board:review-finding-question skill workflow for the review agent: investigate via a read-only helper, present evidence and a verdict, and wait for the human's choice before revising the report or re-raising the gate (SKILL.md).
  • Saves and restores review-sheet drafts (ticked findings, comments, outcome, notes) across gate rebuilds via GET/PUT /review/sheet-draft. Drafts are dropped on a final verdict, on re-review launch, and when the MR leaves the board. Saved comment text is skipped for findings revised in the current gate (review-sheet-draft.ts).
  • Detects revised findings by comparing the open review-post gate with its superseded predecessor, and shows a revised strip with the original title and body (review-revision.ts, ReviewDraftCard.tsx).
  • GateCache now retains replaced gate rows, exposes an old-to-new replacement mapping in board data, and the decision queue replaces a superseded gate with its successor without marking it answered (cache.ts, decision-queue.ts).
  • Behavioral Change: POST /review/finding-question returns 409 for missing panes or unlisted findings and 400 for blank, over-2,000-character, or malformed questions; older servers omit the new gateReplacements field.

Macroscope summarized 94450b5.

Summary by CodeRabbit

  • New Features
    • Ask a question about an individual finding directly from its review card and send it to the active review pane.
    • See which findings changed when a review is updated, with access to the original finding details.
    • Review-sheet selections, comments, outcomes, and notes are saved and restored across review updates when applicable.
  • Bug Fixes
    • The decision queue follows replacement review gates instead of leaving a superseded gate active.
    • Saved review edits are cleared when starting a new review or completing the review.

@coderabbitai

coderabbitai Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: d32e3801-fdc9-457d-ad97-82c7f7bf85ae
Walkthrough

Changes

The board adds a per-finding question flow to the active review session. It also detects revised findings across superseding review gates and saves review-sheet edits for restoration across gate rebuilds.

Review finding workflow

Layer / File(s) Summary
Finding-question request and review-session workflow
apps/board/src/finding-question.ts, apps/board/src/server.ts, apps/board/src/herdr.ts, apps/board/src/question-form.ts, apps/board/skills-src/review-finding-question/SKILL.md, apps/board/skills/review-finding-question/*, apps/board/src/__tests__/finding-question.test.ts, apps/board/src/__tests__/herdr.test.ts, apps/board/src/__tests__/question-form.test.ts, apps/board/docs/api.md, docs/superpowers/plans/*, docs/superpowers/specs/*
The local endpoint validates the request and review gate before sending a question to the review pane. If the pane is at the question form, it sends Escape and retries once. The skill defines read-only investigation and human-approved revision steps. API documentation, tests, and design documents also change; earlier question-flow plans and specifications are marked superseded.
Superseded gates and finding revisions
apps/board/src/gates/cache.ts, apps/board/src/review-revision.ts, apps/board/src/client/types.ts, apps/board/src/server.ts, apps/board/src/client/board/decision-queue.ts, apps/board/src/__tests__/gates-cache.test.ts, apps/board/src/__tests__/review-revision.test.ts, apps/board/src/client/board/__tests__/*
The cache retains predecessor gates and exposes replacement mappings. The server supplies revision data for changed findings and gate replacements. The decision queue follows mapped successors when reconciling its entries.
Review-sheet draft persistence and restoration
apps/board/src/sheet-draft-shape.ts, apps/board/src/review-sheet-draft.ts, apps/board/src/client/board/sheet-draft.ts, apps/board/src/server.ts, apps/board/src/review-launch.ts, apps/board/src/client/board/ReviewGateSheet.tsx, apps/board/docs/api.md, apps/board/src/__tests__/review-sheet-draft.test.ts, apps/board/src/__tests__/review-launch.test.ts, apps/board/src/client/board/__tests__/sheet-draft*, docs/superpowers/specs/2026-10-27-review-finding-question-design.md
The server stores validated drafts by merge request. The client restores eligible draft fields and saves changes after a debounce. Drafts are removed on fresh review launches, qualifying review verdicts, and board departure.
Review-sheet question and revision controls
apps/board/src/client/board/Board.tsx, apps/board/src/client/board/DecisionQueueModal.tsx, apps/board/src/client/board/ReviewGateSheet.tsx, apps/board/src/client/board/ReviewDraftCard.tsx, apps/board/src/client/board/launch-flow.ts, apps/board/src/client/board/icons.tsx, apps/board/src/style.css, apps/board/src/client/board/__tests__/review-question-dom.test.tsx
The review sheet sends questions through the board action and displays per-finding question controls. Finding cards show revision summaries and can reveal the original finding text.

Estimated code review effort: 4 (Complex) | ~60 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant ReviewGateSheet
  participant Board
  participant FindingQuestionEndpoint
  participant handleFindingQuestion
  participant ReviewPane
  ReviewGateSheet->>Board: submit gate ID, finding ID, question, optional tab ID
  Board->>FindingQuestionEndpoint: POST /review/finding-question
  FindingQuestionEndpoint->>handleFindingQuestion: validate and handle request
  handleFindingQuestion->>ReviewPane: send question to the review session
  ReviewPane-->>handleFindingQuestion: delivery result
  handleFindingQuestion-->>Board: HTTP result
  Board-->>ReviewGateSheet: success or refusal
Loading

Possibly related PRs

  • m4ttstack/mattstack#947: Reworks the review-card components that this change extends with question controls, revision details, and draft restoration.
  • m4ttstack/mattstack#950: Reworks the same review-sheet components for card rendering and timelines, which must account for the added per-finding behavior.

Suggested reviewers: m4ttheweric

Security architecture risk: Moderate · up to 497e5

The question flow validates the selected review, but delivery does not always verify that it reaches that review’s session. If a saved destination has been reused, question content may reach an unrelated session. Exposure is limited by local-only access and existing delivery checks.

Retained concerns

  • Medium · security · inferred: Finding-question delivery can fall back to an unverified stored pane when the intended review session cannot be resolved. If that pane now hosts another running session, a request valid for the original review can disclose question content to the unrelated session. Successful live-session resolution prevents this, but missing-session fallback does not fail closed.
Security review details

Security Blast Radius

  • inferred — The supported exposure is the local board and its review sessions. An accepted local caller selects an MR’s open gate and listed finding. A reused destination can extend delivery to another local session; remote reachability, cross-tenant access and production privilege expansion were not established.

Security Findings and Attack Paths

  • inferred — If review A’s saved pane is reused by session B and A cannot be resolved, a question valid for A can reach B. The sink accepts an idle or working application session without checking its review identity. Conversely, a resolvable live session overrides the stale pane, and nonmatching application types are refused. No exploited misdelivery was demonstrated.

Trust Boundaries and Controls

  • observed — The route combines local-peer, host and forwarded-header checks with an exact application/json media-type requirement. It then requires the supplied gate to be the MR’s open review gate and the finding to belong to that gate. These controls constrain request reachability and selection, but do not authenticate the final receiving session.

Resilience and Maintainability Implications

  • observed — Draft restoration requires the saved gate or its identified predecessor, and revised findings exclude saved comment text. Saving waits for a successful restore read and stops on submission. Terminal review verdicts delete drafts, while iterate and hold retain them. Concurrent writers remain last-arrival-wins rather than versioned.

Hardening Proposals

  • proposed — Use strict session-bound delivery for finding questions: reject unavailable or mismatched session identity instead of falling back to a stored pane. Preserve that identity requirement through screen inspection, Escape and retry.
Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 73.91% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed

Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the pull request's main change: adding a board flow for asking the reviewer about a review finding.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 73.91% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 46 functions across 30 files. (8 skipped: 8 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches

Generate docstrings

  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)

  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Review coverage is incomplete: 1 file could not be fully reviewed. Findings from completed review steps are included; see review info for details.

Tip

🎯 Customize your risk assessments

Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.

✅ Automatic approvals, with your rules

Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.

Recent review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3e680997-dc57-4cc4-8e51-6261409b22fd
Commits

Reviewing files that changed from the base of the PR and between 870166b and 497e548.

Files selected for processing: 39

  • apps/board/docs/api.md
  • apps/board/skills-src/review-finding-question/SKILL.md
  • apps/board/skills/review-finding-question/SKILL.md
  • apps/board/skills/review-finding-question/compiled.json
  • apps/board/src/__tests__/finding-question.test.ts
  • apps/board/src/__tests__/gates-cache.test.ts
  • apps/board/src/__tests__/herdr.test.ts
  • apps/board/src/__tests__/question-form.test.ts
  • apps/board/src/__tests__/review-launch.test.ts
  • apps/board/src/__tests__/review-revision.test.ts
  • apps/board/src/__tests__/review-sheet-draft.test.ts
  • apps/board/src/client/board/Board.tsx
  • apps/board/src/client/board/DecisionQueueModal.tsx
  • apps/board/src/client/board/ReviewDraftCard.tsx
  • apps/board/src/client/board/ReviewGateSheet.tsx
  • apps/board/src/client/board/__tests__/decision-queue.test.ts
  • apps/board/src/client/board/__tests__/queue-superseded-refresh-dom.test.tsx
  • apps/board/src/client/board/__tests__/review-question-dom.test.tsx
  • apps/board/src/client/board/__tests__/sheet-draft-dom.test.tsx
  • apps/board/src/client/board/__tests__/sheet-draft.test.ts
  • apps/board/src/client/board/decision-queue.ts
  • apps/board/src/client/board/icons.tsx
  • apps/board/src/client/board/launch-flow.ts
  • apps/board/src/client/board/sheet-draft.ts
  • apps/board/src/client/types.ts
  • apps/board/src/finding-question.ts
  • apps/board/src/gates/cache.ts
  • apps/board/src/herdr.ts
  • apps/board/src/question-form.ts
  • apps/board/src/review-launch.ts
  • apps/board/src/review-revision.ts
  • apps/board/src/review-sheet-draft.ts
  • apps/board/src/server.ts
  • apps/board/src/sheet-draft-shape.ts
  • apps/board/src/style.css
  • docs/apps/design/board/board.pen
  • docs/superpowers/plans/2026-10-24-board-finding-questions.md
  • docs/superpowers/specs/2026-10-23-board-finding-questions-design.md
  • docs/superpowers/specs/2026-10-27-review-finding-question-design.md
Files not fully reviewed because their changes were unavailable: 1

  • docs/apps/design/board/board.pen

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

@edroch
edroch marked this pull request as draft October 26, 2026 18:26
@edroch
edroch force-pushed the board-finding-questions branch from 88d6193 to f92c9c3 Compare October 27, 2026 20:47
@edroch edroch changed the title board: ask a question about a review finding board: ask the reviewer about a review finding Oct 27, 2026
@edroch
edroch force-pushed the board-finding-questions branch from 9805ed5 to 94450b5 Compare October 28, 2026 12:52
@edroch
edroch marked this pull request as ready for review October 28, 2026 12:53
@edroch
edroch force-pushed the board-finding-questions branch 2 times, most recently from 9991a96 to 497e548 Compare November 2, 2026 18:51

@m4ttheweric m4ttheweric left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Really nice first PR! Left one blocker and a few comments inline.

disabled={sending}
autoFocus
onChange={e => setText(e.currentTarget.value)}
onKeyDown={e => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

issue: cmd+enter in this box posts the whole review, since this only catches Escape and sheet-keys.ts submits from any field. could cmd/ctrl+enter stopPropagation here and send the question instead, with a dom test?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed: cmd/ctrl+enter in the question box stops there and sends the question, and an empty one sends nothing. The DOM tests cover both keys and check the sheet's own listener never sees them.

text,
...(lane.sessionId ? { selfSession: lane.sessionId } : {}),
});
let res = await send(paneId);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

issue: if the session's gone, the daemon falls back to this stored pane id, which can be stale (livePane ends in ?? claimed). so another agent's pane can get the slash command, and maybe the Escape too. could we resolve the session first, i think paneSelf does it, and 409 with NO_REVIEW_PANE when nothing runs it?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

It resolves the session first now, with paneSelf and no pane id, so the stored pane is never the fallback. When nothing runs the session it's a 409 with NO_REVIEW_PANE and nothing gets typed or escaped.

// Only an open gate has a review pane holding at it to ask.
const askFor = useFindingAsks(
gate.gateId,
mr && onAskQuestion && gate.status === 'open'

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

issue: past the 90 minute park the sweep closes the pane and this drops the ask link with no reason, so older reviews just lose the feature. could the route resume the session with the question as its prompt instead? the catch is supersede only closes open rows, so the re-raise has to close the parked gate too.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done. A parked gate keeps its ask link, and the route resumes the session through resumeAgentPane with the question as the prompt, under the same mrTabLabel(iid, undefined, '↺') as the parked resume, so an open resume tab only gets focused. gates-store.ts now supersedes open and parked rows, with a test.

): ReviewRevision | undefined {
const open = cache.get(`mr:${mrUrl}`, REVIEW_GATE_KIND);
if (!open || open.status !== 'open') return undefined;
const previous = cache.supersededBy(open.id);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

issue: a re-review relaunch also supersedes the open gate, and finding ids are positional, so a fresh run's f2 can show "Revised" with an unrelated original behind it. could we ignore a predecessor older than the lane's runStartedAt?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Added: a predecessor opened before the lane's runStartedAt is ignored, so a fresh run or a re-review gets no revision and no draft carry-over.

/** Whether a finding reads differently on the new gate. */
export function findingChanged(a: FindingEntry, b: FindingEntry): boolean {
return (
a.severity !== b.severity ||

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

issue: this skips comment and fix, but the skill can revise the comment. then the pane says revised, the sheet shows nothing, and an older edit silently wins. could we compare those too?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

It compares fix and comment too now, and the strip names them ("fix changed", "comment rewritten").

## 1. Restate, then explore through a helper

Restate in two lines: the finding (tier, title, `file:line`) and the
question. Then dispatch one read-only explorer with the Agent tool

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

suggestion: with no subagent_type this explorer gets Edit and Write, and it's reading MR code. could we name Explore so read-only is enforced?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

It names subagent_type: Explore now.

@@ -0,0 +1,321 @@
> Superseded by [the review finding question design](2026-10-27-review-finding-question-design.md): the question now runs in the reviewer's own pane, with no separate question agent.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

suggestion: this and the 10-24 plan describe the design that got replaced. can we drop both? that's 789 lines nobody needs.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Dropped both.

Comment thread apps/board/docs/api.md Outdated
| `POST /roster` | add or drop a teammate |
| `POST /tabs` | replace the tab list |
| `POST /draft` | flip one of your own MRs between draft and ready, by rewriting the title prefix |
| `GET /review/sheet-draft?mr=<url>` | the review sheet's unsent ticks and edits for one MR, or `null`. Kept so a review gate the review agent re-raises after revising a finding restores them |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nitpick: the GET needs gate too (400 without it) and returns { draft, previousGateId }, and the PUT takes gateId. goes away if the draft store does.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Gone with the draft store. The finding-question row covers the parked resume now too.

const text = [
'Revised in the review pane',
...revisionSummary(original, revised),
].join(' · ');

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nitpick: we don't join ui fragments with · on the board. could these be separate elements with spacing?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Each part is its own span now, spaced with a flex gap.

Comment thread apps/board/src/finding-question.ts Outdated
}
if (screen === null || !hasQuestionForm(screen))
return { status: 409, body: PANE_AT_OTHER_PROMPT };
await io.sendEscape(livePane);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

issue: this isn't in a try/catch like the screen read and focus are, so a herdr failure here rejects the handler instead of returning the documented 409. could we catch it and return failureReason-style text?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Wrapped it: a failed Escape returns a 409 with the herdr error and doesn't send the line again.

@coderabbitai coderabbitai 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.

  • Fix comments: Fix CodeRabbit comments on this PR

Comment thread apps/board/src/gates/cache.ts Resolved
@m4ttheweric

Copy link
Copy Markdown
Collaborator

suggestion: could we get some storybook stories for this? the review stories in Gates.stories.tsx don't pass onAskQuestion or a reviewRevision, so none of the new ui shows up there.

something like: the ask link, the question box open, sending and a 409 error, the pane gone reason, a parked gate's ask, and the revised strip. fine to go past the "variants go in dom tests" line in apps/board/AGENTS.md for these.

@edroch

edroch commented Nov 3, 2026

Copy link
Copy Markdown
Collaborator Author

could we get some storybook stories for this?

Added in 3137fd3: eight Review question: … stories under Gates/Board, one per state you listed plus "asked". They send through runLaunchFlow with a scripted reply so the toasts match the board, and the ones that need clicks get there in their play step. The AGENTS.md line names them as the exception now.

edroch and others added 6 commits November 6, 2026 12:29
Every finding on the review sheet gets "ask a question". The board types
/board:review-finding-question <gate> <finding> "<question>" into the
review's own pane and brings Flock to it. There the reviewer explores with
a read-only helper, reports a verdict, and asks for the outcome with a
mattstack:wrap-up form. On a revise it rewrites the finding and re-raises
the gate; the human finishes the review on the board.

- POST /review/finding-question (finding-question.ts), which presses
  Escape only over the gate's own question form.
- The board:review-finding-question skill.
- The open sheet follows a re-raised gate onto its successor: /data.json
  carries gateReplacements and the decision queue swaps the old gate in
  place.
- A revised card shows "Revised in the review pane" with the original,
  derived by comparing the new gate with the one it replaced.
- Ticks and comment edits carry over to the re-raised gate through the kv
  table, so the board schema is unchanged.
- Mockups B48 and B48b in docs/apps/design/board/board.pen.

Rebuilt on main as one commit; the branch's earlier 43-commit history
included a first design it later removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Resolve the review session's pane before typing into it, resume a parked
review with the question, and seed a re-raised gate from gate-kit's draft
instead of a server-side store.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One story per state of the question flow, through the board's own launch
flow and toasts, so the UI can be worked on in Storybook.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main's board hooks now listen for sync-start on the event source.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The rebase took main's board.pen, which now uses B48 for another frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@edroch
edroch force-pushed the board-finding-questions branch from 3137fd3 to 2e8e883 Compare November 6, 2026 17:34

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