Pentagon stores all data locally in ~/.pentagon/. This directory is the source of truth for agent configurations, identity files, organizational structures, and hook scripts.
Directory Structure
~/.pentagon/
├── agents/
│ └── {uuid}/
│ ├── config.json # Agent configuration
│ ├── SOUL.md # Role, personality, instructions
│ ├── TASKS.md # Markdown checkbox list
│ ├── MEMORY.md # Persistent notes and context
│ ├── heartbeat-config.json # Restart behavior
│ ├── status.json # Written by hook scripts
│ └── report.json # Written by agent self-reporting
├── pods/
│ └── {uuid}/
│ ├── config.json # Pod configuration
│ ├── TASKS.md # Pod-level tasks
│ ├── MEMORY.md # Pod-level memory
│ └── DISCUSSION.md # Pod conversation log
├── teams/
│ └── {uuid}/
│ ├── config.json # Team configuration
│ ├── TASKS.md # Team-level tasks
│ ├── MEMORY.md # Team-level memory
│ └── DISCUSSION.md # Team conversation log
├── souls/
│ └── {uuid}.json # Reusable soul templates
├── hooks/
│ ├── session-start.sh # Hook: session started
│ ├── agent-stop.sh # Hook: agent stopped
│ ├── tool-activity.sh # Hook: pre-tool use (sync)
│ ├── post-tool.sh # Hook: post-tool use (async)
│ └── session-end.sh # Hook: session ended
└── canvas-layout.json # Canvas positions and zoom state
Agent Files
config.json
Stores the agent’s core configuration. Created when an agent is spawned.
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Backend Agent",
"directory": "/Users/you/projects/my-app",
"sessionId": "session-abc123",
"podId": "pod-uuid-here",
"teamId": "team-uuid-here",
"soulPath": "~/.pentagon/agents/550e8400.../SOUL.md",
"heartbeatPath": "~/.pentagon/agents/550e8400.../heartbeat-config.json",
"memoryPath": "~/.pentagon/agents/550e8400.../MEMORY.md",
"provider": "anthropic",
"deskPosition": 0,
"shapeSides": 6,
"color": "#FBBF24",
"originalDirectory": "/Users/you/projects/my-app",
"worktreePath": "/Users/you/projects/my-app-wt-550e8400",
"worktreeBranch": "pentagon/backend-agent"
}
| Field | Type | Description |
|---|
id | UUID | Unique agent identifier |
name | String | Display name on the canvas desk |
directory | String | Working directory for the Claude Code process |
sessionId | String | Current Claude Code session identifier |
podId | UUID? | Pod this agent belongs to, if any |
teamId | UUID? | Team this agent belongs to, if any |
soulPath | String | Path to the agent’s SOUL.md |
heartbeatPath | String | Path to heartbeat-config.json |
memoryPath | String | Path to MEMORY.md |
provider | String | API provider (anthropic) |
deskPosition | Int | Grid position index on the canvas |
shapeSides | Int | Desk polygon shape (e.g., 6 for hexagon) |
color | String | Hex color for the desk ring |
originalDirectory | String | Original directory before worktree creation |
worktreePath | String? | Path to the git worktree, if created |
worktreeBranch | String? | Branch name for the worktree |
status.json
Written atomically by hook scripts. Pentagon watches this file via DispatchSource to track agent activity.
{
"status": "active",
"since": "2025-07-15T14:30:00Z",
"event": "PreToolUse",
"activeTool": "Read"
}
| Field | Type | Description |
|---|
status | String | Current status: idle, active, waitingInput, dormant, error |
since | ISO 8601 | Timestamp of the last status change |
event | String | Hook event that triggered the write: SessionStart, Stop, PreToolUse, PostToolUse, SessionEnd |
activeTool | String? | The tool currently in use (only present for PreToolUse / PostToolUse events) |
report.json
Written by the agent itself to self-report progress. Pentagon reads this for display in the Detail Panel.
{
"summary": "Implementing auth module",
"task": "Add JWT validation",
"progress": "3/5"
}
| Field | Type | Description |
|---|
summary | String | Brief description of current work |
task | String | The specific task being worked on |
progress | String | Freeform progress indicator |
heartbeat-config.json
Controls the agent’s restart and keep-alive behavior.
{
"mode": "alwaysOn",
"intervalSeconds": null,
"maxRetries": 3,
"restartDelaySeconds": 30
}
| Field | Type | Description |
|---|
mode | String | manual (no auto-restart), alwaysOn (restart on exit), interval (periodic restart) |
intervalSeconds | Int? | Seconds between heartbeat checks (only used with interval mode) |
maxRetries | Int | Maximum consecutive restart attempts before giving up |
restartDelaySeconds | Int | Seconds to wait before restarting after exit |
SOUL.md
Freeform markdown that defines the agent’s role, personality, and instructions. Injected into the Claude Code system prompt.
# Backend Engineer
You are a senior backend engineer focused on API development.
## Instructions
- Write tests for all new endpoints
- Use the existing project patterns
- Ask before making breaking changes
## Constraints
- Do not modify the database schema without approval
- Keep changes scoped to the /api directory
TASKS.md
A markdown checkbox list of work items. The TaskEngine parses this file reactively to track completion.
- [x] Set up project scaffolding
- [x] Implement user model
- [ ] Add JWT authentication
- [ ] Write integration tests
- [ ] Deploy to staging
Checked items ([x]) are complete. Unchecked items ([ ]) are pending. Pentagon displays a progress count (e.g., “2/5”) derived from this file.
MEMORY.md
Persistent notes and context that survive across agent restarts. The agent can read and write to this file.
## Project Context
- Using PostgreSQL 15 with pgvector extension
- Auth tokens expire after 24 hours
- The CI pipeline runs on every push to main
## Decisions
- Chose JWT over session cookies for stateless auth
- Rate limiting set to 100 req/min per user
Pod Files
pods//config.json
{
"id": "660e8400-e29b-41d4-a716-446655440000",
"name": "API Team",
"origin": "550e8400-e29b-41d4-a716-446655440000",
"gridWidth": 3,
"gridHeight": 2,
"color": "#818CF8",
"emoji": "rocket",
"parentPodId": null
}
| Field | Type | Description |
|---|
id | UUID | Unique pod identifier |
name | String | Display name |
origin | UUID | The agent that anchors this pod on the canvas |
gridWidth | Int | Pod grid width in cells |
gridHeight | Int | Pod grid height in cells |
color | String | Hex color for the pod border |
emoji | String | Emoji displayed on the pod header |
parentPodId | UUID? | Parent pod for nested hierarchies |
DISCUSSION.md
A shared conversation log for pods and teams. Agents can append messages here for inter-agent coordination.
Team Files
teams//config.json
{
"id": "770e8400-e29b-41d4-a716-446655440000",
"name": "Platform Team",
"emoji": "shield"
}
| Field | Type | Description |
|---|
id | UUID | Unique team identifier |
name | String | Display name |
emoji | String | Emoji displayed on the team badge |
Teams also have TASKS.md, MEMORY.md, and DISCUSSION.md files with the same format as pod-level files.
Soul Templates
souls/.json
Reusable soul definitions that can be applied to multiple agents. Stored as JSON with the soul content embedded.
Hook Scripts
The five scripts in ~/.pentagon/hooks/ are auto-generated by HookInjector. Each script:
- Receives event data from Claude Code as arguments
- Writes a
status.json file atomically (write to a temp file, then mv to the final path)
- Targets
~/.pentagon/agents/{id}/status.json
These scripts are registered with Claude Code via .claude/settings.local.json, which HookInjector injects into each agent’s working directory.
Do not edit hook scripts manually. Pentagon regenerates them on launch. Any manual changes will be overwritten.
Canvas Layout
canvas-layout.json
Stores the canvas viewport state and agent desk positions.
{
"deskPositions": {
"550e8400-e29b-41d4-a716-446655440000": { "x": 30, "y": 30 },
"660e8400-e29b-41d4-a716-446655440000": { "x": 280, "y": 30 }
},
"zoom": 1.0,
"panX": 0,
"panY": 0
}
| Field | Type | Description |
|---|
deskPositions | Dict | Maps agent UUIDs to {x, y} canvas coordinates |
zoom | Float | Current zoom level (1.0 = default) |
panX | Float | Horizontal pan offset |
panY | Float | Vertical pan offset |
File Watching
Pentagon uses DispatchSource.makeFileSystemObjectSource to monitor each agent’s directory. When any watched file changes, the corresponding handler fires:
status.json changes trigger StatusEngine state transitions
TASKS.md changes trigger TaskEngine progress updates
report.json changes update the agent’s self-reported summary
heartbeat-config.json changes reconfigure HeartbeatScheduler
SOUL.md and MEMORY.md changes refresh the Detail Panel tabs
File watching starts when an agent is created and stops when it is deleted. There is no polling — all updates are event-driven.
Related Pages