Skip to content

feat(#67): /handover generates a stub C4 L2 container diagram#70

Merged
atlas-apex merged 4 commits into
mainfrom
feature/#67-handover-c4-stub
Apr 17, 2026
Merged

feat(#67): /handover generates a stub C4 L2 container diagram#70
atlas-apex merged 4 commits into
mainfrom
feature/#67-handover-c4-stub

Conversation

@atlas-apex

Copy link
Copy Markdown
Collaborator

Summary

Extends /handover with a new step that writes a projects/<name>/architecture/container.md stub alongside the existing handover assessment. Detection covers six slots (web / api / worker / db / cache / queue) plus five external-system families (auth / payments / email / storage / LLM), with docker-compose.yml overriding package.json when both exist.

What changed

Testing

Doc-only change to the SKILL.md. No executable code; no unit tests.

Validation comes from the next real /handover invocation on a JS/TS project (the detection tables are richest there; Python / Go / Rust / Ruby are covered but not as deeply as Node). The generated file should:

  • Render on GitHub immediately (Mermaid inline)
  • Match the c4-container.md template shape
  • Have a top note explicitly calling out "auto-generated on YYYY-MM-DD — refine me"
  • Skip gracefully if projects/<name>/architecture/container.md already exists

Non-goals / deferred

  • L1 context stub — L1 requires external-system knowledge the repo signals don't always expose reliably. If added later, it becomes step 6a.
  • Automatic rel/edge inference from code (e.g. parse fetch() calls to infer "api → llm-api") — too much false-positive risk. The skill emits a reasonable first-pass wiring and lets the team refine.
  • Non-Mermaid formats — see [Feature] Structurizr DSL as escape hatch for L3+ C4 diagrams #68 (deferred Structurizr DSL for L3+).

Glossary

Term Definition
C4 L2 container Deployable / runnable unit inside the system boundary (web app, API, worker, database)
detection signal A file or package that reveals a container's existence (e.g. prisma/schema.prismaContainerDb)
slot A category in the detection table (web / api / worker / db / cache / queue / external) — each slot emits at most one container unless multiple services fit (workers, caches)
override When docker-compose.yml exists, it supersedes package.json for composition — compose describes the actual deployment shape
stub A starting-point file meant to be refined by the team, with an explicit "auto-generated — review me" header

Related

Adds step 6 to /handover: after writing the assessment, emit a stub
projects/<name>/architecture/container.md derived from repo signals.

Detection table covers five container slots + external-system inference:

- web (Next.js / React/CRA / Vite / Remix / SvelteKit / Nuxt / Angular
  / src/components heuristic)
- api (Express / Fastify / Hono / NestJS / Koa / Next.js API routes /
  Go+gin / FastAPI / Django / Flask / Rails / Sinatra / Rust+axum /
  actix / rocket / fiber / chi / echo)
- worker (BullMQ / bee-queue / agenda / Inngest / workers/ dir /
  Celery)
- db (Prisma schema.prisma incl. provider extraction / Drizzle /
  Knex / DATABASE_URL protocol sniff / Supabase / Firestore)
- cache (ioredis / redis / @upstash/redis / memcached / memjs,
  REDIS_URL / UPSTASH_REDIS_URL .env hints)
- queue (SQS SDK / kafkajs / amqplib — only when distinct from worker)

Externals: Auth0 / Clerk / Supabase Auth / next-auth → Auth Provider;
Stripe / Paddle → Payment Processor; Postmark / SendGrid / Resend /
SES → Email Provider; S3 / Vercel Blob / R2 → Object Storage;
OpenAI / Anthropic / Google AI → LLM API.

docker-compose.yml overrides package.json (compose services ARE the
containers). Dockerfile-only case: one container with FROM-derived
tech label, no fabricated DB.

Skip semantics:

- Existing architecture/container.md is preserved, NEVER overwritten
  (rule #11). Team refinements survive re-runs.
- Zero signals detected → skip file entirely, note in summary, don't
  fabricate a diagram.

Updated:

- Output-location section mentions both files
- Summary in step 8 includes architecture/container.md status (written
  | preserved | skipped)
- Rules #11 (never overwrite) and #12 (starting point, not truth) added
- Stub file includes a "auto-generated on YYYY-MM-DD — refine me"
  header so the team knows to review

Closes #67

@atlas-apex atlas-apex left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review: PR #70

Commit: 1df34e5f8a645cb63ee6b3d958892c5016bf2b73

Summary

Doc-only extension of /handover SKILL.md adding step 6 that emits a stub C4 L2 container diagram from repo signals. Six slots (web / api / worker / db / cache / queue) plus five external families, with docker-compose.yml overriding package.json. Skip-if-exists, summary distinguishes written | preserved | skipped, rules #11/#12 protect the stub from overwrite.

Checklist Results

  • Architecture & Design: Pass (doc-only)
  • Code Quality: Pass
  • Testing: N/A (process doc)
  • Security: Pass (rule #8 .env never-read preserved)
  • Performance: N/A
  • PR Description & Glossary: Pass (5 terms)
  • Technical Decisions (AgDR): N/A — implements earlier decision (#67, template from #50); no new tech choice

Findings

Detection table (spot-checked):

  • @auth0/* → Auth0 — correct (@auth0/nextjs-auth0, @auth0/auth0-react)
  • prisma/schema.prisma with provider = "postgresql" → PostgreSQL — correct Prisma datasource syntax
  • ioredis / redis / @upstash/redis → Redis — correct
  • @aws-sdk/client-sqs → SQS queue — correct

Next.js web+api collapse logic: Actionable. "Collapse web + api into one container labelled Web App + API" is explicit. The api-row qualifier "same container as web, or split if clearly separate service" is slightly soft — a naive read could emit two — but the dedicated monolith paragraph plus rule #12 disambiguate. Acceptable.

docker-compose precedence: Clear — "When compose and package.json conflict, trust compose."

Skip-if-exists vs skipped: Unambiguous. preserved = file exists, skipped = zero signals. Rule #11 enforces never-overwrite.

Step renumbering integrity: Clean. All internal refs checked (line 181 "step 7", line 250 "step 3", line 457 "step 8", line 493 "step 3"). No stale pointers.

Non-goals boundary: Confirmed — no L1 context stub, no edge inference from code, no Structurizr DSL. Scope discipline held.

Suggestions (non-blocking)

  • drizzle.config.ts row leaves <driver> to be filled — consider noting the config uses a dialect: field as the hint source.

Verdict

APPROVED (posted as comment — cannot self-approve via GitHub review API)


Reviewed by Rex (Code Reviewer Agent)
Reviewed commit: `1df34e5f8a645cb63ee6b3d958892c5016bf2b73`

@atlas-apex atlas-apex merged commit 988f449 into main Apr 17, 2026
3 checks passed
@atlas-apex atlas-apex deleted the feature/#67-handover-c4-stub branch April 17, 2026 10:24
osama-abu-baker pushed a commit to osama-abu-baker/apexyard that referenced this pull request Jun 3, 2026
…e2resh#70)

* feat(me2resh#67): /handover generates a stub C4 L2 container diagram

Adds step 6 to /handover: after writing the assessment, emit a stub
projects/<name>/architecture/container.md derived from repo signals.

Detection table covers five container slots + external-system inference:

- web (Next.js / React/CRA / Vite / Remix / SvelteKit / Nuxt / Angular
  / src/components heuristic)
- api (Express / Fastify / Hono / NestJS / Koa / Next.js API routes /
  Go+gin / FastAPI / Django / Flask / Rails / Sinatra / Rust+axum /
  actix / rocket / fiber / chi / echo)
- worker (BullMQ / bee-queue / agenda / Inngest / workers/ dir /
  Celery)
- db (Prisma schema.prisma incl. provider extraction / Drizzle /
  Knex / DATABASE_URL protocol sniff / Supabase / Firestore)
- cache (ioredis / redis / @upstash/redis / memcached / memjs,
  REDIS_URL / UPSTASH_REDIS_URL .env hints)
- queue (SQS SDK / kafkajs / amqplib — only when distinct from worker)

Externals: Auth0 / Clerk / Supabase Auth / next-auth → Auth Provider;
Stripe / Paddle → Payment Processor; Postmark / SendGrid / Resend /
SES → Email Provider; S3 / Vercel Blob / R2 → Object Storage;
OpenAI / Anthropic / Google AI → LLM API.

docker-compose.yml overrides package.json (compose services ARE the
containers). Dockerfile-only case: one container with FROM-derived
tech label, no fabricated DB.

Skip semantics:

- Existing architecture/container.md is preserved, NEVER overwritten
  (rule me2resh#11). Team refinements survive re-runs.
- Zero signals detected → skip file entirely, note in summary, don't
  fabricate a diagram.

Updated:

- Output-location section mentions both files
- Summary in step 8 includes architecture/container.md status (written
  | preserved | skipped)
- Rules me2resh#11 (never overwrite) and me2resh#12 (starting point, not truth) added
- Stub file includes a "auto-generated on YYYY-MM-DD — refine me"
  header so the team knows to review

Closes me2resh#67

* fix: switch to ~~~ fence to avoid MD001 false-positive from nested backticks

* fix: replace nested fenced block with prose instructions (markdownlint MD031)

* fix: bump outer template fence to 4 backticks so inner yaml fence doesn't prematurely close (MD031)

---------

Co-authored-by: me2resh <ahmed.abdelaliem@gmail.com>
mosta7il pushed a commit to mosta7il/apexyard that referenced this pull request Jun 8, 2026
…e2resh#70)

* feat(me2resh#67): /handover generates a stub C4 L2 container diagram

Adds step 6 to /handover: after writing the assessment, emit a stub
projects/<name>/architecture/container.md derived from repo signals.

Detection table covers five container slots + external-system inference:

- web (Next.js / React/CRA / Vite / Remix / SvelteKit / Nuxt / Angular
  / src/components heuristic)
- api (Express / Fastify / Hono / NestJS / Koa / Next.js API routes /
  Go+gin / FastAPI / Django / Flask / Rails / Sinatra / Rust+axum /
  actix / rocket / fiber / chi / echo)
- worker (BullMQ / bee-queue / agenda / Inngest / workers/ dir /
  Celery)
- db (Prisma schema.prisma incl. provider extraction / Drizzle /
  Knex / DATABASE_URL protocol sniff / Supabase / Firestore)
- cache (ioredis / redis / @upstash/redis / memcached / memjs,
  REDIS_URL / UPSTASH_REDIS_URL .env hints)
- queue (SQS SDK / kafkajs / amqplib — only when distinct from worker)

Externals: Auth0 / Clerk / Supabase Auth / next-auth → Auth Provider;
Stripe / Paddle → Payment Processor; Postmark / SendGrid / Resend /
SES → Email Provider; S3 / Vercel Blob / R2 → Object Storage;
OpenAI / Anthropic / Google AI → LLM API.

docker-compose.yml overrides package.json (compose services ARE the
containers). Dockerfile-only case: one container with FROM-derived
tech label, no fabricated DB.

Skip semantics:

- Existing architecture/container.md is preserved, NEVER overwritten
  (rule me2resh#11). Team refinements survive re-runs.
- Zero signals detected → skip file entirely, note in summary, don't
  fabricate a diagram.

Updated:

- Output-location section mentions both files
- Summary in step 8 includes architecture/container.md status (written
  | preserved | skipped)
- Rules me2resh#11 (never overwrite) and me2resh#12 (starting point, not truth) added
- Stub file includes a "auto-generated on YYYY-MM-DD — refine me"
  header so the team knows to review

Closes me2resh#67

* fix: switch to ~~~ fence to avoid MD001 false-positive from nested backticks

* fix: replace nested fenced block with prose instructions (markdownlint MD031)

* fix: bump outer template fence to 4 backticks so inner yaml fence doesn't prematurely close (MD031)

---------

Co-authored-by: me2resh <ahmed.abdelaliem@gmail.com>
G0maa added a commit to marsa-cloud/apexyard that referenced this pull request Jun 13, 2026
…books

Nine new Rex handbooks from @G0maa's review on marsa-cloud/marsa#70:

- builder-constructor-defaults — builders seed sensible defaults via constructor
- nullable-column-type — nullable columns typed T | null
- uuid-primary-key-naming — UUID PKs named uuid, FKs *_uuid
- explicit-fk-relation — model relations as typed Ref<Parent> (ref: true)
- test-layer-boundaries — unit use-cases, e2e endpoints, no repository unit tests
- sinon-stub-instance — stub collaborators with createStubInstance
- external-client-seam — one abstract client seam per external service (AgDR-0014)
- constants-file — magic values in .constant(s).ts
- types-file-placement — shared types in .types.ts

Refs #9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] /handover skill generates a stub C4 L2 container diagram

2 participants