Canonical Example

This example demonstrates how the ABC Pattern structures a real application using only:

  • Constructs (ABC‑C0)

  • Application Stack (ABC‑C1)

  • Logical Units (ABC‑C2)

  • Resource Groups (ABC‑C3)

  • Input/Output Contracts (ABC‑C4, ABC‑C5)

  • Instantiation Interface (ABC‑C6)

  • Capturing Down (ABC‑C7)

  • Bubbling Up (ABC‑C8)

Every interaction is explicit. Every dependency is visible. Nothing leaks sideways.

Overview

We model a classic 3‑tier architecture:

  • Data Tier - database + storage

  • Logic Tier - compute + messaging

  • Presentation Tier - CDN + web frontend

Each tier is a Logical Unit (ABC‑C2).

Each component inside a tier is a Resource Group (ABC‑C3).

The Application Stack (ABC‑C1) composes them, wires them, and exposes the final outputs.

Conceptual Diagram

                 ┌──────────────────────────────┐
                 │       Application Stack      │
                 │          (ABC‑C1)            │
                 └─────────────┬────────────────┘
                               │
        ┌──────────────────────┼────────────────────────┐
        │                      │                        │
┌───────▼────────┐    ┌───────▼────────┐      ┌─────────▼────────┐
│  DataUnit      │    │    LogicUnit   │      │ PresentationUnit │
│   (C2)         │    │      (C2)      │      │      (C2)        │
└───────┬────────┘    └───────┬────────┘      └────────┬─────────┘
        │                     │                        │
        │                     │               ┌────────│──────┐
   ┌────▼─────┐         ┌────▼─────┐     ┌────▼──────┐ ┌──────▼─────┐
   │StorageGrp│         │ComputeGrp│     │WebAppGrp  │ │  CDNGrp    │
   │   (C3)   │         │   (C3)   │     │   (C3)    │ │   (C3)     │
   └──────────┘         └──────────┘     └───────────┘ └────────────┘

Application Stack (ABC‑C1)

The Application Stack is the root construct.

It has no parent and defines the deployment boundary.

Responsibilities

  • Instantiate each Logical Unit (ABC‑R1).

  • Provide downward inputs (ABC‑F1).

  • Receive upward outputs (ABC‑F2).

  • Route outputs between Logical Units (ABC‑R44).

  • Expose a final Output Contract representing the whole system.

Input Contract (ABC‑C4)

The Application Stack receives only global configuration:

AppStackInputs:
  environment: string
  region: string
  global_tags: map<string,string>

Output Contract (ABC‑C5)

The Application Stack exposes:

AppStackOutputs:
  frontend_url: string
  api_endpoint: string

These values originate from the Presentation and Logic tiers, respectively.

Logical Units (ABC‑C2)

Each Logical Unit encapsulates a functional domain.

They do not know about each other.

They communicate only through the Application Stack.

We define three:

  • DataUnit

  • LogicUnit

  • PresentationUnit

Each has its own Input/Output Contracts and internal Resource Groups.

Data Logical Unit (ABC‑C2)

Purpose

Provide persistent storage and database capabilities.

Resource Groups (ABC‑C3)

  • StorageGroup - object storage

  • DatabaseGroup - relational database

Input Contract

DataUnitInputs:
  environment: string
  region: string
  storage_class: string
  db_engine: string
  db_instance_size: string

Output Contract

DataUnitOutputs:
  storage_bucket_name: string
  database_endpoint: string

Internal Wiring

  • StorageGroup produces storage_bucket_name.

  • DatabaseGroup produces database_endpoint.

  • DataUnit aggregates both and bubbles them up (ABC‑F2).

Note

  • StorageGroup and DatabaseGroup do not know about each other (ABC‑R10).

  • All configuration flows downward from DataUnit (ABC‑F1).

Logic Logical Unit (ABC‑C2)

Purpose

Provide compute and messaging capabilities for the application backend.

Resource Groups

  • ComputeGroup - application compute (e.g., functions, containers)

  • MessagingGroup - queue or pub/sub system

Input Contract

LogicUnitInputs:
  environment: string
  region: string
  compute_size: string
  message_retention: number
  database_endpoint: string   # Provided by DataUnit via AppStack

