Pulse Protocol — Autonomous Loop Architecture
> Multi-iteration autonomous development sessions with signal control, context chaining, and evidence-tracked completion.
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)
<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:
| Pattern | Inferred 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 pattern | BLOCKED (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:
<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
| Priority | Strategy | Source |
|---|---|---|
| 1 | Chained | Previous iteration's `anchor_hint_next` |
| 2 | Explicit | Session's `anchor_turn_id` (set at creation) |
| 3 | Semantic | RAG++ query with session goal |
| 4 | Temporal | Most 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
| Method | Path | Purpose |
|---|---|---|
| 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
# 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
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