Code Review

Pull request descriptions

Ellipsis keeps a summary of the change at the top of every pull request, rewritten on each push. It owns one marked block; your own text is never touched.

Every review starts by summarizing the pull request. A description agent reads the change and writes a summary; Ellipsis puts it in a marked block on the pull request body and rewrites that block on every push. The description is current when a reviewer opens it, not accurate only on the first commit.

It is on by default. The built-in pr-description agent runs on Claude Haiku 4.5 with no YAML required.

What lands on the pull request

The summary goes in a branded block: a > [!IMPORTANT] callout, and a footer naming the commit it describes.

Adds rest-period validation to shift assignment, in `scheduling/rest_period.py`
and the assignment path in `routes/shifts.py`.

- Behavior: assigning a shift within 8 hours of a worker's previous shift end
  now returns `409` with a `rest_period_violation` code.
- Schema: `staff_rules` gains `min_rest_hours`, defaulting to 8.
- Refactor: `assign_shift` moves its conflict checks into
  `validate_assignment` so the trade path reuses them.

The footer reads "This description was created by Ellipsis for 4f2c1ab. It will automatically update as commits are pushed." A reader racing a push can see which commit the summary describes.

Your text is never overwritten

Ellipsis fences its block with <!-- ELLIPSIS_HIDDEN --> HTML comments, invisible on GitHub. Rewriting only ever replaces what sits between them.

Fixes #4821. Deploying this behind the `rest_periods` flag.   <- yours, untouched

<!-- ELLIPSIS_HIDDEN -->
> [!IMPORTANT]
> ...the summary...                                           <- Ellipsis rewrites
<!-- ELLIPSIS_HIDDEN -->

## Test plan                                                  <- yours, untouched
- [ ] verified against the staging schedule

Three properties follow from that:

  • Your prose, checklists, and issue links survive every update. They sit outside the block.
  • Ellipsis reads the live body immediately before writing it, so an edit you made while the agent was working is carried back verbatim rather than reverted.
  • Delete the block and it comes back on the next push, in place. Delete only one of the two markers and Ellipsis reads the body as having no block at all, then appends a fresh one below your text.

The write happens the moment the description agent finishes, before the reviewers start. The summary updates within seconds of the push rather than waiting on the review.

What the agent decides each push

The agent is handed the current summary and the commits since the last review pass, and writes one of three outcomes. The reviews dashboard shows which one, per review.

OutcomeWhenDashboard
The summary is rewrittennew commits changed what a reader needs to knowSummary updated
Nothing changesthe current summary still holds, so it is not re-emittedNo change
The block is removedthis pull request should carry no summarySummary removed

The summary always describes the whole pull request as it now stands, not only the newest commits: a reader lands on it fresh. This is the one place code review is not incremental. The new commits are what tells the agent what to fold into the summary it already wrote.

If the update fails, the dashboard shows Update failed and the review continues. A lost summary never costs you the review.

Writing your own description agent

Declare description: in your pipeline file. It takes exactly one agent as a mapping, with the same claude block an agent config uses; a list with entries is a validation error. Declaring it replaces the built-in agent, and a file that sets only description: keeps the built-in reviewer:

ellipsis:
  version: v1
  kind: code_review
  name: Reviewed with our own summaries

description:
  name: pr-description
  budget: 2.00
  claude:
    model: claude-haiku-4-5-20251001
    system: |
      Summarize this pull request for the reviewer who has to approve it.
      Open with one sentence: what the change does and which modules it
      touches. Then short grouped bullets, naming real functions and files
      in backticks. Always call out schema changes to `staff_rules` and
      any change to the shift-trade engine in its own bullet, since those
      need a second approver. Never mention documentation-only changes.

Guidance that holds:

  • Haiku is the right default. This agent summarizes a change rather than judging it, and it runs on every push, so it is the pipeline's most frequent call. A wrong summary is visibly wrong and rewritten on the next push.
  • Write only the summary text. No headings, no images, no HTML, no signature. Ellipsis owns the markers, the callout, and the footer, so a prompt that produces them gets them twice.
  • Say what your team needs flagged. The prompt is where "always call out schema changes" or "name the ticket in the first line" belongs.
  • Never tell the agent to edit the pull request. Ellipsis applies the summary. An agent that runs gh pr edit itself fights the block it is supposed to be filling, and Ellipsis instructs it not to.
  • Give it an explicit budget. The built-in agent takes 2.00. Without one, an agent takes an equal share of what budget.run has left after the explicit budgets, divided across every agent in the pipeline.

Turning it off

Set description: []. The pipeline then never touches any pull request description:

description: []

Leaving description: out is not the same thing: an unset stage inherits the built-in agent. The empty form is the only way to stop it. Turning it off does not remove summaries Ellipsis already wrote, so delete any block you no longer want.

Field shapes and defaults are in the configuration reference.