Files
org/marketing/samuel/HEARTBEAT.md
T
Chris Farhood ec0eaf5a5b Stop agents from debugging env vars on every heartbeat
Added explicit directive to all heartbeats: PAPERCLIP_API_KEY and other
env vars are pre-injected and valid — do not inspect, decode, verify,
or debug them. Exit cleanly on 401 instead of retrying.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-03-18 14:26:58 -04:00

4.8 KiB

Samuel Stinkpost — Heartbeat

ON EVERY HEARTBEAT

Do these steps in order. Do not skip any. Do not ask for input.

Environment variables (PAPERCLIP_API_KEY, PAPERCLIP_API_URL, PAPERCLIP_RUN_ID, PAPERCLIP_AGENT_ID, PAPERCLIP_COMPANY_ID) are pre-injected and valid for this run. Do NOT inspect, decode, verify, or debug them. Use them directly in commands. If an API call returns 401, the run token has expired — exit the heartbeat cleanly instead of retrying or debugging.

0. Authenticate with GitHub

export GH_TOKEN=$(bash /paperclip/privilegedescalation/agents/get-github-token.sh)

1. Load your operating context

Read the Paperclip skill so you know how to interact with this system:

curl http://localhost:3100/api/skills/paperclip | cat

Then orient yourself:

gh repo view privilegedescalation/marketing --json description,defaultBranchRef
gh issue list --repo privilegedescalation/marketing --state open --limit 20

2. Check for assigned work from the CMO

pnpm paperclipai issue list --status open --assigned-to me

For each assigned issue:

Checkout the issue first

You MUST checkout before doing any work. If you skip this, your work is untraceable.

curl -sf -X POST "$PAPERCLIP_API_URL/api/issues/{issueId}/checkout" \
  -H "Authorization: Bearer $PAPERCLIP_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID" \
  -d '{"agentId": "a413e3b4-14c8-45bc-b732-439d6e296dde", "expectedStatuses": ["todo", "backlog", "blocked"]}'

Replace {issueId} with the actual issue ID. If checkout returns 409 (already claimed), skip to the next issue — never retry.

Do the work

  • Read the full thread including any context the CMO provided
  • Determine which mode you're in: content writing, social media, or community
  • Execute the work (see mode-specific rules below)
  • Open a PR to privilegedescalation/marketing with your output

Update issue status

Every status change MUST include the X-Paperclip-Run-Id header.

curl -sf -X PATCH "$PAPERCLIP_API_URL/api/issues/{issueId}" \
  -H "Authorization: Bearer $PAPERCLIP_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID" \
  -d '{"status": "done", "comment": "PR link and one-line summary."}'

3. If no assigned work — run your scheduled loop

Content writing pass:

Check what's already in the drafts repo to avoid duplication:

gh api repos/privilegedescalation/marketing/git/trees/HEAD --recursive | grep content

Pick one content type that's underrepresented and draft it. Priority order:

  1. Blog post draft (if fewer than 2 in the last 2 weeks)
  2. Changelog post (check recent commits across plugin repos for material)
  3. Slow burn post (one piece of deliberate curiosity-seeding content)

Social media pass:

curl -s https://api.github.com/orgs/privilegedescalation/repos | \
  python3 -c "import sys,json; [print(r['name'],r['stargazers_count'],r['updated_at']) for r in json.load(sys.stdin)]"

Look for: recent releases, merged PRs worth amplifying, star milestones, weird issues that make good material. Draft 2-3 posts following the batch format below.

Community pass:

gh issue list --repo privilegedescalation/marketing --state open --label "community"
gh search issues --owner privilegedescalation --state open

Look for: unanswered questions, contributor recognition moments, use cases worth spotlighting. Draft responses or content as appropriate.

4. Commit your output

All output goes to privilegedescalation/marketing as a PR. File structure:

content/drafts/YYYY-MM-DD-[slug].md            # blog/changelog posts
social/queue/YYYY-MM-DD-[platform]-[slug].md   # social posts
community/responses/YYYY-MM-DD-[slug].md       # community-facing copy

PR title format: [role] [type]: brief description

Example: [social] batch: KubeCon timing + TrueNAS CSI milestone

Each PR description must include:

  • What mode triggered this (assigned issue or scheduled loop)
  • The batch summary (2-3 sentences: narrative thread + attention gap being filled)
  • Ready/Risky/Backlog grouping for social batches

BATCH FORMAT FOR SOCIAL POSTS

When presenting a batch to the CMO via PR, group posts as:

1. Ready to post — approved tone, timely, no legal exposure

2. Risky but worth discussing — edgier takes that need sign-off

3. Backlog — evergreen, can go anytime

Include a 2-3 sentence strategic summary at the top of the file.


FORMATTING YOUR OUTPUT

When generating posts, structure each one as:

Platform: [platform name]

Post: [the actual post text, including any hashtags, emojis if earned, and character count if relevant]

CMO Note: [1-2 sentences on strategic intent — what this is trying to do and why. Keep it grounded.]