Skip to content

Latest commit

 

History

History
256 lines (176 loc) · 8.75 KB

File metadata and controls

256 lines (176 loc) · 8.75 KB

Agent Autonomous Loop v6

Fresh context each cycle. Read STATE.md, execute phases, write STATE.md. That's it. CEO Operating Manual (daemon/ceo.md) is the decision engine — read every 50th cycle.


Cycle Start

Read these and ONLY these:

  1. daemon/STATE.md — what happened last cycle, what's next
  2. daemon/health.json — cycle count + circuit breaker state

That's your entire world. Do NOT read any other file unless a phase below explicitly tells you to.

Your addresses (STX, BTC, Taproot) are in conversation context from CLAUDE.md (read at session start).

Unlock wallet if STATE.md says locked. Load MCP tools if not present.


Phase 1: Heartbeat

Sign "AIBTC Check-In | {timestamp}" (fresh UTC .000Z). POST to https://aibtc.com/api/heartbeat with {signature, timestamp, btcAddress}. Use curl, NOT execute_x402_endpoint.

Reads: nothing. Addresses are in context from CLAUDE.md.

On fail → increment circuit_breaker.heartbeat.fail_count in health.json. 3 fails → skip 5 cycles.


Phase 2: Inbox

curl -s "https://aibtc.com/api/inbox/<your_stx_address>?status=unread"

Reads: nothing. The API returns only unread messages — no local filtering needed.

New messages? Classify:

  • Task message (fork/PR/build/deploy/fix/review) → add to daemon/queue.json
  • Non-task → queue a brief reply for Phase 5
  • Zero new messages → set idle=true, move on

GitHub notifications (every cycle):

gh api /notifications?all=false --jq '.[] | {reason, repo: .repository.full_name, url: .subject.url, title: .subject.title}'

If GitHub not configured in CLAUDE.md (not-configured-yet), skip — no error.

Do NOT read contacts, journal, learnings, or outbox in this phase.


Phase 3: Decide

Reads: daemon/queue.json — only if Phase 2 found new messages or there are pending tasks.

If queue is empty AND no new messages, pick ONE action by cycle number:

First: check agent discovery. Read health.json field last_discovery_date. If it's not today, do discovery instead of whatever's scheduled below. Set last_discovery_date to today after.

  • Discovery: curl -s "https://aibtc.com/api/agents?limit=50" — compare against contacts.md

Otherwise, by cycle modulo:

  1. cycle % 6 == 0: Check open PRsgh pr list --state open. Check if merged, has comments, needs changes. Respond to review feedback.
  2. cycle % 6 == 1: Contribute — pick a contact's repo, find an open issue you can fix, file PR or helpful comment.
  3. cycle % 6 == 2: Track AIBTC core — check github.com/aibtcdev repos for new issues, PRs, releases. Contribute if you can.
  4. cycle % 6 == 3: Contribute — pick a different contact's repo than last time.
  5. cycle % 6 == 4: Monitor bounties — check bounty boards for new bounties or ones you can submit to.
  6. cycle % 6 == 5: Self-audit — spawn scout on own repos. File issues for findings.

Rules:

  • One action per cycle. Don't try to do two.
  • Contributions must be useful. Bad PRs hurt reputation worse than no PRs.
  • After contributing, message the agent in Phase 6.
  • If a contribution action finds nothing to do, check your open PRs instead as fallback.

Phase 4: Execute

Do the one thing from Phase 3.

Read files ONLY if the task requires it:

  • Replying to a specific agent? → check contacts.md for their info
  • Hitting an API error? → grep "relevant_keyword" memory/learnings.md
  • Need to check recent context? → read last few entries of journal.md
  • Building/deploying something? → read the relevant repo files, not memory files

Most cycles this phase reads 0-1 files.

Subagents for heavy work:

  • scout (haiku, background) — repo recon
  • worker (sonnet, worktree) — PRs, code changes
  • verifier (haiku, background) — bounty checks

Phase 5: Deliver

Send all queued replies from Phase 2/3.

AIBTC replies:

# Sign and send — all info is already in conversation memory from Phase 2
export MSG_ID="<id>" REPLY_TEXT="<text>"
PREFIX="Inbox Reply | ${MSG_ID} | "
MAX_REPLY=$((500 - ${#PREFIX}))
if [ ${#REPLY_TEXT} -gt $MAX_REPLY ]; then REPLY_TEXT="${REPLY_TEXT:0:$((MAX_REPLY - 3))}..."; fi
# Sign the full string: "${PREFIX}${REPLY_TEXT}"
# Write JSON to temp file, POST with -d @file

GitHub: gh issue comment / gh pr comment

Reads: nothing new. Everything needed is already in conversation from earlier phases.


Phase 6: Outreach

Reads: daemon/outbox.json — check follow-ups due and budget.

Budget: 300 sats/cycle, 1500 sats/day, 1 msg/agent/day.

Only if you have something to send:

  • Check for duplicates in outbox.json sent list
  • Need agent's address? → check contacts.md
  • Contribution announcement (filed issue, opened PR)? → message them about it
  • Follow-up due per pending list? → send follow-up

No pending follow-ups + nothing to announce = skip this phase entirely. Reads: 1 file (outbox.json).

After sending: update outbox.json (sent list + pending list + budget).


Phase 7: Write

This phase is WRITE-ONLY. No reads.

7a. health.json (every cycle):

{"cycle":N,"timestamp":"ISO","status":"ok|degraded|error",
 "phases":{...},"stats":{...},"circuit_breaker":{...},
 "next_cycle_at":"ISO"}

7b. Journal (meaningful events only):

Append to memory/journal.md. One line per event. Skip on idle cycles with nothing to report.

7c. Learnings (only if you learned something new):

Append to memory/learnings.md. Don't write "everything worked."

7d. Contact updates (only if you interacted with an agent):

Update contacts.md with new info, status changes, or CRM notes.

7e. STATE.md (EVERY cycle — this is critical):

## Cycle N State
- Last: [what happened this cycle]
- Pending: [queued tasks or "none"]
- Blockers: [issues or "none"]
- Wallet: [locked/unlocked]
- Runway: [sats] sBTC
- Mode: [peacetime/wartime]
- Next: [one thing for next cycle]
- Follow-ups: [who's due when, or "none"]

Max 10 lines. This is the ONLY file the next cycle reads at startup.


Phase 8: Sync

git add daemon/ memory/
git commit -m "Cycle {N}: {summary}"
git push origin main

Skip if nothing changed (rare — health.json always changes).


Phase 9: Sleep

Output cycle summary, then exit. The bash wrapper or platform handles sleep + restart.


Periodic Tasks

Freq Task Extra reads
Once/day Agent discovery (/api/agents?limit=50) contacts.md
cycle % 6 == 0 Check open PRs for review feedback none
cycle % 6 == 1,3 Contribute to contact's repo contacts.md
cycle % 6 == 2 Track AIBTC core repos none
cycle % 6 == 4 Monitor bounties none
cycle % 6 == 5 Self-audit (spawn scout on own repos) none
Every 50th cycle CEO review: read daemon/ceo.md ceo.md (~1.3k tokens)
Every 10th cycle Evolve: edit THIS file if improvement found none

File Read Summary Per Cycle

Always read (startup): STATE.md (~80 tokens) + health.json (~300 tokens) = ~380 tokens

Phase 2 inbox: API returns only unread messages — no local file read needed = ~380 tokens total

Sometimes read (only when needed):

File When Tokens
queue.json New messages or pending tasks ~260
contacts.md Discovery, lookup, outreach ~400
outbox.json Phase 6 outreach ~200
learnings.md (grep) Something failed ~100 (grep result)
journal.md Checking recent context ~150
ceo.md Every 50th cycle ~1,300

Typical idle cycle: ~380 tokens of file reads. Busy cycle (new messages + outreach): ~1,500 tokens of file reads.


Failure Recovery

Any phase fails → log it, increment circuit breaker, continue to next phase. 3 consecutive fails on same phase → skip for 5 cycles, auto-retry after.


Reply Mechanics

  • Max 500 chars total signature string. Safe reply ~418 chars.
  • Sign: "Inbox Reply | {messageId} | {reply_text}"
  • Use -d @file NOT -d '...' — shell mangles base64
  • ASCII only — em-dashes break sig verification
  • One reply per message — outbox API rejects duplicates

Archiving (every 10th cycle, check thresholds)

  • journal.md > 500 lines → archive oldest entries to journal-archive/
  • outbox.json sent > 50 entries → rotate entries > 7 days to monthly archive
  • processed.json > 200 entries → keep last 30 days
  • queue.json > 10 completed → archive completed/failed > 7 days

Evolution Log

  • v4 → v5 (cycle 440): Integrated CEO Operating Manual. Added decision filter, weekly review, CEO evolution rules.
  • v5 → v6: Fresh context per cycle via STATE.md handoff. 9 phases (evolve is periodic). Minimal file reads (~380 tokens idle, ~1500 busy). Inbox API switched to ?status=unread. Circuit breaker pattern. Modulo-based periodic task rotation.