One rule set enforced in three places: the panel's publish button (which returns the specific blockers and offers a deliberate override), the autonomous publisher (where force is not available at all), and the agent submission endpoint (which adds link-count and H1 checks and returns 422 with the exact problems). A blocked post stays a draft with the reason recorded.
Also called: stop bad posts going live · publish checks · draft validation
- 1publishBlockers() checks for a plan block, counts words against the 350 floor, and requires hero_url.
- 2The panel returns HTTP 409 with the blockers array and canForce: true, and the UI shows them in place with the override.
- 3The autonomous publisher records 'Held "title" back — it's only N words' in the ledger and writes the reason onto the post, then moves on.
- 4The agent submission endpoint additionally rejects an H1, fewer than two internal links, or no outbound source.
- 5The writer is told these thresholds up front, so a draft that comes back is publishable.
The gate exists because of exactly one incident, described in the panel route: "The seeded drafts ship as a plan block plus a bullet outline, and Publish happily put one of those on the live site — 536 characters of 'Delete this plan block when writing' under a real headline, with no hero. Nothing checked, because nothing had ever needed to." The machine-side rule is separate and stricter: "force is NOT available to a machine. A post that fails the gate stays a draft with the reason recorded — the point of an unattended publisher is that it publishes finished work, not that it publishes."
- An unwritten outline was published to the live marketing site.
- Nothing checked whether a post was finished before it went out.
- An unattended publisher with an override is not a gate.
See it on your own jobs
Twenty minutes, your numbers, no slide deck. We’ll build one of your real buildings in front of you and send you the estimate link at the end — yours to keep either way.
or keep browsing features →