Pack Authoring¶
Pack authoring is how you turn your workflow into CaseGraph code.
For the first workflow, use the package-first bootstrap:
Use the lower-level transactional scaffold when you need direct control:
uv run --all-groups --python 3.13 casegraph packs scaffold --kind transactional \
--pack-id my_transactional \
--output .casegraph/my_transactional_pack \
--json
What The Generated Files Mean¶
| File | What you edit |
|---|---|
engine.v1.yaml |
Engine id, version, prompts, and declared action ids. |
architectures/*.yaml |
Which workers belong to the pack. |
prompts/workers/.../task.j2 |
Prompt text for future model-assisted worker paths. |
prompts/workers/.../tests.yaml |
Expected prompt fragments for author-check. |
models.py |
Typed metadata and action input models. |
workers.py |
Decorated worker functions that return WorkerOutput. |
actions.py |
Preview, apply, verify, and compensate callbacks for your action. |
capabilities.py |
build_transactional_capabilities(...) wiring. |
registry.py |
Worker registry. Edit when adding workers. |
__init__.py |
Public pack factory and demo helpers. |
developer_api_demo.py |
Runnable example for your pack. |
Worker Shape¶
Generated workers use ordinary typed Python functions marked with @worker(...) and named worker
steps:
from casegraph import WorkerContext, WorkerOutput, worker
@worker(id="intake_reviewer", resolves="intake")
def review_record(context: WorkerContext) -> WorkerOutput:
metadata = _demo_metadata(context)
with context.step("review_record", input_summary=metadata) as step:
review = _review_record(metadata)
step.output_summary(review)
step.source(...)
step.tool_call(...)
step.observation(...)
step.claim(...)
return WorkerOutput()
CaseGraph turns recorded steps and WorkerOutput into worker-run provenance. Use one step for each
operation a future reader should understand, such as retrieval, comparison, classification, or claim
synthesis.
worker_function(...) remains available when you need to construct worker adapters manually, but
new generated packs use the decorator because it keeps registry code small.
Transactional Action Shape¶
Generated transactional packs use helper-backed capabilities:
from casegraph import TransactionalActionDefinition, build_transactional_capabilities
from casegraph import local_commit_receipt, local_preview_diff
You own the action input and callbacks in actions.py. CaseGraph handles the repetitive proposal,
preview, policy, commit, verification, and replay records for one local/fake action.
Edit And Check Loop¶
For the first edit, change one statement in workers.py and one preview or receipt summary in
actions.py. Keep capabilities.py for proposal wording, policy rule id, and action wiring.
After editing generated files:
uv run --all-groups --python 3.13 casegraph packs validate \
--pack-root .casegraph/my_transactional_pack \
--json
uv run --all-groups --python 3.13 casegraph packs author-check \
--pack-root .casegraph/my_transactional_pack \
--json
Then run the demo. CaseGraph uses Postgres to persist append-only case events and replayable graph projections, so run the CaseGraph database command before persisted execution:
docker compose up -d postgres
uv run --all-groups --python 3.13 casegraph db upgrade --json
uv run --all-groups --python 3.13 python .casegraph/my_transactional_pack/developer_api_demo.py
Expected output:
worker=intake_reviewer
proposal_action=mark_intake_ready
policy_status=auto
commit_status=committed
replay_status=in_sync
inspect_command=casegraph cases inspect <case-id> --json
Inspect the persisted case after the demo:
Use that report to confirm the edited worker evidence, proposed action, policy, commit receipt, and replay status before opening lower-level graph or event views.
If author-check fails after a worker edit, start with the file named in the issue. The most common
fix is to keep the generated source, tool call, observation, and claim together, and to keep
step.observation(subject=context.selected_item.topic, ...) unless you changed the gap topic too.
Larger Examples¶
examples/minimal_transactional_packis the checked-in version of the generated transactional shape.examples/minimal_readonly_packshows a worker-only pack.examples/pydantic_ai_adapter_packshows how to cover a Pydantic-AI agent run from a worker without making Pydantic-AI a required dependency.examples/support_escalationis a larger reference/demo pack.
Optional framework packs should declare their own extra install path, such as
uv add "casegraph[pydantic-ai]", instead of making every CaseGraph project install every
framework adapter.