Validate and update C4 architecture diagrams against the codebase. Usage: /validate-c4-diagrams
Validate and update the C4 architecture diagrams (AIR-wide overview in docs/diagrams/, Air Automations diagrams in
automations/docs/diagrams/C4/) to match the current codebase.
Read these sources to build a picture of the actual architecture:
automations/docs/SERVICES.md — canonical service map with ports, URLs, environments, and external dependenciesautomations/apps/*/package.json — each service's name, dependencies, and tech stack (all five are NestJS on the Fastify adapter)automations/apps/*/src/config/env.config.ts — each service's external dependency URLs (the source of truth for dependency edges)automations/apps/*/deploy/values.yaml — deployment topology: ports, probes, gatewayPrefix/httpRoute exposure, Kafka, databases@concierge/*-client, controllers)automations/CLAUDE.md — the Architecture section for canonical service descriptionscloud/backend config (Config.kt, application*.conf) — Air Cloud backend dependencies (for the AIR-wide overview)cloud/frontend/vite.config.ts — frontend API proxies → which backends the frontend callsdocs/ARCHITECTURE.md — the repo-level system overview (Mermaid); must stay consistent with the diagramsBuild a structured summary:
Service: <name>
Package: @concierge/<name> | @air/<name>
Framework: NestJS | Ktor | React/Vite
Port: <port>
Status: active | deferred | deprecated
Calls: [list of services it calls]
Called by: [list of services that call it]| Diagram | File | What it shows |
|---|---|---|
| AIR Services Overview | docs/diagrams/air-services-overview.puml | Whole context: Air Cloud + Air Automations + JCP platform dependencies |
| System Context | automations/docs/diagrams/C4/context-diagram.puml | External actors, JCP boundary, Agentic Core, AIR product |
| Container | automations/docs/diagrams/C4/container-diagram.puml | All containers, workstream color coding, relationships |
| Deployment (Air Automations) | automations/docs/diagrams/C4/deployment-diagram.puml | AWS EKS clusters, namespaces, JCP API Gateway exposure, Kafka, RDS |
| Deployment (Air Cloud) | cloud/docs/diagrams/C4/deployment-diagram.puml | Air Cloud (jcp-airwebex) EKS topology, frontend served into the JCP Console, backend behind the API Gateway, Kafka, RDS |
| Triggering Subsystem | automations/docs/diagrams/C4/triggering-subsystem-diagram.puml | Webhook/direct/scheduled trigger flows through Gateway and Launcher |
| Monitoring | docs/diagrams/monitoring-architecture-diagram.puml | AIR-wide service relations for monitoring: Air Cloud + Air Automations apps, JCP dependencies, edge → dashboard panel mapping |
Historical diagrams live in automations/docs/diagrams/archive/ — do not validate or update them.
(Frozen snapshots and pre-Agent-Spawner concepts: Q1-DP container diagram, platform primitives,
Merge Agent Handler design, agent workflow, cloud-function state diagram.)
For each diagram, extract:
Compare and identify discrepancies:
AIR Services Overview (docs/diagrams/air-services-overview.puml):
env.config.ts (automations) and Config.kt/application.conf (cloud backend)?docs/ARCHITECTURE.md? (Update both together.)Container diagram (container-diagram.puml):
automations/apps/ represented as containers?SERVICES.md?Context diagram (context-diagram.puml):
Deployment diagram (deployment-diagram.puml):
eks-eu-west-1 / eks-staging-eu-west-1 / eks-prod-eu-west-1), namespaces jcp-air-automations-{stgn|preprod|prod} (SERVICES.md)gatewayPrefix + httpRoute in deploy/values.yaml are behind the JCP API Gateway; the rest are cluster-internalvalues.yaml)Triggering subsystem (triggering-subsystem-diagram.puml):
apps/gateway/src/modules/{automations,events}/)? Routes are automation-id based.Monitoring diagram (monitoring-architecture-diagram.puml):
apps/*/src/config/env.config.ts, apps/*/package.json)?packages/nestjs-otel/src/sdk.ts and apps/*/src/instrumentation.ts?apps/*/deploy/values.yaml and automations/docs/monitoring-and-logging.md?Status tags across all diagrams:
Print a structured report grouped by diagram:
## Discrepancy Report
### container-diagram.puml
| Element | Diagram Says | Code Says | Suggested Change |
|---------|-------------|-----------|-----------------|
| Gateway | "Fastify" | NestJS (package.json) | Update tech label |
| ... | ... | ... | ... |
### No issues found:
- context-diagram.puml ✓Cite file:line evidence for every claimed discrepancy. If no discrepancies are found in any diagram, report that all diagrams are up to date.
Before modifying any diagram:
When updating .puml files, preserve:
skinparam blocks (styling) — all current diagrams use Dpi 300; keep it that wayLay_* directives (layout hints)AddElementTag / AddRelTag definitions (color coding)SHOW_LEGEND() and footer linesOnly change:
Container, System, Person, etc.) — labels, tech stack, descriptionsRel, Rel_R, Rel_D, etc.) — descriptions, tags$tags="...")Readability rules (learned the hard way — keep diagrams scannable):
note ... of <element> when the element is inside a boundary — notes are layout nodes and distort
clusters (observed swings of 6000px+). Prefer prose in the companion doc; at most one legend-like note
attached to a standalone element.Lay_D columns over long Lay_R rows for groups of 4+ elements.Rel_U creates reverse rank constraints that can force clusters side by side; use plain Rel for
back-edges (e.g. Kafka consumption) when stacking matters.System / System_Ext have NO technology parameter (only Container does). A 4th positional string
is silently parsed as a sprite name and renders as literal <$...> text inside the box. Fold the
technology into the description: System_Ext(alias, "Label", "tech — description", $tags=...).C4-PlantUML macro signatures — positional args only; pass $tags/$link as named args. An extra
positional string never errors — it becomes a sprite and renders as literal <$...> text in the box:
| Macro | Positional signature |
|---|---|
Person[_Ext], System[_Ext|Db|Queue] | (alias, label, ?descr) — no technology slot |
Container[_Ext|Db|Queue], Component[_Ext|Db] | (alias, label, ?techn, ?descr) |
System_Boundary, Container_Boundary | (alias, label) |
Deployment_Node | (alias, label, ?type, ?descr) |
Rel, Rel_R/L/U/D, BiRel* | (from, to, label, ?techn, ?descr) |
After editing, lint macro arity before rendering — count positional strings per call and flag any
Person/System*/*_Boundary call with >2, or Container*/Component*/Deployment_Node/Rel*
with >3:
grep -nE 'System(_Ext|Db|Queue)?\(\w+, ("[^"]*", ){2,}"' <diagram>.puml # systems with a 3rd string
grep -nE '(Person|_Boundary)\w*\(\w+, ("[^"]*", ){2,}"' <diagram>.puml # persons/boundaries with a 3rd string
grep -nE '(Container|Component)\w*\(\w+, ("[^"]*", ){3,}"' <diagram>.puml # containers with a 4th string
grep -nE 'Rel\w*\(\w+, \w+, ("[^"]*", ){3,}"' <diagram>.puml # rels with a 4th stringEvery .puml has a rendered PNG in a sibling renders/ directory; re-render after any source change.
Standard settings: all current diagrams use Dpi 300 in their skinparam block. At that DPI the wider diagrams
exceed PlantUML's default 4096px canvas limit, and PlantUML silently clips oversized output instead of erroring —
always render with PLANTUML_LIMIT_SIZE=20000.
Preferred (no local install needed) — the official Docker image bundles the C4-PlantUML stdlib:
cd <directory containing the .puml>
docker run --rm -e PLANTUML_LIMIT_SIZE=20000 -v "$PWD":/data plantuml/plantuml \
-tpng -o renders/ /data/<diagram>.pumlWith a local CLI (brew install plantuml):
PLANTUML_LIMIT_SIZE=20000 plantuml -tpng -o renders/ <diagram>.pumlVerify nothing was clipped — PlantUML silently caps an oversized render at exactly 4096 px on one axis. Flag any render that hit the cap:
for f in renders/*.png; do
read w h < <(sips -g pixelWidth -g pixelHeight "$f" \
| awk '/pixelWidth/{w=$2}/pixelHeight/{h=$2}END{print w, h}')
if [ "$w" -eq 4096 ] || [ "$h" -eq 4096 ]; then
echo "CLIPPED (hit 4096px) → re-render with PLANTUML_LIMIT_SIZE=20000: $f (${w}x${h})"
else
echo "ok: $f (${w}x${h})"
fi
donedocs/diagrams/*.puml — AIR-wide overview diagram (source of truth for the whole-context visualization)automations/docs/diagrams/C4/*.puml — Air Automations C4 diagrams*/renders/*.png — rendered PNG outputs (always regenerate together with source changes)docs/ARCHITECTURE.md — repo-level overview (Mermaid) that must stay consistent with the diagramsautomations/docs/SERVICES.md — canonical service map with ports and URLsautomations/apps/*/package.json, automations/apps/*/src/config/env.config.ts — service tech stacks and dependenciesautomations/CLAUDE.md — architecture section with service descriptionsb758a8e
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.