Review Before Live: Publish-Gated Tickets for Lovable and WordPress
Review Before Live: Publish-Gated Tickets for Lovable and WordPress
Here's a ticket that did exactly what it was told, and that was the problem.
We had an agent ticket — "Build an About page for agentlaunch in
Lovable." The agent connected to Lovable over MCP, wrote the page,
and then called Lovable's deploy_project tool. The About page went
live on the production site (agents-launch.lovable.app/about) in
one shot. No preview step. No one looked at it first.
A second ticket did the same thing — it went live directly even though the description explicitly asked for a preview.
For a surprising amount of work, "the agent published it to your real, public website without asking" is a non-starter. You want to see it first. The whole reason our coding-agent tickets feel safe is the review gate: every PR gets a preview URL, you look at it, and only then does it merge. Third-party publishing surfaces like Lovable and WordPress had no equivalent — the agent just shipped.
So we built one.
What changed
Tickets that touch a publish-gated integration — today that's
Lovable and WordPress, with Sanity, Framer, and others to
follow — now stop at the Review column instead of going live.
The agent builds on the preview (Lovable's preview--<project>.lovable.app
sandbox) or as a WordPress draft, then hands you:
- a summary of what it built,
- the preview URL to open,
- the editor/admin link, and
- on-demand screenshots via the existing Visual Proof reviewer.
Nothing is public yet. When you're happy, you click Make it live —
and that's the moment Cogny publishes: it calls Lovable's
deploy_project, or flips the WordPress draft to publish. Then the
ticket moves on to analysis, exactly like before.
Two ways to gate, because publishing isn't one thing
Lovable and WordPress publish very differently, so the gate has two enforcement modes.
Lovable has a real publish verb. deploy_project exists for one
purpose: push to production. So we hard-block it during ticket
runs. If the agent tries to call it, it gets an error telling it to
build the preview and stage for review instead. Clean.
WordPress doesn't. You publish a post by passing status: "publish"
on create_post/update_post — publishing is a parameter, not a
separate tool. You can't block a parameter value with a tool allowlist.
So we rewrite the arguments server-side: during a gated run, any
post or page write is forced to status: "draft", no matter what the
agent asked for. The draft is real and previewable; it's just not
public. "Make it live" is what sets it to publish.
The key detail: both of these are enforced on the server, in the execution loop — before the tool call goes out. We learned the hard way that a per-tool blacklist isn't enough on its own, because tickets auto-approve the tools of any integration they're tagged with. The gate has to take precedence over that approval, or it silently does nothing. So the block runs first.
How "Make it live" actually publishes
When the agent stages a ticket for review, it declares the exact call
that should publish it later — something like
{ server: "Lovable", tool: "deploy_project", args: { project_id: "…" } }.
We store that, validated against your connected integrations, and
replay it when you click the button. The publish runs with fresh
credentials, it's idempotent (a double-click can't double-publish), and
every go-live is written to the MCP audit ledger like any other write.
If the agent somehow never stages a preview but did try to deploy, the ticket still lands in Review with a note — never in a state that falsely implies it went live. The gate fails safe.
Why this matters
A ticket agent that can edit your live website is powerful. A ticket agent that edits your live website without asking is a liability. The preview-then-approve loop is what turns the first thing into something you'd actually let run on a schedule.
It's on now for every Lovable and WordPress ticket — no flag, no setting. Connect the integration, run a ticket, and you'll find it waiting for you in Review.