cortext
cortext is the memory engine powering augmem.ai for augmenting human and LLM memory. It is a brownfield C++ system that ingests multimodal signals, persists durable memory traces, and resurfaces relevant context for applications, agents, analyses, and realtime chat experiences.
Core Value: Important context should resurface at the right time for humans and models without requiring manual memory management.
- Tech stack: C++20 with CMake, SQLite, and local model runtimes — the current engine architecture is already in production use and should be evolved, not replaced casually
- API stability: Public headers in
include/and the C API require explicit approval before breaking changes — bindings and examples depend on them - Research traceability: Algorithm and experiment changes must be reflected in
docs/paper/sections/and the generated manuscript — this repo treats paper evidence as part of the product record - Performance: On-device latency matters, especially for speech and realtime interaction paths — augmem.ai needs memory augmentation that feels live, not batch-oriented
- C++20 - Core engine, public API, examples, and tests live in
CMakeLists.txt,src/,include/,examples/, andtests/. - C - Low-level integration code and embedded extensions live in
CMakeLists.txt,src/capi.cpp,include/cortext/capi.h,third_party/sqlite-vec/sqlite-vec.c, andthird_party/sqlite-objstore/src/*.c. - Python 3.10+ - experiment and data/model tooling live in
scripts/*.pyandtools/**/*.py. Language package: standaloneaugmem/cortext.py. - Optional N-API - Node addon source lives in
ffi/node/addon.cpp(package consumers use standaloneaugmem/cortext.ts). - CMake - Build orchestration lives in
CMakeLists.txt,CMakePresets.json,tests/CMakeLists.txt,examples/**/CMakeLists.txt, andcmake/*.cmake.
- Native host runtime on macOS/Linux is the default build path in
CMakeLists.txtandCMakePresets.json. - Optional WebAssembly runtime is configured through
CMakePresets.jsonandcmake/EmscriptenToolchain.cmake. - CMake + FetchContent + git submodules - native dependency resolution is defined in
CMakeLists.txtand.gitmodules.
- CMake 3.16+ - primary native build system in
CMakeLists.txt; presets require CMake 3.21+ inCMakePresets.json. - SQLite 3 - primary persistence layer built from vendored
third_party/sqlitesources inCMakeLists.txtandinclude/cortext/store/sqlite_store.hpp. - Eigen 3.4.0 - numeric/vector math dependency fetched in
CMakeLists.txt. - nlohmann/json v3.12.0 - JSON handling for C API responses and tests in
CMakeLists.txtandsrc/capi.cpp. - Catch2 v3.5.3 - unit/integration test framework fetched in
tests/CMakeLists.txt. - CTest - test registration and execution live in
CMakeLists.txtandtests/CMakeLists.txt. - Emscripten - optional WASM toolchain in
cmake/EmscriptenToolchain.cmake.
opentelemetry-cppv1.24.0 - opt-out tracing/metrics/logging API dependency fetched inCMakeLists.txtand used insrc/telemetry/telemetry.cpp.ggml- required AIST GGUF kernel backend for audio/image-capable native builds inCMakeLists.txt,src/models/aist_gguf_encoder.cpp, andsrc/models/ggml_support.hpp.sqlite-vec- embedded vector index for 256-dim embeddings inCMakeLists.txt,src/store/schema.cpp, andsrc/store/extension_loader.cpp.sqlite-objstore- blob/object payload storage inCMakeLists.txt,src/store/schema.cpp,src/store/extension_loader.cpp, andsrc/operations/memory_storage.cpp.- Node.js headers / N-API v8 - optional Node addon build path in
CMakeLists.txtandffi/node/addon.cpp.
- Build toggles are controlled through CMake options in
CMakeLists.txtand presets inCMakePresets.json. - Runtime model discovery is handled by encoder/backend resolution in
src/encoder/text_encoder_factory.hpp, using bundled/default assets orCORTEXT_AIST_MODEL_PATHfor explicit overrides. - Important runtime overrides are read from environment variables in:
.envfiles: not detected by filename in the repo root during this scan.- Root build graph:
CMakeLists.txt - Presets:
CMakePresets.json - CI build recipe:
.github/workflows/build.yml - Language packages: standalone repos
augmem/cortext.{py,ts,go,dart,wasm}
- AIST GGUF release model in
models/AIST-87M-GGUF/ - Optional fallback/demo embedding assets in
models/mdbr-leaf-ir/ - Preferred text encoder resolution is implemented in
src/encoder/text_encoder_factory.hpp.
- C++20-capable compiler and CMake are required by
README.md,CMakeLists.txt, and.github/workflows/build.yml; SQLite is built fromthird_party/sqlite. - No hosted deployment target is defined in the repo.
- The shipping artifact is a native shared/static library plus optional examples/tools built locally from
CMakeLists.txt. - CI only verifies Linux native build/test on GitHub Actions in
.github/workflows/build.yml.
- Use lower_snake_case for C++ source and header files. Public/private pairs usually mirror each other, for example
src/operations/focus.cppwithinclude/cortext/operations/focus.hpp, and tests follow the same stem with.test.cpp, for exampletests/operations_focus.test.cpp. - Keep subsystem prefixes in filenames so related files sort together:
src/store/schema.cpp,src/store/facts.cpp,tests/store.test.cpp,tests/store_extensions.test.cpp. - Internal-only helpers are explicit in the filename instead of hidden behind umbrella headers, for example
src/operations/meta_learning_internal.hpp,src/operations/constructive_recall_internal.hpp, andsrc/operations/eviction_policy_override.hpp. - In the library and most tests, use PascalCase for functions and methods, including file-local helpers:
NowMillis,ParseDbOperation,LoadObjstorePayload,InitializeCoreSchema,SeedEmbeddingV2, andIOperation::Execute. - Preserve local style when a file already uses a different convention. Some tests and scripts use lower_snake_case helpers such as
create_temp_db,cleanup_temp_db,parse_metrics, andrun_caseintests/store.test.cppandscripts/run_memory_harness.py. - Operation classes expose work through
Execute (OperationContext &, Transaction &) constas defined ininclude/cortext/processor/operation.hpp. - Use lower_snake_case for locals, parameters, and fields:
observed_cosine,ctx_window_size,db_path_,had_value_,weight_relevance_prior, andinterrupt_gate_blocked_no_store. - Member fields commonly end with
_, especially RAII wrappers and private state, for examplename_,old_value_,db_path_, andimpl_. - Constants use
k+ PascalCase, for examplekEmbeddingDim,kHourMs,kHumanHalfLifeSeconds, andkCoverageGainFloorBase. - Boolean names read like predicates or state flags:
focus_priors_initialized,should_interrupt,interrupt_aborted,reinforcement_enabled. - Use PascalCase for classes, structs, and interfaces:
Cortext,SignalProcessor,SQLiteConnection,TempDatabase,ScopedEnvVar, andIOperation. - Namespace names are lower-case subsystem names, usually nested under
cortext:cortext::operations,cortext::store,cortext::testing,cortext::telemetry, andcortext::internal. - Test doubles follow the same type naming as production code:
TestEncoder,CapturingSummarizer,KeywordEncoder, andTriggerBoundaryOp.
- No repo-level formatter config was detected.
.clang-format,.clang-tidy, and.editorconfigare not present at the repository root. - The dominant library style in
src/andinclude/uses 2-space indentation, opening braces on the next line, and spaces before parentheses: seesrc/store.cpp,src/cortext.cpp,src/operations/focus.cpp, andinclude/cortext/cortext.hpp. - Tests in
tests/operations_focus.test.cpp,tests/store.test.cpp, andtests/integration_consolidation.test.cppgenerally follow the same Allman-style formatting as the library. - Some example and app-facing code uses a different local dialect with tighter spacing and same-line braces. Preserve the local file style when editing
examples/topical_chat_analysis/main.cppinstead of normalizing it to the core style. - Formatting is enforced mostly by review and by matching nearby code, not by a checked-in formatter.
- Compiler warnings are the practical style gate.
CMakeLists.txtenables-Wall -Wextra -Wpedanticfor non-MSVC builds and/W4for MSVC. CORTEXT_WARNINGS_AS_ERRORSdefaults toONinCMakeLists.txt, so library changes should be written as warning-clean by default.- Sanitizers are opt-in quality checks in
CMakeLists.txt:CORTEXT_ENABLE_ASAN,CORTEXT_ENABLE_UBSAN, andCORTEXT_ENABLE_MSAN.
- Public headers are included with the installed-style prefix, for example
<cortext/processor.hpp>,<cortext/store/sqlite_store.hpp>, and<cortext/operations/focus.hpp>. - Internal-only test coverage sometimes reaches into non-public code with relative includes when there is no public seam.
- There are no alias macros or umbrella headers acting as barrel files. Include the exact header you need.
- Throw typed or standard exceptions for hard failures in low-level components.
src/store.cppthrowsStoreErroron SQLite prepare/open failures. - Catch exceptions at system boundaries when the code can degrade gracefully, then emit telemetry instead of crashing.
LoadObjstorePayloadandLoadSignalBlobsinsrc/cortext.cppcatchstd::exceptionand log warnings before returningfalse. - Use
std::optional, empty containers, or boolean return values for absence and best-effort behavior, for exampleContext::ProcessorOutputfields ininclude/cortext/cortext.hppand theboolreturns insrc/cortext.cpp. - Mark intentionally unused parameters explicitly with
(void)tx;in operation implementations such assrc/operations/focus.cpp.
- Library code uses the wrapper in
include/cortext/telemetry/telemetry.hppandsrc/telemetry/telemetry.cppinstead of ad hocstd::coutlogging. - Emit structured event names and attributes rather than interpolated strings. Examples:
telemetry::LogDebug ("cortext.focus.init", {...})andtelemetry::LogWarn ("Failed to load signal blobs", {...})insrc/operations/focus.cppandsrc/cortext.cpp. - Telemetry is safe to call even when no SDK provider is installed.
tests/telemetry_noop_by_default.test.cppverifies the no-op path. - Example binaries and scripts may still print to stdout or log files directly, for example
examples/topical_chat_analysis/main.cppandscripts/run_memory_harness.py.
- Use
/// @briefcomments for public headers and reusable helpers where callers need contract-level guidance, as seen ininclude/cortext/cortext.hpp,include/cortext/store/schema.hpp, andinclude/cortext/processor/operation.hpp. - Use short
//comments for rationale, algorithm references, schema blocks, and test setup notes. Good examples aresrc/store/schema.cpp,tests/formula_validation.test.cpp,tests/regression_behavior.test.cpp, andtests/operations_threshold.test.cpp. - Prefer comments that explain why a step exists or which paper/spec rule it traces back to. Avoid line-by-line narration.
- Doxygen-style
/// @brief,/// @param, and/// @returncomments are the main documentation pattern for C++ APIs and test helpers, not block comments or generated doc annotations from another toolchain.
- Keep file-local helpers narrow and focused in anonymous namespaces.
src/store.cppsplits query work intoParseDbOperation,PrepareStatement,BindParameters, andFetchResultRowinstead of a single large function. - Complex workflows are composed from small operation objects rather than one monolith.
src/cortext.cppwires manyIOperationimplementations together instead of embedding the algorithm logic inline. - Favor explicit domain objects over long primitive parameter lists for processing code: operations receive
OperationContext &andTransaction &, and high-level APIs useCortext::Config,SignalProcessor::Config, and typed structs ininclude/cortext/cortext.hpp. - Helper functions in tests and benchmarks often accept plain values when seeding deterministic state, for example
SeedMemoryV2,SeedSignalV2,MakeSignal, andSeedLongTermMemory. - Pure helpers return plain values or
std::optionalwhere absence is meaningful, for exampleNowMillis,ToMillis,FindModelPath, andContext::ProcessTextAt. - Stateful operations usually mutate context and transaction state rather than returning values. Follow the
IOperationcontract unless you are writing a pure helper outside the pipeline.
- Public surface area lives under
include/cortext/and is marked withCORTEXT_EXPORTwhen needed, for exampleinclude/cortext/cortext.hpp. - Keep internal implementation details in
src/or internal headers such assrc/operations/meta_learning_internal.hppandinclude/cortext/internal/cancellation.hpp. - Do not widen the public API accidentally. Tests are willing to include internal headers directly when coverage needs it.
- Not used. Headers are imported directly by subsystem path, for example
include/cortext/operations/focus.hppandinclude/cortext/store/sqlite_store.hpp. - When adding a new operation or subsystem, create a matching header/source pair and include it explicitly from the call sites that need it.
include/cortext/cortext.hppexposes a small facade API whilesrc/cortext.cppowns wiring, backend selection, and memory hydration.include/cortext/processor.hpp,include/cortext/processor/operation.hpp, andinclude/cortext/processor/operation_set.hppdefine a sequential operation pipeline executed bysrc/signal_processor.cpp.include/cortext/store/store.hppabstracts persistence whileinclude/cortext/store/sqlite_store.hpp,src/store.cpp, andsrc/store/schema.cppimplement a SQLite-first runtime with migrations and nested transactions.
- Purpose: Stable entrypoints for native and FFI consumers.
- Location:
include/cortext/cortext.hpp,include/cortext/capi.h,src/capi.cpp - Contains:
cortext::Cortext, theContextDTO, config structs, C ABI wrappers, JSON serialization helpers. - Depends on:
SignalProcessor, encoder factory, store implementation. - Used by:
examples/topical_chat_analysis/main.cpp,ffi/node/addon.cpp, tests such astests/cortext.test.cpp, and standalone language packages. - Purpose: Build the runtime graph and choose local model backends.
- Location:
src/cortext.cpp,src/encoder/text_encoder_factory.hpp - Contains:
Cortext::Impl, operation-pipeline assembly, text encoder selection, context hydration. - Depends on: operations, processor, store, telemetry, encoder implementations.
- Used by:
Cortext::Create()insrc/cortext.cpp. - Purpose: Execute one signal through the algorithm stack while mutating long-lived processor state.
- Location:
include/cortext/processor.hpp,include/cortext/processor/processor_context.hpp,include/cortext/processor/operation_context.hpp,src/signal_processor.cpp - Contains:
SignalProcessor,ProcessorContext,OperationContext, transaction-scoped output assembly, state load/persist helpers. - Depends on:
Store,IOperation,Signal, telemetry, Eigen. - Used by:
src/cortext.cpp, tests such astests/signal_processor.test.cppandtests/operation_context.test.cpp. - Purpose: Implement the actual cognitive/memory algorithms as small pipeline steps.
- Location:
include/cortext/operations/*.hpp,src/operations/*.cpp - Contains: scoring, thresholding, retrieval, graph construction, consolidation, working-memory, neuromodulation, accumulation, storage, and feedback steps.
- Depends on:
OperationContext,ProcessorContext, andStore. - Used by:
BuildPipelineRoot()insrc/cortext.cpp. - Purpose: Own schema, migrations, SQL execution, transaction nesting, and low-level content storage.
- Location:
include/cortext/store/*.hpp,src/store.cpp,src/store/schema.cpp,src/store/facts.cpp,src/store/extension_loader.cpp - Contains:
Store,Transaction,SQLiteStore, schema migrations, sqlite extension loading, fact queries/helpers. - Depends on: SQLite C API, bundled sqlite extensions, telemetry.
- Used by:
SignalProcessor,Cortexthydration, store-focused tests such astests/store.test.cppandtests/migration_core.test.cpp. - Purpose: Encoders and local model adapters.
- Location:
include/cortext/encoder/*.hpp,include/cortext/models/*.hpp,src/encoder/*.hpp, andsrc/models/*.cpp - Contains:
Encoder, AIST GGUF embedding support, and local model pinning. - Depends on: model assets under
models/. - Used by: the composition layer in
src/cortext.cppand targeted AIST/model-pin tests. - Purpose: Optional binaries for manual use, experiments, telemetry smoke tests, and research sweeps.
- Location:
examples/,tools/,scripts/ - Contains: benchmark programs, topical-chat analysis, sqlite telemetry smoke test, offline label/text tools, Python/bash experiment harnesses.
- Depends on:
cortext::cortext, and in several cases private headers undersrc/. - Used by: local development and experiment workflows, not by the core library.
- Long-lived adaptive state lives in
ProcessorContextininclude/cortext/processor/processor_context.hpp. - Transaction-scoped per-signal state lives in
OperationContextininclude/cortext/processor/operation_context.hpp. - Persisted state, memories, signals, embeddings, associations, and accumulators live in the v2 SQLite schema created by
src/store/schema.cpp.
- Purpose: Main user-facing object for processing and consolidation.
- Examples:
include/cortext/cortext.hpp,src/cortext.cpp - Pattern: Pimpl facade with backend composition hidden in
Cortext::Impl. - Purpose: One atomic algorithm step in the processing chain.
- Examples:
include/cortext/processor/operation.hpp,include/cortext/processor/operation_set.hpp,src/operations/threshold.cpp,src/operations/graph_retrieval.cpp - Pattern: Command-style interface executed sequentially by
OperationSet. - Purpose: Carry EWMAs, thresholds, priors, recent context, consolidation timers, working-memory state, and blender weights across signals.
- Examples:
include/cortext/processor/processor_context.hpp,src/signal_processor.cpp - Pattern: Mutable state bag persisted to the database between runs.
- Purpose: Isolate SQL execution from the rest of the library.
- Examples:
include/cortext/store/store.hpp,include/cortext/store/sqlite_store.hpp - Pattern: Interface + SQLite implementation with nested transactions/savepoints.
- Purpose: Hide model-specific runtime details from the processing pipeline.
- Examples:
include/cortext/encoder/encoder.hpp,include/cortext/models/aist_gguf_encoder.hpp,include/cortext/models/embedding_model_pin.hpp - Pattern: Runtime-selected strategy objects passed into
SignalProcessor::Config.
- Location:
src/cortext.cpp - Triggers:
Cortext::Create()from C++ callers andcortext_create_with_config()fromsrc/capi.cpp - Responsibilities: Open store, run migrations, choose encoder backend, build pipeline root, create
SignalProcessor. - Location:
include/cortext/cortext.hpp,src/cortext.cpp - Triggers: Text/audio/image calls from examples, tests, and bindings.
- Responsibilities: Encode input, execute processor, hydrate memory results, return
Context. - Location:
include/cortext/capi.h,src/capi.cpp - Triggers: Go, Python, JavaScript bindings.
- Responsibilities: C-compatible lifecycle, status/error handling, JSON serialization.
- Location:
tests/CMakeLists.txt - Triggers:
cortext_testsexecutable andctest. - Responsibilities: Build a single Catch2 binary that exercises both public APIs and internal/private subsystems.
- Location:
examples/topical_chat_analysis/main.cpp,examples/otel_sqlite_smoketest/main.cpp,examples/benchmark/*.cpp - Triggers: Optional
CORTEXT_BUILD_EXAMPLES=ONbuilds. - Responsibilities: Telemetry analysis, smoke tests, and research benchmarking.
- Store and schema code throw
StoreError-derived exceptions frominclude/cortext/store/store.hppand log failures insrc/store.cpp/src/store/schema.cpp. src/cortext.cppandsrc/signal_processor.cppcatch selected failures around hydration/state restore and log warnings through telemetry instead of crashing the caller.src/capi.cppwraps all public C functions in exception-catching helpers and exposes details viacortext_last_error().
- Public consumers should prefer
include/cortext/*, but examples and some tools deliberately include private headers fromsrc/by adding${PROJECT_SOURCE_DIR}/srcor${CMAKE_SOURCE_DIR}/srcinexamples/*/CMakeLists.txtandtools/*/CMakeLists.txt. - Tests are intentionally white-box.
tests/CMakeLists.txtdefinesCORTEXT_TESTING=1, enabling helpers such asDebugHydrateForTest()ininclude/cortext/cortext.hpp.
No project skills found. Add skills to any of: .claude/skills/, .agents/skills/, .cursor/skills/, or .github/skills/ with a SKILL.md index file.
Profile not yet configured. Run
/gsd-profile-userto generate your developer profile. This section is managed bygenerate-claude-profile-- do not edit manually.
src/+include/: C++ core engine and public headers.tests/: Catch2 unit/integration tests (cortext_teststarget).examples/: runnable demos and analysis tooling (e.g.,examples/topical_chat_analysis).scripts/+tools/: experiment harnesses and generators (e.g.,scripts/run_memory_harness.py).docs/paper/sections/: manuscript source;docs/paper/_manuscript/is generated output.models/+third_party/: runtime assets (AIST, sqlite extensions, optional audio/runtime support).
- Configure/build:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug cmake --build build -j - Run tests:
ctest --test-dir build -R cortext_tests --output-on-failure
- Run topical chat analysis:
./build/examples/topical_chat_analysis/cortext_topical_chat_analysis --help
- Long-horizon harness example:
python scripts/run_memory_harness.py --max-conversations 2 --max-turns 360 --max-total 720 --no-multi
- Match local style in the file you touch (e.g., 2-space indentation, braces on new lines).
- Prefer existing naming patterns (PascalCase helpers, lower_snake locals) over introducing new conventions.
- Pre-release rule: breaking changes are fine, but do not leave unused/deprecated code behind.
- Add tests when changing algorithms or thresholds (interrupts, retrieval, consolidation).
- Use
examples/topical_chat_analysisfor end-to-end validation before large sweeps. - Keep outputs deterministic where possible; prefer fixed seeds when adding new metrics.
- Run long sweeps with
nohup(or equivalent) so they survive terminal/session disconnects. - Avoid
sleepto poll background commands; for long runs, watch output withtail -for checknohup.out/snapshot logs directly.
- Always update
docs/paper/sections/when algorithms change or experiment results are produced. - Regenerate the manuscript:
QUARTO_DISABLE_GIT=1 QUARTO_DISABLE_GITHUB=1 quarto render docs/paper
docs/paper/_manuscript/index.mdis the generated source of truth for the compiled paper.
- Commit messages are short, imperative, and descriptive (e.g., “Add interrupt precision/recall metrics”).
- PRs should include a brief summary, test commands run, and any updated experiment logs/paths.
- Behavior should derive from the three knobs (F/S/T) wherever possible.
- Consolidation is explicit, shallow, and embedding/graph-only; embeddings use the configured text encoder.
- Do not modify the public API surface (public headers in
include/, C API) without explicit approval.
- For new realtime orchestration work, treat
docs/rules/sml.rules.mdas binding. - Follow the RTC actor model and no-queue invariant. Do not use
sml::process_queue,sml::defer_queue, mailboxes, or post-for-later mechanisms. - Keep dispatch run-to-completion, deterministic, single-writer per actor, allocation-free during dispatch, and provably bounded.
- Do not call an actor's own
process_eventfrom guards, actions, or entry/exit handlers. - Model internal multi-step flows with
sml::completion<TEvent>, anonymous transitions, and/or entry actions. Keep anonymous/completion chains acyclic or statically bounded. - Treat transient handoff data as event payload, not context. Use explicit events and
sml::completion<TEvent>for per-dispatch or cross-state handoff data; reserve context for persistent actor-owned runtime state only. - Do not use completion transitions or anonymous transitions as data-plane iteration loops. Bulk numeric/data iteration belongs in bounded allocation-free kernels inside a single transition phase.
- Keep guards pure predicates of
(event, context)with no side effects. - Keep actions bounded, non-blocking, and allocation-free during dispatch.
- Do not put runtime branching (
if,else,switch,?:) in actions or in functions called from actions. Express runtime control flow with explicit guards, choice states, and transitions. - Do not emulate branching with loop constructs, handler tables, or runtime-indexed dispatch arrays.
- Inject time through event payloads; do not read wall-clock time in guards or actions.
- Keep publicly exposed events small and immutable. Internal-only synchronous handoff events may carry mutable references/pointers only within the same RTC chain and must never escape via public APIs.
- Use constructor dependency injection with a component-local context aggregate.
- Use
visit_current_statesoris(...)for state inspection. - Define explicit behavior for unexpected events and use
sml::unexpected_eventrather than silent drops. - Keep tracing deterministic, bounded, and allocation-free.
- Reproduce reported SML bugs with a failing unit test before fixing them.