GenieOS · Approvals

Checkpoints before anything ships or spends.

Your agents can draft, schedule and spend. Whether they do it unsupervised is a policy you write once, not a vibe you hope survives the next prompt. The loop pauses at judgement points you define, holds the artefact in a queue, and resumes on a decision, yours over MCP or a colleague's from a link.

policy.tsts
// The rule is configuration, not a prompt.await manage_approval_policy({  channel: "social",  hold: "everything",}); await manage_approval_policy({  channel: "email",  hold: { audience_over: 500 },}); await list_approval_policies();// → social · hold everything//   email  · hold sends over 500 recipients//   pages  · hold publishes to production
The surface
  • manage_approval_policyWrite the rule: what holds, per channel, per loop, per spend.
  • list_approval_policiesRead the standing rules, so your agents plan around the checkpoints.
  • list_pending_approvalsEverything holding for a human, with what it is and why it held.
  • decide_approvalApprove, or send it back with a note. The loop resumes where it paused.
  • recent_audit_entriesThe trail: what held, who released it and what shipped on the strength of it.
leash.tsts
// Week one: hold everything.await manage_approval_policy({  channel: "social",  hold: "everything",}); // Week four: the hooks have been right for a while.// Posts flow. Anything that spends still holds.await manage_approval_policy({  channel: "social",  hold: { spend_over: 0 },}); // Loosen per policy, as trust builds.// Tighten the same way, in one call.

The rule is configuration.

Deterministic checks, not flaky prompt output. Asking a model nicely to check with you first is a hope, not a control. An approval policy is enforced by the platform: when a policy says hold, the artefact stops existing as a send and starts existing as a queue item, whatever the model had in mind.

manage_approval_policy writes the rule and list_approval_policies reads it back, so your agents can plan around the checkpoints rather than trip over them. Hold everything on a channel, hold above an audience threshold, hold anything that spends. The loop pauses at judgement points and nowhere else, and you loosen per policy as trust builds.

IN-APP · SUPERVISEWhat your agents have queued, waiting on a decision.
ApprovalsFueld
Approvals3 waiting on you
  • LinkedInSOCIALLaunch post, LinkedInMost people are world-class at collecting health data and genuinely stretched thin on everything else.Derived by the loopderived from Your health data finally has a home · SocialApproveChanges
  • EMAILYour health data finally has a homeOne place for every metric, every provider, every insight. The Fueld Directory is live.Briefed by PriyaApproveChanges
  • InstagramSOCIALCarousel, InstagramOne place for every metric, every provider, every insight.Derived by the loopderived from Your health data finally has a home · SocialApproveChanges

To decide, you first have to look.

You can decide_approval over MCP, and for the subject-line tweak your agent proposed at 2am you probably will. But approval is a judgement about whether the thing is any good, and no JSON field answers that. The queue shows the artefact itself: the email as it will render, the post as the network will crop it.

That is the whole argument for a screen on this side of the site. The agent drafted it. Someone has to look at it. This is where looking happens.

audit.tsts
await recent_audit_entries({ limit: 3 });// [//   { at: "09:14", actor: "agent",//     action: "queued",//     item: "email · The Directory launch" },//   { at: "09:31", actor: "jordan",//     action: "approved",//     note: "Hook is right. Ship it." },//   { at: "09:32", actor: "system",//     action: "sent", audience: 2140 }// ]

Every decision, on the record.

recent_audit_entries returns the trail: what held, who released it, what shipped on the strength of it and when. Automatic releases are logged the same way as human ones, so loosening a policy never means losing the history.

It reads like a commit log for your marketing, because that is what it is. When someone asks why a send went out, the answer is a query, not an archaeology project.

IN-APP · HAND OVERThe same queue, as a link. Approve from a phone.
ApprovalsFueld
Approvals3 waiting on you

SHARE FOR APPROVAL

genieos.pro/r/the-directoryCopy link
privateinternalpublic2 reviewers

Anyone with the link can read the whole campaign and say yes. No login, no screenshots, no thread of attachments.

Give the queue to whoever holds the judgement.

Half the point of checkpoints is that the right judge is often not the person who wired them up. A founder should sign off the launch email. Your colleague is never going to read a webhook payload, and they should not have to.

Share the queue as a link. They see the same artefacts, approve or send back with a note, and their decision lands in the same audit trail and releases the same loop. Approval is a judgement, so route it to the person who holds it.

When this happens
  • WhenYou set one objective, once

    ThenThe loop creates, launches, measures, learns and goes again, holding at your checkpoints

    • spawn_creation
    • decide_approval
  • WhenA weekly cron fires

    ThenLast week's numbers read, the strategy patched from what worked

    • get_social_post_analytics
    • patch_marketing_strategy