Skip to main content

Decision Records for production AI.

Project description

Lumyn

Decision Records for production AI.

Lumyn is a deterministic decide() gateway for AI agents. It enforces strict policies, returns explicit verdicts (ALLOW, DENY, ESCALATE, ABSTAIN), and writes durable Decision Records for instant incident replay.

With Lumyn Memory, it learns from verified outcomes to block repeated failures ("Pre-Cognition") and fast-track proven successes ("Self-Healing").

[!NOTE] v1.0.0 Stable: This documentation covers the v1 engine. For legacy v0 documentation, see Legacy Specs.

When an AI incident happens

Support shares a screenshot. Engineering tries to reconstruct what the model saw and what policy/risk rules fired. Nobody can answer, precisely and repeatably: what happened, what changed, and why did we allow it?

Lumyn's unit of evidence is a decision_id. Paste it into the ticket, then:

  • lumyn show <decision_id>
  • lumyn explain <decision_id> --markdown
  • lumyn export <decision_id> --pack --out decision_pack.zip
  • lumyn replay decision_pack.zip --markdown

Why teams adopt Lumyn

  • Write-path safety: gates consequential actions with explicit policy and outcomes.
  • Replayable decisions: stable digests (policy.policy_hash, request.context.digest, determinism.inputs_digest, and determinism.memory.snapshot_digest when Memory is enabled).
  • Record-chain ready: optionally pass through upstream Context Record linkage (context_ref.context_id + context_ref.record_hash).
  • No bluffing: uncertainty becomes ABSTAIN or ESCALATE with stable, validated reason codes.
  • Compounding reliability: labeled failures/successes feed Experience Memory similarity.
  • Drop-in: works as a Python library and as an optional HTTP service.

Operations & Safety

📺 The War Room (lumyn monitor)

"Less drama. Fewer incidents." A live, scrolling Matrix-style TUI showing decisions as they happen.

lumyn monitor --limit 50

🛡️ Regression Testing (lumyn diff)

"Did my change block valid users?" Run a candidate policy against a history of past records to catch regressions before deployment.

lumyn diff past_traffic.json --policy new_policy.v1.yml

The primitive

You wrap a risky action with decide():

  1. you provide a DecisionRequest (subject, action, evidence, schema_version: decision_request.v1)
  2. Lumyn evaluates deterministic policy.v1 (strict stages + conditions)
  3. Lumyn returns a DecisionRecord and persists it (append-only)

The Decision Record is the unit you export into incidents, tickets, and postmortems.

How it works (one screen)

  • You provide a DecisionRequest (no external fetches in v1; your app supplies evidence).
  • Lumyn evaluations occur in 5 strict stages: REQUIREMENTS -> HARD_BLOCKS -> ESCALATIONS -> ALLOW_PATHS -> DEFAULT.
  • Lumyn computes Experience Memory similarity from prior labeled outcomes.
  • When Memory is consulted, Lumyn includes a replayable memory snapshot digest in record.determinism.memory.snapshot_digest.
  • When an upstream Context Record exists (e.g. Fabra), include request.context_ref and Lumyn will persist it as record.context_ref for ticketing and chain linkage.
  • Lumyn persists the Decision Record to SQLite before returning (or returns ABSTAIN on storage failure).

What a Decision Record looks like

{
  "schema_version": "decision_record.v1",
  "decision_id": "01JZ1S7Y1NQ2A0D5JQK2Q2P3X4",
  "created_at": "2025-12-15T10:00:00Z",
  "context_ref": {
    "context_id": "ctx_01JZ1S7Y1NQ2A0D5JQK2Q2P3X4",
    "record_hash": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
  },
  "request": {
    "schema_version": "decision_request.v1",
    "subject": { "type": "service", "id": "support-agent", "tenant_id": "acme" },
    "action": {
      "type": "support.refund",
      "intent": "Refund duplicate charge for order 82731",
      "amount": { "value": 201.0, "currency": "USD" }
    },
    "evidence": { "ticket_id": "ZD-1001", "order_id": "82731", "payment_instrument_risk": "low" },
    "context": { "mode": "digest_only", "digest": "sha256:aaaaaaaa..." },
    "context_ref": {
      "context_id": "ctx_01JZ1S7Y1NQ2A0D5JQK2Q2P3X4",
      "record_hash": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
    }
  },
  "policy": {
    "policy_id": "lumyn-support",
    "policy_version": "1.0.0",
    "policy_hash": "sha256:bbbbbb...",
    "mode": "enforce"
  },
  "verdict": "ESCALATE",
  "reason_codes": ["REFUND_OVER_ESCALATION_LIMIT"],
  "matched_rules": [
    { "rule_id": "R008", "stage": "ESCALATIONS", "effect": "ESCALATE", "reason_codes": ["REFUND_OVER_ESCALATION_LIMIT"] }
  ],
  "risk_signals": {
    "uncertainty_score": 0.12,
    "failure_similarity": { "score": 0.07, "top_k": [] }
  },
  "determinism": {
    "engine_version": "1.0.0",
    "inputs_digest": "sha256:cccc...",
    "memory": {
      "schema_version": "memory_snapshot.v1",
      "snapshot_digest": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
      "hits": [{ "decision_id": "01JZ1S7Y1NQ2A0D5JQK2Q2P3X4", "outcome": -1, "score": 0.95 }]
    }
  }
}

