Grand Diomande Research · Full HTML Reader

Pulse Protocol — Autonomous Loop Architecture

> Multi-iteration autonomous development sessions with signal control, context chaining, and evidence-tracked completion.

Agents That Account for Themselves architecture technical paper candidate score 30 .md

Full Public Reader

Pulse Protocol — Autonomous Loop Architecture

> Multi-iteration autonomous development sessions with signal control, context chaining, and evidence-tracked completion.

---

Session Lifecycle

┌─────────┐  start   ┌─────────┐  loop   ┌───────────┐
│ pending  │────────▶│ running  │────────▶│ iteration │──┐
└─────────┘         └─────────┘         └───────────┘  │
                         ▲                               │
                         │ CONTINUE                      │
                         └───────────────────────────────┘
                                                         │
                    ┌─────────┬──────────────────────────┘
                    │         │              │
                    ▼         ▼              ▼
              ┌──────────┐ ┌─────────┐ ┌──────────┐
              │ complete │ │ blocked │ │  failed  │
              │ COMPLETE │ │ BLOCKED │ │  error   │
              └──────────┘ └─────────┘ └──────────┘

Statuses: pending → running → complete | blocked | failed | aborted | paused

---

Signal Protocol

Each iteration MUST emit exactly one signal. The agent includes it in output:

Explicit Signals (preferred)

xml
<signal>CONTINUE</signal>       <!-- More work to do, keep looping -->
<signal>COMPLETE</signal>       <!-- Goal achieved, stop -->
<signal>BLOCKED: reason</signal> <!-- Needs human input, pause -->

### Inferred Signals (fallback)
If no explicit tag, the system infers from output patterns:

PatternInferred Signal
"all tasks are complete", "implementation is complete"COMPLETE
"need your input", "please provide", "cannot proceed"BLOCKED
Code blocks present, "created file", "next step"CONTINUE
No recognizable patternBLOCKED (safe default)

---

Iteration Pipeline

┌──────────────┐
│ Loop Runner  │
│ (per session)│
└──────┬───────┘
       │
       ▼
┌──────────────────────┐
│ 1. Context Builder   │
│                      │
│  ┌─ Anchor Resolver ─┐
│  │ Strategy priority: │
│  │ 1. Chained (prev  │
│  │    iteration hint) │
│  │ 2. Explicit        │
│  │    (session anchor)│
│  │ 3. Semantic        │
│  │    (RAG++ query)   │
│  │ 4. Temporal        │
│  │    (most recent)   │
│  └────────────────────┘
│                      │
│  ┌─ Graph Kernel ────┐
│  │ createSlice()     │
│  │ → slice_id        │
│  │ → turn_ids        │
│  │ → node_count      │
│  └────────────────────┘
│                      │
│  ┌─ RAG++ ───────────┐
│  │ queryRag(goal,    │
│  │   project, slice) │
│  │ → relevant turns  │
│  │ → similarity      │
│  └────────────────────┘
│                      │
│  → buildIterationPrompt()
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│ 2. Dispatch          │
│                      │
│  INSERT inbox_tasks  │
│  source: "pulse"     │
│  media_context: {    │
│    pulseSessionId,   │
│    iterationNumber,  │
│    projectId,        │
│    branchName,       │
│    sliceId           │
│  }                   │
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│ 3. Agent Execution   │
│                      │
│  Agent daemon picks  │
│  up inbox_task       │
│  Spawns Claude Code  │
│  CLI with context    │
│                      │
│  Context strategies: │
│  - none              │
│  - prefetch (prompts)│
│  - mcp (servers)     │
│  - hybrid (both)     │
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│ 4. Wait + Extract    │
│                      │
│  Poll inbox_tasks    │
│  every 5s (5m max)   │
│                      │
│  Extract:            │
│  - Signal (XML tag   │
│    or heuristic)     │
│  - Anchor hint       │
│  - Commit hash       │
│  - Files changed     │
│  - Output summary    │
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│ 5. Record + Branch   │
│                      │
│  UPDATE pulse_       │
│  iterations with:    │
│  - signal            │
│  - output            │
│  - commit_hash       │
│  - files_changed     │
│  - anchor_hint_next  │
│                      │
│  Branch on signal:   │
│  CONTINUE → loop     │
│  COMPLETE → done     │
│  BLOCKED → pause     │
└──────────────────────┘

---

Context Chaining (Anchor Hints)

