Nous - LLM Inference and Reasoning Engine
This document describes the technical architecture of the Nous domain: library organization, module topology, design patterns, data flows, and integration architecture.
Nous is the AI infrastructure backbone of the Oshun monorepo. It answers the question: how do you run large language models, vision models, and audio models on real hardware, at production throughput, without paying per-token cloud API costs or sending user data off-premises? The answer is a carefully layered set of TypeScript libraries that abstract hardware specifics away from every caller. An Iris assistant feature, a Sophia research synthesis pipeline, or a Maya NPC dialogue system all reach Nous through the same interfaces — and Nous figures out whether to run on a GPU, an Apple Neural Engine, or a plain CPU thread pool.
Because Nous ships no services or applications of its own, there is no Nous
deployment to operate separately. Domains import @nous/* packages directly and
the inference work happens wherever those domains run.
1. Domain Overview#
Nous is a library-only domain — it ships no applications, no standalone
services, and no APIs exposed over the network. It is purely a set of TypeScript
libraries consumed by other domains and applications in the Oshun monorepo.
libs/nous/ holds twenty package directories; nineteen contain implemented
source and one (@nous/platform) is a config-only scaffold (no src/).
What Nous provides:
- A hardware-abstracted ONNX inference runtime, session manager, and model
registry (
@nous/core) - High-throughput inference primitives — batching, KV cache, speculative
decoding, multi-GPU parallelism, multi-LoRA serving (
@nous/core) - An embedding pipeline with multi-modal and multi-provider support, plus
similarity search and reranking (
@nous/core) - Provider-registry-based LLM completion APIs, prompt templates, an agent
runtime, and a document-ingestion/RAG surface (
@nous/llm) - Image and video computer vision — detection, segmentation, OCR, scene
understanding, diffusion generation (
@nous/vision) - Speech, music, and audio analysis (
@nous/audio) - A model-training surface — distributed training, fine-tuning, preference
alignment, diffusion training (
@nous/training) - Safety classifiers, output enforcement, interpretability, formal verification,
and V2 Model Card hosting (
@nous/safety) - Controllable generative-media packages — image/video control, video object removal, video-to-audio, advanced speech, relighting, portrait animation, joint A/V generation
- Cooperative-intelligence primitives for the Concordia domain — preference inference, agreement search, bargaining sessions, sealed memory
What Nous does not provide:
- Network APIs (no REST, WebSocket, or gRPC server)
- Persistent storage (consuming applications manage storage)
- Authentication or authorization
- User-facing applications
2. Design Principles#
These six principles shape every architectural decision in Nous. They explain why the domain is structured the way it is, and what invariants consuming domains can depend on.
- Hardware Abstraction — All inference runs behind a unified provider interface. The calling application never writes CUDA-specific or Metal-specific code.
- Optional Runtime —
onnxruntime-nodeis an optional dependency. Nous can be imported without installing the GPU runtime (useful in browser/edge environments using the WebGPU provider). - Zero Cloud Lock-In — Every capability in Nous runs locally. No API keys, no external services, no internet required.
- Progressive Enhancement — Applications start with CPU inference and add GPU acceleration, batching, and parallelism incrementally as hardware allows.
- Composable Primitives — Each module (
dynamic-batching,kv-cache,flash-attention, etc.) is independently importable. Applications compose the primitives they need, not a monolithic inference stack. - ESM-First — All three libraries are built as ESM modules for compatibility with modern runtimes (Node.js 22+, browsers via bundlers, Deno, Bun).
3. Technology Stack#
The table below summarises the tooling choices for every @nous/* package.
Nothing here is domain-specific configuration — these defaults apply uniformly
across all nineteen implemented packages.
| Layer | Technology |
|---|---|
| Language | TypeScript 5+ (strict mode) |
| Module format | ESM ("type": "module" in every package) |
| Build | @nx/esbuild:esbuild (format: ["esm"], bundle: false) |
| Package shape | Source-only — main/types point at ./src/index.ts |
| Testing | Vitest (@nx/vite:test) |
| Type checking | Explicit typecheck target via tsc --noEmit -p tsconfig.lib.json |
| Schema validation | zod (Concordia packages and some V2 contracts) |
| Inference backend | ONNX Runtime (optional dependency: onnxruntime-node ^1.20.0) |
Source-Only Packages and esbuild#
Every libs/nous/*/package.json sets "main" and "types" to ./src/index.ts
— packages are consumed directly as TypeScript source through the workspace. The
Nx build target uses @nx/esbuild:esbuild with format: ["esm"] and
bundle: false, producing unbundled ESM module files so consumers can
tree-shake. Each project.json also defines lint, test, and typecheck
targets.
4. Library Structure#
libs/nous/ contains twenty package directories. Every implemented package
keeps its modules flat under src/ (no nested subdirectories) — each module
is a single .ts file with a sibling *.spec.ts, and src/index.ts is a
barrel that re-exports every module.
libs/nous/
├── core/ # @nous/core — 84 source modules (flat src/)
├── llm/ # @nous/llm — 78 source modules
├── vision/ # @nous/vision — 103 source modules
├── audio/ # @nous/audio — 81 source modules
├── training/ # @nous/training — 137 source modules
├── safety/ # @nous/safety — 64 source modules
├── image-control/ # @nous/image-control — 50 source modules
├── video-control/ # @nous/video-control — 43 source modules
├── video-removal/ # @nous/video-removal — 48 source modules
├── video-to-audio/ # @nous/video-to-audio — 21 source modules
├── advanced-speech/ # @nous/advanced-speech — 31 source modules
├── generative-relighting/ # @nous/generative-relighting — 23 source modules
├── portrait-animation/ # @nous/portrait-animation — 23 source modules
├── joint-av-generation/ # @nous/joint-av-generation — 34 source modules
├── agreement-search/ # @nous/agreement-search — 22 source modules
├── preference-inference/ # @nous/preference-inference — 24 source modules
├── cooperative-bargaining/ # @nous/cooperative-bargaining — 2 source modules
├── concordia-sealed-memory/ # @nous/concordia-sealed-memory — 5 source modules
└── platform/ # @nous/platform — config-only scaffold (no src/)
@nous/core Module Inventory#
@nous/core is the foundational package. Its 84 modules fall into five
functional groups, all residing flat in core/src/:
Runtime and session management — the entry types and runtime (types.ts,
runtime-loader.ts, session-manager.ts, inference-engine.ts,
model-loader.ts).
Execution providers — one module per hardware backend (cpu-, cuda-,
rocm-, metal-, webgpu-, vulkan-, dml-, npu-execution-provider.ts)
plus the shared execution-providers.ts registry.
Inference primitives — throughput and memory optimization techniques:
dynamic-batching, continuous-batching, llm-serving,
speculative-decoding, kv-cache, paged-attention, flash-attention,
tensor-parallelism, pipeline-parallelism, model-sharding,
moe-parallelism, prefix-caching, radix-attention, prompt-caching,
multi-lora-serving, adapter-switching, context-extension.
Generation control — sampling and stopping: streaming-generation,
stop-sequences, logit-processors, temperature-sampling,
top-k-top-p-sampling, beam-search.
Graph optimization — compile-time improvements: graph-optimization,
memory-planning, operator-fusion, quantization.
Model management — the full lifecycle from discovery to eviction:
model-registry, model-versioning, model-metadata, model-discovery,
model-download, checksum-verification, model-conversion,
format-detection, model-caching, model-eviction, model-preloading,
warm-model-pool, model-benchmarking, model-profiling,
model-optimization-pipeline.
Format readers — direct file format support: safetensors, gguf, ggml,
pytorch-loading, tensorflow-loading, jax-loading, tensor.
Embedding and search pipeline — vector generation and retrieval:
embedding-generation, text-embeddings, image-embeddings,
audio-embeddings, multi-modal-embeddings, embedding-normalization,
dimensionality-reduction, batch-embedding, streaming-embedding,
embedding-caching, embedding-compression, binary-embeddings,
matryoshka-embeddings, similarity-search, approximate-nearest-neighbor,
exact-nearest-neighbor, distance-metrics, hybrid-search, reranking,
cross-encoder-reranking.
See DOMAINS/nous/specifications.md §10–§19 for the @nous/llm,
@nous/vision, @nous/audio, @nous/training, @nous/safety,
generative-media, and Concordia module groups.
5. Module Topology#
The diagram below shows how the packages depend on each other. @nous/core is
the foundation: it provides the inference engine, providers, and embedding
pipeline that all higher-level packages build on. @nous/llm, @nous/vision,
@nous/audio, and @nous/training each sit one layer above core, composing its
primitives for their respective domains. @nous/safety is a cross-cutting layer
that can consume any package. The generative-media and Concordia packages sit at
the edges — they wrap specific capabilities without creating circular
dependencies.
@nous/core
(84 source modules)
┌──────────────────┼──────────────────┐
| | |
Execution Inference Model
Providers Pipeline Management
| | |
cpu, cuda, dynamic-batching, model-registry,
rocm, metal, continuous-batching, model-versioning,
webgpu, vulkan, speculative-decoding, model-download,
dml, npu llm-serving, checksum-verification,
(8 modules + kv-cache, model-conversion,
12 known paged-attention, format-detection,
provider flash-attention, safetensors, gguf,
names) | ggml, pytorch, …
Graph |
Optimization Parallelism / Caching / Adapters
| |
memory-planning, tensor-parallelism,
operator-fusion, pipeline-parallelism,
quantization model-sharding, moe-parallelism,
prefix-caching, radix-attention,
multi-lora-serving, …
|
┌──────────────┼───────────────┬─────────────┐
| | | |
@nous/llm @nous/vision @nous/audio @nous/training
(78 modules) (103 modules) (81 modules) (137 modules)
| | | |
completion, detection, ASR, TTS, distributed
agents, segmentation, music, training,
prompts, OCR, scene, audio fine-tuning,
reasoning, diffusion, analysis preference
RAG, NLP video alignment
@nous/safety (64 modules)
classifiers, output enforcement,
interpretability, formal verification,
V2 Model Card hosting
Generative-media packages Concordia packages
image-control, video-control, preference-inference,
video-removal, video-to-audio, agreement-search,
advanced-speech, cooperative-bargaining,
generative-relighting, concordia-sealed-memory
portrait-animation,
joint-av-generation
6. nous-core Architecture#
@nous/core implements two interlocking concerns: how a session is acquired
and reused (the session manager), and how hardware is selected (provider
resolution). Understanding these two flows is the key to understanding how all
higher-level Nous packages work.
Inference Session Lifecycle#
The OnnxSessionManager maintains a reference-counted cache of live ONNX
sessions. Each entry is keyed by a fingerprint derived from the model source,
the resolved provider list, and the session options. When two parts of the
application ask for the same model and configuration, they share a single
underlying session rather than loading the model twice.
Application
│
│ sessionManager.acquire({ model, preferredProviders, ... })
▼
┌──────────────────────────────────────────┐
│ OnnxSessionManager │
│ │
│ Reference-counted session cache │
│ (keyed by model fingerprint + providers)│
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Session │ │ Session │ │ ... │ │
│ │ refs: 2 │ │ refs: 0 │ │ │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │
│ On acquire(): │
│ 1. resolveExecutionProviders() │
│ 2. Build cache key; hit → refcount++ │
│ 3. Miss → create (dedup in-flight │
│ creations); evict LRU zero-ref │
│ entry if cache is full │
│ 4. CPU fallback if primary fails │
└──────────────────────────────────────────┘
│
│ ManagedOnnxSession { session, key, release() }
▼
Application runs inference, then release()
│
│ (decrements refcount; zero-ref entries
│ stay cached until LRU eviction)
▼
closeSession(key) releases a zero-ref entry
Provider Resolution Chain#
Before a session can be created, Nous must decide which hardware backend to use.
The resolver walks the caller's preferred provider list in order, testing each
against the detected hardware environment, and always appends a cpu fallback
so the chain can never be exhausted without producing a working session.
Preferred providers: ['cuda', 'metal', 'cpu']
|
v
Is provider available on this hardware?
|
Yes ──────────┼──────────── No
| |
Use this provider Try next in list
| |
OnnxRuntime (fallback loop)
.create() |
| Exhausted all →
Session throw error
7. nous-llm Architecture#
@nous/llm adds two major abstractions on top of @nous/core: a
provider-registry pattern for LLM completions (so the calling code never
hard-codes a backend), and an agent runtime for orchestrating multi-step
reasoning tasks.
LLM Completion Flow#
The completion layer is provider-registry based: callers register
ChatCompletionProvider / CompletionProvider implementations on a
ChatCompletionAPI / CompletionAPI instance, then dispatch a request. An
ONNX-backed provider can compose @nous/core primitives internally — the caller
is shielded from that complexity.
caller: chatCompletionAPI.complete({ messages, providerId?, ... })
│
v
┌──────────────────────┐
│ ChatCompletionAPI │
│ │
│ 1. Select provider │
│ (providerId or │
│ default) │
│ 2. Try provider; │
│ fall back to │
│ fallbackProviderIds │
│ 3. Record latency / │
│ usage stats │
└──────────┬───────────┘
│ provider.complete(request)
v
┌──────────────────────────────────────┐
│ ChatCompletionProvider implementation │
│ │
│ A provider is supplied by the │
│ consumer. An ONNX-backed provider │
│ may compose @nous/core primitives: │
│ OnnxSessionManager.acquire → │
│ DynamicBatchScheduler → session.run →│
│ logit processors / stop sequences / │
│ token sampling. │
└──────────┬───────────────────────────┘
│
v
ChatCompletionResponse { choices, usage, latencyMs }
Agent Task Execution Flow#
The agent runtime follows a plan-then-execute model. The planning phase (optional, enabled per agent) translates a high-level goal into an ordered list of concrete steps with a confidence score before any tool is called. The execution loop then steps through those tasks, using memory recall and tool selection to resolve each one.
submit(agentId, task)
│
v
┌─────────────┐
│ Task Queue │ (priority-ordered)
└──────┬──────┘
│
v
┌─────────────────────────┐
│ Planning Module │
│ (if enabled) │
│ - summarize goal │
│ - decompose to steps │
│ - estimate confidence │
└──────────┬──────────────┘
│
v
┌──────────────────────────┐
│ Execution Loop │
│ │
│ for each step: │
│ 1. Recall memory │
│ 2. Generate action │
│ 3. Select tool │
│ 4. Execute tool │
│ 5. Store result │
│ 6. Update state │
│ │
│ On error: │
│ - retry with backtrack│
│ - emit failure event │
└──────────┬───────────────┘
│
v
TaskResult { state, output, steps }
8. nous-vision Architecture#
@nous/vision builds on the same @nous/core session infrastructure as the LLM
stack, but adds vision-specific pre- and post-processing steps: image buffers
are resized, normalised, and tensor-encoded before inference, and raw model
outputs are decoded through non-maximum suppression, mask decoding, or text
parsers depending on the task.
Standard Vision Inference Pipeline#
Input Image (Buffer | ImageData)
│
v
┌──────────────────┐
│ Image Preprocess│
│ - resize │
│ - normalize │
│ - tensor encode │
└────────┬─────────┘
│
v
┌──────────────────┐
│ Model Session │ (@nous/core session-manager)
│ Provider: │
│ cuda/metal/cpu │
└────────┬─────────┘
│
v
┌──────────────────┐
│ ONNX Inference │
│ (run) │
└────────┬─────────┘
│
v
┌──────────────────┐
│ Output Decode │
│ - postprocess │
│ - NMS (detect.) │
│ - decode masks │
│ - parse text │
└────────┬─────────┘
│
v
Typed result object
Diffusion Pipeline#
Image generation with Stable Diffusion or Flux requires a multi-stage pipeline that interleaves a text encoder, a noise scheduler, many denoising iterations through a UNet, and a final VAE decode. Nous models each stage as a separate ONNX session so the hardware provider can be selected per stage.
text prompt
│
v
┌─────────────────────────────────┐
│ Diffusion Pipeline │
│ │
│ 1. Text Encoder (CLIP) │
│ prompt → conditioning │
│ │
│ 2. Scheduler Init │
│ noise schedule, timesteps │
│ │
│ 3. Denoising Loop (N steps) │
│ ┌────────────────────────┐ │
│ │ UNet forward pass │ │
│ │ (ONNX session) │ │
│ │ predict noise │ │
│ │ scheduler step │ │
│ └────────────────────────┘ │
│ │
│ 4. VAE Decode │
│ latent → pixel image │
│ │
└─────────────────────────────────┘
│
v
Buffer (PNG/JPEG)
9. Key Design Patterns#
The following patterns recur across all @nous/* packages. A new engineer
implementing a feature or a new provider should follow them to stay consistent
with the existing codebase.
Provider Interface Pattern#
Provider names are an open union (OnnxExecutionProviderName).
resolveExecutionProviders ranks a requested list against detected hardware and
always appends a cpu fallback; OnnxSessionManager.acquire takes a
NousOnnxSessionConfig and never needs backend-specific calling code. The
calling site looks like this regardless of whether the runtime machine has a
GPU:
// Calling code — no CUDA-specific logic
const managed = await sessionManager.acquire({
model: modelPathOrBytes,
preferredProviders: ['cuda', 'metal', 'cpu'], // priority list
allowProviderFallback: true,
});
const outputs = await managed.session.run(feeds);
await managed.release();
Optional Dependency Pattern#
runtime-loader.ts loads onnxruntime-node lazily and throws a typed error
when it is absent, so @nous/core compiles without the native runtime. This is
what enables @nous/core to be imported in browser or serverless targets that
cannot install a native binary — the error is only thrown at the moment
inference is actually attempted:
// libs/nous/core/src/runtime-loader.ts (shape)
export async function loadOnnxRuntime(
options: OnnxRuntimeLoaderOptions = {}
): Promise<OnnxRuntimeModule> {
const runtimePackage = options.runtimePackage ?? 'onnxruntime-node';
try {
const candidate = await (options.load ?? defaultRuntimeLoader)(
runtimePackage
);
return resolveOnnxRuntimeModule(candidate); // validates Tensor + InferenceSession
} catch (error) {
if (isMissingModuleError(error, runtimePackage)) {
throw new OnnxRuntimeNotAvailableError(runtimePackage, error);
}
throw error;
}
}
Composable Pipeline Pattern#
Rather than a single monolithic inference class, consumers assemble a pipeline from the specific primitives they need. A high-throughput serving setup might combine a dynamic batch scheduler, a KV cache manager, and tensor parallelism; a lightweight edge deployment might use only the session manager:
// Consumer assembles their own pipeline
const batcher = new DynamicBatchScheduler(engine, {
maxBatchSize: 16,
maxQueueDelayMs: 8,
});
const kvCache = new KvCacheManager({
maxTotalBytesReserved: 512 * 1024 * 1024,
});
const cache = kvCache.allocate({
modelId: 'llama-3-8b',
layerCount: 32,
numHeads: 32,
headSize: 128,
});
Agent Event Sourcing Pattern#
The AgentArchitecture runtime (libs/nous/llm/src/agent-architecture.ts)
records typed AgentRuntimeEvents as agents and tasks transition through their
lifecycle states. The event log is queryable for replay, debugging, and
monitoring. Because every state change is recorded as an event (not mutated in
place), the full history of an agent run is always recoverable:
// Query the runtime event log
const events = agentRuntime.getEvents(100); // last 100 events
const stats = agentRuntime.getStats(); // AgentArchitectureStats
// Agent lifecycle: stopped | idle | running | paused | error
// Task lifecycle: queued | running | completed | failed | cancelled | timeout
10. Data Flow Diagrams#
Embedding Generation Flow#
Embeddings are the bridge between raw text or media and vector search. The
EmbeddingGenerator abstracts multiple providers (a local sentence-transformer,
an OpenAI embedding endpoint, a Cohere model) behind a single interface, routing
by modality and falling back across providers on failure.
Application
│ generate({ modelId, input: { content, modality: 'text' } })
▼
┌──────────────────────────────┐
│ EmbeddingGenerator │
│ │
│ 1. Select provider │
│ (by id / priority + │
│ supported modality) │
│ │
│ 2. Call provider.generate() │
│ fall back on failure │
│ │
│ 3. Truncate to │
│ outputDimensions │
│ 4. Record provider stats │
└──────────────┬───────────────┘
│
v
EmbeddingGenerationResult { vector, dimensions, ... }
RAG Pipeline Flow#
RAG (Retrieval-Augmented Generation) grounds an LLM response in specific documents by retrieving relevant passages and injecting them into the context window. The pipeline runs through five stages: embedding the query, searching the vector index, reranking candidates with a cross-encoder, building an injection context, and finally calling the LLM with that context attached.
Query: "What is the refund policy?"
│
v
┌────────────────────┐
│ Query Embedding │ (EmbeddingGenerator)
└────────┬───────────┘
│ vector
v
┌────────────────────┐
│ Vector Index │ (hybridSearch)
│ search(topK=5) │
└────────┬───────────┘
│ SearchResult[]
v
┌────────────────────┐
│ Reranker │ (cross-encoder)
└────────┬───────────┘
│ reranked SearchResult[]
v
┌────────────────────┐
│ Context Builder │
│ chunk[0..k] → │
│ injected context │
└────────┬───────────┘
│
v
┌────────────────────┐
│ LLM Completion │
│ (with RAG context)│
└────────┬───────────┘
│
v
Grounded response
11. Deployment Characteristics#
Runtime Environments#
Nous supports a wide range of deployment targets. The runtime environment determines which execution provider is selected; no code changes are needed between targets — only the hardware and the installed ONNX Runtime variant differ.
| Environment | Provider Used | Notes |
|---|---|---|
| NVIDIA GPU server | cuda |
Requires CUDA 12.x and onnxruntime-node |
| AMD GPU server | rocm |
Requires ROCm 5.6+ and onnxruntime-node |
| macOS (Apple Silicon) | metal |
Metal acceleration via onnxruntime-node |
| Windows desktop | dml |
DirectML via DirectX 12 |
| Browser (WebGPU) | webgpu |
Uses onnxruntime-web, not onnxruntime-node |
| Any CPU | cpu |
Universal fallback, no GPU drivers needed |
| Serverless/edge | cpu |
Use quantized models (INT8/INT4) for size |
WASM Considerations#
When bundling @nous/core for browser use (e.g., in a PWA), use webgpu or
cpu providers. The onnxruntime-web package includes WASM binaries. The
metal, cuda, and rocm providers are Node.js-only.
Memory Sizing Guidelines#
Model memory requirements grow with parameter count and numerical precision. The table below gives approximate VRAM floors for common configurations — the actual requirement depends on the KV cache allocation on top of these weights.
| Model Size | Min GPU VRAM | Recommended Config |
|---|---|---|
| 7B (FP16) | 14 GB | Single GPU, no parallelism needed |
| 7B (INT4) | 4 GB | Single GPU with quantization |
| 13B (INT8) | 13 GB | Single GPU or 2-GPU tensor parallelism |
| 70B (INT4) | 40 GB | Multi-GPU tensor parallelism (2× 24 GB or 4× 12 GB) |
Package Entry Points#
@nous/core (and every other @nous/* package) is a source-only workspace
package — package.json sets main and types to ./src/index.ts and
declares "type": "module". There is no exports map and no published dist/;
the Nx build target emits unbundled ESM to libs/nous/<pkg>/dist only when
explicitly run. Consumers resolve @nous/* through the tsconfig.base.json
path mapping "@nous/*": ["libs/nous/*/src/index.ts"]. The Concordia packages
(@nous/agreement-search, @nous/cooperative-bargaining,
@nous/preference-inference, @nous/concordia-sealed-memory) additionally
declare an explicit exports field pointing at ./src/index.ts.
12. Domain Dependencies#
External Dependencies#
The only external runtime dependency is onnxruntime-node, and even that is
optional. Nous deliberately avoids third-party service dependencies at the
library level — consuming applications wire in any external providers (such as
an OpenAI embedding endpoint) through the provider registration interfaces.
| Dependency | Type | Notes |
|---|---|---|
onnxruntime-node |
Optional | Core inference backend. Not required in browser environments using webgpu. |
Domains That Depend on Nous#
Each consuming domain uses Nous for a different purpose, which is why the boundary is clean: Nous knows nothing about Iris assistant UX, Sophia research workflows, or Maya world generation. It exposes primitives; the consuming domain decides what to do with them.
| Domain | Libraries Used | How Nous Is Consumed |
|---|---|---|
| Iris | @nous/core, @nous/llm |
Local LLM serving for privacy mode; embedding generation for knowledge base and memory |
| Sophia | @nous/llm |
LLM reasoning for research synthesis |
| Psyche | @nous/vision |
Facial emotion recognition and perception models |
| Maya | @nous/llm |
NPC dialogue generation and world content AI |
Cross-Domain Dependencies Within Nous#
Most @nous/* packages are self-contained — they bring only devDependencies
and depend on nothing outside the package at runtime. The two exceptions exist
for concrete architectural reasons:
@nous/safetydepends on@kalika/coreand@kalika/formal-verificationbecause formal safety verification requires the Kalika theorem-prover runtime. The safety invariant proofs are not a Nous concern to implement from scratch; they delegate to Kalika's proven core.- The three Concordia packages (
@nous/preference-inference,@nous/agreement-search,@nous/cooperative-bargaining) depend on@concordia/contractsbecause they implement the computational half of a bargaining session — the preference models and search kernels — while Concordia owns the type contracts that describe parties, cases, and outcomes. Nous cannot define those contracts without creating a circular dependency, so it consumes them from@concordia/contractsinstead.
@nous package |
Workspace dependency |
|---|---|
@nous/safety |
@kalika/core, @kalika/formal-verification |
@nous/preference-inference |
@concordia/contracts |
@nous/agreement-search |
@concordia/contracts |
@nous/cooperative-bargaining |
@concordia/contracts |
13. Concordia Cooperative-Intelligence Packages#
Four @nous/* packages provide reusable cooperative-intelligence primitives
consumed by the Concordia domain (DOMAINS/concordia). These packages sit at
the intersection of Nous and Concordia: Nous owns the algorithms (utility
model fitting, multi-objective optimisation, privacy primitives), while
Concordia owns the policy (legal boundaries, settlement authority, user
experience). The boundary exists precisely so that the algorithms can be tested,
versioned, and reused independently of any specific dispute or governance
domain.
Data that crosses the boundary: @concordia/contracts types for parties, cases,
and outcomes flow into Nous as inputs to the preference and search kernels.
Calibrated utility estimates and Pareto-frontier candidate agreements flow out
to Concordia as results. No settlement decisions, legal boundaries, or product
UX logic cross into Nous.
| Package | Architectural role |
|---|---|
@nous/preference-inference |
Pairwise preference elicitation and five calibrated utility-model estimators (Bradley-Terry, Thurstone-Mosteller, Plackett-Luce, Gaussian-process, neural ranker); calibration, fairness metrics, BATNA analysis |
@nous/agreement-search |
Search-kernel registry plus seven search kernels (Nash genetic, NSGA-II, MAP-Elites, MCTS/LATS, CP-SAT, Bayesian optimization, PSRO) and a coalition-stability search; candidate generation and clause mutators |
@nous/cooperative-bargaining |
Session-scoped bargaining substrate bridging @concordia/contracts and the search kernels (phase machine, stakeholder registry, budget) |
@nous/concordia-sealed-memory |
Privacy primitives — envelope-encrypted sealed-memory store, zero-retention routing/attestation, confidential-compute scoring |
These packages provide reusable preference/search/bargaining/privacy primitives only. Domain policy, legal boundaries, settlement authority, and user experience are owned by the Concordia domain and its peer domains (Themis, Kuanyin, Maat, Aje, and others).
Document Provenance#
This architecture document was written against the source under libs/nous/.
Package inventory and module counts come from ls libs/nous/ and the
src/index.ts barrels; the dependency table is read from each
libs/nous/*/package.json; build targets from each project.json. It describes
the AI-infrastructure module topology, the inference/LLM/vision/audio
architecture, execution providers, session/model/inference/embedding/search/
agent/document pipelines, deployment characteristics, and the cross-domain and
Concordia dependency structure.