State System & Multi-Session Workflows
Learn how AILANG's state system enables persistent, multi-session development workflows with Claude Code skills.
Overview
AILANG provides a sophisticated state management system that enables multi-day sprints, agent handoffs, and session continuity. Unlike traditional AI assistants that lose context when you close them, AILANG's state system persists progress across sessions.
The state system gives Claude Code a "hard drive" - work persists across sessions, days, or weeks!
Three Integrated Systems
1. AILANG Messaging System
Built into AILANG itself (Go implementation), provides persistent message passing between agents.
Storage: ~/.ailang/state/collaboration.db (SQLite)
Full CLI reference (send/list/read/ack/unack/forward/search) lives in the Agent Messaging guide.
Inbox types:
- User inbox: Messages for the human developer
- Agent inboxes: Messages for specific agents (sprint-planner, sprint-executor, etc.)
2. JSON State Files
Structured progress tracking for long-running tasks like sprints.
Location: .ailang/state/sprints/sprint_<id>.json
Purpose:
- Track milestone completion (
passes: true/false/null) - Record actual LOC vs estimates
- Store velocity metrics
- Enable multi-session continuity
Example:
{
"sprint_id": "M-TESTING-INLINE",
"status": "in_progress",
"milestones": [
{
"id": "M1",
"description": "Pipeline Integration",
"passes": true,
"actual_loc": 210,
"started": "2025-11-27T09:00:00Z",
"completed": "2025-11-27T15:00:00Z"
},
{
"id": "M2",
"description": "Examples & Tests",
"passes": null,
"started": "2025-11-27T15:00:00Z"
}
]
}
3. Claude Code Skills
Specialized workflows following Anthropic's October 2025 specification.
Location: .claude/skills/<skill-name>/
Key skills:
- sprint-planner - Creates plans, sends handoffs
- sprint-executor - Executes plans, reads state
- agent-inbox - Checks messages from agents
How They Work Together
Complete Workflow Example
Session 1: Planning (15 minutes)
# Start Claude Code
You: "Plan sprint for inline testing"
# sprint-planner skill activates automatically
✓ Analyzes design docs
✓ Checks recent velocity (31 LOC/day)
✓ Discovers feature is 90% complete!
✓ Creates sprint plan:
design_docs/planned/v0_4_2/M-TESTING-INLINE-COMPLETION-SPRINT.md
✓ Creates JSON state:
.ailang/state/sprints/sprint_M-TESTING-INLINE.json
✓ Sends handoff message:
ailang messages send sprint-executor '{"type":"plan_ready","sprint_id":"M-TESTING-INLINE"}' \
--title "Sprint: M-TESTING-INLINE" --from "sprint-planner"
# Message persists in:
~/.ailang/state/collaboration.db
# You close Claude Code
# Days pass... no memory retained in Claude
Session 2: Start Implementation (next day)
# You open Claude Code (fresh session, no memory)
You: "Start the sprint"
# sprint-executor skill activates
✓ Checks inbox:
ailang messages list --unread --inbox sprint-executor
✓ Finds message from sprint-planner:
"plan_ready" for M-TESTING-INLINE
✓ Loads JSON state:
.ailang/state/sprints/sprint_M-TESTING-INLINE.json
✓ Shows summary:
╔═══════════════════════════════════════════╗
║ Sprint M-TESTING-INLINE ║
╚═══════════════════════════════════════════╝
Status: not_started
Progress: 0/2 milestones
Next: M1 - Pipeline Integration (8 hours)
- Create executor.go
- Update runner.go
- Write unit tests
✓ Begins work with TDD:
1. Write test first
2. Implement code
3. Run make test && make lint
4. Update JSON: {"id": "M1", "passes": true}
5. Commit code
# You work for 6 hours, complete M1
# Need to stop for the day
You: "Pause sprint"
✓ Updates JSON:
{
"status": "paused",
"last_checkpoint": "M1 complete, M2 ready to start",
"milestones": [
{"id": "M1", "passes": true, "actual_loc": 210}
]
}
# You close Claude Code
# A week passes...
Session 3: Resume Work (a week later)
# You open Claude Code (fresh session, no memory of last week)
You: "Continue the sprint"
# sprint-executor skill activates
✓ Loads JSON state (no inbox check needed - state is current)
✓ Shows "Here's where we left off":
╔═══════════════════════════════════════════╗
║ Sprint M-TESTING-INLINE ║
╚═══════════════════════════════════════════╝
Status: paused
Progress: 1/2 milestones complete
Completed:
✓ M1: Pipeline Integration (210 LOC, 6 hours)
Next:
→ M2: Examples & Tests (4-6 hours)
- Fix examples/testing_basic.ail
- Update examples/factorial.ail
- Write integration tests
Last checkpoint: "M1 complete, M2 ready to start"
Velocity: 35 LOC/hour (on track!)
✓ Continues implementation from exactly where it left off
✓ NO manual recap needed
✓ NO context lost
Directory Structure
your-project/
├── .claude/ # Claude Code skills (IDE-local)
│ └── skills/
│ ├── sprint-planner/ # Creates plans & handoffs
│ └── sprint-executor/ # Executes plans, tracks progress
│
├── .ailang/ # AILANG state (persistent)
│ └── state/
│ ├── sprints/ # Sprint progress tracking
│ │ ├── sprint_M-TESTING-INLINE.json
│ │ ├── sprint_M-DX11.json
│ │ └── sprint_M-POLY-B.json
│ │
│ └── collaboration.db # Agent messaging (SQLite)
│
└── design_docs/
└── planned/v0_4_2/
└── M-TESTING-INLINE-COMPLETION-SPRINT.md
Inspecting State from the Command Line
The state is plain JSON + SQLite, so everything is inspectable without Claude:
# Sprint progress at a glance
jq '.milestones[] | {id, passes, actual_loc}' \
.ailang/state/sprints/sprint_M-TESTING-INLINE.json
# Multiple sprints run in parallel — one JSON file each
ls .ailang/state/sprints/
# Messages waiting for an agent
ailang messages list --inbox sprint-executor --unread
Because state survives crashes and session loss, recovery is just "Resume sprint M-TESTING-INLINE" in a fresh session — the skill reloads the JSON and continues from the last checkpoint.
Technical Details
Message Format
Messages use JSON with standard fields:
{
"type": "plan_ready",
"correlation_id": "sprint_M-TESTING-INLINE_2025-11-27",
"sprint_id": "M-TESTING-INLINE",
"plan_path": "design_docs/planned/v0_4_2/M-TESTING-INLINE-COMPLETION-SPRINT.md",
"progress_path": ".ailang/state/sprints/sprint_M-TESTING-INLINE.json",
"estimated_duration": "1-2 days (10-14 hours)",
"milestones": [
{
"id": "M1",
"name": "Pipeline Integration",
"estimated_hours": 8
}
],
"discovery": "Feature is 90-95% complete!",
"total_loc_estimate": 400,
"risk_level": "low"
}
State File Schema
Sprint JSON files follow a consistent schema:
{
"sprint_id": "M-TESTING-INLINE",
"created": "2025-11-27T09:00:00Z",
"status": "in_progress",
"plan_path": "design_docs/...",
"milestones": [
{
"id": "M1",
"description": "Pipeline Integration",
"estimated_loc": 200,
"actual_loc": 210,
"passes": true,
"started": "2025-11-27T09:00:00Z",
"completed": "2025-11-27T15:00:00Z",
"notes": "Completed ahead of schedule"
}
],
"velocity": {
"target_loc_per_day": 150,
"actual_loc_per_day": 35,
"estimated_total_loc": 400,
"actual_total_loc": 210
},
"last_session": "2025-11-27T15:00:00Z",
"last_checkpoint": "M1 complete, M2 ready"
}
Best Practices
1. Commit State Files
# Track sprint progress in git
git add .ailang/state/sprints/sprint_*.json
git commit -m "Update sprint progress: M1 complete"
2. Regular Checkpoints
# After completing each milestone:
You: "Update sprint checkpoint"
# Claude updates JSON with latest progress
3. Clear Messages
# When sending custom messages, include context:
ailang messages send sprint-executor "Pause: need to context-switch to urgent bug. M2 50% complete. Resume 2025-11-28." \
--title "Pause request" --from "user"
4. Clean Up Old Sprints
# Archive completed sprints
mkdir -p .ailang/state/sprints/archive
mv .ailang/state/sprints/sprint_M-OLD.json \
.ailang/state/sprints/archive/
Troubleshooting
State not loading → validate the JSON: jq -e . .ailang/state/sprints/<file>.json.
Messages not appearing → see the Agent Messaging guide.
Two sessions edited the same sprint → the state is git-tracked JSON; diff,
merge by hand, commit.
Related Documentation
- Agent Workflows - Overview of agent patterns
- Claude Code Integration - Setting up Claude Code
- Hooks Setup - Configuring hooks for automation
Further Reading
- Anthropic: Long-Running Agents - Design patterns this system implements
- AILANG Agent System - Source code and examples