Statuses & badges
Status is the heart of Contentpipe. Every content item — publication or promo — carries exactly one, and the colors form a vivid idea → live progression. Shared statuses use one color across publications and promos, and every color is always paired with an icon so the pipeline stays legible for color-blind users.
The color system
| Status | Color | Meaning |
|---|---|---|
stub | Cyan | A fresh idea — title plus an optional note. |
draft | Amber | Being written. |
reviewing | Violet | Under critique. |
approved | Emerald | Signed off, good to go. Publications only. |
scheduled | Emerald | A promo that's been approved and, on an auto channel, booked with upload-post. Promos only. |
promoting | Fuchsia | Live at its canonical URL and amplifying — fanning out into promos. Publications only. |
published | Blue | A promo that is out on its channel. Promos only. |
archived | Muted slate | The deliberate outlier — retired content. Publications only. |
draft and reviewing use a single color across both publications and promos, so the same review instinct applies everywhere. approved and scheduled are the same slot under two names — the state an approval lands in — so they share emerald too, and are told apart by their glyph: a check for a publication, a calendar for a promo. archived is intentionally muted — it's the one status that reads as "out of the flow."
published belongs to promosA publication has no published status: promoting is live. The two were merged because a promo links to the article, so it can't be written before the article has a URL, and the article has no URL before it's live — the states always coincided. A promo keeps its own published, which means something different: the post has gone out on its channel.
scheduled is a bookingA promo reaches scheduled by being approved, and on an auto channel approving is what books the post with upload-post — the two are one action, so the state and the job arrive together. An approval that can't be booked is refused rather than half-applied.
The exception is a manual channel, which has no job to create: there scheduled means "approved, waiting for you to publish it". dispatch.job_id tells the two apart.
Solid status chips use darkened backgrounds so white text clears the 4.5:1 contrast threshold. The soft chip backgrounds and dark-theme variants are tuned separately — see the status.css token file, the single source of truth shared with the web app.
Transitions
Statuses only move along the allowed edges of the publication and promo pipelines. A trigger validates every transition against the allowed-transition map; invalid jumps raise an exception. Because enforcement lives in the database, the rule holds no matter the caller — admin UI, REST, workflow RPC, or MCP.
Every transition is recorded in an append-only status_events audit table, capturing the from/to status and the actor (admin_ui, mcp:<client>, or system).