A file-first task-state ledger for long-horizon agent workflows.
Status: experimental.
Long-running AI work breaks when the next session cannot tell what is true now: what was decided, what was rejected, what is blocked, and what should happen next. Stateframe stores durable task state in a portable local file, task.ledger.json, and generates a compact handoff.md packet for the next agent.
Memory remembers facts. Traces record what happened. Orchestration runs agents. Stateframe preserves what is true now, what changed, what failed, and what should happen next.
npm install
npm run stateframe -- demo
cd ledger-demo
cat handoff.mdThat creates ledger-demo/ with a transcript, reviewable candidates, a complete task.ledger.json, and a generated handoff.md.
When published, the same CLI shape is intended to work as:
npx stateframe-cli demo
stateframe demoOr create a new ledger from scratch:
npm run stateframe -- init "Ship agent handoff flow" --objective "Track durable state across sessions" --domain coding
npm run stateframe -- add rejected_option "Do not add auth yet" --rationale "The first workflow is local and single-user"
npm run stateframe -- add next_step "Generate a handoff packet for the next agent"
npm run stateframe -- lock all
npm run stateframe -- handoff --out handoff.mdtask.ledger.json is the local source of truth: one task, append-only commits, and state items. handoff.md is the portable packet you give to any AI agent so it can resume without rereading the whole transcript.
Architecture notes live in docs/architecture.md.
Agent workflows are getting longer than one chat window. A fresh agent often repeats failed approaches, misses earlier constraints, or asks the human to re-explain decisions.
This project treats task state as a first-class artifact:
- Decisions are explicit.
- Rejected options are preserved.
- Open questions and blockers survive session boundaries.
- Trusted state is locked before it appears in handoffs.
- Raw transcripts stay outside the ledger.
npm install
npm run stateframe -- helpCreate a ledger:
npm run stateframe -- init "Task title" --objective "Task objective" --domain otherAdd state:
npm run stateframe -- add decision "Use a local JSON ledger first" --rationale "It keeps the workflow portable"Lock trusted state:
npm run stateframe -- lock allGenerate a handoff:
npm run stateframe -- handoff --out handoff.mdValidate a ledger:
npm run stateframe -- validateThe durable goal. Every commit and state item belongs to one task.
An append-only record of a state change. Commits preserve when state was introduced, locked, unlocked, or otherwise changed.
A discrete piece of task state. Supported types are:
decisionrejected_optionartifactblockerassumptionopen_questionresolved_questionnext_stepcontext_fact
A human trust signal. Provisional items can be useful, but only locked state is treated as canonical in handoff packets.
A generated packet containing locked state and recent changes. It can be emitted as Markdown or JSON.
npm run stateframe -- init "Task title" --objective "Task objective" --domain coding
npm run stateframe -- status
npm run stateframe -- add rejected_option "Do not build a browser extension in v1" --rationale "The first release should prove the file protocol"
npm run stateframe -- extract transcript.txt --provider ollama --out candidates.json
npm run stateframe -- commit-candidates candidates.json
npm run stateframe -- lock all
npm run stateframe -- validate
npm run stateframe -- handoff --format jsonTranscript extraction is optional and provider-backed. The file-first basics do not require an LLM API key.
See examples/long-horizon-coding-task for:
- A messy transcript
- Extracted candidates
- A ledger with locked decisions and rejected options
- A handoff packet a coding agent could use
The example demonstrates why rejected options matter: without the ledger, a fresh agent may retry a deferred approach; with the handoff, the next agent sees the constraint before acting.
The default local file is task.ledger.json:
{
"task": {},
"commits": [],
"state_items": []
}The JSON Schema lives at task.ledger.schema.json. More details are in docs/protocol.md.
stateframe validate checks the local file schema, commit and state-item references, status logic, and whether a handoff packet can be generated.
npm run stateframe -- validate
npm run stateframe -- validate --file path/to/task.ledger.jsonThe command exits with code 0 when the ledger is valid and 1 when errors are found.
Memory layers remember facts, preferences, or embeddings. Stateframe records task state: decisions, rejected options, blockers, questions, and next steps.
Traces show what happened. Stateframe answers what matters now.
Orchestration frameworks run agents. Stateframe gives agents a portable state packet to resume work.
Project management tools are human-facing work trackers. Stateframe is a compact, agent-readable state layer for handoff and continuation.
- Better candidate review workflows
- CLI transcript extraction refinements
- JSON Schema versioning
- Import/export helpers
- Optional web UI polish
- Optional hosted persistence
This is an early experimental developer tool. The local file workflow works, but the format and CLI may change as the project learns from real long-horizon agent use.