Skip to Content

Roadmap — Shipped & Still Open

A candid assessment of what has landed recently and what remains incomplete or will break at scale.

Recently shipped

The canvas work (Phases 1–6) closed several of the largest gaps this doc used to list:

  • Nested rendering. Containment (parentId, isContainer) now renders visually — children are packed inside their parent’s bounds, with collapse, drag-to-reparent, and double-click container focus. The layout lives in a pure, tested engine (src/canvas/layout.ts). See Visual Mapping.
  • A renderer that scales. useCanvasRenderer is now a reconciling renderer (diff-and-patch keyed records, no innerHTML wipe) with viewport culling and semantic level-of-detail, plus auto-layout (“Tidy” via gridPack). Hand-built and imported graphs both stay responsive.
  • IAM / network / heat as overlays. Instead of drawing every IAM role or security relationship as a peer node, these are toggleable overlays (src/aws/overlays.ts) that trace the relationship graph and highlight the resources involved.
  • Cheap history. Undo/redo (src/hooks/useHistory.tsx) now relies on structural sharing — the store mutates immutably, so snapshots reuse unchanged references instead of deep-cloning the whole graph each action.
  • CI guardrails. validateRegistry() runs in tests, and the test/lint/build suite (including registry and rendered-UI snapshots) runs in GitHub Actions. See Testing.
  • IaC export. The design → code loop is closed: src/aws/iacExport.ts emits CloudFormation (JSON/YAML) and Terraform (HCL) from the graph, with an ExportReport that’s honest about lossiness (skipped resources, TODO fields). See IaC Import & Export.
  • Live discovery. The producer for the discovery transform now exists: src/aws/discovery.ts (pure) plus a server-only /api/discover Route Handler over @aws-sdk/client-cloudcontrol, with a paste-import fallback. See Live Discovery & MCP.
  • Drift detection. src/aws/drift.ts diffs the canvas against a baseline (live export, IaC, or Strata JSON) into added / removed / changed, matching across sources by ARN — else serviceId + name — rather than by id. See Drift Detection Engine. This is also a first step toward the stable-key strategy in §1.
  • Cost estimation. src/aws/cost.ts puts a rough monthly figure on the design (per-node badges + a toolbar total), refined by size/count/multi-AZ/ storage for the big-ticket services. Deliberately a heuristic, not a forecast.
  • Cost coverage & honesty. Config-aware pricing for the high-variance movers (OpenSearch Serverless OCUs, Fargate vCPU/mem, EIP, Flow Logs) plus base prices for previously-$0 billables, and a floor signal: estimateTotal reports unmappedBillableTypes/isFloor (distinguishing free control-plane services from unpriced-but-billable ones) so a partial total never masquerades as complete. Optional CostAssumptions (region / hours / discount) tune the figure. See Estimated Cost.
  • Multi-account, at scale. combineGraphs (src/aws/combine.ts) folds N imported per-account graphs onto one canvas (id-namespaced, grid-laid-out) via the merge_graphs MCP tool; the layout auto-grids position-less roots; and import_iac gained a server-side path + non-persistent graphId handle so multi-MB state stays out of the agent’s context. Offline strata cost / render CLI one-shots. See Multi-Account Cost Model.
  • Reports. Resource inventory (CSV/JSON — asset dump / manifest / config baseline) and a bill-of-materials rollup (src/aws/inventory.ts), plus vector SVG/PNG image export, from Data ▾.
  • Renderer — 2D / 2D⚡ / 3D. A runtime view toggle: the classic DOM 2D (detailed, print/embed), a WebGL (PixiJS) 2D that scales to thousands of nodes with full editing at feature parity, and a 3D orbit view where containment depth is elevation. Shared draw primitives keep the on-screen render and the SVG export from drifting. A dev /perf route measures the WebGL layer at 1k/2k/5k. See Views.
  • Local version history. src/lib/snapshots.ts keeps a bounded localStorage ring of full-graph snapshots (Data ▾ → “Version history…”): save, restore, and use any snapshot as a drift/cost baseline via compareWithVersion (src/hooks/useFlow.tsx). The cross-device/durable version is gated on the sharing backend.
  • Accessible canvas navigation. src/components/AccessibleNodes.tsx plus the pure src/canvas/navGrid.ts (readingOrder / nextInDirection) expose the imperatively-rendered canvas to keyboard and screen-reader users (roving tabindex, spatial arrow keys). See the user-facing Keyboard & Commands guide.

Still open

1. Id strategy: UUID vs ARN coexistence

Manually-created resources get server-assigned UUIDs (randomUUID()); imported resources have real ARNs. ResourceInstance carries both (id + optional arn).

Largely addressed: a merge/upsert path now existssrc/aws/merge.ts (mergeGraphs) reconciles an incoming scan/import into the current graph, keyed on ARN, else serviceId + name (the same identityKey the drift engine uses). Matched resources update in place — config is refreshed while the internal id, canvas position, parentId, and any user rename are preserved; unmatched incoming resources are added; unmatched base resources are left untouched (a partial scan never deletes). The “Merge” discovery/import path routes through it, so re-scanning reconciles instead of duplicating.

A merge preview now also ships: the discovery/import “Merge” path stages the incoming graph and shows a before-apply summary of what will be added / updated / unchanged / kept (mergePreview derived via diffGraphs in useFlow.tsx, confirmMerge/cancelMerge, rendered by MergePreviewDialog).

Still next: make ARN a first-class stable external key end-to-end (e.g. server storage keyed on it).

2. Overlays are topology, not policy

The IAM and network overlays trace the modeled relationship graph — the edges you drew or imported — not real security-group rules, NACLs, or IAM policy evaluation. They’re a legibility aid, not a reachability or trust analysis.

Next: evaluate actual SG/NACL/route and IAM policy semantics (from imported config) to back the overlays with real reachability, clearly distinguished from the hand-drawn topology.

3. No per-user / per-tenant model yet

An opt-in shared-secret guard already exists: set AWS_FLOW_API_TOKEN and every API route (graphs, graphs/[id], discover) requires a matching Authorization: Bearer header, else 401 (requireAuth(), src/server/auth.ts; see Persistence → auth guard). What’s still missing is identity: the token is one shared secret, so the Route Handlers and Repository have no concept of a user or tenant — any authenticated caller can list/read/write/delete any graph. Fine for a single-tenant or local deployment; not enough for true multi-tenancy.

Next: add real authentication (sessions / JWT / OIDC) in auth.ts, per-tenant scoping on every Repository method, and authorization checks in the Route Handlers before any multi-user deployment.

4. Discovery is read-only and flat

Live discovery lists resources but doesn’t infer relationships from Cloud Control. (Re-scans now reconcile rather than duplicate, via the ARN-keyed upsert in §1 — but a flat scan still produces a flat graph.)

Next: derive containment/edges from discovered properties (as the IaC importer does), so a discovered account lands nested and connected, not as a flat grid.

5. Packaging: no one-click install yet

Strata runs via npm run dev and the MCP server via npm run mcp, wired into an agent by hand (see Installing & MCP Setup). That’s fine for developers but not for an “average user.”

Next: a desktop shell (Electron, or Tauri with a Node sidecar) that bundles the Next server + the MCP stdio server and can write the MCP client config for a one-click “Connect to Claude Desktop / Cursor.” The local features (child-process terraform, provider SDKs, MCP stdio) need a Node runtime, so a Node-bearing shell is the pragmatic path — Next.js stays the UI/framework; the renderer is entirely client-side and works unchanged. Durable local storage (SQLite/file) would replace localStorage in that shell.

Last updated on