fix: address review — JSON handoff for multi-line bodies, commit+push draft

- Replace env-file inter-step handoff with JSON (jq) to safely handle
  multi-line body content across steps
- Add branch creation, git commit, and git push in write-draft step
  (AD-003: worktree destroyed after completion — unpushed work is lost)
- Create PR in notify-human step and signal PHASE:awaiting_ci instead
  of PHASE:done so orchestrator manages the PR lifecycle

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
openhands 2026-03-25 14:40:28 +00:00
parent 81bfb8085a
commit 369e19bbe2

View file

@ -79,19 +79,14 @@ Draft the content that a human will copy-paste onto {{platform}}.
4. The draft MUST be ready to use with zero editing the human should only 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]. need to copy-paste. No placeholders like [INSERT X HERE].
5. Store the drafted content in environment variables for the next step: 5. Store the drafted content as JSON (handles multi-line bodies safely):
DRAFT_TARGET="<target destination, e.g. r/autonomousAI>" jq -n \
DRAFT_TITLE="<title if applicable>" --arg target "<target destination, e.g. r/autonomousAI>" \
DRAFT_BODY="<body content>" --arg title "<title if applicable>" \
SLUG="<url-safe slug derived from title, e.g. ai-agent-factory>" --arg body "<body content — may be multi-line>" \
--arg slug "<url-safe slug derived from title, e.g. ai-agent-factory>" \
Write these to a temp file for the next step: '{target: $target, title: $title, body: $body, slug: $slug}' \
cat > /tmp/rent-a-human-draft.env << 'DRAFTEOF' > /tmp/rent-a-human-draft.json
DRAFT_TARGET=<value>
DRAFT_TITLE=<value>
DRAFT_BODY=<value>
SLUG=<value>
DRAFTEOF
""" """
[[steps]] [[steps]]
@ -99,10 +94,13 @@ id = "write-draft"
title = "Write draft file to vault/outreach" title = "Write draft file to vault/outreach"
needs = ["draft-content"] needs = ["draft-content"]
description = """ description = """
Write the drafted content to the outreach directory. Write the drafted content to the outreach directory, commit, and push.
1. Read the draft from the temp file: 1. Read the draft from the JSON temp file:
source /tmp/rent-a-human-draft.env 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)
2. Create the output directory: 2. Create the output directory:
DRAFT_DIR="${PROJECT_REPO_ROOT}/vault/outreach/{{platform}}/drafts" DRAFT_DIR="${PROJECT_REPO_ROOT}/vault/outreach/{{platform}}/drafts"
@ -132,16 +130,22 @@ Write the drafted content to the outreach directory.
5. Verify the file was written: 5. Verify the file was written:
cat "$DRAFT_FILE" cat "$DRAFT_FILE"
6. Stage and commit the draft: 6. Create a branch, commit, and push the draft (AD-003: worktree is
destroyed after completion unpushed work is lost):
cd "$PROJECT_REPO_ROOT" cd "$PROJECT_REPO_ROOT"
BRANCH="chore/rent-a-human-$(date -u +%Y%m%d-%H%M)"
git checkout -B "$BRANCH"
git add "$DRAFT_FILE" git add "$DRAFT_FILE"
git commit -m "chore: rent-a-human draft — {{platform}} {{action_type}}"
git push -u "${FORGE_REMOTE:-origin}" "$BRANCH"
7. Save the file path and title for the notification step: 7. Save the file path, title, and branch for the notification step:
echo "$DRAFT_FILE" > /tmp/rent-a-human-path echo "$DRAFT_FILE" > /tmp/rent-a-human-path
echo "$DRAFT_TITLE" > /tmp/rent-a-human-title echo "$DRAFT_TITLE" > /tmp/rent-a-human-title
echo "$BRANCH" > /tmp/rent-a-human-branch
8. Clean up the temp env file: 8. Clean up the temp JSON file:
rm -f /tmp/rent-a-human-draft.env rm -f /tmp/rent-a-human-draft.json
""" """
[[steps]] [[steps]]
@ -149,33 +153,41 @@ id = "notify-human"
title = "Notify human via Matrix" title = "Notify human via Matrix"
needs = ["write-draft"] needs = ["write-draft"]
description = """ description = """
Send a Matrix notification so the human knows a draft is ready. Notify the human, create a PR, and hand off to the orchestrator for CI.
1. Read saved state: 1. Read saved state:
DRAFT_FILE=$(cat /tmp/rent-a-human-path) DRAFT_FILE=$(cat /tmp/rent-a-human-path)
DRAFT_TITLE=$(cat /tmp/rent-a-human-title) DRAFT_TITLE=$(cat /tmp/rent-a-human-title)
BRANCH=$(cat /tmp/rent-a-human-branch)
2. Send the notification: 2. Send the Matrix notification:
source "$FACTORY_ROOT/lib/env.sh" source "$FACTORY_ROOT/lib/env.sh"
matrix_send "rent-a-human" "New {{platform}} {{action_type}} draft ready: ${DRAFT_TITLE}" matrix_send "rent-a-human" "New {{platform}} {{action_type}} draft ready: ${DRAFT_TITLE}"
3. Post a summary comment on the action issue: 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:
curl -sf -X POST \ curl -sf -X POST \
-H "Authorization: token ${FORGE_TOKEN}" \ -H "Authorization: token ${FORGE_TOKEN}" \
-H 'Content-Type: application/json' \ -H 'Content-Type: application/json' \
"${FORGE_API}/issues/${ISSUE}/comments" \ "${FORGE_API}/issues/${ISSUE}/comments" \
-d "{\"body\": \"Draft written to \`${DRAFT_FILE}\`\\n\\nHuman: copy-paste the content, then change \`status: DRAFT\` to \`status: POSTED\` in the file.\"}" -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\`.\"}"
4. Clean up temp files: 5. Clean up temp files:
rm -f /tmp/rent-a-human-path /tmp/rent-a-human-title rm -f /tmp/rent-a-human-path /tmp/rent-a-human-title /tmp/rent-a-human-branch
5. Close the action issue: 6. Signal the orchestrator to monitor CI (do NOT write PHASE:done the
curl -sf -X PATCH \ orchestrator handles PR lifecycle, CI monitoring, and review injection):
-H "Authorization: token ${FORGE_TOKEN}" \ echo "PHASE:awaiting_ci" > "$PHASE_FILE"
-H 'Content-Type: application/json' \
"${FORGE_API}/issues/${ISSUE}" \
-d '{"state": "closed"}'
6. Signal completion: 7. STOP and WAIT. The orchestrator polls CI, injects results and review
echo 'PHASE:done' > "$PHASE_FILE" feedback. When you receive injected feedback, follow its instructions.
""" """