Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

waypoint

A durable, checkpointed workflow engine for chaining Claude-powered steps, with human-in-the-loop approval gates and a full audit trail.

Why

Agentic automation that runs unattended needs three things a plain prompt loop doesn't give you:

  1. Durability — if the process dies mid-workflow, you should be able to resume from the last completed step, not from scratch.
  2. Human checkpoints — some steps (publishing, sending, spending money) shouldn't happen without a person saying yes, and that "yes" might come hours later, from a different process entirely.
  3. An audit trail — a record of what ran, when, what it produced, and who approved what — independent of whatever logs the LLM calls themselves produce.

waypoint is a small engine built around exactly those three properties, not a general-purpose orchestrator.

How it works

A workflow is a YAML list of steps. Two step types:

name: research-brief

steps:
  - type: llm
    name: draft
    system: You are a concise technical writer.
    prompt: Write a 3-sentence brief on X.

  - type: approval
    name: review
    message: Review the draft before it gets polished.

  - type: llm
    name: polish
    prompt: |
      Polish this for publication:
      {{steps.draft.output}}
waypoint run examples/research_brief.yaml
# Started run 3f9a2b1c...
# ┌────────┬────────────────────┬─────────────────┐
# │ Step   │ Status             │ Output / Error   │
# ├────────┼────────────────────┼─────────────────┤
# │ draft  │ completed          │ A durable...     │
# │ review │ awaiting_approval  │                  │
# └────────┴────────────────────┴─────────────────┘
# Run status: awaiting_approval

waypoint approve 3f9a2b1c... examples/research_brief.yaml
# ... polish step runs, run status: completed

{{steps.<name>.output}} in a prompt is substituted with that step's completed output, so later steps can build on earlier ones.

Architecture

models.py    — WorkflowSpec, StepSpec (LLMStepSpec | ApprovalStepSpec, discriminated union),
               RunState, StepResult, AuditEvent (all pydantic)
store.py     — StateStore protocol; SQLiteStateStore (default) + InMemoryStateStore (tests)
claude_client.py — ClaudeClient protocol; AnthropicStepRunner (real API, adaptive thinking, streaming)
engine.py    — WorkflowEngine: start / resume / approve, the checkpoint + approval-gate logic
cli.py       — Typer CLI over the engine

Checkpointing: after every completed step, WorkflowEngine writes the full run state to the StateStore before moving to the next step. resume() reloads that state and skips any step already marked completed — so a crash between steps loses nothing, and a crash during a step just re-runs that one step.

Approval gates: an approval step doesn't call Claude at all — it marks itself awaiting_approval, persists that, and the engine returns. Nothing continues until a separate call to approve() (a different process, a different day) either completes the gate and resumes the workflow, or rejects it and fails the run. The audit log records the request and the decision independently of the run state.

Audit trail: every state transition (run_started, step_started, step_completed, step_failed, approval_requested, approval_granted, approval_denied, run_completed) is appended to a separate, append-only log keyed by run ID — queryable via waypoint audit <run_id> regardless of the run's current status.

ClaudeClient and StateStore are both protocols with a real implementation and a fake/in-memory one — the engine's tests run entirely against fakes (fast, deterministic, no API key needed), while AnthropicStepRunner is exercised in a real end-to-end run before every push.

Usage

Requires an ANTHROPIC_API_KEY in the environment.

pip install -e .
waypoint run examples/research_brief.yaml
waypoint status <run_id>
waypoint approve <run_id> examples/research_brief.yaml
waypoint resume <run_id> examples/research_brief.yaml   # after a crash/restart
waypoint audit <run_id>

Development

pip install -e ".[dev]"
ruff check .
mypy src
pytest --cov=waypoint

Known limitations

  • Steps run strictly sequentially — no parallel branches or conditionals. This is intentional scope: the point of this project is durable sequencing and approval gates, not a general DAG scheduler.
  • The engine and CLI have been run end-to-end against the real Anthropic API and correctly handle both the request path and API-level failures (verified: a 400 from a real request was caught, the step and run were marked failed, and the state persisted correctly). A full happy-path run (successful completion through an approval gate) has not yet been exercised against a live account and is the natural next verification step.
  • Template substitution is a single pattern, {{steps.<name>.output}}; there's no expression language.
  • A workflow's structure (the YAML) is not itself versioned in the run state — if you edit the YAML between start() and resume(), the engine reconciles by step name, not by position, so renaming a step effectively creates a new one.

License

MIT

About

Durable, checkpointed workflow engine for chaining Claude-powered steps with human-in-the-loop approval gates

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages