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.
useCanvasRendereris now a reconciling renderer (diff-and-patch keyed records, noinnerHTMLwipe) with viewport culling and semantic level-of-detail, plus auto-layout (“Tidy” viagridPack). 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.tsemits CloudFormation (JSON/YAML) and Terraform (HCL) from the graph, with anExportReportthat’s honest about lossiness (skipped resources,TODOfields). See IaC Import & Export. - Live discovery. The producer for the discovery transform now exists:
src/aws/discovery.ts(pure) plus a server-only/api/discoverRoute Handler over@aws-sdk/client-cloudcontrol, with a paste-import fallback. See Live Discovery & MCP. - Drift detection.
src/aws/drift.tsdiffs the canvas against a baseline (live export, IaC, or Strata JSON) into added / removed / changed, matching across sources by ARN — elseserviceId+ 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.tsputs 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.tskeeps a boundedlocalStoragering of full-graph snapshots (Data ▾ → “Version history…”): save, restore, and use any snapshot as a drift/cost baseline viacompareWithVersion(src/hooks/useFlow.tsx). The cross-device/durable version is gated on the sharing backend. - Accessible canvas navigation.
src/components/AccessibleNodes.tsxplus the puresrc/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 exists — src/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.