0007 — Review: acceptance checklist with screenshots¶
- Status: Implemented (step 11.5) for 0.3.0, after comments (0005) and environments (0006). Shipped behaviour: SPEC; recipes: Screenshots for review.
- Size: ~4–4.5 agent-days (data, storage and safety tests ~1, MCP ~0.5, Review tab and viewer ~1–1.5, review stage and paged board ~0.5, Review queue and notification ~0.5–1, screenshot recipes ~0.25).
Goal¶
The owner accepts a task step by step inside relaybay; the agent prepares the steps and the evidence and is told as each step is accepted or rejected.
Model¶
review_step: id, task_id, position, title, details_md (what, how and why to check), status (open/accepted/rejected), decided_at, decided_by, created_by (session), created_at, updated_at.attachment: id, task_id, step_id (nullable), kind (image), stored_name (random id + extension), original_name, mime, size, sha256, caption_md, created_by, created_at.comment(0005) gains optionalstep_id/attachment_id.- Events
review.step_added|updated|accepted|rejected,attachment.added|removed.
Review stage and paged board¶
- New stage
reviewbetween dev and test: plan → dev → review → test → live → done. Existing tasks keep their stage; a migration widens the stage check. MCP tools and rules acceptreview. - Six columns do not fit one screen, so the board is paged: page 1 = plan, dev, review, test; page 2 =
live, done. On-screen arrows and keyboard ←/→ switch pages (not inside inputs, text areas or an
open dialog or viewer); the page is in the URL (
?page=2) and survives live updates. Phones keep the stage tab bar, now with six tabs.
Owner check lives in the checklist¶
What the owner should check by eye is written by the agent into the checklist through
review_steps_set, not only into the report. Moving a task to review or test with an empty
checklist returns a hint to fill it in.
API¶
review_steps_set(task, steps[]) (replace: title, details), review_step_update(task, step, …),
attach_file(task, path | content_base64, step?, caption), attachment_caption(id, caption),
review_get(task) (steps, statuses, attachments with captions, owner comments). The owner's
decisions reach the bound session through the comment path: "Step 2 'Login with 2FA' accepted —
continue with step 3" / "rejected:
UI¶
- Review tab in the task dialog (tabs Overview | Review | History): ordered steps; each row has an Accept checkbox, title, an expandable "What, how and why" block, thumbnails with captions and a comment box.
- Viewer: full screen over the dialog, image fit to screen, caption below, ←/→ and arrows, Esc, counter "3 / 7", swipe on phones.
- Card: a "Review 2/5" counter when a checklist exists.
- Review queue in the Inbox (0004): tasks in
reviewortestwith a checklist across all projects, oldest first; an item opens the dialog on its Review tab. - Browser notification "Waiting for your acceptance:
" when a task moves to reviewortest; permission is requested only from a button in Settings (Notification API, while a board tab is open). - Clipboard paste as the fallback: the owner pastes a screenshot into a step with Ctrl+V.
File storage and safety¶
- Files under
<data dir>/attachments/<project>/<task key>/<random id>.<ext>; the database keeps only the stored name. Served byGET /files/<attachment id>behind the board cookie with the storedContent-Type,X-Content-Type-Options: nosniff,Content-Disposition: inline; the CSP staysimg-src 'self'. - Allowed: PNG, JPEG, WebP, GIF, checked by magic bytes; SVG and everything else refused. Limits
10 MB per file and 200 MB per task (
attachments_max_mb,attachments_task_max_mb). attach_filereads only paths insideattachment_roots(default: the project'srepo_path, the user's temp directory, a configured screenshots folder), resolves symlinks and..before the check, refuses device files, copies (never moves or links) and hashes to avoid duplicates.content_base64for agents elsewhere, same rules.- Deleting a task (or archiving with purge) deletes its folder; removing an attachment deletes the file; a startup sweep removes orphans.
How agents produce screenshot files¶
The desktop app's built-in browser returns a screenshot to the model only, not as a file. Recipes for
agents (published as a how-to with attach_file examples):
- Sign in once, then screenshot by URL (local and test environments only, never live, and only where the environment allows it, see 0006): sign in once with a test account, save the login state (for example a Playwright storage state), then capture pages by URL with that state. The saved state and test credentials live outside the project repository and outside relaybay's database (a user directory whose path is in the environment's settings); relaybay stores only where the state lives. Public examples use neutral demo accounts.
- Headless Chrome / Edge without login:
--headless --screenshot=<file> --window-size=… <url>. - Android emulator:
adb exec-out screencap -p > shot.png; actions viaadb shell input …anduiautomator dump, or a mobile MCP server. - iOS simulator (macOS):
xcrun simctl io booted screenshot shot.png. - Then
attach_file(task, path, step, caption).
As built¶
Choices made while implementing, where the design left room:
- Steps are addressed by their number (
step=2) in MCP and by id on the board.review_steps_setmatches steps by position: an unchanged step keeps its decision and screenshots, a changed one opens again, removed steps leave their screenshots on the task ("Other screenshots"). - Agents may set a step only back to
open(after a fix); accepting and rejecting is the owner's, on the board. The decision text for the agent is an owner comment linked to the step. - The dialog has Overview and Review tabs; the binding and tracker history stay in Overview (no separate History tab yet). The task page shows the checklist as a section.
attach_filetakes absolute paths only, refuses files directly in the data folder (database, token) and anything inattachments/, and checks that the opened file is the one it resolved.attachment_rootsadds folders to the defaults (repository, temp folder).- relaybay has no task deletion yet; files of tasks that disappear (and of crashed writes) are removed by the startup sweep. Owners remove single screenshots on the board.
- The notification fires for every move to review or test, with or without a checklist; the task key is its tag, so several open tabs show one.
Risks¶
| Risk | Mitigation |
|---|---|
| A malicious file served as a page | Magic-byte check, no SVG, nosniff, CSP, served behind the cookie |
Path traversal through attach_file |
Allowed roots after resolving, copy only, no device files |
| Login state for a real account leaks | Never on live; state outside the repo and the DB; docs use test accounts |
| Disk fills up | Per-file and per-task limits, purge with the task, orphan sweep |