Drag to orbit · click, then scroll to zoom

Kognita 1.0 · alpha

Prove an AI answer was permitted, and evidence it.

Content guardrails filter what a model says. Kognita decides whether the request was allowed at all, before any data is retrieved, and writes the record that proves it.

Two independent regimes refused. Neither masked the other. Nothing was retrieved.

Example

A denial returns no data, and names its rule

from kognita import Envelope, decide, load_snapshot

evaluation = decide(
    Envelope(principal="rm@bank.example", purpose="ELIGIBILITY_CHECK",
             tool="check_eligibility", actor_location="AE",
             subject_type="client", subject_id="1",
             subjects={"instrument": "1"}),
    load_snapshot(session),
    attributes=pack.resolve_attributes(...),
    rules=pack.rules(),
)

evaluation.outcome        # DENY
for check in evaluation.basis():
    print(check.regime, check.citation)
# HK_SFC        SFC Code of Conduct para 5.5
# DIFC_DFSA     DFSA COB 3; GEN 2

How a request moves

Authorise before discovery

An envelope describes an intent. It is evaluated before anything is fetched, so a refused request never touches the data it asked for.

Envelope who · why · what Agent + purpose registry · kill switch Policies evaluated engaged, cited, as_of Fail closed most severe result wins Record + release evidence chain Every step writes to the hash-chained evidence log. Data is released only on ALLOW or a granted approval.

Outcomes

Fail closed, by precedence

A single failing check among any number of passes still denies. Adding permissive rules cannot widen a policy set.

DENYA check failed. No tool body runs and no data is returned.
ESCALATEA policy could not be evaluated, or needs a higher reviewer. Escalated, never silently passed.
HUMAN_APPROVALWork may be prepared, but data is held until a person grants a bound approval.
ALLOWNothing objected. Data is released and the release is evidenced.

Guarantees

What the library promises

Every decision cites its rule

A check without a citation is an assertion, not a decision. The conformance kit enforces it.

Decisions are pure and replayable

decide() writes nothing and takes the instant as a parameter. "What would this have decided in March?" has an answer.

decide(envelope, snapshot,
       as_of=datetime(2026, 3, 1, tzinfo=timezone.utc))

Evidence is tamper-evident

Each event carries the previous event's hash. Altering any payload breaks every hash after it.

$ kognita evidence verify --db store.db
BROKEN: evidence chain broken at sequence 2

$ kognita evidence export --db store.db -o audit.json

Approvals bind to what was reviewed

An approval is issued against an envelope hash covering the arguments, roles and checks. Changing any of them yields no matching approval.

Privacy

Evidence holds references, not content

An append-only log full of personal data collides with erasure rights, so payloads default to hashes and references. hashes_only strips content entirely while keeping the log provable.

Egress is guarded, not merely refused

A local-or-refuse rule confines a governed system to models running on the box. The guard adds redaction for everything else.

result = guard.send(text, call_the_model,
                    classification=Classification.C2,
                    destination="api.openai.com", destination_is_local=False)

result.decision          # REDACT
# the provider saw:  [TERM_1] ([EMAIL_1]) holds account [ACCOUNT_1]
# the caller got the real values back; the log records a hash, never content

PatternRedactor is a floor, not a guarantee. Regexes miss names in prose. Deployments handling real personal data should supply an NER-based redactor. The tests prove nothing unredacted escapes the guard, not detection recall.

Integration

Domain packs supply the domain

The core is domain-blind. A pack says what a request's attributes are and how to load the subjects it refers to. Policies are effective-dated rows; the evaluator for each rule_type is registered by the pack. A policy with no evaluator escalates rather than being skipped.

class MyPack:
    name = "my-domain"
    def load_subjects(self, envelope, session): ...
    def resolve_attributes(self, envelope, subjects): ...
    def rules(self): return build_registry(MY_EVALUATORS)
PrimitiveMeaning
ATTRIBUTE_ALLOWLISTEvery named attribute must be in its allowlist
ATTRIBUTE_DENYLISTNo named attribute may match its denylist
REQUIRES_FLAGNamed attributes must all be truthy
REQUIRES_HUMAN_APPROVALMandate human review for matching tools or purposes
PROHIBITEDAn unconditional bar once the policy is engaged

Conformance kit

Subclass ConformanceCase in your pack's test suite. The invariants (fail-closed, cited, evidenced) run against your rules, not just the bundled fixture.

from kognita.testing import ConformanceCase, Harness

class TestMyPack(ConformanceCase):
    @pytest.fixture(autouse=True)
    def _bind(self):
        self.harness = Harness(pack=MyPack(), purposes=PURPOSES, seed=seed)

Layout

Small core, optional reach

PackageWhat it isInstall
kognitaThe decision engine: decisions, evidence, retrieval, egress, tools. No network.pip install kognita
kognita.graphGraphiti + Kuzu knowledge graph, with a deterministic system-of-record mirrorkognita[graph]
kognita.adaptersProvider-backed embedders and clientskognita[openai] and others
kognita.testingThe conformance kitincluded

The core runs on pydantic, sqlmodel, numpy and python-dotenv. Import-linter contracts and a test that installs with no extras keep it that way.

Status

Where it stands

Kognita is alpha. Core packaging, governance, the evidence chain, retrieval, the egress guard, the tool runner, the broker, the conformance kit and adapters are in place.

Done decisions, evidence, egress, tools
Done single-signature approvals
In progress two-signature approvals (ADR 0006)
In progress propose-then-apply (ADR 0007)
Pending v0.2.0 release and benchmarks

Design records live in docs/decisions/, including the gap analysis that drives the roadmap.