โ† Specification catalog

Persistent memory

aicortex

A governed memory service for AI clients, built on Rahi.

Observed 2026-10-03 ยท Producer spec-spine 0.28.0

e05a5a9c3a7724f2c491b24b8e1dc896518b741a โ†—

38 specifications. Verification and deployment qualification are unknown in this export.

000-aicortex-bootstrap

Bootstrap spec system for aicortex (specify first, build by spec, clean of the system it replaces)

The founding spec. It fixes the authoring boundary (markdown in, compiler-owned JSON out), the identity rule (directory name equals id), the typed authority graph, the closed taxonomies, the lifecycle that makes a spec a work order, and the gate chain. It also fixes the two rules that are specific to this product: the coherence guard that forbids amending a spec to ratify code, and the clean-room rule that separates what may be carried from the system this product replaces (observations) from what may not (its expression).

Lifecycle approvedImplementation n-a
001-agentic-harness

Agentic engineering harness: session protocol, skills, agents, hooks, and the gate

The machinery that turns the corpus into work: AGENTS.md as the cross-agent session protocol and backlog discipline, CLAUDE.md as the Claude Code overlay, six behavioral rules of which three are path-scoped, four subagents, ten skills, settings hooks that report and refuse, one Makefile that is the single definition of the gate and splits its reading half from its writing half, and a CI workflow that runs the same targets. This spec is complete on arrival: the harness exists before the first line of product code.

Lifecycle approvedImplementation complete
002-memory-thesis

Memory thesis: nine responsibilities, one governed cell, provider agnostic by protocol

What aicortex is, what it refuses, and the order it is built in. It is persistent memory for AI clients, delivered as a governed cell on the rahi chassis, reached by any client that speaks MCP over streamable HTTP. Nine responsibilities across eight domains, thirteen crates and one binary, four build waves. The refusals are as load-bearing as the claims: no second store, no static key, no fork-per-feature, no local stdio server, and no memory that a model may treat as an instruction unless a human promoted it.

Lifecycle approvedImplementation n-a
010-chassis-adoption-and-workspace

The cell: a Cargo workspace, pinned rahi crates, a declared manifest, and one line of main

The workspace and the seam to the chassis. rahi crates are pinned to one exact version in the workspace manifest and are never vendored or patched. The application is a `Cell`: it returns a manifest, a migration list, a router, and an operator router, and `main` hands it to rahi's runner, which owns argument parsing, boot, the verbs, and the exit codes. The manifest is the capability ceiling, and it starts closed: no egress host is declared until a spec needs one.

Lifecycle approvedImplementation complete
011-memory-model

The memory record: scope, trust class, actor, provenance, and the states a memory can be in

What a memory is, as types, before anything can store one. A memory is a claim by a named actor, from a named source, at a known time, inside a scope owned by a rauthy subject, carrying a trust class that decides whether a client may act on it and a status that decides whether it is still true. The type system enforces the parts that matter: there is no way to construct a memory without provenance, and no way to promote one to instruction grade without an authority token that only a human decision produces.

Lifecycle approvedImplementation complete
012-store-schema-and-repositories

Schema and repositories: versioned migrations, scope in the predicate, counters instead of scans

The tables and the only code allowed to touch them. Schema arrives as an ordered list of rahi migrations with versions, never as SQL a user pastes from a guide. Every repository call takes a scope and puts it in the SQL, so an unscoped read is not expressible. Aggregates are maintained counters updated in the writing transaction, because the predecessor's statistics call read every row's metadata into memory. Listing is keyset-paged; there is no offset pagination and no unbounded select.

Lifecycle approvedImplementation complete
013-write-gate-and-redaction

The write gate: refuse secrets, cap size, establish origin, quarantine the rest

Everything that enters the store passes one gate, and the gate runs before the transaction opens. It refuses credentials rather than redacting them, because a redacted secret is still a secret that was transmitted, stored in a log, and possibly embedded. It caps size, requires an establishable origin, and quarantines rather than admits when origin is doubtful. Every refusal is a ledgered Decision with a reason code and never the offending content. The rule set is data, the corpus of fixtures is committed, and the gate is a pure function so its verdicts are reproducible in review.

Lifecycle approvedImplementation complete
014-memory-lifecycle-and-erasure

Lifecycle: supersession, correction, expiry, deduplication, and erasure that reaches the vectors