Output Contract

LogicUnitOutputs:
  api_endpoint: string
  message_queue_url: string

Internal Wiring

  • ComputeGroup receives database_endpoint via Capturing Down (ABC‑F1).

  • MessagingGroup is independent.

  • LogicUnit aggregates outputs and bubbles them up.

Note

  • LogicUnit does not know where the database came from.

  • It only knows it received a database_endpoint in its Input Contract (ABC‑R22).

Presentation Logical Unit (ABC‑C2)

Purpose

Serve the frontend and expose the public entry point.

Resource Groups

  • CDNGroup - global content distribution

  • WebAppGroup - static or dynamic frontend

Input Contract

PresentationUnitInputs:
  environment: string
  region: string
  frontend_assets_bucket: string
  api_endpoint: string   # Provided by LogicUnit via AppStack

Output Contract

PresentationUnitOutputs:
  frontend_url: string

Internal Wiring

  • WebAppGroup receives api_endpoint via Capturing Down.

  • CDNGroup receives the output of WebAppGroup.

  • PresentationUnit bubbles up the final frontend_url.

Resource Groups (ABC‑C3)

Each Resource Group is a small, focused construct with:

  • A minimal Input Contract

  • A minimal Output Contract

  • No knowledge of siblings

  • No access to parent state except via inputs

  • No side effects during instantiation (ABC‑R33)

Example: Database Group

Input Contract

DatabaseGroupInputs:
  db_engine: string
  db_instance_size: string
  environment: string

Output Contract

DatabaseGroupOutputs:
  database_endpoint: string

Instantiation Interface

new DatabaseGroup(DatabaseGroupInputs) -> DatabaseGroupOutputs

This pattern repeats for all Resource Groups.

Full Data Flow (ABC‑F1 and ABC‑F2)

The complete data flow includes:

  • AppStack → Logical Units

  • Logical Units → Resource Groups

  • Resource Groups → Logical Units

  • Logical Units → AppStack

This is the full vertical chain required by the ABC Pattern.

Downward Flow (Capturing Down — ABC‑F1)

  1. AppStack → DataUnit
    • environment

    • region

    • storage_class

    • db_engine

    • db_instance_size

  2. DataUnit → StorageGroup
    • environment

    • region

    • storage_class

  3. DataUnit → DatabaseGroup
    • environment

    • db_engine

    • db_instance_size

  4. AppStack → LogicUnit

    • environment

    • region

    • compute_size

    • message_retention

    • database_endpoint (bubbled up from DataUnit)

  5. LogicUnit → ComputeGroup
    • environment

    • compute_size

    • database_endpoint

  6. LogicUnit → MessagingGroup
    • environment

    • message_retention

  7. AppStack → PresentationUnit
    • environment

    • region

    • frontend_assets_bucket

    • api_endpoint (bubbled up from LogicUnit)

  8. PresentationUnit → WebAppGroup
    • environment

    • frontend_assets_bucket

    • api_endpoint

  9. PresentationUnit → CDNGroup
    • environment

    • webapp_origin_url (bubbled up from WebAppGroup)

Upward Flow (Bubbling Up — ABC‑F2)

  1. StorageGroup → DataUnit
    • storage_bucket_name

  2. DatabaseGroup → DataUnit
    • database_endpoint

  3. DataUnit → AppStack
    • storage_bucket_name

    • database_endpoint

  4. ComputeGroup → LogicUnit
    • api_endpoint

  5. MessagingGroup → LogicUnit
    • message_queue_url

  6. LogicUnit → AppStack
    • api_endpoint

    • message_queue_url

  7. WebAppGroup → PresentationUnit
    • webapp_origin_url

  8. CDNGroup → PresentationUnit
    • frontend_url

  9. PresentationUnit → AppStack
    • frontend_url

Rationale

This example demonstrates:

  • Strict encapsulation

  • Explicit dependencies

  • No lateral references

  • Deterministic wiring

  • Testability at every level

  • Predictable evolution

  • Agent‑friendly structure

It is the canonical reference for all profiles (CDK, Terraform, etc.).