Cases, Tasks, and Records
Preserve useful shared state without turning Epismo into the execution runtime.
A Case is one real matter. It can be pinned to an immutable Playbook Version or started ad hoc with a title. A Playbook-backed Case stores the Playbook ID and Version ID; it does not track Step progress.
Case lifecycle
A Case is open or closed. Closing sets an outcome of completed, cancelled, or abandoned. completed requires every Task to be closed; cancellation or abandonment closes remaining open Tasks as part of the Case transition. Reopening a Case does not reopen its Tasks.
Archiving is separate from closing. An archived Case leaves every list, count, and handoff graph and stops resolving for reads, while its Tasks, Records, and Handoffs are retained rather than deleted. Only the Case starter or its current assignee can archive one, from the web app.
A Case may finish with no Tasks and no Records. Use that lightweight form when only the fact and outcome need to be retained.
Case mutations use optimistic concurrency. Send the latest lockVersion; after a conflict, re-read the Case and reconsider the change rather than replaying stale intent.
Tasks are created on demand
A Task is explicit work within a Case. Its kind is work or review; it may be assigned to a User, linked to a source Step, and, for review work, point to the exact subject Record.
Starting a Case does not create one Task per Step. Create a Task only when responsibility, handoff, review, or a separately tracked piece of work should be visible. Multiple Tasks can be open and closing one does not advance the Case automatically.
Task updates also use lockVersion. A closed Task can be reopened only while its parent Case is open.
Directed handoffs connect Cases
Cases can be linked into a directed acyclic graph (DAG) using handoffs (fromCaseId -> toCaseId). Handoffs model multi-stage or cross-team continuations while preserving individual Case ACLs and lifecycles:
- Cycle prevention: Handoff creation enforces cycle-free graphs using transactional reachability checks. Self-links and cyclic paths are rejected.
- Candidate discovery: Query eligible upstream or downstream Cases to discover valid connection targets without trial-and-error.
- Handoff graph: View the connected DAG around a root Case across configurable scopes (
self,ancestors,descendants,neighbors,connected).
Records are the handoff surface
Records are immutable, append-only entries on a Case timeline and may also belong to a Task or source Step. They include an application-defined kind, optional human-readable content, structured data, origin (user, agent, or system), creator, client identity, and creation time.
Good Records include outcomes, evidence, decisions, review comments, file or object references, handoff summaries, meaningful errors, and coordination activity. Do not automatically store chain-of-thought, every tool call, raw shell output, credentials, retry history, heartbeat, or the runtime graph.
Correct a Record by appending a new Record. Records are listed within a Case, with stable cursor pagination and optional Task, author, kind, origin, ACL, and sort-order filters. Passing a handoff scope (such as ancestors or connected) expands the query across connected handoffs while evaluating caller access for each Case independently.