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.
  • 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.

Last updated on