EviCortex

Getting started

This guide installs the source checkout, stores two temporally related observations, recalls the current and historical values, and expands the exact supporting evidence.

Requirements

The deterministic kernel has no required third-party runtime dependencies. Dense local Transformers support is optional and covered in the API guide.

Install from a source checkout

git clone https://github.com/Varun-SV/EviCortex.git
Set-Location EviCortex
py -3.12 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -e .

On macOS or Linux, activate the environment with:

source .venv/bin/activate

The distribution is currently named evicortex-research; the Python import package is evicortex. The project is pre-alpha, so pin a commit when another application depends on it.

Run the bundled example

python examples/quickstart.py

The example uses an in-memory database, writes a light-theme preference followed by a superseding dark-theme preference, and prints separate current and historical capsules.

Build the same flow step by step

Create try_evicortex.py:

from evicortex import ClaimInput, EviCortex


NAMESPACE = "assistant/user-ada"

with EviCortex.open("evicortex.db") as memory:
    earlier = memory.remember(
        namespace=NAMESPACE,
        content="Ada prefers the light interface theme.",
        source="conversation/session-1/turn-4",
        occurred_at="2026-01-02T10:00:00Z",
        claims=[
            ClaimInput(
                subject="user:ada",
                predicate="prefers_theme",
                value="light",
            )
        ],
    )

    latest = memory.remember(
        namespace=NAMESPACE,
        content="Ada switched to the dark interface theme.",
        source="conversation/session-7/turn-12",
        occurred_at="2026-04-18T09:30:00Z",
        claims=[
            ClaimInput(
                subject="user:ada",
                predicate="prefers_theme",
                value="dark",
                supersedes=earlier.claims[0].id,
            )
        ],
    )

    current = memory.recall(
        namespace=NAMESPACE,
        query="Which interface theme does Ada prefer?",
        budget_tokens=300,
    )
    historical = memory.recall(
        namespace=NAMESPACE,
        query="Which interface theme did Ada prefer?",
        as_of="2026-02-01T00:00:00Z",
        budget_tokens=300,
    )

    print("Current:", current.to_prompt())
    print("Historical:", historical.to_prompt())
    print("Current evidence IDs:", current.evidence_ids)

    exact = memory.expand(
        namespace=NAMESPACE,
        memory_id=latest.id,
    )
    print("Exact evidence:", exact.content)

Run it:

python try_evicortex.py

The important behavior is:

Use namespaces deliberately

Every write, recall, expansion, extraction audit, and purge is scoped by a namespace. Choose an application-owned convention such as:

product/account-42/assistant-7

A namespace is a logical filter, not an authentication mechanism. The host application must authenticate its caller and authorize the namespace before invoking EviCortex. Do not accept an arbitrary namespace directly from an untrusted client.

Make retries idempotent

Use an application-stable key when a write may be retried:

record = memory.remember(
    namespace=NAMESPACE,
    content="Ada prefers concise notifications.",
    source="conversation/session-8/turn-2",
    idempotency_key="session-8/turn-2",
)

Replaying the same normalized request with the same key returns the existing record. Reusing the key for different content or write parameters raises an idempotency conflict. Keys are unique within a namespace.

Verify the local store

For a persistent database, periodically inspect integrity and row counts:

with EviCortex.open("evicortex.db") as memory:
    report = memory.verify_integrity(namespace=NAMESPACE)
    print(report.ok, report.corrupt_memory_ids, report.index_issues)
    print(memory.stats(namespace=NAMESPACE))

rebuild_indexes() repairs deterministic claim-status and FTS projections. It does not call an embedding provider; semantic projections use the explicit namespace-scoped sync_semantic() path described in the API guide.

Next steps