Skip to content

IDP choice decision dossier — Backstage vs alternatives vs Extended console-next

Story : CVN-N012-EA-S01 (wp#94) Need : CVN-N012 (wp#75) — Internal Developer Platform / replace Streamlit Console + unified cockpit Epic : CVN-N012-EA (wp#77) — Backstage platform skeleton Date : 2026-04-29 Author : Dominique (operator) + Claude Type : ADR / Process — plan_review dossier Status : Committee plan_review PASSED OK on 2026-04-29 (session 316c39b3, strong consensus, 0 blockers). Revision incorporates expert-ops + expert-architect recommendations as new invariants I6-I8 (§9) and strengthens I2 with a portability test. Next : ADR-78 PR, then OP wp#75/77 consolidation.


1. TL;DR

The Story prescribes evaluating four candidates (Backstage / React Admin custom / Port.io / Cortex) against eight weighted criteria. Reading the surrounding state of the project surfaces a tension the Story does not name : Need CVN-N008 has already been ratified, ADR-66 has locked the UI stack (Next.js 14 + shadcn/ui + Storybook + Tailwind + DTCG tokens), and console-next/ is actively being built as the Streamlit replacement. CVN-N012 (this Need, "replace Streamlit + unified cockpit via Backstage") therefore overlaps with CVN-N008 on the Streamlit-replacement surface, while extending the scope (service catalog, runbooks, embedded observability).

Choosing Backstage forces a decision the Story does not flag : what becomes of the in-flight console-next/ work ? Three sub-options exist, all of them costly :

  • Fork console-next into a Backstage plugin → rewrite shadcn primitives onto Material UI, abandon Storybook gate, abandon DTCG → Figma sync, restart the design system.
  • Iframe-embed console-next inside Backstage → exactly the cross-system "discipline workflow" memory feedback_no_discipline_workflows.md forbids ; defeats Backstage's plugin architecture.
  • Reject Backstage and extend console-next to absorb IDP capabilities → coherent with ADR-66 + ADR-77, no new tech, but breaks the operator's stated prior toward Backstage in Need §9.

The honest outcome is that the four-candidate framing is incomplete. A fifth candidate — "Extended console-next" — must be evaluated alongside the others, and the boundary between CVN-N008 and CVN-N012 must be resolved by this dossier rather than left to drift across two parallel Needs.

Recommendation (preview, full rationale §6) : adopt "Extended console-next" — keep the Next.js + shadcn stack ratified by ADR-66, extend it with the IDP capabilities scoped by Need CVN-N012 (service catalog, embedded observability views, ops actions, runbooks index), and consolidate CVN-N008 + CVN-N012 into a single Need to remove the boundary ambiguity. Reject Backstage as the primary IDP, but adopt its catalog YAML schema and TechDocs convention as portable formats inside the extended Console.


2. The CVN-N008 ↔ CVN-N012 boundary problem

Two Needs were registered independently and now collide on the same surface :

Need Date Scope as written UI stack
CVN-N008 (wp #675, needs/CVN-N008-NEED-unified-configuration-platform.md) 2026-04-24 Unified Configuration Platform — replace Streamlit, parameter catalog in DB, run-to-paramset binding, runtime distribution Next.js 14 + shadcn + Storybook + Tailwind + DTCG (locked by ADR-66)
CVN-N012 (wp#75) 2026-04-28 Internal Developer Platform — replace Streamlit, unified cockpit, service catalog, runbooks, embedded obs, RBAC, approval workflow Backstage (operator's stated prior, §9)

The "replace Streamlit" surface is shared. The four extra capabilities listed in N012 §2-4 (cockpit unifié, service catalog, runbooks, embedded observability) are incremental on top of N008's Configuration Console — they do not require a different framework, they require additional routes / modules.

The implicit assumption inside CVN-N012 is that Backstage provides these capabilities for free. It does not :

  • Service catalog : Backstage ships a catalog plugin that reads catalog-info.yaml from each repo. The catalog UI is ~3-4 list/detail screens — buildable in console-next in days, not weeks.
  • Runbooks : Backstage TechDocs is mkdocs-in-an-iframe. We already have mkdocs at docs.cvntrade.eu ratified as the docs SSoT by ADR-77. Adopting Backstage TechDocs creates a second docs surface and violates ADR-77 §I1.
  • Embedded observability : Backstage's Grafana plugin is a pre-built iframe wrapper with auth pass-through. We can replicate this in console-next with a 50-line <GrafanaEmbed dashboardId> component.
  • Approval workflow : not a Backstage feature — Need §3 explicitly defers it to Temporal as a backend, with Backstage as the trigger UI. The trigger UI is a form ; console-next already has React Hook Form + Zod (ADR-66).
  • RBAC : Backstage's RBAC plugin is mid-maturity (community plugin, not core). We need RBAC anyway for console-next per N008 §3, so the work is shared.

In other words, the marginal value Backstage adds above what console-next is already structurally capable of providing is mostly the ergonomic plugin marketplace — at the cost of a fundamentally different UI primitive layer (Material UI vs shadcn) and a second TechDocs surface.

Proposed resolution : merge CVN-N012 into CVN-N008 as additional Epics (catalog Epic, ops Epic, runbooks-index Epic, embed Epic). The unified Need keeps the N008 title — "Unified Configuration Platform" — but extends its scope to include the cockpit / catalog / ops / runbooks features. Wp#75 is closed as "merged into wp#673" with a redirect comment. Wp#77 (this Epic) is reframed from "Backstage platform skeleton" to "IDP capabilities atop console-next" with new Stories.

This consolidation is itself a decision that requires committee validation — it is part of the dossier, not a side-effect.


3. Decision criteria

The Story prescribes 8 criteria with weights. Two clarifications applied here :

  • Weight semantics : high = 3, medium = 2, low = 1, low-medium = 1.5. Multiplicative against per-candidate scores 0-5.
  • Concrete CVN context : every criterion is grounded in a specific paths/numbers in the existing codebase, not abstract principles. The committee can audit the grounding by following the references.

3.1 Plugin ecosystem maturity (high, 3.0)

What it measures : how much of the EC/ED/EE Story scope is buildable from existing plugins vs from scratch.

CVN context : - EC (committee migration) — needs auth + form + table + mermaid render. No plugin in any candidate provides "committee" — fully custom either way. - ED (DAG ops panel) — Airflow has a Backstage community plugin (@backstage-community/plugin-apache-airflow, backstage/community-plugins) ; otherwise direct REST calls to Airflow API. - EE (embed dashboards) — Grafana panel iframe is trivial in any framework ; Backstage adds auth-pass-through.

Honest read : the plugin ecosystem advantage is real but smaller than usually claimed for a single-product context like CVN. The largest plugin-ecosystem wins (Spotify, Expedia) come from sharing across hundreds of services we don't have.

3.2 Self-host vs SaaS (high, 3.0)

What it measures : whether trading config + audit data leave operator-controlled infrastructure.

CVN context : - Cluster is Scaleway Kapsule PRO2-S, EU, GDPR-resident - Memory feedback_no_discipline_workflows.md + Need §10 explicitly preferred OSS over SaaS - Configuration data includes risk parameters that are commercially sensitive

SaaS candidates (Port.io, Cortex) auto-fail this criterion regardless of feature wins.

3.3 Auth integration (OIDC) (high, 3.0)

What it measures : does the candidate support OIDC against the existing identity provider with reasonable effort.

CVN context : - No OIDC provider deployed yet — currently nginx ingress + basic-auth for Console - Decision pending on Keycloak vs Authentik vs Authelia (out of this Story's scope) - All candidates support OIDC via standard libraries

This criterion is largely a wash across candidates because the OIDC standard is well-supported. The differentiator is whether the candidate forces an OIDC adoption decision in a specific direction (it doesn't, in any case).

3.4 RBAC granularity (medium, 2.0)

What it measures : the granularity at which permissions can be applied (page-level, field-level, action-level).

CVN context : - Need §6 lists policy rules : "kill switch global → double validation", "limit > 20 % → Risk approval", "no critical change market-open" — these are policy (OPA), not RBAC. RBAC is "who can edit what". - Field-level RBAC is needed for at least 5 surfaces : kill-switches, capital limits, model promotion, PTE selection, FTF run launch. - Backstage core RBAC is page-level ; field-level requires a community plugin or custom permission framework - shadcn/Next.js has no built-in RBAC — we'd build on top of NextAuth + custom middleware - React Admin has resource-level RBAC, similar coarseness to Backstage

Honest read : every candidate needs custom RBAC code for field-level. Backstage's "RBAC plugin" exists but is the same level of maturity as a hand-rolled solution. Not a strong differentiator.

3.5 Extensibility cost (medium, 2.0)

What it measures : developer hours / lines of code to add a new "plugin" (a new IDP module).

CVN context : the most representative test case is the existing FTF Config UI (scripts/ftf_config_ui.py, 928 lines of Streamlit) which has to be re-implemented as a "plugin" on each candidate.

Estimated cost (rough, based on framework conventions) : - Backstage : 6-8 weeks (new Backstage app dev pattern, MUI translation, Backstage entity API integration). ~3-4k LOC TypeScript. - React Admin custom : 4-6 weeks. ~2-3k LOC. - Port.io / Cortex : 1-2 weeks for catalog views, not feasible for the FTF Config form (would require a custom service against the SaaS API, defeating the purpose). - Extended console-next : 2-3 weeks (component library already there, design system ratified, Zod schemas reusable from the existing codebase). ~1.5-2k LOC.

The Extended console-next number is lower because the work already started — design tokens, button primitive, Tailwind config, Storybook, Vitest, Playwright are in place per console-next/package.json.

3.6 Maintenance burden (medium, 2.0)

What it measures : ongoing operator-time cost. Need §3 + memory tags feedback_no_discipline_workflows.md + "we are 1 operator" make this load-bearing.

CVN context : - Backstage releases ~monthly with non-trivial migration steps (e.g. plugin API breakage, MUI version bumps) - Backstage upstream is high-velocity ; staying on a fork is very costly long-term - shadcn upstream is "copy code into your repo" — we own it, no breaking upstream - React Admin has slow but breaking major versions - Port.io / Cortex maintenance is "vendor problem" but balanced by SaaS lock-in cost

For 1 operator, "we own the code" beats "we track an upstream" by a wide margin.

3.7 Mobile / PWA story (low-medium, 1.5)

What it measures : whether the operator can read and act on the platform from a phone.

CVN context : - Need §1 lists "besoin opérationnel mobile" as a use case (kill switch from phone, alert acknowledgement) - Backstage default theme is desktop-first, MUI-responsive but heavy - Next.js + Tailwind mobile-first by default, PWA support via standard service-worker / manifest - Port.io / Cortex have native mobile apps in some plans (premium tier only) - ADR-66 console-next already targets mobile per the design tokens

Differentiator : Next.js + Tailwind handles mobile by default ; Backstage requires explicit theme + plugin work for any mobile-first UI.

3.8 Lock-in risk (high, 3.0)

What it measures : cost of migrating away if the candidate becomes the wrong choice in 12 months.

CVN context : - SaaS candidates : all data exit costs + workflow re-implementation - Backstage : significant lock-in via plugin ecosystem (we'd write code against Backstage APIs ; migration = rewrite) - React Admin : moderate lock-in via resource/action conventions - Extended console-next : minimal — Next.js + shadcn is industry-standard React, components can be reused on any future framework with cosmetic changes

For a platform expected to operate 5-10 years, lock-in compounds.


4. Candidates

4.A — Backstage (Spotify, OSS)

Description : Open-source IDP framework, plugin-based, Material UI primitives, TypeScript / React. Service catalog from catalog-info.yaml, TechDocs from mkdocs, plugin marketplace.

Concrete fit assessment : - Plugin marketplace : ~150 plugins, ~30 of which are mature. Airflow plugin exists but limited to DAG list view (no run-trigger UI). Grafana plugin = iframe wrapper. - TechDocs : conflicts with ADR-77 (mkdocs site IS our docs SSoT) — would create a second docs surface. - MUI vs shadcn : irreconcilable — adopting Backstage means abandoning ADR-66 invariants on the IDP layer (Storybook gate, DTCG tokens, shadcn primitives) OR maintaining two design systems (the Configuration Console as a sub-iframe with shadcn, the rest of the IDP with MUI). The latter fails feedback_no_discipline_workflows.md. - Self-host : yes, K8s deployable, Helm chart available. - 1-operator load : high — plugin upgrade cycles, MUI breaking changes, custom plugin maintenance. - Existing investment : zero alignment with console-next ; 928 lines of FTF config UI must be rewritten as a Backstage plugin in MUI.

Candidate score :

Criterion Score 0-5 × weight
Plugin ecosystem maturity 4 12
Self-host vs SaaS 5 15
OIDC 4 12
RBAC granularity 3 6
Extensibility cost 2 4
Maintenance burden 2 4
Mobile / PWA 2 3
Lock-in risk 2 6
Total 62 / 100

Verdict : viable but expensive. The plugin marketplace value is real but smaller than advertised at our scale ; the cost on the existing console-next investment + ADR-66 invariants + ADR-77 docs SSoT is large.

4.B — React Admin custom

Description : Open-source admin framework, opinionated CRUD + RBAC + auth ; Material UI by default (themable). Lighter than Backstage, no service catalog, no plugin ecosystem.

Concrete fit assessment : - No service catalog or TechDocs — would build from scratch. Defeats the point of choosing a framework "for IDP". - MUI default but theme-customizable — same shadcn/MUI tension as Backstage but easier to swap because React Admin's components are less invasive than Backstage's full app shell. - Best fit for the Configuration Console alone — but that is exactly what console-next already does, with a more modern stack. - 1-operator : moderate. Slower release cadence than Backstage but breaking majors.

Candidate score :

Criterion Score 0-5 × weight
Plugin ecosystem maturity 2 6
Self-host vs SaaS 5 15
OIDC 3 9
RBAC granularity 3 6
Extensibility cost 3 6
Maintenance burden 3 6
Mobile / PWA 3 4.5
Lock-in risk 3 9
Total 61.5 / 100

Verdict : strictly dominated by Extended console-next on every dimension that matters at our scale. No reason to adopt.

4.C — Port.io (managed SaaS)

Description : Vendor IDP, hosted, "low-code" service catalog, blueprint system, integrations marketplace.

Concrete fit assessment : - SaaS auto-fails §3.2 (self-host). - Vendor lock-in : maximum. Custom UI surfaces are limited to Port's "blueprint" widget set. - FTF Config UI cannot be implemented as a Port blueprint — the form complexity (cascading dependencies, conditional fields, OPA-style validation) exceeds blueprint expressiveness. Would require a separate hosted service that Port talks to, defeating the point of using Port. - Cost : ~$20-40 / user / month at typical pricing. For 1-2 users, modest ; the issue is data exfiltration, not budget.

Candidate score :

Criterion Score 0-5 × weight
Plugin ecosystem maturity 4 12
Self-host vs SaaS 0 0
OIDC 4 12
RBAC granularity 4 8
Extensibility cost 1 2
Maintenance burden 5 10
Mobile / PWA 4 6
Lock-in risk 0 0
Total 50 / 100

Verdict : eliminated by §3.2 + §3.8 hard constraints. Detail score irrelevant.

4.D — Cortex (managed SaaS)

Description : Vendor IDP focused on service maturity scoring, less catalog flexibility than Port.

Concrete fit assessment : same SaaS hard-fail as Port.io. Stronger on "service maturity scoring" (a set of pre-built scorecards) — irrelevant to a 5-service platform like CVN. Weaker on custom UI than Port.

Candidate score : capped at the same SaaS-disqualified band as 4.C. Total ≤ 50/100, eliminated.

4.E — Extended console-next (proposed addition)

Description : Keep the Next.js 14 + shadcn/ui + Storybook + Tailwind + DTCG stack ratified by ADR-66. Extend with new App Router routes that absorb the IDP capabilities of CVN-N012 : - /catalog — service catalog, reading catalog-info.yaml files from each repo (Backstage-compatible format, kept as a portable convention) - /runs — Airflow DAG operations (list, trigger, kill, logs link to Loki) via Airflow REST - /dashboards — Grafana embed wrapper (<GrafanaEmbed dashboardId>) - /runbooks — index of mkdocs runbooks at docs.cvntrade.eu (links + search, no second docs site) - /committee — committee browser (already on the EC roadmap)

Crucially does not rename the app away from "Console" until the CVN-N008 / N012 consolidation lands as a separate decision in this dossier.

Concrete fit assessment : - Plugin ecosystem : zero. Compensated by the in-repo component library + shadcn upstream + the fact that the IDP "plugins" we need are ~5 surfaces, all custom anyway. - Self-host : yes (already deployed on K8s as part of CVN-N008-EA). - OIDC : standard via NextAuth.js, decision deferred to dedicated Story (out of N012-EA-S01 scope). - RBAC : built on NextAuth + custom field-level middleware, same effort as on Backstage but reusable across all IDP surfaces. - Extensibility cost : lowest of all candidates because the work has already started. ~1.5-2k LOC for the FTF Config UI port (vs 3-4k on Backstage). - Maintenance : we own the code (shadcn = copy-into-repo by design), no plugin upgrade cycles. - Mobile : Next.js + Tailwind is mobile-first by default ; PWA via standard manifest. - Lock-in : minimal, framework is industry-standard React. - Adopt Backstage's catalog-info.yaml schema as a portable artifact — repos keep declaring services in the standard format ; Console reads them. If Backstage becomes the right choice in 3 years (e.g. team grows past 10 engineers), migration is reduced to "install Backstage, point at the same YAMLs" rather than "rewrite the catalog".

Candidate score :

Criterion Score 0-5 × weight
Plugin ecosystem maturity 1 3
Self-host vs SaaS 5 15
OIDC 4 12
RBAC granularity 4 8
Extensibility cost 5 10
Maintenance burden 5 10
Mobile / PWA 5 7.5
Lock-in risk 5 15
Total 80.5 / 100

Verdict : highest score. The single weak dimension (no plugin marketplace) is mitigated by the fact that, at our scale, we'd build most "plugins" from scratch on any candidate.


5. Summary scoring

Candidate Plugin Self-host OIDC RBAC Extens. Maint. Mobile Lock-in Total
A. Backstage 12 15 12 6 4 4 3 6 62
B. React Admin 6 15 9 6 6 6 4.5 9 61.5
C. Port.io (SaaS) 12 0 12 8 2 10 6 0 50
D. Cortex (SaaS) ≤ Port 0 0 ≤ 50
E. Extended console-next 3 15 12 8 10 10 7.5 15 80.5

⛔ = hard-fail by §3.2 / §3.8 invariants regardless of detail score. ✅ = recommended.


6. Recommendation

Adopt 4.E "Extended console-next" as the IDP for CVNTrade. Reject Backstage as the primary platform.

Rationale, in plain language :

  1. Backstage's strongest advantage — the plugin marketplace — is small at our scale. Of the ~30 mature Backstage plugins, only Grafana embed + Airflow list view map to N012 capabilities. Both are 50-200 LOC of custom code in console-next.
  2. Backstage's costs are large. Adopting it forces abandoning ADR-66 invariants (shadcn, DTCG, Storybook gate) on the IDP layer, OR maintaining two design systems (cross-system discipline that violates feedback_no_discipline_workflows.md). Either path has compounding cost.
  3. console-next is already up. The package.json + tokens + Storybook + Vitest + Playwright wiring exists on main. The marginal effort to extend to IDP capabilities is days/weeks per surface, not Epics.
  4. ADR-77 says mkdocs is the docs SSoT. Backstage TechDocs would either duplicate this surface or replace it — both fail the SSoT discipline already ratified.
  5. For 1 operator, "we own the code" beats "we track an upstream." This is a recurring memory in feedback_no_discipline_workflows.md and the operator's stated maintenance posture.
  6. Lock-in is the hardest reversal cost. Extended console-next on industry-standard React is the lowest-lock-in option ; Backstage is the second-most-locked-in OSS candidate after SaaS.

Adopt as portable artefacts (not the framework, just the conventions Backstage standardized) :

  • catalog-info.yaml schema for service descriptors (per-repo file, parsed by console-next)
  • TechDocs concept (markdown adjacent to code) — already aligned with mkdocs
  • Plugin shape for future migration if scale demands it (one folder per IDP surface, isolated state, defined API)

This preserves the option of a future Backstage migration if team scale crosses ~10 engineers, while paying none of the cost today.


7. Consolidation : merge CVN-N012 into CVN-N008

The IDP capabilities of CVN-N012 become additional Epics on CVN-N008 :

Original Epic (CVN-N012) Reframe under CVN-N008
EA — Backstage platform skeleton withdraw ; replaced by extension Stories on existing CVN-N008-EA Epic
EB — Console migration already covered by CVN-N008-EA
EC — Committee migration CVN-N008-EX (new) — committee browser plugin for console-next
ED — DAG operations panel CVN-N008-EY (new) — Airflow ops module for console-next
EE — Dashboard embed CVN-N008-EZ (new) — Grafana embed module for console-next

Wp#75 (Need CVN-N012) → close as merged into wp#673 with redirect comment. Wp#77 (Epic CVN-N012-EA) → close as superseded by CVN-N008-EA + new Epics CVN-N008-EX/EY/EZ. Wp#94 (this Story) → close on merge of this dossier + ADR-78.

This consolidation is itself part of the recommendation and requires committee validation alongside §6.


8. Implications on Stories EB-EE (per Story §3 brief)

If §6 + §7 are accepted, the original suggested Stories of CVN-N012-EA (S02-S06 in the Epic description) become :

Original suggested Story New shape under CVN-N008
S02 — Backstage scaffold + SSO + ingress withdrawn ; SSO becomes a CVN-N008-EA Story (decoupled from any IDP framework choice)
S03 — Service catalog seed CVN-N008-EX-S01/catalog route + catalog-info.yaml parser + ownership rules
S04 — Helm + CI/CD + deploy K8s already done by CVN-N008-EA scaffold (existing console-next Helm chart)
S05 — Proof plugin (Grafana) + TechDocs CVN-N008-EZ-S01<GrafanaEmbed> component + Storybook story + test ; TechDocs withdrawn (mkdocs SSoT)
S06 — OPERATIONS runbook + RBAC bootstrap RBAC becomes a CVN-N008-EA Story ; OPERATIONS runbook merges into existing

Net effort delta : roughly −60 % vs the Backstage path, because (a) scaffold + Helm + CI is done, (b) TechDocs withdrawn, (c) auth and SSO decisions are not framework-specific.


9. ADR-78 stub

A draft ADR-78 will be authored at documentation/adr/0078-idp-framework-choice.md in a follow-up PR after this dossier merges (out of scope for the present PR — see §13 acceptance checklist). Skeleton :

  • Title : ADR-78 — Internal Developer Platform framework : Extended console-next over Backstage
  • Status : proposed (until committee plan_review PASSED), then active
  • Context : the §1-2 framing of this dossier
  • Decision : adopt 4.E ; reject 4.A-D ; consolidate N008 + N012
  • Invariants :
  • I1 — IDP capabilities ship as Next.js routes inside console-next/, not as standalone services
  • I2 — catalog-info.yaml is the service descriptor format (Backstage-compatible) — kept as a portable artefact even though Backstage itself is not adopted. Portability test mandatory : a CI job MUST verify that the produced catalog-info.yaml files round-trip through the canonical Backstage schema validator without modification (per committee 316c39b3 reco — strengthens I2 against cargo-cult risk)
  • I3 — TechDocs concept is honored by mkdocs at docs.cvntrade.eu (per ADR-77) — not by a parallel TechDocs site
  • I4 — every IDP module respects ADR-66 invariants (Storybook story, a11y green, DTCG tokens, no inline CSS)
  • I5 — no SaaS dependencies for the IDP control plane (per Need CVN-N008 §10 + CVN-N012 §10)
  • I6 — IDP kill-switchconsole-next MUST have an out-of-band kill-switch mechanism (operator can stop the control plane from outside the application itself, e.g. via direct K8s scale-to-0 or a dedicated PG flag readable by ingress) so a malfunctioning IDP cannot lock the operator out of recovery. Pattern aligned with ADR-71 (trading kill-switch invariants). Per committee 316c39b3 (expert-ops, P1).
  • I7 — Immutable audit trail — every state-changing action through the IDP (config edit, kill-switch toggle, run launch, model promotion) MUST land in an append-only, tamper-evident audit log (PostgreSQL append-only table + signed entries, or external SIEM). Required for governance and incident forensics. Per committee 316c39b3 (expert-ops, P1).
  • I8 — Blast radius — IDP modules (catalog, runs, dashboards, runbooks, committee) MUST NOT share runtime state (e.g. shared Redux store, shared cache, shared DB transaction scope) with the Configuration Console module. Each module is independently failure-isolated : a crash or auth bug in /dashboards MUST NOT take down /config. Per committee 316c39b3 (expert-architect).
  • Alternatives rejected : A-D from §4
  • Consequences : per §6
  • Rollback : revert this ADR, withdraw the extended modules, optionally start a Backstage POC (cost : 6-12 months of migration)

10. Risks accepted / mitigations

Risk Likelihood Impact Mitigation
Underestimate of catalog UI complexity medium medium scope a 2-week catalog spike before committing the full Story EX-S01
Plugin-marketplace shortfall — a future need (e.g. PagerDuty integration) takes 3× longer to build than installing a Backstage plugin low-medium low accept as the explicit cost of the choice. If pattern repeats > 3 times, revisit
Team scale grows past 10 engineers and the discipline of building "plugins" inside one Next.js app degrades low (current scale 1-2) high the catalog-info.yaml portability invariant (I2 above) preserves an exit path to Backstage
ADR-66 invariants slow down catalog dev (Storybook gate per component) medium low this is by design ; the gate paid off on the design tokens, will pay off on the catalog views
Operator regrets the consolidation mid-flight (Backstage prior reasserts) low medium the dossier is committee-reviewed ; reasserting requires opening a new Need + new dossier — friction by design

11. Committee verdict (2026-04-29)

Session : 316c39b3committee/sessions/316c39b3_committee.json (artifact archived at committee/sessions/316c39b3_artifact.md) Verdict : PASSED OK — strong consensus, avg score ~8.1/10 (range 7.0–9.0), 0 blockers, 14 forward-looking recommendations. Cost : 212k tokens, ~$0.24, 11 LLM calls.

Endorsements (matching the 3 questions)

  1. Scope enlargement (5th candidate + N008/N012 consolidation) — APPROVED. Committee considers it essential for comprehensive evaluation and prevents fragmentation.
  2. Recommendation §6 (Extended console-next over Backstage) — DEFENSIBLE and endorsed. Cited rationale : ADR-66 alignment, ADR-77 docs SSoT, 1-operator context, in-flight work leverage, lock-in minimization.
  3. ADR-78 invariants I1-I5 — SUFFICIENT. Specifically I2 (catalog-info.yaml portability) endorsed as future-proofing, not cargo-culting.

Areas of dissent (non-blocking)

  • Backstage plugin ecosystem score : 2 experts argue 5/5, 2 argue 4/5. Doesn't change the conclusion.
  • IDP operational safeguards : expert-ops is the sole voice flagging missing operational invariants for the IDP itself (kill-switch, staged rollout, observability, audit trail). Addressed in this dossier revision via new invariants I6-I8 in §9.

Recommendations integrated into this dossier (revision post-committee)

Reco source Integration
Strengthen I2 with portability test (expert-architect) §9 I2 — round-trip validator now mandatory
IDP kill-switch (expert-ops) §9 new I6
Audit trail invariant (expert-ops) §9 new I7
Blast radius (expert-architect) §9 new I8

Recommendations carried as backlog (out of this Story's scope, tracked for EX-S01 onwards)

  • 2-week catalog spike before EX-S01 commit (cf. §10 risks table + §12 historical Q3, explicitly endorsed by committee) — Story to open under CVN-N008-EX
  • 1-day spike on Backstage Airflow plugin to validate "DAG list view only" assumption — Story under CVN-N008-EY (or as a §6 mitigation if scope warrants)
  • OIDC provider decision (Keycloak / Authentik / Authelia) as blocking dependency for EX/EY/EZ — open a dedicated CVN-N008-EA Story
  • Staged rollout strategy (canary / blue-green) for console-next updates — likely a sister ADR
  • IDP observability dashboard (Grafana + Loki, dedicated metrics + alerts) — Story under CVN-N008-EA
  • Field-level RBAC priority — promote to first CVN-N008-EA Story after the consolidation lands
  • Drift monitoring operationalization in extended Console (per ADR-15 / ADR-14) — backlog under CVN-N010

These items will be filed as discrete OP work_packages once the consolidation §7 is ratified at the Need / Epic level (cf. §13 acceptance).


12. Initial questions (resolved by committee plan_review)

The 5 questions below were the operator's pre-committee unknowns. All resolved by session 316c39b3 (verdict PASSED OK — see §11 for details). Kept verbatim for traceability of the deliberation surface.

  1. Is the 5th candidate addition + N008/N012 consolidation in scope for this Story, or do they require a separate dossier ? → Q1 resolved : in-scope, endorsed by committee (§11 endorsement #1 — "essential for comprehensive evaluation").
  2. Are the candidate scores defensible ? In particular : Backstage at 4 on plugin ecosystem (some reviewers may argue 5). → Q2 resolved : non-blocking dissent (2 vs 2 split, see §11 dissent — doesn't change conclusion).
  3. Is the §6 recommendation strong enough on its own, or does the committee want a 2-week catalog spike (per §10) before the verdict ? → Q3 resolved : recommendation accepted as-is ; 2-week catalog spike deferred to CVN-N008-EX backlog (§11 backlog item 1).
  4. Does the committee endorse the catalog-info.yaml portability invariant (I2) as future-proofing, or see it as cargo-culting ? → Q4 resolved : endorsed as future-proofing AND strengthened by the new round-trip portability test (§9 I2 revision).
  5. Is the OIDC provider decision (Keycloak vs Authentik vs Authelia) something this dossier should pre-empt, or is the deferral to a CVN-N008-EA Story acceptable ? → Q5 resolved : deferral acceptable but flagged as blocking dependency for EX/EY/EZ (§11 backlog item 3).

13. Acceptance checklist (Story §Acceptance)

  • Decision dossier covers all 4 prescribed candidates against the 8 weighted criteria with concrete CVN examples (paths, LOC counts, cluster references)
  • Adds a 5th candidate "Extended console-next" surfaced from the existing project state (operator-approved 2026-04-29)
  • Resolves the CVN-N008 ↔ CVN-N012 boundary with an explicit consolidation proposal
  • Notes implications on EB-EE Stories (§8)
  • Committee plan_review PASSED OK — session 316c39b3, strong consensus, 0 blockers, 14 recos (4 integrated in §9 invariants, 7 carried as backlog — see §11)
  • ADR-78 merged with chosen IDP + invariants I1-I8 — to be authored in a follow-up PR
  • Epic CVN-N012-EA description updated on OP — pending consolidation decision (§7) at Need-level review

14. Linked context