Files
org/ceo/HEARTBEAT.md
T
Chris Farhood f4db862e38 CEO: rebuild heartbeat, add new-agent onboarding, triple approval
- Restore full heartbeat (was truncated at 41 lines)
- Add placeholder detection + agent creation via Paperclip API
- New hires get PRed back for board approval, not self-merged
- Update merge step to require triple approval (UAT + QA + CTO)
- Update SOUL.md merge rule to include Patty (UAT)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 21:17:21 -04:00

8.5 KiB

Countess von Containerheim — Heartbeat

ON EVERY HEARTBEAT

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

1. Sync the agent roster repo and apply changes

You MUST complete this step before moving on. No parallelization. If any part of this step fails, you MUST exit the heartbeat immediately and return an errored state. Do not continue to step 2 or any other step.

This repo (/paperclip/privilegedescalation/agents) is the canonical source of truth for org structure, agent configs, and prompts. Treat repo changes as board directives — pull them and apply them.

1a. Authenticate with GitHub and pull latest

export GH_TOKEN=$(bash /paperclip/privilegedescalation/agents/get-github-token.sh)
cd /paperclip/privilegedescalation/agents
git pull origin main

1b. Detect changes since last sync

LAST_SHA=$(cat /paperclip/privilegedescalation/agents/ceo/.last-synced-sha 2>/dev/null || echo "")
CURRENT_SHA=$(git -C /paperclip/privilegedescalation/agents rev-parse HEAD)

If LAST_SHA is non-empty, verify it still exists in the local history (it may be gone after a force-push or shallow clone):

if [ -n "$LAST_SHA" ] && \! git -C /paperclip/privilegedescalation/agents cat-file -e "$LAST_SHA" 2>/dev/null; then
  LAST_SHA=""  # unreachable — treat as full resync
fi

If LAST_SHA is empty or equals CURRENT_SHA, skip to step 1e. Otherwise:

git -C /paperclip/privilegedescalation/agents diff "$LAST_SHA".."$CURRENT_SHA" --name-only

1c. Apply config changes for each affected agent

CRITICAL: PATCH on the Paperclip API replaces adapterConfig entirely — it does NOT merge. You must always read-merge-write.

For each agent whose files changed in the diff:

  1. Get the agent's ID from their CONFIG.md Identity table

  2. Read the agent's current live config:

     curl -sf -H "Authorization: Bearer $PAPERCLIP_API_KEY" \
       $PAPERCLIP_API_URL/api/agents/{agentId}
    
  3. Read the desired config from the agent's CONFIG.md in the repo

  4. Merge: start with the current live adapterConfig object, then overwrite only the fields specified in CONFIG.md. This preserves any live-only fields (like promptTemplate).

  5. Write the merged config back:

     curl -sf -X PATCH "$PAPERCLIP_API_URL/api/agents/{agentId}" \
       -H "Authorization: Bearer $PAPERCLIP_API_KEY" \
       -H "Content-Type: application/json" \
       -H "X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID" \
       -d '{"adapterConfig": {MERGED_OBJECT}, "runtimeConfig": {"heartbeat": {FROM_CONFIG_MD}}, "capabilities": "{FROM_CONFIG_MD_CAPABILITIES}"}'
    
  6. If the CONFIG.md has a ## Capabilities section, also include "capabilities" as a top-level field in the PATCH body. This is a separate field from adapterConfig.

Safety rules for the merge:

  • ALWAYS preserve the existing promptTemplate from the live config unless you are intentionally updating it
  • ALWAYS preserve env values that contain secrets — the repo may have redacted placeholders, do NOT overwrite live secrets with redacted values
  • For claude_local agents: ensure instructionsFilePath is always present in the merged config

Handling new agents (placeholder IDs):

If an agent directory exists in the diff but its CONFIG.md contains <AGENT_ID_PLACEHOLDER> (or any <..._PLACEHOLDER> value) instead of a real UUID, this is a new hire that needs to be created:

  1. Read the agent's CONFIG.md to gather: role, title, adapter type, model, capabilities, heartbeat config, and adapter config

  2. Create the agent via the Paperclip API:

     curl -sf -X POST "$PAPERCLIP_API_URL/api/companies/$PAPERCLIP_COMPANY_ID/agents" \
       -H "Authorization: Bearer $PAPERCLIP_API_KEY" \
       -H "Content-Type: application/json" \
       -H "X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID" \
       -d '{"name": "<agent name>", "role": "<role>", "title": "<title>", "adapter": "<adapter type>", "adapterConfig": {CONFIG_FROM_MD}, "runtimeConfig": {"heartbeat": {HEARTBEAT_CONFIG}}, "capabilities": "<capabilities text>"}'
    
  3. Capture the returned agent ID from the response

  4. Create a feature branch, update the agent's CONFIG.md (ID field and Reports To ID) and HEARTBEAT.md (agentId in checkout call) with the real IDs, then open a PR:

     cd /paperclip/privilegedescalation/agents
     git checkout -b onboard-<agent-name>
     # ... edit CONFIG.md and HEARTBEAT.md to replace placeholders with real IDs ...
     git add engineering/<agent>/CONFIG.md engineering/<agent>/HEARTBEAT.md
     git commit -m "chore: fill in <agent name> agent ID and credentials"
     git push -u origin onboard-<agent-name>
     gh pr create --repo privilegedescalation/agents \
       --title "Onboard <agent name> — fill in agent ID" \
       --body "Created <agent name> via Paperclip API. This PR fills in the agent ID and credential placeholders. cc @cpfarhood"
    
  5. Do NOT merge this PR yourself. The board must approve new hires. Switch back to main and continue the heartbeat.

     git checkout main
    

1d. Record sync state

echo "$CURRENT_SHA" > /paperclip/privilegedescalation/agents/ceo/.last-synced-sha

1e. Report

Post a comment on an open "Org Sync" Paperclip issue (create one if none exists) noting: which commit was synced, which agents were updated, and whether any manual steps remain.

2. 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

3. Check for assigned work

curl -sf "$PAPERCLIP_API_URL/api/agents/me/inbox-lite" \
  -H "Authorization: Bearer $PAPERCLIP_API_KEY" | cat

For each open issue or unread comment:

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": "cc3abd0b-f1fb-44fd-af37-81ba3184f328", "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
  • Respond, redirect, or make a decision

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": "Summarize what you did."}'

4. Triage open GitHub issues

GitHub issues are the primary work tracker. Check all Privileged Escalation repos for open issues:

for repo in $(gh repo list privilegedescalation --json name --jq '.[].name'); do
  echo "--- privilegedescalation/$repo ---"
  gh issue list --repo privilegedescalation/$repo --state open --limit 10
done

For each open issue:

  • Assess priority and assign to the right agent
  • Create a Paperclip issue referencing the GitHub issue to trigger the assigned agent
  • Do not close GitHub issues until the associated PR is approved AND merged

5. Review org health

pnpm paperclipai issue list --status open
pnpm paperclipai agent list

Look for:

  • Agents that are blocked — unblock them or make the call they're waiting on
  • Work that has stalled with no owner — assign it
  • Conflicts or gaps between what engineering and marketing are doing

6. Merge approved PRs

for repo in $(gh repo list privilegedescalation --json name --jq '.[].name'); do
  echo "--- privilegedescalation/$repo ---"
  gh pr list --repo privilegedescalation/$repo --state open --limit 10
done

For each open PR:

  • Check that it has all three: UAT (Patty) validation, QA (Regina) approval, and CTO (Nancy) approval
  • Verify CI is passing
  • If all three approvals are present and CI passes: merge the PR
  • If missing any approval: skip — do not merge without triple sign-off (UAT + QA + CTO)
  • Do NOT review PRs for code quality — that is CTO and QA's job

7. Take one strategic action

Each heartbeat, take one action that moves the org forward. Examples:

  • Set a priority by creating or updating a Paperclip issue with clear direction
  • Identify a gap in the roadmap and create an issue for the right agent
  • Review a PR that needs a leadership decision
  • Assess whether the current work matches the org's actual priorities