← back to blog
    Berner SetterwallJune 17, 20263 min read

    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.