A memory store that can only append becomes wrong over time and then confidently recalls the wrong thing. This spec gives a memory the rest of its life: an exact fingerprint that merges a repeated capture instead of duplicating it, supersession that keeps the old row readable but unretrievable, correction that records who said the old value was wrong, expiry for memories that were true until a date, and erasure that removes content, chunks, embeddings, and index entries in one transaction while the ledger records only that it happened.

Lifecycle approvedImplementation complete
015-embedding-pipeline

Embeddings: a local default, a governed provider trait, an outbox worker that cannot lose a memory

The predecessor captured a memory in two non-atomic calls: insert the row, then update the embedding. A failure between them produced a memory that search could never reach and nothing ever retried. This spec makes the second half a durable job: capture stages outbox work in the same transaction as the row, a worker drains it idempotently with backoff and a dead letter state that preflight reports, and every stored vector names the model, dimension, and normalization it was produced under so a model change is a migration rather than a silent reinterpretation.

Lifecycle approvedImplementation in-progress
016-vector-index-and-scan

The index: a paged cosine scan, an application-owned text index, and no SQLite extension

Similarity is computed in this process. Vectors are BLOBs read through rahi's paged read, scored by dot product against a normalized query, and reduced by a bounded top-k heap, with the scope predicate in the SQL so a scan never leaves its scope. The text channel is an application-owned inverted index rather than FTS5, because FTS5 is not compiled into hiqlite's SQLite build and a loadable extension is refused by the chassis. A trait boundary exists so an approximate index can replace the scan when the evaluation corpus says it must, and not before.

Lifecycle approvedImplementation pending
017-entities-and-typed-edges

Entities and typed edges: a closed predicate vocabulary, derived facts that never outrank their source

Similarity alone answers "what looks like this", not "what do I know about this person". Entities give recall a second axis: people, projects, organizations, places, and artifacts, resolved to canonical records with aliases, connected by typed edges from a closed vocabulary. Every entity and every edge names the memory it was derived from and the extractor version that produced it, and a derived assertion never outranks the memory it came from. Extraction is a job on the same outbox as embedding, so it inherits the retry and dead-letter discipline rather than inventing its own.

Lifecycle approvedImplementation pending
018-retrieval-and-recall-trace

Recall: four channels fused into one order, every result explainable, scope in the SQL

One query, four candidate channels (vector, text, recency, graph), one fused order, and a trace that explains it. Fusion is reciprocal rank with declared weights and an importance prior, chosen because it needs no score calibration between channels that do not share a scale. Every result set carries the query, the per-channel candidates and scores, the fusion arithmetic, and the reason each returned memory made the cut. A ranking that cannot be explained is not shippable, and an evaluation corpus (040) is the only way a weight changes.

Lifecycle approvedImplementation pending
019-untrusted-content-boundary

Recalled content is data: delimited, labelled, never in an instruction position

A memory store feeds text written by other people, other agents, and web pages into a model's context, which makes it an indirect prompt-injection surface by construction. This constraint spec owns no code and freezes one property across every path that returns content: memory bodies leave this system only inside an envelope that delimits them, labels their trust class and origin, and states that instructions inside them are not to be followed. Instruction grade, the only class a client is told to act on, requires a human promotion recorded in the ledger. An agent never promotes its own memory.

Lifecycle approvedImplementation pending
020-http-api-and-scopes

The HTTP API: bearer-authorized, scope-gated, streaming where it earns it

The product's own HTTP surface, mounted by the cell into rahi's edge. Every route is authorized by a rauthy-issued bearer token or a browser session, both resolved to the same principal, and gated by an OAuth scope that names what it permits. Scopes are coarse enough to be understandable and fine enough to be useful: read, write, delete, admin, a separate scope for promotion, which no agent client is ever granted, and a read and a write scope for coordination, which no memory scope implies. Long operations report progress over server-sent events through the chassis's declared streaming routes. Every response carrying content obeys the untrusted content boundary.

Lifecycle approvedImplementation pending
021-mcp-server

The MCP server: streamable HTTP, a small tool surface, OAuth discovery that bootstraps itself

One remote MCP server over streamable HTTP, stateless per request, serving every client that speaks the protocol. Seven tools, no more: capture, search, fetch, list, update, forget, and relate. Authorization is the chassis's resource server, so an unauthenticated initialize answers the challenge that lets a client discover the authorization server and register itself without the user pasting anything. Tool results carry envelopes and the framing statement, and the tool descriptions themselves never contain recalled content.

Lifecycle approvedImplementation pending
022-client-adapters

