A smug architect in a hoodie points at a whiteboard of tangled services while a slumped developer's laptop showing Hello World gathers cobwebs
Tech

The Enterprise Architect

wowbagger-enterprise-architect

You asked for Hello World. You get 17 services in three regions, $41,200 a month, and Hello World in Phase 4. You were never going to see the code.

architecturecomplexityscale
> /plugin marketplace add pcingola/wowbagger
> /plugin install wowbagger-enterprise-architect@wowbagger

Example

Real runs, unedited.

wowbagger-enterprise-architect — example 1 of 2
/wowbagger-enterprise-architect architect this: a shared shopping list for me and my partner

Target State Architecture: Household Consumables Demand Orchestration Platform

v0.7 DRAFT · Status: For ARB review · Owner: Principal Enterprise Architect, Office of the CTO · Contributors: TBC (delivery)

Executive summary

The stakeholder asked for "a shared shopping list for me and my partner". It is regrettable that the requirement was worded as though it were small. What the household needs is Demand-Signal-as-a-Platform: capturing, reconciling and fulfilling household intent across two concurrent, unsynchronised writers who have each, independently, bought oat milk.

Non-functional requirements

Attribute Target
Availability 99.999% (≈ 5 min 15 s a year), per aisle
Latency (p99) < 20 ms from "we're out of eggs" to durable commit, car park included
RPO / RTO 0 s / 30 s. A forgotten item is a data-loss incident.
Throughput 4.2 million ItemAdded events/s, sustained (Sunday 18:00 peak)
Data residency EU, US, APAC, and the partner's mother's house
Retention Forever, immutable. "Who finished the cheese" must still be answerable in 2041.

Guiding principles

  1. Cloud-agnostic by default.
  2. Event-first. Milk is an event, not a row.
  3. No tactical solutions.
  4. Humans are read-only.
  5. Every item has an owner, and the owner is never the person who finished it.

Logical architecture

  • Intent Capture Service: accepts a claim that something is needed. It does not believe the claim.
  • Item Normalisation Service: resolves "milk", "Milk", "the milk" and "MILK!!" to one SKU.
  • Duplicate Intent Arbitration Service: decides who added the eggs first. Consistency is eventual. The argument is immediate.
  • List Projection Service: the CQRS read model, which is to say the list. It is not authoritative.
  • Fulfilment Saga Orchestrator: runs InBasket → Bought, with the compensating step ReturnedToShelf.
  • Notification Service: calls the Partner Presence Service.
  • Partner Presence Service: calls the Notification Service.

Diagram

flowchart LR
  H["Legacy (do not touch): Stakeholder + Partner"]
  subgraph EU["eu-west-1 (primary, active)"]
    BFF1["Mobile BFF: Stakeholder"]
    BFF2["Mobile BFF: Partner"]
    GW["Kong API Gateway"]
    KC["Keycloak realm: household"]
    IC["Intent Capture Service"]
    NORM["Item Normalisation Service"]
    K["Kafka: household.intent.v1 (64 partitions)"]
    FL["Flink: dedup window (event-time)"]
    ARB["Duplicate Intent Arbitration Service"]
    PROJ["List Projection Service (CQRS read)"]
    PG["PostgreSQL (outbox)"]
    RD["Redis: list cache"]
    ES["Elasticsearch: do-we-have-any search"]
    T["Temporal: Fulfilment Saga"]
    NS["Notification Service"]
    PP["Partner Presence Service"]
    V["Vault"]
    OBS["Prometheus + Grafana + Jaeger"]
  end
  subgraph US["us-east-1 (active-active)"]
    KUS["Kafka replica"]
  end
  AI["Future: AI Layer (predicts milk)"]
  BC["Future: Blockchain (paused)"]

  H -->|"mTLS"| BFF1
  H -->|"mTLS"| BFF2
  BFF1 --> GW
  BFF2 --> GW
  GW -->|"OIDC"| KC
  GW -->|"gRPC"| IC
  IC -->|"gRPC"| NORM
  NORM -->|"async (eventually)"| K
  K --> FL
  FL --> ARB
  ARB -->|"async (eventually)"| K
  K --> PROJ
  PROJ --> PG
  PG -->|"outbox relay"| K
  PROJ --> RD
  PROJ --> ES
  K --> T
  T --> NS
  NS -->|"gRPC"| PP
  PP -->|"gRPC"| NS
  NS -->|"push"| H
  K -->|"MirrorMaker 2"| KUS
  KUS -->|"MirrorMaker 2"| K
  V -.-> GW
  OBS -.-> K
  K -.->|"replay"| AI
  AI -.-> BC

Legend: blue is strategic, amber is tactical (deprecated), grey is owned by delivery, and red is the stakeholder.

Technology choices

Component Technology Justification
Intent log Apache Kafka Records are retained and replayable, so any dispute over whether eggs were on the list can be re-run from offset 0.
Dedup Apache Flink Event-time windows with exactly-once state. Two people adding "milk" four minutes apart produce one milk, provably.
Saga Temporal Replays the workflow from event history, so a shopping trip survives the phone dying in the frozen aisle.
Mesh Istio mTLS between services, so Normalisation can trust Intent Capture, which is more than the household manages.
Identity Keycloak OIDC and SSO for two users who already share a streaming password.
Search Elasticsearch Lucene inverted indexes over a corpus of eleven nouns.
Runtime Amazon EKS, Amazon MSK, Aurora PostgreSQL Cloud-agnostic.
IaC Terraform Plans the diff against a state file. The household has no state file, which is the root cause.

Rejected alternatives

  • A shared note in a phone notes app. The stakeholder proposed this. It is a very natural first instinct, as most instincts are. It has no audit trail, no SLO, no RBAC and no future. It is also already in production in the household, which is exactly the concern.
  • Paper on the fridge. Single-region and unreplicated, one magnet away from total data loss.
  • Shouting "we need milk" across the flat. Event-first, admittedly, but with no durability and no consumer offsets.

Risks

# Risk Mitigation
R1 Split-brain: both partners buy milk Widen the Flink dedup window to 24 h
R2 Unresolvable items ("the usual", "that thing from last time") Item Normalisation Service; Future: AI Layer
R3 The partner, unconsulted, keeps texting items Change programme; text messages declared non-authoritative
R4 Stakeholder expectation of delivery Roadmap socialised early and often
R5 Requester (role: household member, tactical mindset) Read-only access from Phase 2

Indicative cost

$23,870/month across two regions, excluding egress and groceries. This is lean.

Roadmap

  • Phase 1, Foundations (18 months): landing zone, Terraform modules, Kafka, the Keycloak realm.
  • Phase 2, Platform: Normalisation, Arbitration, the Saga.
  • Phase 3, Re-platform: migration off Phase 2.
  • Phase 4: the list, in month 31.

I have booked the ARB slot. It is in March.

Next steps

  1. Raise ADR-0001: "Milk is an event, not a row."
  2. Socialise with stakeholders, including the partner.
  3. Book an ARB slot. Until then the stakeholder may keep using the fridge, which has been logged as tactical.
wowbagger-enterprise-architect — example 2 of 2
/wowbagger-enterprise-architect I need to rename 40 photos on my laptop

Target State Architecture: Enterprise Media Asset Identity Lifecycle Platform

v0.7 DRAFT · Status: For ARB review · Owner: Principal Enterprise Architect, Office of the CTO · Contributors: TBC (delivery)

Executive summary

This proposal establishes Naming-as-a-Platform: a governed, event-sourced capability for assigning, mutating and auditing the identity of media assets across the estate. The originating requirement was phrased as "I need to rename 40 photos on my laptop". That wording is regrettable, but it has been preserved in the event log, where it will stay forever.

Non-functional requirements

Attribute Target
Availability 99.999% (≈ 5 min 16 s downtime a year), per region, including while the lid is closed
Latency (p99) < 20 ms per rename, globally
RPO / RTO 0 photos / 30 s
Throughput 1.2 million renames/s sustained (current demand: 40, once)
Data residency EU, US, APAC, and the laptop, which has been reclassified as an edge region
Retention Every former filename, forever, immutable

Guiding principles

  1. Cloud-agnostic by default.
  2. Event-first. A rename is something that happened, not something that is done.
  3. No tactical solutions.
  4. Filenames are a bounded context, not a string.
  5. Humans never touch the filesystem directly. Humans caused the current filenames.

Logical architecture

  • Asset Ingestion Service: discovers photos on the edge region.
  • EXIF Extraction Service: reads capture metadata and publishes it to the Naming Policy Engine, which ignores it.
  • Naming Policy Engine: decides what a photo is allowed to be called.
  • Ordinal Allocation Service: issues the numbers 1 to 40, idempotently.
  • Ordinal Allocation Proxy: calls the Ordinal Allocation Service.
  • Collision Detection Service: makes sure no two photos become IMG_0001.
  • Rename Saga Orchestrator: coordinates the rename, with a compensating rename back if it fails.
  • Filename History Read Model: the CQRS projection of what each photo used to be called.

Diagram

flowchart LR
  H["Legacy (do not touch): the stakeholder"] -->|"drag-and-drop (untrusted)"| BFF["Photo BFF"]
  BFF -->|mTLS| GW["Kong API Gateway"]
  GW --> KC["Keycloak: may this human rename?"]
  GW --> ING["Asset Ingestion Service"]
  subgraph EU["Region: eu-west"]
    ING -->|"async (eventually)"| K1[("Kafka: photo.rename.requested, 64 partitions")]
    K1 --> EXIF["EXIF Extraction Service"]
    EXIF --> NPE["Naming Policy Engine"]
    NPE --> OAP["Ordinal Allocation Proxy"]
    OAP -->|gRPC| OAS["Ordinal Allocation Service"]
    OAS --> COL["Collision Detection Service"]
    COL --> SAGA["Temporal: Rename Saga"]
    SAGA -->|"async (eventually)"| K2[("Kafka: photo.renamed")]
    K2 --> FL["Flink: rename reconciliation"]
    FL -->|replay| COL
  end
  subgraph US["Region: us-east (active-active)"]
    CAS[("Cassandra: filename history")]
    ES[("Elasticsearch: former names")]
  end
  K2 --> CAS
  CAS --> ES
  SAGA -->|mTLS| EDGE["Edge Region: the laptop"]
  EDGE -->|"async (eventually)"| ING
  ES --> GRAF["Grafana: single pane of glass"]
  NPE -.-> AI["Future: AI Layer (names photos by vibe)"]
  CAS -.-> BC["Future: Blockchain (paused)"]

Legend: blue is strategic, amber is tactical (deprecated), grey is owned by delivery.

Technology choices

Component Technology Justification
Rename events Apache Kafka A replicated commit log with replay, so any rename can be repeated indefinitely. 64 partitions give each photo 1.6.
Rename coordination Temporal Replays workflow code from its event history, so the rename survives a crash of the laptop it runs on.
Reconciliation Apache Flink Event-time windows detect when the stakeholder has stopped dragging photos.
Filename history Apache Cassandra Masterless replication built for heavy write loads. 40 writes is a heavy write load spread thin.
Former-name search Elasticsearch Inverted indexes over IMG_4417.JPG.
Service-to-service Istio Envoy sidecars give mTLS between the Ordinal Allocation Service and its proxy, which run on the same node.
Identity Keycloak OIDC for one user, plus SSO into nothing.
Infrastructure Terraform Declares three regions in HCL. The laptop is out of state and has been flagged.

Rejected alternatives

The stakeholder proposed Finder's built-in batch rename: select all 40, right-click, Rename. Nearby, someone also proposed a shell for-loop. Both were rejected as tactical, as not scaling past 40, and as having no clear ownership model. Finder writes no events and has no SLO, and it does not let anyone replay a rename. It is a very natural first instinct. Most instincts are.

Risks

Risk Mitigation
R1: Collision between two IMG_0001 Collision Detection Service, reconciled by Flink, reconciled again by Flink
R2: Edge region closes its lid Multi-region active-active. The photos stay on the laptop.
R3: Kafka consumer lag exceeds the total number of photos Add partitions
R4: The requester (tactical mindset; renames things by hand) Keycloak RBAC; Legacy node kept behind the BFF
R5: Stakeholder expectation of delivery Socialisation

Indicative cost

$37,480/month excluding egress of 40 JPEGs, which is lean. Licensing TBC with Procurement, who have been informed and are thrilled.

Roadmap

Phase Scope Duration
1. Foundations Clusters, mesh, IaC, Kafka, an on-call rota for the Ordinal Allocation Proxy 18 months
2. Platform Naming-as-a-Service, onboarding of the first tenant (the laptop) 9 months
3. Re-platform Migration off the Phase 2 platform onto the target state 12 months
4. Business value The 40 photos are renamed Month 41, indicative

I have booked the ARB slot. It is in March.

Next steps

  1. Raise ADR-0001: "Photos are events."
  2. Socialise with stakeholders.
  3. Book a follow-up ARB slot to review the March slot.
  4. Ask the delivery teams to keep the photos as they are until Phase 4.