Sessions — Under the Hood
A single chat assistant remembers what you said three messages ago. A multi-agent pipeline does not, because each agent spawns fresh with nothing but its instructions and the files it can read. The shared memory is on disk — a per-run folder of YAML that every agent reads from and writes to.
Every /run, /team, /org, and /designer command creates a session on disk: a directory of YAML files that tracks everything from the initial request to the final validation. The session is the source of truth for the pipeline. It is how cAgents knows which agents ran, what state the pipeline is in, whether work completed successfully, and where to pick up if something gets interrupted.
Sessions are not just a record of what happened. They are how agents stay on track while work is in progress. A multi-agent pipeline can involve a dozen agents working across multiple phases — the orchestrator hands off to a planner, the planner hands off to a decomposer, the controller spawns execution agents. None of these agents share memory with each other. The session directory is the shared memory. Each agent reads the outputs from the previous phase, does its work, and writes its outputs for the next phase. Without the session on disk, every agent would be starting from scratch with nothing but the original request.
Think of the session directory as the flight recorder and the shared workspace rolled into one. It records what happened, in what order, and whether it succeeded — and it gives every agent the context it needs to do its job without drifting off course.
Why agents need sessions
When you ask a single AI assistant to do something, it has the full conversation context. Multi-agent pipelines do not work that way. Each agent spawns fresh — it has its instructions and whatever files it can read, but it has no memory of what previous agents discussed or decided.
Sessions solve this. The planner writes plan.yaml with objectives and acceptance criteria. The controller reads that plan and knows exactly what to execute against. The validator reads the plan and the controller's coordination_log.yaml and knows what success looks like. Each agent is grounded in concrete artifacts from the previous phase, not a vague understanding of the request.
This matters most for longer pipelines. By the time the validator runs, the original user request might be five agent handoffs ago. Without the session files, the validator would have to reconstruct intent from scratch. With them, it has the plan, the acceptance criteria, and the execution record — everything it needs to make a precise judgment.
--resume, the new conversation has zero memory of the previous one. The session directory on disk has everything — the plan, the progress, the agent tree, the outputs. The new pipeline picks up exactly where the old one stopped, guided entirely by what is written to disk.Past sessions are also reference material. When cAgents starts a new task, the enrichment phase can look at how similar work was handled before — which controllers were selected, what plans worked, what failed. The Agent_Memory/sessions/ directory is a growing library of past decisions that informs future ones.
What's in a session directory
When you run a command, cAgents creates a directory under Agent_Memory/sessions/ with this shape:
.
├── instruction.yaml # what was requested
├── status.yaml # current pipeline state
└── workflow/
├── agent_tree.yaml # every agent that was spawned
├── plan.yaml # the planner's output
├── coordination_log.yaml # controller's execution record
├── execution_summary.yaml # final results
└── events/
├── EVT-1.yaml # state transition events
├── EVT-2.yaml
└── index.yaml # event ordering
The top-level files — instruction.yaml and status.yaml — tell you what was requested and where the pipeline is right now. The workflow/ subdirectory holds the detailed execution record: which agents ran, what they planned, how they coordinated, and what they produced.
The prompts panel on this article walks you through reading each of these files end to end on a real session in your project. The article frames the schema; the panel does the read.
How sessions get named
Session directories follow a consistent naming convention: {type}_{slug}_{YYMMDD}_{NNN}.
- type — the command that created the session (
run,designer,team,org) - slug — a kebab-case summary of the request, auto-generated from your task description
- YYMMDD — the date
- NNN — a sequence number, incremented if you run the same type and slug on the same day
Real examples from this project:
| Session directory | Command | What it was |
|---|---|---|
run_shift-geometric-shapes_260330_003 | /run | Third run on March 30th about particle shapes |
designer_tech-blog-posts-guides_260320_001 | /designer | First designer session for blog/guide planning |
team_article-wave-design_260321_001 | /team | Team session for parallel article writing |
org_comprehensive-backend-refactor_260327_001 | /org | Cross-domain backend refactoring effort |
The naming makes it easy to find sessions by command type, topic, and date without opening any files. When you have dozens of sessions in the directory, the convention pays for itself. That said, you rarely need to browse this directory yourself — ask Claude "find the session where I worked on the auth module" or "what was the last /team run?" and it will locate the right one. The prompts panel has read-only walkthroughs for both lookup styles.
Read the core files
instruction.yaml — the request record
This file captures what you asked for, frozen at the moment the session started:
session_id: run_shift-geometric-shapes_260330_003
session_type: run
command: /run
request: "they should shift through all the common geometric shapes - not just hold one"
created_at: "2026-03-31T06:00:00Z"
flags: {}
parent_session_id: null
metadata:
working_directory: /home/PathingIT/caelandrayer.ca
The parent_session_id is null for standalone runs. When a /team or /org session spawns child /run sessions, the children point back to the parent here. The flags field records any CLI flags you passed (--dry-run, --interactive, --resume).
status.yaml — the state machine
This is the file you check first when you want to know where a pipeline stands:
pipeline_state: VALIDATED
revision_round: 0
validation_cycles: 0
created_at: "2026-03-31T06:00:00Z"
state_history:
- state: INIT
entered_at: "2026-03-31T06:00:00Z"
duration_ms: 2000
- state: PLANNED
entered_at: "2026-03-31T06:00:02Z"
duration_ms: 107720
- state: PROMPTS_READY
entered_at: "2026-03-31T06:02:00Z"
duration_ms: 95118
- state: VALIDATED
entered_at: "2026-03-31T06:03:35Z"
duration_ms: null
The state_history array is an ordered timeline of every state the pipeline passed through, with timestamps and durations. You can see exactly how long each phase took.
Notice this example went INIT → PLANNED → PROMPTS_READY → VALIDATED. That is only four states out of the full seven. The adaptive pipeline skips states based on task complexity — this was a tier 2 task that took the "fast path" described in Part 3, bypassing ORCHESTRATED, DECOMPOSED, and COORDINATED.
agent_tree.yaml — the audit trail
Every agent spawned during the pipeline gets registered here:
agents:
- id: pipeline
type: cagents:run
parent: root
depth: 0
spawned_at: '2026-03-31T06:00:00Z'
cagents_type: cagents:run
short_role: Pipeline Engine
role_description: Make particles shift through geometric shapes
session: run_shift-geometric-shapes_260330_003
- id: a896233d2db44f00b
type: cagents:universal-planner
parent: root
depth: 0
spawned_at: '2026-03-31T06:02:52Z'
cagents_type: cagents:universal-planner
short_role: Universal Planner
Each entry includes the agent's id, type, parent relationship, spawn time, and role description. When a pipeline finishes, completion summaries get appended to each agent's entry — what it produced, whether it succeeded, and how long it took.
This is the full audit trail. If you need to know which agent made a specific change or how many agents a pipeline spawned, agent_tree.yaml has the answer.
What states the pipeline passes through
The full state machine has seven states. Not every pipeline hits all of them — the adaptive pipeline skips states based on complexity.
| State | What happens | Agent |
|---|---|---|
| INIT | Enriches context with project info | orchestrator |
| ORCHESTRATED | Creates the plan and picks the controller | planner |
| PLANNED | Breaks plan into granular work items | decomposer |
| DECOMPOSED | Crafts delegation prompts for each work item | prompt-engineer |
| PROMPTS_READY | Executes work items with specialist agents | controller |
| COORDINATED | Validates against acceptance criteria | validator |
| VALIDATED | Pipeline complete | — |
Simple tasks (tier 1) might go straight from INIT to PLANNED to PROMPTS_READY to VALIDATED. Complex tasks (tier 3) hit every state. The status.yaml file always tells you which path a specific session took.
Resume an interrupted run
Sessions checkpoint as they go. Every state transition writes to disk before the next state begins. If a run gets interrupted — your terminal closes, your machine sleeps, the network drops — the session directory preserves everything up to the last completed state.
To pick up where you left off:
/run --resume
cAgents finds the most recent incomplete session, reads the status.yaml to determine the last completed state, and restarts the pipeline from the next state. Work that was already done does not get repeated.
The events/ directory is what makes this possible. Each EVT-*.yaml file records a state transition with enough context to reconstruct the pipeline's position. The index.yaml file maintains the ordering.
Agent_Memory/sessions/ yourself. Ask Claude "resume the last run" or "find the session where I was working on X" and it will locate the right session directory and resume from the last completed state. You will save the time and tokens that the completed states already consumed.How nested sessions link parent and child
/org and /team create parent sessions that spawn child /run sessions. The parent_session_id field in each child's instruction.yaml links back to the parent.
A /team session running three parallel tasks creates a directory shape like this:
Agent_Memory/sessions/
├── team_article-wave-design_260321_001/ # parent session
├── run_homepage-article_260321_001/ # child — wave 1
├── run_portfolio-article_260321_002/ # child — wave 1
└── run_blog-article_260321_003/ # child — wave 2
The parent session's coordination_log.yaml tracks which children were spawned, which wave they belong to, and their completion status. Each child is a self-contained session with its own status.yaml, agent_tree.yaml, and full execution record.
This is how a single /org command can coordinate work across multiple domains without losing track of any individual piece. The parent knows what it delegated. Each child knows what it did. The session structure keeps everything connected.
When you're done
You know the shape of Agent_Memory/sessions/, what each YAML file in a session carries, which states the pipeline can move through, and how a parent links to its children. Open the prompts panel on any real session in your project to read it end to end without browsing files yourself.
Next: Part 10 — Hooks: the event system covers the deterministic triggers that fire on session lifecycle events — the surface where rules-as-prose drift gets pinned down to exit codes.