Generated from cat-harness/skills/process/workflow/session-context.md — do not edit here.

✎ Edit this page’s source

Session context

A session is one actor working, from the moment it picks up until it stops. A process instance is a token’s position in one diagram. They are not the same object and the difference is load-bearing:

A session starts before any instance, may open several, switches between them, and outlives each. A session with nothing open is the commonest state there is.

Model the session as a field on an instance and the first process opened owns facts that belong to the actor — and the idle session, which is most of them, becomes unrepresentable. So it is its own record, referencing instances rather than containing them.

Shape: schemas/session-context.ts. Graph typology: session-state, layer state — a session writes its own record as it goes, which is exactly what content-context-and-state-graphs means by live state.

The fields — read them off the schema, never off this page

SessionContextSchema in schemas/session-context.ts is authoritative. This description said “the six fields” until 2026-09-24, by which point there were eight — waitingOn and $schema had joined id, actor, startedAt, updatedAt, open, claimed. Bean s8mo carried the same “six” and drifted with it, so the bean and this skill agreed with each other and both disagreed with the code, which is the one shape comparing them cannot catch.

No count is given here on purpose. A field list in prose beside a Zod object is a second answer to a question the schema already answers, and it is wrong the first time somebody adds a field.

actor is required, and it is the point of the record

Every other field can be recovered by looking at the repository. Open instances are in the bean graph; claimed beans carry their own status; timestamps can be reconstructed from commits. WHO is acting cannot be derived from anything.

The machine keeping the session cannot infer it — the same reason the Logger cannot infer who wrote a log line, which is why log-message takes actor too. A session record that cannot name its actor records that something is happening and nothing about who is answerable for it, which is the first question a sibling session needs answered before it touches the same bean.

It is a reference with a declared flag, not an ActorDefinition. An agent may act without a node under the actors graph, and requiring one would make the field unfillable in exactly the cold-start case the record is most useful for. The two facts — an id that resolves and a name nobody declared — are kept apart because a consumer acts differently on each: an audit can follow the first to a role and a permission set, and can only quote the second.

And declared is written, not inferred at read time. A reader resolving it themselves gets a different answer than the writer did if the node was added or removed in between, and the record says what was true when the session acted.

The rest of the fields, and what each is for

fieldfornotes
idnaming this sessionstable for its life
startedAt / updatedAttelling a live session from an abandoned oneISO-8601 UTC
open[]which instances this session is insideempty is normal, not a gap
claimed[]which beans this session announcedby reference, never copied
waitingOnwhy nothing is movingwhat + since, together

open empty is the normal state. An agent answering a question, reading, or deciding what to do next is in no process at all, and process-state calls that idle rather than broken. A record that treated empty as a defect would report every reading session as one.

claimed is by reference because a claim announces rather than reserves. The bean is the authority on its own status (bean-coordination); a status copied here would be free to contradict it, and a sibling reading the copy would act on a claim that had already been released.

waitingOn carries since or it carries nothing. A wait with no start cannot be told from abandoned work — the same argument bean-blocking makes for requiring an expiry. what is free text on purpose: a human answer, a CI run, a sibling’s PR is an open set no enum would survive.

The session’s view of a node is ADVISORY

open[].atNode is what the session believes. The instance wins. The instance is the authority on its own token; this can be stale by exactly one step — the gap between a step completing and the session noticing.

It is recorded anyway for two reasons. The commonest question about a session (“what is it doing”) should not need a second file read. And a disagreement between the two is itself worth seeing: a session whose view has drifted from the instance is a session that lost track, which is one of the detectors process-state names for being out of process.

Who reads it, and why it is parsed rather than trusted

A sibling session, deciding whether a bean is genuinely being worked or was claimed by someone who stopped. A person, asking what is in flight. The session itself on resume, in a fresh container, where the alternative is starting a second session beside the one that already exists.

The writer may be an LLM playing the part of a state machine (bean 3nfv), so the shape cannot be assumed from the writer’s care. parseSessionContext() parses at the boundary, which is what makes a non-deterministic writer safe to read from — and that is the general rule this record is the first case of: where a machine may be played rather than executed, the schema is the contract and the parse is where it is enforced.

What this is NOT

Not the work plan. A bean says what is being worked on and survives the session; this says who is working and where they are right now. Delete every session record and the plan is intact.

Not a log. log-message records what an actor DID at a moment, append-only. This is the current position, overwritten as it moves. A log tells you how you got here; this tells you where you are.

Not interaction preferences. cat-harness/memory/interaction.json holds how a person wants to be asked — durable, read at session start, never written by a process. That is context, and this is state: the two are on opposite sides of the layer line and must not be merged, however adjacent they look.

Not a store yet. The kind is registered and the shape is defined; nothing writes one. The state machine is bean 3nfv, and declaring a directory before anything fills it is the defect where a consumer scans nothing and reports a clean run.

Processes that run this skill

processstep(s) that name it
Session state machineEstablish who is acting; Open the session record; Refresh updatedAt only; Write what changed; Close the session

folio-assistant — code under the Apache License 2.0, documentation under CC BY 3.0. Generated schema and API references are rebuilt from source on every push to main.

deployed b08c961 · 2026-10-23T23:11:09Z