01 / 11
Use or Space to move
ShipLoop · per-storefront admin · ToT Storefront

The human gate in an
agent-driven dev loop.

An agent marks a change ready_for_review. A person sees the evidence, the preview, and the gate — then approves and releases in one informed click. Built on the DevLoop evidence contract; the compliance gate is visible, not bypassable.

Storefront: Hazel & Rapidstenant_id hazel-rapids-vineyardReviewer op:rae-m
01 · start here

The storefront admin home.

Every storefront gets one home. It opens with the storefront's own clearance status — are the compliance-critical checks green right now? — and puts the work that needs a human first.

  • A storefront-level seal: this storefront is clear — age gate, excise, jurisdiction all green.
  • 1 Review & release is the centerpiece — 1 change is held, surfaced before anything else.
  • Future surfaces — releases, feedback inbox, storefront health, theme — ring the same home.
admin · hazel-rapids-vineyard · /admin
Storefront admin home: a clearance status hero with a green seal reading 'this storefront is clear', a Review & release module listing three queued changes, and tiles for releases, feedback, storefront health and settings.
02 · the queue

Everything waiting on a human decision.

The review queue shows only this storefront's changes in ready_for_review. Each row reads in plain language and shows its evidence state at a glance — so you triage before you open anything.

  • Plain-language summary · opaque submitter id (dev:agent-7Q2K) · time in queue.
  • A held row names which compliance checks fail right on the card — age_gate, excise.
  • Per-tenant isolation is structural: no other storefront's work appears here.
admin · /admin/review
Review queue with three change cards: a green 'cleared to release' row, a red 'release held' row listing age_gate and excise failing, and a green row with a sitemap advisory warning.
03 · the central artifact

Decide from evidence — the Release Manifest.

The reviewer decides primarily from one EvidenceReport. We render it as a sealed manifest: compliance-critical checks are visually load-bearing and sit apart from advisory ones.

  • ! Compliance-criticalage_gate · excise · jurisdiction. Any non-pass blocks release.
  • i Advisoryllms_txt · json_ld · sitemap · cutover_crawl. Informational; never blocks.
  • Every row links to its proof — a route, a crawl report, the llms.txt path.
The Release Manifest: a ticketed document with a green '3/3 pass' compliance-critical section above a quieter advisory section, each check showing an icon-plus-text status and a monospace evidence link.
04 · one informed click

Green evidence unlocks the seal.

When every compliance-critical check passes, promotable is true: the Clearance Seal stamps CLEARED FOR RELEASE and Approve is a live, one-click action — with the proof sitting right beside it.

  • The seal's microtext ring encodes the verdict — legible, not decorative.
  • Approve & release is one click — no committee, no second screen.
  • A reviewer can still reject a green change — with a typed reason.
The decision rail: an embossed green clearance seal reading 'cleared for release, compliance verified', the line 'Cleared to release — all 3 compliance-critical checks pass', an Approve & release button, and a Reject option.
05 · the gate has weight

Red evidence: Approve doesn't exist.

This is the non-negotiable. When promotable is false, Approve is structurally absent — not a greyed-out button you could wish into working. In its place: a locked plate naming the exact failing checks.

  • The seal is broken & hazard-hatched: 2 of 3 fail · do not promote.
  • 🔒 age_gate bypassable · excise unmapped — shown as the reason, not a footnote.
  • Only Reject remains. A change that hides the age gate can't be approved through this UI.
The held decision rail: a broken, hazard-hatched brick seal reading '2 of 3 fail', a hatched 'Approve is locked' plate listing age_gate and excise as the failing checks, and only a Reject option — no Approve button exists.
06 · the block, in full

The manifest shows why — in the reviewer's words.

The same blocked change, end to end: the before→after preview catches the bundle route rendering before the age gate, and the manifest's compliance-critical rows turn red with a plain-language detail and a link to the crawl proof.

  • age_gate · Fail — “the bundle route renders products without firing the 21+ interstitial.”
  • excise · Fail — “the $120 bundle SKU isn't mapped to excise categories.”
  • Advisory rows can warn or skip without blocking — the gate only cares about the critical three.
admin · /admin/review/chg:A4C7 · held
Full blocked review screen showing the lifecycle track, the what-changed summary, a before/after preview flagging the bundle route skipping the age gate, the red Release Manifest, and the locked decision rail.
07 · reject is auditable

Sending it back takes a reason.

Reject isn't a silent bounce. It requires a typed reason, returns the change to in_progress, and writes an immutable audit entry — approver identity, reason, timestamp. Even a green change can be rejected this way.

  • The reason goes to the developer by their opaque id — no PII on this screen.
  • The change drops back to in_progress; the feedback item stays open.
  • Every decision — approve or reject — is recorded against op:rae-m.
The reject flow: a green 'cleared to release' seal with the reject form open, a typed reason explaining the eligibility wording should not read as a guarantee, and a 'Return to in progress' button, noting it is sent to the developer's opaque id.
08 · release & announce

Ship, then announce — nothing auto-publishes.

On approval the change ships and an editable announcement draft is generated from the change summary and the feedback it closes. The reviewer edits, then publishes — to the changelog, and as a notification back to the original reporter.

  • A guardrail: announcements describe the change only — never legal, age, excise, or price copy.
  • Publishing notifies rpt:8F3C by opaque id — the loop closes back to who reported it.
  • Nothing publishes until the reviewer presses the button.
admin · /admin/review/chg:9F21 · shipped
The release and announce screen: a green 'approved & shipped to production' banner, a completed lifecycle track, an editable announcement draft with a guardrail note, and a live changelog entry preview noting the reporter will be notified by opaque id.
09 · the full lifecycle

Every change knows where it sits.

A lifecycle track rides the top of every detail screen, so the reviewer always knows the stage — and the off-track outcomes are explicit.

triage in_progress ready_for_review approved shipped announced
rejected → back to in_progress closed

And it degrades gracefully: when the queue is clear, the screen is an invitation, not a void.

admin · /admin/review · empty
The empty review queue: a dashed seal outline and the message 'the queue is clear — when a developer or agent marks a change ready for review for this storefront, it lands here with its evidence already gathered.'
The four non-negotiables, designed in

The gate is visible, and it's real.

🔒 Approve is gated on green

If promotable is false, Approve is structurally unavailable — replaced by the failing compliance checks. Not discouraged. Impossible.

No PII, per-tenant only

Submitters and reporters are opaque ids — never email. The surface shows only this storefront's changes.

Announcements describe the change

Never merchant claims or legal / age / excise / price copy. That lives on the storefront, not the changelog.

Status is never color-only

Every pass / warn / fail / skip pairs color with an icon and a word. Lifecycle carries a text label and an aria description.

Lives in the per-storefront admin on the storefront app · designed against the real EvidenceReport contract in @tot/shared.
Prototype: docs/design/shiploop-approver-console.html — every state is switchable.