Client adapters: one capability matrix, four install paths, zero client code in the core

Connecting is one URL, and everything a client needs beyond that is generated rather than written by hand. This spec owns the capability matrix: which clients support remote MCP, which support OAuth against it, and what each offers for automatic capture, which is the only place they genuinely differ. It ships per-client configuration snippets and the hook or notification payloads that turn a session into captured memories, and a route that serves the correct snippet for a client so setup is a copy rather than a document to follow.

Lifecycle approvedImplementation pending
023-review-and-promotion

Review: the queue where quarantine, contradiction, and promotion wait for a human

Three situations need a person: content whose origin could not be established and was quarantined, two edges that contradict each other, and a memory that someone wants a client to act on. This spec is the one queue where all three wait, the decisions that empty it, and the ledger records those decisions produce. Promotion is the important one: it is the only path to instruction grade, it requires the promote scope and an interactive principal, and it writes a rahi Decision whose id becomes part of the memory's trust.

Lifecycle approvedImplementation pending
024-decision-and-audit-references

One chain, referenced: decisions live in rahi's ledger and memories point at them

There is exactly one hash chain in a deployment and it belongs to the chassis. This product appends Decisions to it and stores references to them; it never builds a second chain, and it never puts memory content into the one that exists. The audit view is a join: a memory's history is its lifecycle rows plus the decisions that reference it, rendered in one timeline. This also fixes the vocabulary, because the sibling product in this family has its own object called a ledger and two things called ledger in one deployment would be a permanent source of confusion.

Lifecycle approvedImplementation pending
030-source-adapter-framework

Source adapters: one contract, incremental and resumable, so a capability is never a fork

The predecessor's ecosystem grew by forking the server: fifty-odd capabilities, each a copy of the same six hundred lines, so a fix in one never reached the others. This spec is the alternative. A source is an implementation of one trait, registered by name, driven by one runner that owns fetching pages, mapping to candidates, passing the gate, staging the transaction, recording a resumable cursor, and reporting progress. Adding a source is a module and a fixture set, and it inherits dedup, retries, provenance, egress governance, and the untrusted content boundary without restating any of them.

Lifecycle approvedImplementation pending
031-conversation-and-archive-imports

Bringing a history in: chat exports, note vaults, and read-later archives

A memory system is worth little on day one and a great deal once it knows what you already said. This spec brings a user's existing history in: chat exports from the major assistants, a note vault on disk, a read-later archive, and mail, each as an adapter over the framework. The interesting work is not fetching, it is turning a transcript into memories worth keeping rather than a wall of every message, and doing it without sending the archive anywhere.

Lifecycle approvedImplementation pending
032-capture-sources-and-webhooks

Live capture: signed webhooks from chat systems and the browser, quarantined by default

Capture that happens while you work: a message forwarded from a chat system, a page clipped from the browser. Both arrive as webhooks, which means both are unauthenticated in the OAuth sense and must be treated accordingly. Signatures are verified per platform, the external identity is bound to a local subject by an explicit linking step, and content from a channel other people can write to is quarantined by default rather than trusted because it arrived over a verified transport.

Lifecycle approvedImplementation pending
033-observatory-and-agent-ingestion

Machine intake: session decisions from the orchestrator and memories written by agents

The most valuable memories in a software team are the decisions made inside driven sessions and then forgotten when the session ends. This spec accepts them: a generic session-event ingestion contract that any orchestrator or agent runtime can post to, with claude-observatory as its first producer, and a decision feed that turns sealed session decisions into memories. It is deliberately not Claude-specific, and it is deliberately a push into a documented schema rather than a reader of any particular tool's private files.

Lifecycle approvedImplementation pending
034-curation-workers

Curation: atomize, enrich, consolidate, expire, digest, all bounded and reversible

Without curation a memory store becomes a landfill: long notes that match nothing, near-duplicates from three sources, facts that stopped being true, and no way to see what a week contained. Five workers address that, all sharing one discipline: they run under a lease in bounded batches, every change they make is a lifecycle transition that is visible and reversible, they never delete, and anything they produce inherits the lowest trust class of its inputs. A curator can propose; only a human promotes.

Lifecycle approvedImplementation pending
035-agent-coordination

Agent coordination: per-agent identity, work claims, and a shared working memory

