Case Files
What you'll learn
- What a case file is (and what it deliberately isn't).
- The shape of the contract: objective, policy, evidence, assumptions, stale-risk, verification plan.
- How the local assembler builds one, and what gets recorded when context is unavailable.
- How to inspect, replay, and seal a case file.
Case file
A task-specific context package assembled before an agent acts. It is the bounded work packet that makes the starting point of a task explicit and reviewable.
A case file is not a memory store, and it is not a transcript. It is a sealed, durable snapshot of what the runtime believed at the moment the task began.
Every case file gives the next runtime step a single typed object to read from. That payload covers:
- The task objective.
- The policy envelope id that will gate execution.
- The intent lock id that defines scope.
- Current repository state (branch, head, clean/dirty, default branch).
- The mutable docs the agent may edit.
- The immutable docs it may only cite.
- Evidence references for everything the runtime loaded.
- Assumptions that remain unresolved.
- Stale-risk markers calling out context that may have moved.
- A list of missing context the runtime would have liked to have.
- Deterministic context-budget metadata so the runner doesn't blow past its token budget.
Anatomy of a case file
The on-disk schema is craik.case_file. Conceptually:
Build a case file
craik case build task_docs_reconcile
craik case show task_docs_reconcile
craik case show dumps the full JSON. Pipe it through jq or your editor of
choice — it's designed to be read and reviewed by humans, not just consumed
by runners.
The local assembler can read:
- Repo state — Git branch, head, clean/dirty, default branch, remote identity, and immutable path configuration from the project profile.
- Docs and ADRs — mutable doc roots and immutable evidence roots.
- GitHub state — issues and PRs in read-only mode when a GitHub remote
is configured (skipped under
--no-github). - Memory facts — only when a memory backend is configured. Otherwise the case file records "no memory backend" as an open assumption.
- Recent handoffs — the last few handoffs for this project, so the run can pick up where prior runs left off.
- Local contradiction reports — surfaces unresolved contradictions alongside the evidence that proposed them.
Evidence and assumptions
Every case file is honest about where its context came from — and where it didn't come from.
Evidence
Local evidence references use craik.evidence_reference records embedded
in the case file. Immutable documentation is marked explicitly so the
runner can't promote it to a mutable doc by mistake:
{
"kind": "doc",
"path": "docs/adr/0004-policy-envelope-shape.md",
"metadata": {
"immutable": true,
"indexed_at": "2026-05-19T12:14:08Z"
}
}
Assumptions
Unsupported conclusions stay assumptions. The assembler records open assumptions when configured context is unavailable — for example, when no memory backend is provided, the case file gets an assumption like:
{
"id": "no-memory-backend",
"claim": "No project-scoped memory facts were loaded.",
"reason": "Project has no memory backend configured.",
"remediation": "Connect Stigmem or set CRAIK_MEMORY_BACKEND.",
"promoted_to_fact": false
}
Agents should review assumptions before acting and must not promote them to facts without evidence. The next handoff is the natural place to document what was promoted and why.
Storage and replay
Case files persist as craik.case_file records in the local SQLite store
($CRAIK_HOME/state/). Once built, a case file is sealed — Craik never
silently rewrites it. To refresh the context for a re-run, build a new
case file. The old one stays addressable for audit.
Current scope
The local assembler today supports repository files, read-only GitHub issues and pull requests, memory facts (when a backend is wired in), recent local handoffs, and local contradiction reports. Anything optional that's missing is recorded as an open assumption so prompts and reviewers can tell known project state from unavailable context.