2026-03-25 14:31:35 +00:00
# formulas/run-rent-a-human.toml — Draft human actions for one-click execution
#
# "Rent a Human" — when the factory needs a human to do something it can't
# (post on Reddit, sign up for a service, approve a payment, etc.), it drafts
# the action and notifies the human for one-click copy-paste execution.
#
# Trigger: action issue created by planner or any formula.
# The action-agent picks up the issue, executes these steps, writes a draft
# to vault/outreach/{platform}/drafts/, notifies the human via Matrix,
# and closes the issue.
#
# YAML front matter in the dispatching action issue:
# formula: run-rent-a-human
# vars:
# platform: reddit
# action_type: post
# context: "Write about our AI agent factory for r/autonomousAI"
name = "run-rent-a-human"
description = "Draft a human action (post, comment, signup, etc.) for one-click execution"
version = 1
[ vars . platform ]
description = "Target platform (reddit, hackernews, twitter, linkedin, etc.)"
required = true
[ vars . action_type ]
description = "Type of action (post, comment, signup, reply, payment, etc.)"
required = true
[ vars . context ]
description = "What to write about — links, data, talking points, target subreddit/channel"
required = true
[ vars . target ]
description = "Specific target (subreddit, HN category, Twitter handle, etc.)"
required = false
default = ""
[ [ steps ] ]
id = "draft-content"
title = "Draft copy-paste-ready content for the human"
description = "" "
Draft the content that a human will copy-paste onto { { platform } } .
1 . Read the context provided : { { context } }
2 . Determine the target destination :
- If { { target } } is provided , use it ( e . g . r / autonomousAI , HN Show )
- If not , infer the best target from the context and platform
3 . Draft the content based on platform = { { platform } } and action_type = { { action_type } } :
For reddit posts :
- Title : attention-grabbing but not clickbait , matches subreddit tone
- Body : conversational , authentic , includes relevant details
- No marketing-speak — write like a developer sharing their project
For hackernews posts :
- Title : factual , follows HN title conventions ( Show HN : X — Y )
- Body / URL : concise description or link
For twitter / X :
- Tweet text : under 280 chars , engaging , no hashtag spam
- Thread format if content needs multiple tweets
For comments / replies :
- Natural , adds value to the conversation
- References the parent post / comment context
For signups / registrations :
- Step-by-step instructions for the human
- What information to enter , what options to select
For other platforms / actions :
- Adapt format to the platform conventions
- Always produce copy-paste-ready output
4 . The draft MUST be ready to use with zero editing — the human should only
need to copy-paste . No placeholders like [ INSERT X HERE ] .
2026-03-25 14:40:28 +00:00
5 . Store the drafted content as JSON ( handles multi-line bodies safely ) :
jq -n \
--arg target "<target destination, e.g. r/autonomousAI>" \
--arg title "<title if applicable>" \
--arg body "<body content — may be multi-line>" \
--arg slug "<url-safe slug derived from title, e.g. ai-agent-factory>" \
'{target: $target, title: $title, body: $body, slug: $slug}' \
> / tmp / rent-a-human-draft . json
2026-03-25 14:31:35 +00:00
"" "
[ [ steps ] ]
id = "write-draft"
title = "Write draft file to vault/outreach"
needs = [ "draft-content" ]
description = "" "
2026-03-25 14:40:28 +00:00
Write the drafted content to the outreach directory , commit , and push .
2026-03-25 14:31:35 +00:00
2026-03-25 14:40:28 +00:00
1 . Read the draft from the JSON temp file :
DRAFT_TARGET = $ ( jq -r '.target' / tmp / rent-a-human-draft . json )
DRAFT_TITLE = $ ( jq -r '.title' / tmp / rent-a-human-draft . json )
DRAFT_BODY = $ ( jq -r '.body' / tmp / rent-a-human-draft . json )
SLUG = $ ( jq -r '.slug' / tmp / rent-a-human-draft . json )
2026-03-25 14:31:35 +00:00
2 . Create the output directory :
DRAFT_DIR = "${PROJECT_REPO_ROOT}/vault/outreach/{{platform}}/drafts"
mkdir -p "$DRAFT_DIR"
3 . Generate the filename :
DATE = $ ( date -u + % Y- % m- % d )
DRAFT_FILE = "${DRAFT_DIR}/${DATE}-${SLUG}.md"
4 . Write the draft file in the standard format :
# ${DRAFT_TARGET}
< ! -- platform : { { platform } } -- >
< ! -- action : { { action_type } } -- >
< ! -- status : DRAFT -- >
< ! -- drafted : $ { DATE } -- >
## Title
$ { DRAFT_TITLE }
## Body
$ { DRAFT_BODY }
The file must contain ONLY copy-paste-ready content under the Title and
Body headings . No instructions , no meta-commentary inside those sections .
5 . Verify the file was written :
cat "$DRAFT_FILE"
2026-03-25 14:40:28 +00:00
6 . Create a branch , commit , and push the draft ( AD-003 : worktree is
destroyed after completion — unpushed work is lost ) :
2026-03-25 14:31:35 +00:00
cd "$PROJECT_REPO_ROOT"
2026-03-25 14:40:28 +00:00
BRANCH = "chore/rent-a-human-$(date -u +%Y%m%d-%H%M)"
git checkout -B "$BRANCH"
2026-03-25 14:31:35 +00:00
git add "$DRAFT_FILE"
2026-03-25 14:40:28 +00:00
git commit -m "chore: rent-a-human draft — {{platform}} {{action_type}}"
git push -u "${FORGE_REMOTE:-origin}" "$BRANCH"
2026-03-25 14:31:35 +00:00
2026-03-25 14:40:28 +00:00
7 . Save the file path , title , and branch for the notification step :
2026-03-25 14:31:35 +00:00
echo "$DRAFT_FILE" > / tmp / rent-a-human-path
echo "$DRAFT_TITLE" > / tmp / rent-a-human-title
2026-03-25 14:40:28 +00:00
echo "$BRANCH" > / tmp / rent-a-human-branch
2026-03-25 14:31:35 +00:00
2026-03-25 14:40:28 +00:00
8 . Clean up the temp JSON file :
rm -f / tmp / rent-a-human-draft . json
2026-03-25 14:31:35 +00:00
"" "
[ [ steps ] ]
id = "notify-human"
title = "Notify human via Matrix"
needs = [ "write-draft" ]
description = "" "
2026-03-25 14:40:28 +00:00
Notify the human , create a PR , and hand off to the orchestrator for CI .
2026-03-25 14:31:35 +00:00
1 . Read saved state :
DRAFT_FILE = $ ( cat / tmp / rent-a-human-path )
DRAFT_TITLE = $ ( cat / tmp / rent-a-human-title )
2026-03-25 14:40:28 +00:00
BRANCH = $ ( cat / tmp / rent-a-human-branch )
2026-03-25 14:31:35 +00:00
2026-03-25 14:40:28 +00:00
2 . Send the Matrix notification :
2026-03-25 14:31:35 +00:00
source "$FACTORY_ROOT/lib/env.sh"
matrix_send "rent-a-human" "New {{platform}} {{action_type}} draft ready: ${DRAFT_TITLE}"
2026-03-25 14:40:28 +00:00
3 . Create a PR for the draft :
PR_RESPONSE = $ ( curl -sf -X POST \
-H "Authorization: token ${FORGE_TOKEN}" \
-H "Content-Type: application/json" \
"${FORGE_API}/pulls" \
-d "{\"title\":\"chore: rent-a-human — {{platform}} {{action_type}} draft\" ,
\ "head\":\"${BRANCH}\",\"base\":\"${PRIMARY_BRANCH}\" ,
\ "body\":\"Rent-a-Human draft for {{platform}} ({{action_type}}).\\n\\nDraft file: \`${DRAFT_FILE}\`\\n\\nHuman: after merge, copy-paste the content from the draft file, then change \`status: DRAFT\` to \`status: POSTED\`.\"}" )
PR_NUMBER = $ ( echo "$PR_RESPONSE" | jq -r '.number' )
4 . Post a summary comment on the action issue :
2026-03-25 14:31:35 +00:00
curl -sf -X POST \
-H "Authorization: token ${FORGE_TOKEN}" \
-H 'Content-Type: application/json' \
"${FORGE_API}/issues/${ISSUE}/comments" \
2026-03-25 14:40:28 +00:00
-d "{\"body\": \"Draft written to \`${DRAFT_FILE}\` — PR #${PR_NUMBER}\\n\\nHuman: after merge, copy-paste the content, then change \`status: DRAFT\` to \`status: POSTED\`.\"}"
2026-03-25 14:31:35 +00:00
2026-03-25 14:40:28 +00:00
5 . Clean up temp files :
rm -f / tmp / rent-a-human-path / tmp / rent-a-human-title / tmp / rent-a-human-branch
2026-03-25 14:31:35 +00:00
2026-03-25 14:40:28 +00:00
6 . Signal the orchestrator to monitor CI ( do NOT write PHASE : done — the
orchestrator handles PR lifecycle , CI monitoring , and review injection ) :
echo "PHASE:awaiting_ci" > "$PHASE_FILE"
2026-03-25 14:31:35 +00:00
2026-03-25 14:40:28 +00:00
7 . STOP and WAIT . The orchestrator polls CI , injects results and review
feedback . When you receive injected feedback , follow its instructions .
2026-03-25 14:31:35 +00:00
"" "