# How to Get Sign-Off on an HTML Report (Approve or Request Changes)

Canonical: https://commareports.com/approve-html-report
Published: 2026-10-19

> Collect approvals on an HTML report the way you collect them on a pull request: reviewers approve or request changes, verdicts go stale when the content changes, and the share link can serve only the last approved version.

# How to get sign-off on an HTML report

Code gets reviewed on a pull request: someone reads the diff, clicks
**Approve** or **Request changes**, and if you push again the approval
goes stale. Everyone understands the model.

Reports rarely get that. The weekly metrics page, the incident write-up,
the client deliverable, the HTML your agent generated overnight — they get
a thumbs-up emoji in Slack, and nobody can say later _which version_ was
approved.

Comma gives an HTML report the pull-request model. This page shows how it
works and how to set it up.

## The short version

1. **Publish the report** — paste, upload, or let an agent call
   `create_report`.
2. **Share the link** with your reviewers as commenters.
3. **Reviewers click Approve or Request changes**, optionally with a note.
4. **Edit freely.** Any approval for the old content is marked stale, so
   you know who still needs to look again.
5. **Optional:** have the share link serve only the last approved version.

## What a verdict is

A verdict is one of two values, `approved` or `changes_requested`, with an
optional one-line note. Each reviewer has one current verdict per report;
clicking again replaces it, and clicking the active verdict retracts it.

The part that matters: **every verdict is pinned to the content the
reviewer saw.** Comma snapshots that revision when the verdict is
submitted. The header chip only counts verdicts whose snapshot matches the
current content.

| State in the header   | Meaning                                                       |
| --------------------- | ------------------------------------------------------------- |
| `2 approved`          | Two reviewers approved the content that is live right now     |
| `1 changes requested` | At least one current verdict asks for changes                 |
| `Review stale`        | Verdicts exist, but all of them were for an earlier version   |
| _(per reviewer)_      | "approved · earlier version" when that person saw old content |

This is the difference between sign-off and a thumbs-up. A thumbs-up on
Monday says nothing about the numbers you re-ran on Tuesday. A stale
verdict says so out loud.

## Comments and sign-off do different jobs

[Anchored comments](/comment-on-html) are for _"this number looks wrong"_ —
pinned to the exact paragraph or table cell, threaded, resolvable.
Sign-off is for _"this is good to send."_ Most reviews use both: comments
until the threads are resolved, then an approval on the version that came
out the other side.

## Staged publishing: the link only shows approved work

Sometimes the people reading a report should never see a draft — a client,
leadership, a public status page. Comma handles that without a second URL.

In the share dialog, turn on **Viewers see the last approved revision**.
From then on:

- **View-only audiences** on the share link get the newest revision a
  reviewer approved.
- **Reviewers and editors** keep seeing the latest draft, so they can keep
  reviewing it.
- **The URL stays the same.** When the next draft gets approved, readers
  move to it automatically.

That turns one link into a lightweight release process: edit, review,
approve, and only then does the audience see it.

## Who can approve

Anyone with **comment** permission on the report can submit a verdict:

- people you invite as reviewers,
- your team, when the report is filed under a team,
- link visitors, when the link permission is set to _comment_.

View-only visitors can read but not vote. Reviewers sign in (free, on
every plan) so each verdict carries a name, and reviewer emails are only
shown to people who own or edit the report.

## Sign-off for agent-generated reports

This is where pinned verdicts earn their keep. An agent that regenerates a
report every morning changes the content every morning — so yesterday's
approval should not vouch for today's output, and it doesn't.

Over MCP, an agent can read and write verdicts:

```
get_report_signoffs(report_id: "6f1c…")
→ { signoffs: [{ verdict: "approved", is_stale: true, reviewer: {…} }],
    head_revision_id: "…", approved_revision_id: "…" }
```

```
set_report_signoff(
  report_id: "6f1c…",
  verdict: "changes_requested",
  note: "Q3 totals don't match the warehouse export",
)
```

A sensible agent rule: _only post the link to the wider channel when at
least one approval has `is_stale: false`._ The same data is on the REST
API at `/api/v1/reports/:id/signoffs` (GET to list, POST to submit, DELETE
to retract) under a scoped `comma_sk_…` token — see the
[API docs](/docs/api).

## Get pinged when someone signs off

Each verdict emits a `signoff.submitted` event. Add a notification webhook
(from the notifications panel in the app, or with the
`create_notification` MCP tool) and pick
Slack, Discord or plain JSON. You get a message the moment a reviewer
approves or asks for changes, with their note.

## When to use this

- **Client deliverables** — the client approves the exact version you
  invoice for.
- **Weekly or monthly reports** — a lead approves before it goes to the
  wider list; staged publishing keeps the draft out of sight.
- **Incident and post-mortem write-ups** — record who signed off on the
  final timeline.
- **AI-generated reports** — a human approves before the agent
  distributes, and a regenerated report needs a fresh look.
- **Test, coverage and security reports** — QA or security signs off on
  the run that gates a release.

## Try it

Paste any HTML report, share it with one reviewer as a commenter, and ask
them to click Approve. Then change one number and watch the approval go
stale.

**[Create a report →](https://commareports.com/)**

### Related

- [How to leave anchored comments on an HTML report](/comment-on-html)
- [How to share an HTML report](/share-html-report)
- [Password-protect an HTML report](/password-protect-html-report)
- [Let an agent respond to comments](/agents/let-an-agent-respond-to-comments)
- [Comma MCP server](/mcp)
