The campaign lifecycle (DRAFT, IN_REVIEW, PUBLISHED)
Lifecycle of a Postward campaign as a package — when it can be edited, who moves it forward, and how revert and delete differ. Mirrors the analisedefiis email-campaign editor's state machine, adapted to one campaign that centralizes many publications.
Every Postward campaign starts in DRAFT. While DRAFT the Markdown brief is editable, and runs can be authored in any state — each run is a new immutable version. The brief renders live in the Studio so the reviewer sees exactly what the agent sees.
Three states, audited transitions
Every transition — DRAFT → IN_REVIEW → PUBLISHED — is one tap in the Studio, one MCP call (submit_campaign_for_review / approve_campaign_review), and one audit row. The reviewer who approves cannot be the same human who submitted.
DRAFT — the editable window
DRAFT is the only state where the brief is editable. Runs may be in DRAFT, SUBMITTED or anywhere in review — in this and every state, submitting a run or a source revision creates a new immutable version and never overwrites. The editor enforces this server-side: brief edits are rejected the moment the campaign has been submitted for review.
- Edit the Markdown brief at any time before submission (the title is editable in every state via the campaign settings).
- Delete the whole campaign — only DRAFT campaigns are deletable (mirrors analisedefiis: 'apenas rascunhos podem ser excluídos').
- Submit for review once at least one run exists; from IN_REVIEW the brief stops being editable. Content is never frozen — a new source revision or a new run is a new immutable version.
IN_REVIEW — the package gate
IN_REVIEW is the waiting room. Brief editing is closed; the submitted source revision and every finalized run are already immutable. New revisions and new runs stay allowed — they create new versions the reviewer can consider. The reviewer sees the canonical source, the brief, the runs, the approval status of every destination, and can either approve (→ PUBLISHED) or revert (→ DRAFT).
No self-approval
The submitter cannot also be the approver on the same campaign. Server-side check, not just UI gating.
PUBLISHED — dispatch on schedule
PUBLISHED is the state from which publication plans dispatch on their scheduled time. The campaign can still be reverted to DRAFT (audited; this is never implicit), but not deleted.
Preview the brief as Markdown
The Studio has a live split editor: the left pane is a textarea writing Markdown, the right pane is the rendered preview using the same react-markdown pipeline the rest of the product uses. What you write is what the reviewer reads — no surprise on preview.
MCP and API
get_campaign_lifecycle
update_campaign_brief (DRAFT only)
submit_campaign_for_review
approve_campaign_review
revert_campaign_to_draft
delete_campaign_draft (DRAFT only)Errors carry typed codes: not_draft (editing past DRAFT), already_in_state (reverting a DRAFT), no_runs (submit empty package), not_in_review (approving when not pending), not_found (campaign missing). The Studio maps each code to an actionable message.
Operational playbook
- Before publish, the Studio shows whether the package has any unresolved approval gaps or unscheduled destinations.
- After a successful dispatch, leave the campaign PUBLISHED; only revert when the package materially changes.
- Never delete a non-DRAFT campaign — the audit trail (who published what, when) is the only record that remains.
- Recovery after incident: re-submit a fresh revision + a new run; the previous PUBLISHED state stays in the audit log.
Next
Review and publish safely