Quickstart (no keys, no Docker)

Install:

  • pip install lumyn
  • Service mode: pip install lumyn[service]

Fastest "aha" (compounding in seconds):

  • lumyn doctor --fix
  • lumyn demo --story

Common CLI workflows:

  • lumyn init (creates local SQLite + starter policy)
  • lumyn monitor (watch decisions live)

Key capabilities:

  • Policy-as-Code (YAML)
  • Institutional Memory (Learn from outcomes)
  • GitOps-native workflow
  • Local & Fast (SQLite + deterministic engine)

Quickstart

1. Initialize

uv tool install lumyn
lumyn init

2. Make a Decision

lumyn decide request.json

3. Teach (Optional)

# If a decision turns out to be bad (e.g. fraud), teach Lumyn:
lumyn learn <decision_id> --outcome FAILURE
  • lumyn show <decision_id>, lumyn explain <decision_id>
  • lumyn export <decision_id> --pack --out decision_pack.zip
  • lumyn replay decision_pack.zip (validate pack + digests, including the memory snapshot digest when present)
  • lumyn policy validate (strict v1 validation, including reason code validation against schemas/reason_codes.v1.json)
  • lumyn migrate old_policy.v0.yml (upgrade to v1)

SDK (drop-in)

Lumyn does not call your model. You call Lumyn before (or around) a real write-path action.

from lumyn import LumynConfig, decide_v1

cfg = LumynConfig(
    policy_path="policies/starter.v1.yml",  # built-in starter policy (v1)
    store_path=".lumyn/lumyn.db",
)

record = decide_v1(
    {
        "schema_version": "decision_request.v1",
        "request_id": "req_123", # recommended for retries
        "subject": {"type": "service", "id": "support-agent", "tenant_id": "acme"},
        "action": {
            "type": "support.refund",
            "intent": "Refund duplicate charge",
            "amount": {"value": 20.0, "currency": "USD"},
        },
        "evidence": {
            "ticket_id": "ZD-1001",
            "order_id": "82731",
            "customer_id": "C-9",
            "payment_instrument_risk": "low",
            "chargeback_risk": 0.05,
            "previous_refund_count_90d": 0,
            "customer_age_days": 180,
        },
        "context": {
            "mode": "digest_only",
            "digest": "sha256:0000000000000000000000000000000000000000000000000000000000000000"
        },
        "context_ref": {
            "context_id": "ctx_01JZ1S7Y1NQ2A0D5JQK2Q2P3X4",
            "record_hash": "sha256:1111111111111111111111111111111111111111111111111111111111111111"
        }
    },
    config=cfg,
)

if record["verdict"] == "ALLOW":
    pass  # perform the write-path action
elif record["verdict"] == "ESCALATE":
    pass  # route to human queue
else:
    pass  # block (ABSTAIN/DENY)

Service mode (FastAPI)

Run:

  • lumyn serve

Call:

curl -sS -X POST http://127.0.0.1:8000/v1/decide -H 'content-type: application/json' --data-binary @request.json

Endpoints:

  • POST /v1/decide -> DecisionRecord (v1)
  • GET /v1/decisions/{decision_id}
  • GET /v1/policy

Documentation

Design principles

  • Decision as an artifact: every gate yields a record.
  • Policy + outcomes, not prompts: rules tie to action classes and objective outcomes.
  • Telemetry ≠ truth: OpenTelemetry is for visibility; the Decision Record is the system of record.

Try in Browser · Quickstart · Docs

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lumyn-1.3.5.tar.gz (439.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lumyn-1.3.5-py3-none-any.whl (92.7 kB view details)

Uploaded Python 3

File details

Details for the file lumyn-1.3.5.tar.gz.

File metadata

  • Download URL: lumyn-1.3.5.tar.gz
  • Upload date:
  • Size: 439.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for lumyn-1.3.5.tar.gz
Algorithm Hash digest
SHA256 b249388b1a671419966249cbe487669a4f9f4a53a2b1185badba1120d1312bd3
MD5 e335bb171a44f0bcf0d0f896da245fdb
BLAKE2b-256 838c49283e7edb6643e667660425305fcdcddebefe21d56e864c04ce74ef3df9

See more details on using hashes here.

Provenance

The following attestation bundles were made for lumyn-1.3.5.tar.gz:

Publisher: release.yml on davidahmann/lumyn

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file lumyn-1.3.5-py3-none-any.whl.

File metadata

  • Download URL: lumyn-1.3.5-py3-none-any.whl
  • Upload date:
  • Size: 92.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for lumyn-1.3.5-py3-none-any.whl
Algorithm Hash digest
SHA256 e2ef914c1cb1a1994b9123ad79938eecc7e3fdde49c9b23eb2bb752aa498c21c
MD5 018c8f0dc6e0c3872a171814b0f1ba2f
BLAKE2b-256 e91a257c28f1e1c53edd6ed4bd841da3d36aa59a5f356e82609a529a23e67f63

See more details on using hashes here.

Provenance

The following attestation bundles were made for lumyn-1.3.5-py3-none-any.whl:

Publisher: release.yml on davidahmann/lumyn

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page