Each iteration can suggest what context the next iteration should start with:

xml
<anchor_hint>
  <turn_id>uuid-of-relevant-conversation-turn</turn_id>
  <reason>This turn contains the API design we're implementing</reason>
</anchor_hint>

Resolution Priority

PriorityStrategySource
1ChainedPrevious iteration's `anchor_hint_next`
2ExplicitSession's `anchor_turn_id` (set at creation)
3SemanticRAG++ query with session goal
4TemporalMost recent turn in project

Each resolution records:
- `anchor_strategy`: Which strategy was used
- `anchor_resolution_ms`: How long the lookup took
- `salience`: Relevance score
- `depth`: How deep in conversation tree

---

Database Tables

### pulse_sessions
| Column | Type | Purpose |
|--------|------|---------|
| id | uuid | Session ID |
| project_name | text | Project context |
| goal | text | What to accomplish |
| max_iterations | int | Loop limit |
| current_iteration | int | Current count |
| status | text | pending/running/complete/blocked/failed/paused/aborted |
| last_signal | text | Most recent CONTINUE/COMPLETE/BLOCKED |
| progress_log | jsonb | Array of iteration summaries |
| anchor_turn_id | text | Optional starting anchor |
| branch_name | text | Git branch for session |
| created_by | text | telegram/sms/api/cli |
| total_commits | int | Commits made |
| total_tokens_used | int | Token accounting |

### pulse_iterations
| Column | Type | Purpose |
|--------|------|---------|
| id | uuid | Iteration ID |
| session_id | uuid | FK to session |
| iteration_number | int | 1-indexed |
| inbox_task_id | uuid | FK to inbox_tasks |
| task_content | text | Prompt sent to agent |
| status | text | pending/dispatched/running/complete/failed/timeout |
| signal | text | CONTINUE/COMPLETE/BLOCKED |
| output_summary | text | Short result |
| output_full | text | Complete response |
| commit_hash | text | Git evidence |
| files_changed | text[] | Modified files |
| anchor_turn_id | text | Which anchor was used |
| anchor_strategy | text | explicit/chained/semantic/temporal |
| anchor_hint_next | text | Suggested anchor for next iteration |
| context_tokens | int | Tokens in context |
| slice_id | text | Graph Kernel slice used |

---

Notification Flow

Iteration completes
  │
  └─ notifyIterationComplete()
      │
      ├─ CONTINUE → 📍 "Iteration 3/10: Built login component. Continuing..."
      ├─ COMPLETE → ✅ "Session complete (5 iterations, 3 commits)"
      └─ BLOCKED  → ⏸️ "Blocked: Need API key for Stripe integration"
      │
      └─ Delivered via:
          ├─ Telegram (if chat_id set)
          ├─ SMS (if phone_number set)
          └─ Discord (if discord_thread_id set)

---

API Endpoints

MethodPathPurpose
POST`/api/pulse/start`Create and start session
GET`/api/pulse/:id`Session status + iterations
GET`/api/pulse?status=running`List sessions
POST`/api/pulse/:id/pause`Pause after current iteration
POST`/api/pulse/:id/resume`Resume paused session
POST`/api/pulse/:id/abort`Force stop

---

Operational Notes

Starting a session

bash
# Via MCP tool
pulse_start(projectName: "my-app", projectPath: "/path/to/project", goal: "Implement user auth", maxIterations: 10)

# Via REST
curl -X POST http://localhost:3002/api/pulse/start \
  -H 'Content-Type: application/json' \
  -d '{"projectName":"my-app","projectPath":"/path","goal":"Implement auth","maxIterations":10}'

Monitoring progress

sql
SELECT s.id, s.current_iteration, s.max_iterations, s.status, s.last_signal,
       i.signal, i.output_summary, i.commit_hash
FROM pulse_sessions s
LEFT JOIN pulse_iterations i ON i.session_id = s.id
WHERE s.status = 'running'
ORDER BY i.iteration_number DESC;

### Recovering a blocked session
1. Check why it blocked: `SELECT last_signal, progress_log FROM pulse_sessions WHERE id = '...'`
2. Address the blocker (provide API key, fix config, etc.)
3. Resume: `pulse_resume(sessionId: '...')`

Promotion Decision

Promote into a technical note or architecture paper with implementation anchors.

Source Anchor

Comp-Core/docs/PULSE-PROTOCOL.md

Detected Structure

Method · Architecture