decisionkit
Deterministic, explainable risk scoring and intervention policy for agent
and operational systems. Small, pure-Go, no LLM required.
decisionkit is a tiny Go module that helps a system answer two questions:
- How likely is this commitment to be missed? — weighted risk score
with a per-factor breakdown an operator can read.
- Should we do something about it? — threshold-based intervention
policy (nudge / escalate / automate) with confidence-aware routing.
Both engines are pure functions over plain Go structs. No I/O, no clocks
read from the wall (you pass now), no database, no LLM. Sub-millisecond
to score; trivial to test; obvious in an audit log.
decisionkit was extracted from the Nous
project so the deterministic value could keep being reused after Nous itself
was archived. See ADR 0004 in Mnemos
for the rationale.
Install
go get github.com/felixgeelhaar/decisionkit@latest
Requires Go 1.26+.
Usage
package main
import (
"fmt"
"time"
"github.com/felixgeelhaar/decisionkit/domain"
"github.com/felixgeelhaar/decisionkit/intervention"
"github.com/felixgeelhaar/decisionkit/risk"
)
func main() {
now := time.Now()
due := now.Add(-15 * time.Minute) // overdue
c, _ := domain.NewCommitment(
"alice",
"ship Q2 report",
&due,
0.95, // high-confidence: we're sure this is a real commitment
now,
)
scorer := risk.New(risk.DefaultConfig())
assessment := scorer.EvaluateCommitment(c, nil, nil, now)
fmt.Printf("risk = %.2f\n", assessment.Score)
for _, f := range assessment.Factors {
fmt.Printf(" %s: %.2f — %s\n", f.Type, f.Weight, f.Reason)
}
policy := intervention.New(intervention.DefaultConfig())
iv, _ := policy.MaybeIntervene(c, assessment, now)
if iv != nil {
fmt.Printf("→ %s: %s\n", iv.Type, iv.Message)
}
}
Output (approximately):
risk = 0.79
overdue: 0.60 — Commitment is past its due time.
confidence: 0.19 — Commitment is high-confidence; tracked strictly.
→ nudge: "ship Q2 report" is at risk of being missed (risk=0.79, confidence=0.95). Commitment is past its due time.
Package layout
| Package |
Purpose |
domain |
Pure types: Commitment, Intervention, MemoryRef, ChronosSignal, EntityRef, SourceRef. Validation + transitions. |
risk |
Weighted, deterministic risk scorer. Config-driven; explainable via factor breakdown. |
intervention |
Threshold-based policy mapping risk scores to intervention types. Confidence-aware. |
mnemos |
Dependency-free helper for wiring Mnemos events into the engines without a hard Mnemos dependency. |
Design notes
- Pure functions, no I/O. Easy to test, easy to embed, easy to reason
about. The caller owns storage, scheduling, transport.
- Pass
now in. No wall-clock reads inside engines; tests can pin
timestamps deterministically.
- Explainability is a first-class output. Every score carries the
factors that produced it. Operators get an audit trail without
recomputing.
- No LLM dependency. Decisions like "is this overdue?" are not LLM
problems. decisionkit is the cheap, fast, deterministic path; LLMs
can layer on top if you want qualitative analysis.
- Pre-1.0 versioning. API may evolve based on consumer feedback. We
cut
v1.0.0 after at least two adopters have shipped against the
current shape.
- Mnemos — memory layer that pairs
naturally with decisionkit for fact-driven scoring.
- Chronos — time-series signal
engine; its signals can be fed into the risk scorer.
License
MIT. See LICENSE.