Tech Stack & Deployment
Full spec: docs/os/synedrix-os-tech-stack-v1.9.md. This page summarises the platform stack, the three deployment modes (including the hosting variant split from §1.1), and the MCP/A2A interoperability boundary — the infrastructure-facing half of the architecture (the execution-model half is Architecture → Agent Runtime & Orchestration).
Platform components (12)
Every component below is a deliberate, non-overlapping-responsibility choice — Principle 11 (open by default, sovereign by design) is architectural, not incidental. Hookdeck (the inbound Event Gateway) is the one exception: it is proprietary, closed-source, and managed-cloud-only with no self-hosted deployment documented. It is required in all three deployment modes despite being the sole component in the stack that cannot satisfy Principle 11 as written (see the Mode 3 open item below).
| Platform | Layer | Role |
|---|---|---|
| n8n | 3 Orchestration | Workflow kernel, sequencing, agent handoffs, approvals, retries — orchestration only |
| LangGraph (+ LangChain) | 4 Agent Runtime | Stateful/cyclic/multi-agent reasoning; invoked by n8n as a governed step |
| Hookdeck | 8 Event (ingress) | Proprietary inbound event validation, buffering, replay — managed cloud only (no self-hosting) |
| Hookdeck Outpost | 8 Event (egress) | Apache 2.0; durable outbound notification delivery — self-hostable |
| Redis | 7 Memory | Hot state, pub/sub, idempotency keys, turn-state cache |
| Supabase PG17 | 7 Memory | Canonical relational truth, entities, workflow state, audit trails |
| QuestDB | 7 Memory | High-volume time-series metrics, events, trends |
| Neo4j | 7 Memory | Workflow/outcome lineage, entity relationship graphs (Community Edition, GPL 3.0) |
| Qdrant | 7 Memory | Vector retrieval, semantic recall, RAG, pattern matching — the single vector substrate |
| Langfuse | 10 Observability | Prompt versioning, LLM traces, token/cost, evaluations |
| PostHog | 10 Observability | Behavioural analytics, feature flags, A/B experiments |
| Grafana LGTM Stack | 10 Observability | Grafana, Alloy, Mimir, Loki, Tempo — dashboards, alerts, SLOs, logs, traces |
Three deployment modes
Full spec: docs/os/synedrix-os-deployment-model-spec-v0.4.md. All three modes run the same platform code, the same agent architecture, and the same governance model. The deployment mode affects only one dimension: where model inference occurs and whether external API calls are permitted.
§1.1 Hosting variants: who operates the data plane
ADR-OS-008 splits the platform into a pooled control plane and a per-tenant data plane (n8n, LangGraph, Redis, Qdrant, Neo4j, QuestDB and the observability stack), and admits two hosting variants:
| Variant | Who operates the data plane | Available in |
|---|---|---|
| Self-operated | The customer, on the customer’s own infrastructure | Modes 1, 2 and 3 |
| Managed | Synedrix, on the customer’s behalf, in a tenant-dedicated deployment | Modes 1 and 2 |
- A managed data plane is never pooled: it serves one tenant in every mode.
- The mode keeps its meaning — a managed Mode 1 or Mode 2 instance has the same model-inference and external-call rules as its self-operated counterpart.
- The business instance declares which variant it uses; its field name and schema belong to the Tenancy Spec that ADR-OS-008 calls for.
- The managed variant is a convenience, not a capability gate. Every capability it provides is available self-operated from the same canonical implementation.
- Mode 3 is self-operated only. A Synedrix-operated data plane would give a third party operational access to an environment whose definition forbids third-party handling beyond the single inbound Hookdeck path.
Mode 1 — Cloud-connected
All Synedrix OS platform components run self-hosted on the customer’s own infrastructure (or managed on their behalf). Model inference uses external cloud APIs. No business data is stored on external infrastructure — data flows to model APIs for inference only.
What runs locally: 11 self-hosted platform components (n8n, Hookdeck Outpost, Redis, Supabase, QuestDB, Neo4j, Qdrant, Langfuse, PostHog, Grafana + Prometheus). Hookdeck (the inbound Event Gateway) is the sole component that runs as managed cloud — it is the one managed external service required in Mode 1.
What uses external services: Model inference API calls (OpenAI, Anthropic, Google, or others). Langfuse and PostHog cloud versions may be used as alternatives to self-hosted.
Suitable for: organisations comfortable with standard cloud data processing agreements; development and staging environments; organisations without strict data residency requirements.
Mode 2 — Self-hosted hybrid
All Synedrix OS platform components run self-hosted-hybrid. Model inference is split at the agent level: some agents use external cloud APIs, others use local models via Ollama or vLLM. The split is declared per agent in the runtime policy.
What uses external services: Only the agents explicitly configured with model_type: cloud in their runtime policy. All other agents are fully local.
Suitable for: organisations that require local inference for sensitive, high-risk, or regulated workflows while accepting cloud APIs for lower-sensitivity tasks; organisations managing infrastructure cost by using local models for high-volume low-sensitivity tasks and cloud models for complex reasoning.
Configuration requirement: Each agent runtime policy must declare model_type: cloud | local. Agents without a declared model_type inherit from the business instance default.
Mode 3 — Air-gapped (fully local)
All Synedrix OS platform components run self-hosted, with one accepted exception: the inbound Hookdeck Event Gateway. All model inference uses local models. No outbound connection or external API call of any kind originates from the customer’s infrastructure, and no business data leaves it. Inbound event payloads from external sources are held in transit by Hookdeck before delivery; this is the only third-party custody of data in Mode 3.
What uses external services: Exactly one — the inbound Hookdeck Event Gateway (Layer 8), a proprietary managed cloud service with no self-hosted option. ADR-OS-013 considered replacing it with an open self-hosted Event Receiver and rejected that, accepting the exception instead. No other external service is permitted.
External network requirements: Outbound: none — network egress rules should be configured to block all outbound traffic from platform components. Inbound: delivery from the Hookdeck Event Gateway to the Layer 8 ingress destination, and nothing else. This is a deliberate opening in the perimeter and must be disclosed to, and accepted by, the customer before the instance is declared air-gapped.
Suitable for: regulated industries (Finance, Healthcare, Legal, Government, Insurance); classified or defence environments; organisations with strong data sovereignty requirements — provided their policy tolerates the single inbound Hookdeck path above.
Not suitable for: environments that forbid any third-party transit or custody of inbound payloads, or any inbound connection from an external service. Do not describe Mode 3 as “zero external connections” or “no data ever leaves or enters the perimeter” in sales, documentation or content.
Platform invariant: A business instance declared as deployment_mode: air-gapped cannot contain any agent runtime policy with a cloud model URI in primary_model or fallback_model. This is a validation error enforced at business instance configuration time.
Enforcement invariant
A business instance declared deployment_mode: air-gapped must not contain cloud model URIs (OpenAI/Anthropic/Google endpoints) anywhere in its agent runtime policies — this is enforced as a validation error at business instance configuration time. Model version tags must be pinned in production deployments to prevent silent changes on server update. Air-gapped deployments must plan model and component updates through internal distribution — no runtime internet access should be assumed or required.
Mode 3 air-gapped: the accepted Hookdeck exception
Mode 3 is now defined as “air-gapped with one declared external dependency”: the inbound Hookdeck path. No outbound connections are permitted; the inbound delivery from Hookdeck to the customer’s Layer 8 ingress destination is the sole external dependency. This is a deliberate opening in the perimeter that must be disclosed to, and accepted by, the customer before declaring an instance air-gapped.
The realistic alternatives that were considered and rejected:
| Option | Why it was not chosen |
|---|---|
| Restrict Hookdeck to Modes 1 and 2 | Mode 3 would need a Layer 8 ingress substitute; “required in all modes” would need correction. |
| Define a Mode 3 ingress substitute (Synedrix Event Receiver) | Build cost was not offset by the benefit; the ADR recommendation was not adopted. |
| Pursue a Hookdeck Enterprise arrangement | Custom-priced and undocumented publicly; remains available as a commercial convenience but is not a requirement. |
Hookdeck platform reference: Mode 3 decision records the settled outcome. “Hookdeck, all modes” is a settled specification, with Mode 3 carrying one declared external dependency.
Local model inference (Modes 2 & 3 only)
Ollama and vLLM are the canonical local inference layers, active only in Modes 2 and 3. They expose an OpenAI-compatible API so that Langfuse tracing, evaluation, and cost tracking integrations work without modification. Model selection is business-instance configuration — the OS defines the integration interface, not the model.
- Ollama (MIT) — primary local inference; OpenAI-compatible endpoint at
localhost:11434/v1; auto-detects NVIDIA (CUDA) and AMD (ROCm) GPUs; falls back to CPU. Recommended for development and standard workloads. - vLLM (Apache 2.0) — high-throughput production inference; OpenAI-compatible endpoint at
localhost:8000/v1; requires NVIDIA CUDA GPU (recommended A100/H100 or equivalent). AMD ROCm experimental.
In air-gapped deployments, Langfuse runs fully locally. Token cost attribution is not applicable for local inference; set compute_cost_tracking: true in the agent runtime policy to track GPU compute time instead. Langfuse traces local model inference using the OpenAI SDK integration pointed at the local endpoint — only the OPENAI_BASE_URL environment variable needs to point to the Ollama or vLLM endpoint.
Outpost air-gapped destination constraints
Hookdeck Outpost (Apache 2.0) can be deployed air-gapped with all its dependencies (Redis, PostgreSQL, a message queue) in the same cluster. Anonymous telemetry must be disabled via DISABLE_TELEMETRY=true. However, only the webhook, RabbitMQ and Kafka destination types can terminate inside the customer’s own network. AWS SQS/S3/Kinesis, GCP Pub/Sub, Azure Service Bus and the Hookdeck Event Gateway destination are by definition external services — that is a constraint on which destinations a Mode 3 business instance may configure, not on whether Outpost can be deployed air-gapped.
Responsibility split (who owns what)
Full matrix: docs/os/synedrix-os-responsibility-matrix-v0.7.md. A few rows matter most for infrastructure decisions:
- Deployment mode declaration: OS defines the three modes and their validation rules; owns the air-gapped enforcement invariant. Domain packs must declare compatibility and must not declare cloud model URIs in air-gapped instances. Business instances declare the actual mode and cannot downgrade what’s declared at the OS level.
- Local model selection: OS defines the Ollama/vLLM integration interface only (does not own model selection); business instances select and pin actual model versions and own the inference infrastructure (hardware, GPU, storage).
- External model API keys: never owned or stored by OS or domain packs — always business-instance-owned environment secrets, never committed to source control or stored in canonical memory.
- Data plane hosting variant declaration: OS defines the allowed variants (self-operated, managed) and the rule that Mode 3 is self-operated. Business instances declare which variant they use.
- Data plane isolation: OS owns the rule that a data plane is never pooled across tenants, whichever party operates it.
- Domain-pack version pinning: OS owns the append-only registry mechanism; domain packs publish versions without affecting running instances; business instances own the pin value.
- Capability Module entitlement: OS owns the entitlement-flag mechanism (inactive by default); domain packs build and declare
depends_onfor each module; business instances own the licence/enablement per instance. - Business Instance Extension (BIE): OS owns the registration schema and governs every BIE through Policy Guard and Audit & Lineage; domain packs declare permitted
extension_points; business instances author the BIE itself, which is non-reusable across instances.
Memory ownership boundaries
| Concern | Owner |
|---|---|
| Memory substrate platform (Neo4j, Qdrant, Redis, Supabase, QuestDB) | OS |
| Memory tier model (eight tiers, meaning, write-authoritative store per tier) | OS |
| Memory lifecycle mechanism (formation, consolidation, reflection, promotion, recall, decay, erasure) | OS |
| Memory promotion thresholds (the mechanism) | OS (values: business instance) |
| Retention classes and erasure SLAs (the classes, tombstone semantics) | OS (values: business instance) |
Per-agent memory scope (memory_profile) | OS schema + enforcement; domain packs declare; business instances may narrow |
| Durable memory write authority | os-agt-010 (Memory Curator) only; every other agent may only propose |
n8n ↔ LangGraph runtime boundary
Per Orchestration & Runtime Strategy and ADR-OS-001, complex agent reasoning runs in the LangGraph Agent Runtime (Layer 4), invoked by n8n (Layer 3) as a governed step. This is an internal boundary — it is not cross-system A2A federation — but it deliberately reuses the same transport and governance primitives:
- Transport: HTTP for internal service calls; MCP when the runtime is consumed as a tool/context server; A2A only when the runtime is delegated to or from a separate agent system at the platform edge. LangGraph runs as a Python service (
langgraph-agent) with its governed HTTP invocation endpoint at port8765on thesynedrix_coreDocker network in the self-hosted stack (langgraph-compose.ymlinsynedrix-os-stack-self-hosted). - Lineage: the invocation carries
correlation_id,causation_id, the resolvedactive_tool_set, anddeployment_mode; LangGraph returns the canonical Outcome Envelope and emitsos.outcome.*events. No lineage or observability gap is permitted at the boundary. The executor rejects any tool call outside the resolved active set. - Governance: Policy Guard (
os-agt-002) and HITL Gateway (os-agt-004) remain reachable from inside LangGraph; the same “no protocol bypass of governance” principle applies. Internal invocation is governed as a native tool call, not as an untrusted external A2A partner.
Simple acyclic agents may still run as n8n AI Agent nodes; only stateful, cyclic, or multi-agent patterns (iterative, consensus, reflect-and-revise, hierarchical) require the LangGraph runtime.
Interoperability: MCP and A2A
Full strategy: docs/os/synedrix-os-interoperability-protocol-strategy-v0.3.md.
Protocol roles
| Protocol | Primary role | Scope in Synedrix OS |
|---|---|---|
| MCP (Model Context Protocol) | Standardized access to tools, resources, prompts, and context | Agent-to-tool, agent-to-resource, copilot-to-system integration at the Tool Abstraction layer boundary |
| A2A (Agent2Agent) | Standardised communication between autonomous agents and agent systems | Cross-system agent delegation, partner-agent interoperability, federated collaboration at the platform edge |
MCP and A2A are interoperability standards, not replacements for internal orchestration, governance, memory, or observability. Both are governed identically to native tools and workflows: no MCP tool call or A2A task exchange may bypass Policy Guard, HITL reachability, or observability. This is one of the hard invariants checked by /check-invariants.
MCP: preferred for agent-to-tool and agent-to-context integration
MCP is an open protocol for connecting AI applications to external systems through a structured client-server model based on JSON-RPC. Synedrix OS uses MCP at the tool abstraction boundary, not at the orchestration core:
- Expose selected internal services as MCP servers.
- Publish safe read-only resources first; introduce write-capable tools only when approval and permission semantics are clear.
- Route MCP-exposed tool execution through the same governance and observability controls as native tool calls.
- Trace MCP-backed LLM activity through Langfuse and platform observability.
- In Mode 3, all MCP-connected tools must be locally accessible — no external network dependency is permitted.
First candidates for MCP exposure: knowledge base and architecture documentation resources; schema discovery for canonical data models; read-only analytics and reporting tools; operator assistant queries; selected domain-pack retrieval resources.
A2A: preferred for cross-system agent interoperability
A2A enables secure cross-system task exchange. Synedrix OS uses A2A at the platform edge, not as the internal coordination mechanism:
- Publish selected Synedrix agents or workflows as A2A-compatible endpoints.
- Consume external A2A agents as bounded collaborators, not trusted internal peers by default.
- Treat every external A2A interaction as policy-governed and auditable.
- Preserve correlation IDs and workflow lineage across A2A boundaries.
- A2A-originated tasks must still pass through Synedrix OS governance and approval controls before side effects.
- In Mode 3, all A2A-connected agents must be locally accessible.
Security and governance principles
- No protocol bypass of governance.
- Least privilege by default — implemented per agent in the
mcp_tool_policyanda2a_tool_policyblocks of the Agent Runtime Policy Spec (three-layer model: capability ceiling → runtime restriction → instance override). - Read-first exposure model.
- Observable by default.
- Versioned contracts.
Adoption roadmap
- Phase 1 — Standards-aware internal architecture: define stance, identify MCP exposure candidates, define external-agent trust model.
- Phase 2 — Controlled MCP enablement: publish a small number of internal resources, add tracing/permissions/audit hooks.
- Phase 3 — Bounded A2A interoperability: expose selected workflows, integrate one external agent system in a low-risk flow.
- Phase 4 — Federated protocol ecosystem: expand across domain packs, introduce protocol catalogs, trust tiers, governance templates.
Layered Truth Summary
Synedrix OS separates different kinds of truth across the stack — the substrate axis (which store holds which kind of truth) is orthogonal to the tier axis (what kind of memory a record is) defined in the Memory Fabric Spec. Neither may be inferred from the other.
| Truth class | Platform | Notes |
|---|---|---|
| Canonical relational | Supabase PG17 | Business entities, workflow state, approvals, audit trails. Write-authoritative for every audit-bearing tier |
| Graph / lineage | Neo4j | Workflow and outcome lineage, agent influence networks, cross-session entity graphs |
| Temporal | QuestDB | High-volume time-series records, materialised aggregations, event windows |
| Semantic / similarity | Qdrant | Vector representations for similarity search and case recall. The single vector substrate — no second vector store enters Layer 7 |
| Ephemeral / hot state | Redis | Operational state, pub/sub, dedup windows, idempotency keys. Not a source of truth |
| LLM eval / observability | Langfuse | Agent traces, prompt versions, token and cost attribution |
Non-goals
The three deployment modes are the only OS-level deployment dimensions. Domain packs may own infrastructure at Layers 11 and 12 (e.g. the Voice pack’s session transport). MCP does not replace internal orchestration or native adapters. A2A does not replace internal coordination or direct tool invocation. Standards-awareness does not imply auto-trust for external protocols.