When several agents work in one scope they need to know who did what and to avoid doing the same thing twice. Per-agent identity already exists, because each client is its own OAuth client; this spec adds the two things that build on it. A work claim is a renewable, application-owned hold on a named unit of work with its own fencing token, so two agents cannot both take it. A working-memory scope is a short-lived, high-churn area where agents post what they are doing, visible to their siblings and expired automatically, so coordination does not pollute durable memory.

Lifecycle approvedImplementation pending
040-retrieval-evaluation

Evaluation: a golden corpus, recall and precision at k, and a gate that refuses a silent regression

Retrieval quality is the product, and it degrades invisibly. This spec builds the instrument: a committed golden corpus of memories and queries with judged relevance, a runner that loads it into a temporary instance and executes every query, metrics that are the standard ones rather than invented, a baseline file per configuration, and a gate that fails a change which moves a metric down by more than its tolerance without an explicit, justified baseline update. Constitution XIV becomes a command with an exit code.

Lifecycle approvedImplementation pending
041-privacy-and-egress-boundary

The privacy boundary: what leaves the container, proved by the manifest rather than promised

The product's claim is that the user's memory stays theirs. This spec turns that from a sentence in a README into a checkable property. In the default configuration the manifest declares no egress host at all, so the process can make no outbound call and a test proves it. Every feature that would need one names it, justifies it, and is off by default. Telemetry does not exist. Backups go where the operator configured and nowhere else. The boundary is stated once here and inherited by every spec that could cross it.

Lifecycle approvedImplementation pending
042-portability-and-migration

Portability: a documented export anyone can read, and an import path off the system this replaces

A memory store that cannot be left is a hostage situation, and a product whose pitch is ownership has to prove it. Export writes a documented, self-describing archive of a scope: memories, provenance, entities, edges, lifecycle history, and optionally embeddings, in a format specified here and readable without this software. Import reads it back. The same machinery carries the migration path off the system this product replaces, as an ordinary source adapter reading a user's own data at their request.

Lifecycle approvedImplementation pending
043-packaging-and-operations

Packaging: one image on the chassis, the operator surface, the runbook

The chassis already owns the image shape, the volume, the supervision, the four verbs, the probes, and the metrics. This spec adds only what is this product's: the build that produces the binary and fetches or embeds the local model, the operator routes the cell mounts, the configuration reference, and the runbook for the handful of things that can go wrong. It is deliberately thin, because a packaging spec that grows is a sign the chassis is being reimplemented.

Lifecycle approvedImplementation pending
044-reference-deployment

The reference deployment: three nodes on Kubernetes, object storage behind it, evaluation green

The wave 4 exit condition and the product's own proof. A three-node StatefulSet on Kubernetes with object storage for backups and archived ledger segments, one origin behind an ingress, metrics scraped, backups on a schedule, and an end-to-end harness that drives the whole product through a real client path: sign in, connect, capture, import, curate, recall, promote, export, and erase. When this is green the specification has been demonstrated rather than argued.

Lifecycle approvedImplementation pending
045-durable-coordination-protocol

Coordinate repository work through durable requests, replies, and reconciled evidence

Generalize repository handoff packets and handbacks into a durable, scoped coordination protocol. Requests, acknowledgment, replies, evidence observations, explicit resolutions and corrections retain their identity and revision. Inbox and outbox are projections, not another broker or hash chain. The same hiqlite store holds records, recipient state and consumer cursors transactionally; chassis events only wake consumers. Statecraft-cli supplies local session and Git/provider observations and keeps execution authority. A recalled request cannot authorize an action, a session report cannot approve its own specification, and an interrupted or disconnected consumer can reconcile what it missed.

Lifecycle draftImplementation pending
046-rahi-0-2-0-adoption

Move every chassis pin to rahi 0.2.0 together, and declare which migrations are additive

The nine rahi crates are pinned at `=0.1.0`. rahi 0.2.0 is published on crates.io for all nine and is a minor release that changes the consumer contract: migrations gain an `additive` declaration and the store records a checksum per applied version, restore and first-boot export change their Rust API, backups authenticate with a dedicated passkey, and the ledger gains lifetime decision identity. This spec moves all nine pins in one change, keeps the exact-pin rule of spec 010, decides for each shipped migration whether it is additive, and re-runs spec 010's supply-chain revisit against the new tree. It must land before any claim-history migration (050 to 052) is written, so those migrations are authored against the 0.2.0 contract.

Lifecycle approvedImplementation complete
047-shared-secret-detector-convergence

Converge secret detection upward: aicortex's detectors move into action-gate, and aicortex consumes them

aicortex-gate carries its own credential detectors (013 B-4, `rules.rs`, `secrets.rs`), and action-gate-core, the family's pure action gate, ships a weaker `SecretsCheck` with an overlapping pattern set. The owner chose to converge upward: aicortex's stronger detectors, with their detector ids, byte offsets, and full private-key marker set, move into action-gate under a separate upstream spec, and aicortex-gate then consumes action-gate's table at an exact pin instead of keeping its own. The consumption is admissible only at parity with 013's committed corpus, and aicortex keeps its own verdict, normalization, and keyed-digest ledger record. Until the upstream release exists this spec is blocked, not mocked.

Lifecycle approvedImplementation complete
048-one-spec-per-pull-request

One spec per pull request; a session may land several specs in build order

The owner's decision of 2026-09-25 replaces the repository rule that code lands one spec per session with one spec per pull request: a session may land several specs, each on its own branch and in its own pull request, in build order. This spec amends spec 001 B-6 and carries the new sentence into the harness text that repeated the old one (AGENTS.md, CLAUDE.md, README.md, the orchestrator rule, the architect agent, and constitution principle III).

Lifecycle approvedImplementation complete
050-typed-claims-and-predicate-registry

Typed claims: a subject, a registered predicate, a typed value, an epistemic status, and the source span it came from

aicortex becomes the family's canonical owner of claim history with provenance. This spec defines what one claim says, as types, before any claim is admitted or stored: a subject reference, a predicate from a namespaced, versioned registry that a domain supplies, a typed value (text, integer, fixed-point decimal with a unit or currency, date, datetime with zone, interval, entity reference, enumeration), an epistemic status taken from the source's own stance, typed claim-to-claim relations, and source span references that extend 011's Provenance with a part, a byte or character span, and a content digest. aicortex stays domain agnostic: travel, the first consumer, registers its own predicates. Who may admit a claim is 051; when it holds and how history is kept is 052.

Lifecycle approvedImplementation complete
051-claim-admission-and-authority

Claim admission: an observation is not a proposal, a proposal is not a claim, and a score is never authority

Three things that ingest pipelines routinely blur are kept apart: an observation (the source as received, stored as a memory through 013's gate), a proposal (a typed claim some actor suggests, with its evidence), and an admitted claim (a proposal the gate accepted under a named policy, with a decision record). Admission reuses the existing gate crate and its purity, adds a claim verdict whose `AdmittedClaim` only the gate can mint, and records every admission. Model-produced scores are stored as evidence and never serve as authority. A user's correction is first-class evidence carrying an authority level, and it is appended, never an edit.

Lifecycle approvedImplementation complete
052-bitemporal-claim-history-and-projection

Bitemporal claim history: valid time apart from record time, supersession per slot, and a current view that is a pure function

A claim has three times: when it holds in the world (valid time, with precision, zone, open ends, and uncertainty), when the source said so (source-declared time), and when this store learned it (transaction time). History is append-only on the transaction axis; retraction, correction, and supersession are appended records, and only erasure removes content, leaving a tombstone. Supersession is scoped to one subject, predicate, and slot, so a schedule change to one segment supersedes that attribute alone. The current view is a deterministic projection of history under an explicit as-of on both axes and a policy version, ordered by the source's own time and the claim's authority, never by arrival, so reordered email delivery yields the same answer.

Lifecycle approvedImplementation complete
053-host-library-mode

Host-library mode: named migrations, operator-authorized vocabulary, and one caller-owned transaction

Expose Aicortex as a linked library inside another Rahi cell without giving up migration identity, operator authority, or transaction ownership. The library exports the immutable named migration set `aicortex`, makes predicate registration an explicit operator-configured act, and stages observations, admission records, claim history, erasure records, and outbox work into the caller's `rahi_store::TxnBuilder`. A separate host fixture proves that Rahi ingress state, Aicortex history, a host-owned projection revision, and outbox work share one commit and one rollback.

Lifecycle approvedImplementation complete
054-statecraft-profile-14

Adopt Statecraft profile revision 14 with the ordinary Rust code gate

Authorizes the narrow migration from Statecraft github-actions-rust revision 13 to revision 14 after the spec-spine 0.28.0 bridge and pin sequence. Aicortex keeps its exact engine pin and ordinary Rust code gate, corpus attestation, supply chain and spec DAG jobs. Managed authority files are regenerated by revision 14 using the retained setup parameters.

Lifecycle approvedImplementation complete