Skip to content

feat(inbox): file a draft once you reviewed the PR on GitHub yourself - #29

Merged
jtomaszewski merged 2 commits into
mainfrom
jtomaszewski/inbox-rereview-filter
Aug 21, 2026
Merged

feat(inbox): file a draft once you reviewed the PR on GitHub yourself#29
jtomaszewski merged 2 commits into
mainfrom
jtomaszewski/inbox-rereview-filter

Conversation

@jtomaszewski

Copy link
Copy Markdown
Contributor

The problem

You can review a PR the ordinary way — GitHub's own review button, cerber not
involved. That clears the review request, and nothing here hears about it.

The queue lists what you have not settled locally, so the draft cerber wrote
for that PR goes on sitting in the inbox as work still waiting on you, days
after the PR went back to its author. The daemon can't retire it either: it
only deletes rows that fall out of the awaiting search and hold no work
(isPureStub), and a finished draft is work. Nothing but a merge, a send, or a
click of yours ever moves it.

It is not a corner case. A dry run of the rule below over the author's own
queue found three of five open drafts stuck exactly this way.

The fix

The poll now asks the other question too. For an artifact GitHub no longer
requests you on, it reads the PR's reviews and — when one of yours stands
there — files the draft under settled, recording which review settled it.

Nothing is sent and nothing is deleted. The status goes ready → reviewed, the
new filed block keeps the review it acted on, and the draft is still yours to
open, re-review or send.

One guard keeps this from undoing a deliberate act. Runs now record who asked
for them (run.trigger): a draft you requested after that review — pasted the
URL in, pressed re-review — is a second opinion you went and got, so it is left
alone. Only a draft the poll wrote on its own is filed.

Details

  • fetchOwnReview / latestOwnReview (src/core/gh.ts) — the read, and the
    pure part of it. A PENDING review is one nobody has seen (no submitted_at,
    and GitHub still asks you); a DISMISSED one is a review a maintainer struck
    off. Neither counts.
  • filedByOwnReview (src/server/daemon.ts) — the whole rule, exported and
    unit-tested: a finished unsent draft, a review of yours, and no user-requested
    run since that review.
  • Cost: it rides the existing state-check leash in syncQueue — at most 10
    artifacts per poll, once each per 30 minutes — so it is one extra gh api
    call on rows that qualify and none on the rest. Rows GitHub still requests you
    on never reach it.
  • The cockpit says who did what. A filed row is tagged reviewed on GitHub,
    never reviewed — that would claim a click you never made. The strip names
    the date, and opening the review shows a banner linking your review on the PR.
  • requestTag learned the same fact. When the author later re-requests you,
    a filed row reappears under open requests, where the conversation read would
    have tagged it "you haven't replied" at someone who demonstrably did — the
    same class of bug sentTag was written for, reachable again through this
    path.
  • A re-review rebuilds the artifact with filed: null, so re-drafting a filed
    review un-files it with no extra machinery.

Verification

  • pnpm typecheck && pnpm test && pnpm build — green; 379 tests, 14 new.
  • New tests cover the filing itself (files when GitHub stops asking and holds
    your review; leaves it while the request stands; leaves it when you never
    reviewed; keeps a second opinion you asked for; never touches a sent review),
    the review parse (PENDING, DISMISSED, latest-of-yours), and the three cockpit
    readouts.
  • Dry-run against live GitHub over a real ~/.cerber/reviews: three drafts
    matched with a review of the user's own on each, two rows GitHub still
    requests were left untouched.

Worth knowing

Not addressed here: the daemon can re-draft a PR minutes after you reviewed it
on GitHub, because gh search lags the API. Closing that would mean a reviews
read per awaiting PR on every poll — double the per-poll traffic to save a
few-minute window — so it is deliberately left out.

A review submitted through GitHub's own button never reaches cerber, so the
draft it wrote for that PR went on sitting in the inbox as work still waiting
on you — days after the request had cleared and the PR had gone back to its
author. The queue could only see what you settled locally; the one thing it
could not see was you answering the PR somewhere else.

So the poll asks the other question. For an artifact GitHub no longer requests
you on, it reads the PR's reviews once every 30 minutes — the same leash the
state check rides — and when one of yours stands there, files the draft under
settled with a record of which review settled it. Nothing is sent, nothing is
deleted: the draft is still there to open, re-review or send, and the cockpit
says "reviewed on GitHub" with the date rather than claiming a click you never
made. A pending review is not one anyone has seen and a dismissed one is one
GitHub struck off, so neither counts.

Runs now record who asked for them. A draft you requested yourself after that
review — pasted the URL in, pressed re-review — is a second opinion you went
and got, and filing it away would answer a question you had just posed; only
a draft the poll wrote on its own is filed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Copilot AI 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.

Pull request overview

This PR teaches cerber to automatically file a local draft under “settled” when GitHub is no longer requesting your review and GitHub already shows a submitted review from you—covering the case where you reviewed directly on GitHub rather than via cerber’s Send path.

Changes:

  • Add a filed metadata block to artifacts / inbox rows to record when/why a draft was filed (and which GitHub review triggered it).
  • Extend the daemon poll to fetch your latest standing PR review from GitHub and file eligible drafts, guarded by a new run.trigger field to avoid filing drafts the user explicitly requested after that review.
  • Update the web UI to surface “reviewed on GitHub” tags/banners, and add unit tests + documentation for the new behavior.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
web/src/types.ts Adds Filed and wires filed onto inbox rows and artifacts for UI consumption.
web/src/inbox.ts Displays new “reviewed on GitHub” row/tag behavior and explanatory strip text when filed is present.
web/src/inbox.test.ts Adds coverage for row tagging / strip messaging / open-request tag behavior for filed drafts.
web/src/Detail.tsx Shows a banner on the detail view when a draft was filed due to a GitHub review.
src/server/index.ts Ensures newly created/rerun artifacts record run.trigger: "user" and initializes filed: null; exposes filed in list items.
src/server/daemon.ts Implements the “file if you reviewed on GitHub” rule and adds filedByOwnReview guard logic.
src/server/daemon.test.ts Adds tests for filing behavior, trigger guard, and avoids GitHub calls when still requested.
src/server/chat.test.ts Updates test fixtures for the new filed field.
src/runner/review.ts Adds trigger option and persists it into artifact.run for daemon/user attribution.
src/runner/chat.test.ts Updates test fixtures for the new filed field and run.trigger.
src/core/state.test.ts Updates test fixtures for the new filed field and run.trigger.
src/core/send.test.ts Updates test fixtures for the new filed field.
src/core/revise.test.ts Updates test fixtures for the new filed field.
src/core/refresh.test.ts Updates test fixtures for the new filed field.
src/core/gh.ts Adds fetchOwnReview and latestOwnReview to detect your latest standing GitHub review.
src/core/gh.test.ts Adds tests for latestOwnReview behavior (ignores PENDING/DISMISSED, picks latest standing review).
src/core/autosend.test.ts Updates test fixtures for the new filed field.
src/core/artifact.ts Extends the artifact schema with FiledInfo and run.trigger fields.
README.md Documents the new “reviewed on GitHub → auto-filed” behavior.
CLAUDE.md Updates architecture documentation to reflect the new daemon filing path and trigger guard.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/server/daemon.ts
Comment thread web/src/Detail.tsx Outdated
Review feedback on #29, both real.

`run.startedAt` carries milliseconds and GitHub's `submitted_at` does not, and
ISO-8601 does not compare as text across precisions: "…:00.500Z" sorts *before*
"…:00Z". So a re-review you asked for half a second after your own GitHub
review read as older than it, and the guard that exists to protect exactly that
draft would have filed it away. Parse both sides. The regression test pins the
one case where the mismatch shows — same second on each side.

The detail banner led with "cerber filed this draft on <date>" while rendering
the date of your review, which is a different event. It now leads with the
review and its date, and says the filing followed.

Also states in `filedByOwnReview` why a run recorded before the trigger existed
counts as the poll's: the alternative strands every draft written before this
shipped, and being wrong costs one filing that a re-review undoes for good.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Copilot AI 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.

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated no new comments.

@jtomaszewski
jtomaszewski merged commit d87891b into main Aug 21, 2026
3 checks passed
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 0.21.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@jtomaszewski
jtomaszewski deleted the jtomaszewski/inbox-rereview-filter branch August 21, 2026 08:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants