Trust infrastructure for AI-operated systems. Written in Go.
Most AI backends start at the prompt. They work in demos and collapse in production, because nothing controls what the agent actually does to your state.
KIFF starts earlier. It puts events, state, decisions, approvals, and audit between the agent and your system. Agents propose. KIFF validates. Humans approve when it matters. Everything is replayable.
Make AI useful in real operations without losing control.
For the long version of why this layer matters, read docs/why.md.
Without KIFF, an AI feature in production usually looks like this:
agent → tool call → mutates your database → you hope
With KIFF:
agent → proposal → KIFF validates state, permissions, parameters
→ high-risk? requires human approval
→ executor runs only if everything checks out
→ every step audited and replayable
You keep your domain. KIFF carries the governance.
- A coordination protocol that works. The loop
event → state → decision → action → approval → auditis the framework. Six packages. Fits in your head. - Governance that cannot be bypassed. Approval state is private to the runtime. Callers cannot self-approve. Executors are explicit. Every fact is audited with a trace ID.
- An optional HTTP API. Built on
net/http. No web framework lock-in. Includes a read-only/adminpage over the runtime. - File-backed stores. Persistence for demos and local development with one flag. Production swaps in real backends behind the same interfaces.
- Default-on observability. Wrap the audit store with
observability.WrapAuditStoreand every fact becomes a structured log line and a counter. No dependencies. - Test helpers in the box.
kifftestgives you event builders, a fixed clock, and policy seeds so domain tests stay short. - A runnable demo that proves both paths. Granted approval completes the loop. Denied approval blocks execution. You can see KIFF stop an action as clearly as it executes one.
git clone https://github.com/kiffhq/kiff
cd kiff-framework
go run ./cmd/kiff-tourYou will see a narrated walk-through of the KIFF loop on a tiny refund domain:
- An order is placed and paid. Smooth flow.
- An agent confidently tries to issue a $999 refund. KIFF blocks it.
- A human grants approval. The same action now executes.
- Replay rebuilds the entity's state from events alone, and the audit timeline reconstructs every fact.
Three minutes. The whole framework story.
If you would rather see the original mission domain or the HTTP version:
go run ./cmd/kiff-demo # mission demo, log-style output
go run ./cmd/kiff-http-demo -data-dir ./data # HTTP API with persistenceThen try the curl examples in docs/changelog/brick-14.md.
go install github.com/kiffhq/kiff/cmd/kiff@latest
kiff new github.com/acme/orders
cd orders
go mod tidy
go run ./cmd/serverkiff new scaffolds a runnable HTTP server and a tiny tasks starter domain. Rename the entity, events, states, and actions to match yours and you are running. See docs/conventions.md for the normal way to lay things out.
While the framework is unpublished, scaffold against a local checkout:
kiff new -replace-local /path/to/kiff-framework github.com/acme/ordersWhen you want to evaluate KIFF as governance for an AI agent, scaffold the agentic-ops template instead. It includes a Go domain, an HTTP server, an Agno agent (offline + Bedrock providers), and a make demo target that runs the full governed-agent loop end to end:
kiff new -template=agentic-ops github.com/acme/ops
cd ops && go mod tidy && make demomake demo spawns the server, runs the agent against deterministic tickets, prints the audit timeline (block, approve, execute, replay), and shuts down. Under five minutes from a clean directory.
The same shape is also available as a worked example in examples/refund-agno (depth: one tool, two runs), examples/support-ops (breadth: one agent, five distinct outcomes), and examples/ai-cafe-ops (operational authority: one AI shift manager, four tools, five distinct outcomes).
You are building a backend where:
- multiple actors — humans, services, integrations, AI agents — touch the same state;
- entities have a lifecycle, and what is allowed depends on where they are in it;
- some actions are risky enough that a human should sign off;
- somebody, eventually, will ask "why did this happen?" and need a real answer;
- you would rather declare governance once than relitigate it in every PR.
Common fits: financial-provider coordination, marketplace operations, post-purchase workflows, compliance workflows, internal operational tools, mission or challenge systems.
KIFF is not a chatbot framework. Not a generic web framework. Not an LLM wrapper. Not a workflow engine. Not a universal business ontology.
If your application is simple CRUD, a router with handlers, or direct LLM tool calls with no governed state, KIFF is too much structure. Use something smaller and ship.
For an honest comparison to LangChain, Temporal, raw FSMs, and rolling your own, see docs/comparisons.md.
Your domain owns vocabulary. KIFF owns coordination. A complete domain definition is small — here's the gist of examples/refund:
def, _ := domain.New("refund").
Entity("Order").
Event("ORDER_PLACED").
Event("ORDER_PAID").
Event("ORDER_REFUNDED").
Transition("ORDER_PLACED", "", "CREATED").
Transition("ORDER_PAID", "CREATED", "PAID").
Transition("ORDER_REFUNDED", "PAID", "REFUNDED").
Allow("CREATED", "MARK_PAID").
Allow("PAID", "REFUND_ORDER").
Action(MarkPaidContract()). // low-risk, no approval
Action(RefundOrderContract()). // high-risk, approval required
Build()
rt, _ := runtime.NewForDomain(def, runtime.Config{
PermissionPolicy: refund.NewPermissionPolicy(),
})That is the entire shape. The action contracts declare allowed states, required parameters, required permissions, risk, approval requirement, and the executor function. The runtime handles the rest.
Walk through a complete domain in docs/build-a-domain.md. The shortest worked example is examples/refund/ (one entity, three states, two actions). For a more involved domain see examples/mission/.
Start here:
- Why KIFF — the argument: why agents need a governance layer, not better prompts
- Philosophy — what KIFF is choosing to be, and what it is choosing not to be
- Comparisons — honest positioning next to LangChain, Temporal, FSMs, and rolling your own
Build with it:
- Conventions — the normal way to lay out a KIFF project
- Build a domain — the authoring guide, end to end
- Principles in practice — five short pages, one principle each, with code
Reference:
- Architecture — package boundaries and responsibilities
- Vision — the long-form rationale
- Changelog — how the framework evolved, brick by brick
pkg/kiff/ is intentionally small. Each package has one job.
| Package | Job |
|---|---|
event |
Normalized event records and stores |
state |
Domain-owned state machines, transitions, replay |
decision |
Explainable decision records |
proposal |
Action proposals from agents, humans, or services |
action |
Action contracts, validation, execution |
permission |
Actor permission policies |
approval |
Approval records for high-risk actions |
audit |
Append-only audit trail with trace correlation |
actor |
Human, agent, service, system actor identity |
evidence |
References supporting decisions or actions |
domain |
Domain definitions bundling state and actions |
adapter |
Raw input normalization into events |
httpapi |
Optional net/http surface around the runtime, including a read-only /admin view |
runtime |
The coordinator wiring everything together |
store |
Common store helpers and file-backed implementations |
store/postgres |
Production-grade Postgres backend (also covers Supabase, Neon, RDS) |
store/storetest |
Shared conformance test suite every store implementation must pass |
observability |
Default-on structured logging and counters via an audit-store wrapper |
kifftest |
Test helpers: event builders, fixed clock, predefined actors, policy seeds |
For an example of bridging an LLM tool-call surface into governed KIFF actions, see examples/llm-bridge/.
KIFF is at v0.1. The core coordination loop is complete and tested. The trust boundary is enforced at the framework level: approvals cannot be self-granted, executors must be explicit, every validation and execution is audited.
Production deployments should implement the store interfaces against a real backend. The file-backed JSONL stores are for demos and local development.
MIT. Use it. Fork it. Ship with it.