Skip to main content

Kognita

PyPI version Python Versions License: MIT CI Downloads

Prove an AI answer was permitted — and evidence it.

You want to… Reach for
Connect fragmented files and databases quickly LlamaIndex
Build complex, customised LLM workflows LangChain
Create a team of specialised agents CrewAI
Map complex relationships across data GraphRAG
Prove an answer was permitted, and evidence it Kognita

Content guardrails filter what a model says. Kognita decides whether the request was allowed — before any data is retrieved — and writes the record.

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

Two independent regimes refused; neither masked the other; each names the rule it came from. Nothing was retrieved.

Install

pip install kognita                 # the decision engine — 4 dependencies
pip install kognita[graph]          # + Graphiti/Kuzu knowledge graph
pip install kognita[openai]         # + a real embedder
pip install kognita[all]

The core installs on pydantic, sqlmodel, numpy and python-dotenv, and runs with no network and no API key. Deciding whether a request is permitted should not require the machinery that answers it — and that constraint is enforced by import-linter contracts plus a test that installs with no extras and asserts decide() still runs.

What it does

Authorise before discovery. An envelope describes an intent and is evaluated before anything is fetched. A denial returns no data, not filtered data.

Fail closed. DENY > ESCALATE > HUMAN_APPROVAL > ALLOW. One failing check among a hundred passes still denies, so a policy set cannot be widened by adding permissive rules.

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, so "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: payload does not match its hash

$ kognita evidence export --db store.db -o audit.json   # portable, self-verifying

Payloads hold hashes and references by default — an append-only log full of personal data collides with erasure rights — and hashes_only strips content entirely while keeping the log provable.

Egress is guarded, not merely refused. A binary local-or-refuse rule confines a governed system to whatever model runs on the box. The guard adds redaction:

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, and MODEL_CALL + EGRESS
# record the manifest hash — never the content.

PatternRedactor is a floor, not a guarantee. Regexes miss names in prose and anything the patterns do not anticipate. Deployments handling real personal data should supply an NER-based Redactor; the tests cover the plumbing — that nothing unredacted escapes the guard — never detection recall.

Domain packs

The core is domain-blind. A pack supplies the two things it cannot know: what a request's attributes are, and how to load the subjects it refers to.

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)

Policies are data — effective-dated rows with a JSON payload interpreted by the evaluator registered for their rule_type. The core ships five primitives (allowlist, denylist, required flag, required human review, prohibited); a pack registers whatever its regimes need beyond them. A policy whose rule_type has no evaluator escalates rather than being skipped: it is a rule someone believes is in force.

Conformance

Kognita ships a conformance kit: a set of assertions that every domain pack must satisfy. The kit proves that whatever a pack's regimes say, they are decided fail-closed, cited, and evidenced.

Run the kit over the bundled fixture pack (proves the kit itself works):

pytest --pyargs kognita.testing.conformance

Or subclass it in your own pack's test suite:

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)
        self.allow_envelope = Envelope(...)
        self.deny_envelope = Envelope(...)
        self.human_envelope = Envelope(...)  # optional

The pattern follows langchain-tests: invariants are importable and reusable by external packs running in their own repositories.

The knowledge graph

kognita[graph] adds the Graphiti + Kuzu engine: documents become a bi-temporal, auto-deduplicated knowledge graph.

from kognita.graph import GraphEngine, GraphConfig

async with GraphEngine(config) as kg:
    await kg.ingest_text(document, source="policy-handbook")
    hits = await kg.search("cross-border disclosure")

Two graphs share one Kuzu database: Graphiti's LLM-extracted knowledge, and a deterministic SoR_* mirror of a system of record, so one traversal crosses both planes. All access goes through a single KuzuSession — two kuzu.Database handles on one path do not share a consistent view and raise nothing when they diverge. See docs/decisions/0001-kuzu-cotenancy.md.

Layout

kognita            the decision engine — decisions, evidence, retrieval,
                   egress, tools. Four dependencies, no network.
kognita.graph      Graphiti + Kuzu knowledge engine          [graph]
kognita.adapters   provider-backed embedders and clients     [openai] …
kognita.testing    the conformance kit

kognita is the decision engine, not a namespace that points at one. No graph name is reachable from it: the graph is imported from kognita.graph, so reading an import tells you whether a graph database is about to be loaded. import kognita never loads one, and tests/test_packaging.py asserts it.

Moved in 0.2. kognita.Kognitakognita.graph.GraphEngine, kognita.KognitaConfigkognita.graph.GraphConfig, kognita.KognitaKuzuDriverkognita.graph.KuzuDriver, and kognita.core.*kognita.*. Touching a retired name raises an AttributeError naming the module that now owns it. Reasoning and the full migration table: docs/decisions/0003-the-top-level-namespace.md.

Status

Alpha. Phases 0–5 complete: core packaging, governance, evidence chain, retrieval, egress guard, tool runner, broker, conformance kit, and adapters.

Phase 6 in progress: deterministic graph mirror (SoR_* tables), governed document ingestion with evidence logging, and cross-plane Cypher (REFERENCES edges linking knowledge graph to system of record).

Phase 7 pending: final release, performance benchmarks, docs rewrite, v0.2.0.

MIT licensed.

Download files

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

Source Distribution

kognita-0.2.0.tar.gz (508.5 kB view details)

Uploaded Source

Built Distribution

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

kognita-0.2.0-py3-none-any.whl (81.8 kB view details)

Uploaded Python 3

File details

Details for the file kognita-0.2.0.tar.gz.

File metadata

  • Download URL: kognita-0.2.0.tar.gz
  • Upload date:
  • Size: 508.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for kognita-0.2.0.tar.gz
Algorithm Hash digest
SHA256 b0de710f6d8af7c9caefca069b50c0de3fc0844f3cb230c76124dec0659c4287
MD5 afee902302cad210f18f4c8cb13ebc88
BLAKE2b-256 48dcda27291aab3bb44750a432cb06c10dce5344be2a75ee9a33020f339c5ae0

See more details on using hashes here.

Provenance

The following attestation bundles were made for kognita-0.2.0.tar.gz:

Publisher: publish.yml on mze3e/kognita

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

File details

Details for the file kognita-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: kognita-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 81.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for kognita-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1131d85dff550f3a4c1548dbe2ad5fc062ae80c2bd40179a621e86fc331360fe
MD5 643601761f0a68cb2616b030925a7799
BLAKE2b-256 986a4bfc729cbabdc78c65aba8dacdd1d083860cffcce32c5df65530f52fa778

See more details on using hashes here.

Provenance

The following attestation bundles were made for kognita-0.2.0-py3-none-any.whl:

Publisher: publish.yml on mze3e/kognita

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

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page