Concordance is a distributed configuration service for the iGentAI platform. It provides strongly consistent key-value storage with real-time pub/sub notifications, built on embedded Raft consensus and SQLite. In musical terms, concordance means a state of agreement — this service ensures every node in the cluster agrees on the same configuration state. Single Bun binary. Zero npm dependencies. One port for HTTP, WebSocket, and Raft peer traffic.

What It Stores

CategoryNamespace PatternExample
User preferencestenant:{id}/user:{uid}/preferencesTheme, editor settings, notification prefs
Tenant settingstenant:{id}/settingsOrg-wide defaults, feature flags
Session metadatatenant:{id}/sessions/{sid}Active session state, context
Project definitionstenant:{id}/projects/{pid}Project config, agent assignments
Device registriestenant:{id}/user:{uid}/devices/{did}Push tokens, device capabilities
Encrypted credentialstenant:{id}/credentialsOAuth tokens, API keys (encrypted at rest)
Automation definitionstenant:{id}/automationsWorkflow blueprints, trigger rules
Skill configstenant:{id}/skillsSkill parameters, enabled/disabled state
Integration configstenant:{id}/integrationsSlack, GitHub, Linear connection settings
Audit logstenant:{id}/auditConfiguration change history

Key Properties

PropertyDetail
ConsistencyLinearizable writes via Raft consensus (reads from local FSM state)
DurabilitySQLite with PRAGMA synchronous=FULL for the Raft log
Real-timeWebSocket pub/sub pushes changes to subscribers within milliseconds
Multi-tenancyAll namespaces are tenant-scoped (tenant:{id}/...)
CAS supportCompare-and-swap writes prevent lost updates
TTL supportOptional expiresAt per entry for automatic expiration
VersioningMonotonically increasing version per key for conflict detection
SnapshotsFull-state snapshots via bun:sqlite serialize/deserialize

Architecture at a Glance

                        ┌─────────────────────────────────────────┐
                        │            Concordance Node              │
                        │                                         │
  Diminuendo ──HTTP────►│  Bun.serve()  (:4100)                   │
  (gateway)    PUT/GET  │  ┌────────────────────────────────────┐ │
               DELETE   │  │  HTTP Router                       │ │
                        │  │  /api/v1/kv, /batch, /changes      │ │
  Diminuendo ──WS──────►│  │  /api/v1/cluster/*                 │ │
  (gateway)    JSON-RPC │  ├────────────────────────────────────┤ │
                        │  │  WebSocket Handler (/stream)       │ │
  Podium ──────HTTP────►│  │  kv/get, kv/set, watch/subscribe   │ │
  (agents)     GET only │  ├────────────────────────────────────┤ │
                        │  │  Raft Peer Transport (/raft)       │ │
               ◄───WS──│──│  RequestVote, AppendEntries         │ │
  Other nodes           │  └─────────────┬──────────────────────┘ │
                        │                │                        │
                        │         ┌──────▼───────┐                │
                        │         │  RaftNode     │                │
                        │         │  (consensus)  │                │
                        │         └──────┬───────┘                │
                        │                │ onApply                 │
                        │         ┌──────▼───────┐                │
                        │         │  FSM          │                │
                        │         │  (state       │                │
                        │         │   machine)    │──► pub/sub     │
                        │         └──────┬───────┘    broadcast   │
                        │                │                        │
                        │     ┌──────────┴──────────┐             │
                        │     │                     │             │
                        │  ┌──▼───┐            ┌────▼──┐          │
                        │  │state │            │raft   │          │
                        │  │ .db  │            │ .db   │          │
                        │  │(KV)  │            │(log)  │          │
                        │  └──────┘            └───────┘          │
                        └─────────────────────────────────────────┘

Who Uses It

Diminuendo gateway connects over both HTTP REST (writes) and WebSocket (reads + subscriptions). It authenticates with CONCORDANCE_API_KEY and has full read/write access. Diminuendo resolves client-facing ACP config/* scopes (like “user” or “tenant”) into full Concordance namespaces using the authenticated user’s identity. Podium agents connect over HTTP REST with CONCORDANCE_AGENT_API_KEY for read-only access to configuration values they need at runtime (skill configs, integration settings, credentials). Clients never talk to Concordance directly. They send ACP config/* JSON-RPC methods to Diminuendo, which resolves scopes to namespaces and proxies the request.

Authentication

Concordance uses Bearer token authentication with two distinct API keys:
KeyEnv VariableAccessUsed By
API keyCONCORDANCE_API_KEYFull read/writeDiminuendo gateway
Agent keyCONCORDANCE_AGENT_API_KEYRead-onlyPodium agents
All HTTP and WebSocket requests must include an Authorization: Bearer <key> header. Requests without a valid key receive 401 Unauthorized. The API key is shared between Concordance and Diminuendo — set the same value in both services. The agent key gives agents read-only access to configuration; agents cannot modify config values.
In dev mode, CONCORDANCE_API_KEY defaults to "dev" and CONCORDANCE_AGENT_API_KEY defaults to "dev-agent". For production, always set strong, unique values.

Setup

Dev Mode (Automatic)

No manual setup required. When you run bun run dev in Diminuendo, it automatically:
  1. Spawns a single-node Concordance instance on 127.0.0.1:4100 with --bootstrap
  2. Uses default API keys (dev / dev-agent)
  3. Stores data in ./data/concordance/
  4. Polls /api/v1/health until ready (up to 5 seconds)
If CONCORDANCE_AGENT_API_KEY is not set, Diminuendo auto-generates one (prefixed cak_) and persists it to .env.local so it survives restarts.

Production

In production, Concordance runs as a separate 3-node Raft cluster. You must configure both Concordance and Diminuendo with matching keys: On each Concordance node:
CONCORDANCE_API_KEY=your-strong-api-key        # Full access (Diminuendo)
CONCORDANCE_AGENT_API_KEY=your-agent-key       # Read-only (agents)
On Diminuendo:
CONCORDANCE_URL=http://concordance-leader:4100  # Cluster address
CONCORDANCE_API_KEY=your-strong-api-key         # Must match Concordance
CONCORDANCE_AGENT_API_KEY=your-agent-key        # Passed to agents via Podium secrets
On Podium agents — the agent key is injected automatically. Diminuendo passes CONCORDANCE_AGENT_API_KEY to Podium as part of the agent secrets bundle when creating instances. Agents receive it via secrets.json and use it to read config values at runtime. See Configuration for the full list of environment variables and CLI arguments.

Data Flow

Client (ACP)                 Diminuendo                    Concordance
    │                            │                              │
    │  config/set                │                              │
    │  {scope:"user",           │                              │
    │   key:"theme",            │                              │
    │   value:"dark"}           │                              │
    ├───────────────────────────►│                              │
    │                            │  PUT /api/v1/kv/             │
    │                            │  tenant:acme/user:u1/        │
    │                            │  preferences/theme           │
    │                            ├─────────────────────────────►│
    │                            │                              │──► Raft propose
    │                            │                              │──► quorum commit
    │                            │                              │──► FSM apply
    │                            │          200 OK              │──► pub/sub
    │                            │◄─────────────────────────────┤
    │  config/update             │                              │
    │  {scope:"user",           │  watch/change (WebSocket)    │
    │   key:"theme",            │◄─────────────────────────────┤
    │   value:"dark",           │                              │
    │   version:2}              │                              │
    │◄───────────────────────────┤                              │

Repository Structure

diminuendo/concordance/
├── service/              # Concordance server process
│   ├── main.ts           # Entry point, CLI args, wiring
│   ├── server.ts         # Bun.serve() — HTTP + WebSocket + Raft on one port
│   ├── ws.ts             # WebSocket JSON-RPC handler for clients
│   ├── fsm.ts            # Finite State Machine — applies Raft entries to KV
│   ├── peers.ts          # WebSocket peer connection manager
│   ├── config.ts         # Configuration types and defaults
│   └── raft/
│       ├── node.ts       # Core Raft consensus algorithm
│       ├── log.ts        # SQLite-backed Raft log + stable store
│       ├── snapshot.ts   # Snapshot creation and installation
│       └── types.ts      # Raft message types and configuration
├── shared/               # Shared between Concordance service and Diminuendo
│   ├── types.ts          # KvEntry, ChangeEvent, scope resolution
│   ├── protocol.ts       # JSON-RPC types, WS/ACP method definitions
│   ├── schema.ts         # SQLite DDL for state.db and raft.db
│   ├── store.ts          # KvStore — SQLite-backed KV operations
│   └── index.ts          # Barrel export
└── test/                 # Test suite