Context
ADR-11 settled the engine: Onyx workspace, Mistral chat, Voxtral transcripts, Skynet captions. The wiring contract on top of that was still open. How operators flip Intelligence on for one customer (without flipping it on for everyone). How it pins to OpenDesk versions so upgrades behave like the rest of the platform. How Onyx authenticates against the customer's existing identity. Which integrations work without per-customer configuration. The signup form had already drafted a single boolean for the add-on; the operator-facing schema needed to match.
Decision
One customer-facing toggle: intelligence: true | false in od-platform/customers/<slug>.yaml. When true, Argo renders a new intelligence-base Helm chart from od-platform into the customer's cluster. template-core declares intelligence-base@vX as a pinned Helm dependency, in the same shape as core-base. The chart bundles Onyx + Mistral + Voxtral + Skynet plus six pre-configured connectors out of the box: Mail (IMAP), Files (S3 against the tenant's MinIO bucket), Wiki (XWiki API), Meetings (Voxtral transcripts dropped into the tenant S3), Projects (OpenProject API), Calendar (CalDAV). SSO is OIDC against the per-tenant Nubus Keycloak, same realm as every other OpenDesk app. Onyx's UI is themed via Helm values onto KiwiStack tokens (kiwi-dark primary, bg-cream background, Quicksand display, Nunito body), and the Nubus portal tile uses the Intelligence iconSvg exported from src/data/products.ts on this site. YAML key, Helm chart, portal tile and operator docs all say 'intelligence', never 'onyx'. The vendor name appears only in the engine-attribution line on /office/intelligence. The full component-by-component breakdown (eleven components, six connectors, the umbrella + five overlay subcharts, the Voxtral pipeline, the sovereignty boundary) lives on /architecture/intelligence.
Why
One flag keeps the operator surface narrow. 'Did you turn it on or not?' is the only question, and upgrades roll forward as Renovate-driven base-version bumps, exactly the way the Core baseline already moves. Sharing the Nubus Keycloak realm means an Intelligence user is the same person as a Mail or Files user on day one, with no second account or MFA flow. The six chosen connectors are the ones with concrete paths in Onyx's existing model (S3 for Files via Nextcloud's MinIO, IMAP for Mail, web-API for the others); they cover the 'all integrations done out of the box' promise without inventing new connector code in v1. CryptPad Notes is intentionally excluded (see /office/notes caveat: E2EE means no AI can read it). Matrix Chat is deferred to v2 because no upstream Onyx Matrix connector exists today. Generic naming reduces engine lock-in: a future swap to LibreChat, Open WebUI or another workspace becomes a chart-internal change, with no rename across customer YAMLs, the operator portal, the docs or the marketing surface.
What was rejected
- → Per-feature flags (one boolean per connector and capability): maximum operator control, maximum config surface, most likely place for vendor specifics to leak into customer YAMLs. Defeats the one-flag goal that drove the request.
- → Onyx-branded across the stack (tile says 'Onyx', YAML key is onyx: true, chart is onyx-base): tight branding fit with the engine, but bakes the vendor name into every operator-facing artefact. Future engine swap becomes a rename ritual across od-platform, every customer state repo and every doc page.
- → Separate identity store for Intelligence (Onyx-native auth or its own Keycloak): isolates the AI workspace's auth blast radius, at the cost of a second password / MFA flow per user and a duplicate identity directory to sync. The point of running Nubus once per tenant is that no app outside it carries a parallel user store.
- → Ship Onyx with no out-of-the-box connectors and let customers wire it up: cheaper to launch, but breaks the 'all integrations done out of the box' promise the offer makes, and turns Intelligence into a manual configuration project for every customer.