Kognita
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.
PatternRedactoris 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-basedRedactor; 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.Kognita→kognita.graph.GraphEngine,kognita.KognitaConfig→kognita.graph.GraphConfig,kognita.KognitaKuzuDriver→kognita.graph.KuzuDriver, andkognita.core.*→kognita.*. Touching a retired name raises anAttributeErrornaming 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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0de710f6d8af7c9caefca069b50c0de3fc0844f3cb230c76124dec0659c4287
|
|
| MD5 |
afee902302cad210f18f4c8cb13ebc88
|
|
| BLAKE2b-256 |
48dcda27291aab3bb44750a432cb06c10dce5344be2a75ee9a33020f339c5ae0
|
Provenance
The following attestation bundles were made for kognita-0.2.0.tar.gz:
Publisher:
publish.yml on mze3e/kognita
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kognita-0.2.0.tar.gz -
Subject digest:
b0de710f6d8af7c9caefca069b50c0de3fc0844f3cb230c76124dec0659c4287 - Sigstore transparency entry: 2706730681
- Sigstore integration time:
-
Permalink:
mze3e/kognita@8479ae59c6e26efbae903f425a6a82d094bf9629 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/mze3e
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8479ae59c6e26efbae903f425a6a82d094bf9629 -
Trigger Event:
release
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1131d85dff550f3a4c1548dbe2ad5fc062ae80c2bd40179a621e86fc331360fe
|
|
| MD5 |
643601761f0a68cb2616b030925a7799
|
|
| BLAKE2b-256 |
986a4bfc729cbabdc78c65aba8dacdd1d083860cffcce32c5df65530f52fa778
|
Provenance
The following attestation bundles were made for kognita-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on mze3e/kognita
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kognita-0.2.0-py3-none-any.whl -
Subject digest:
1131d85dff550f3a4c1548dbe2ad5fc062ae80c2bd40179a621e86fc331360fe - Sigstore transparency entry: 2706730723
- Sigstore integration time:
-
Permalink:
mze3e/kognita@8479ae59c6e26efbae903f425a6a82d094bf9629 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/mze3e
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8479ae59c6e26efbae903f425a6a82d094bf9629 -
Trigger Event:
release
-
Statement type: