The ONDEMANDENV Platform

A contract-orchestration layer for distributed systems on AWS. Services declare their interfaces as typed code. The platform proves compatibility at compile time — not at runtime, not in staging.

This is where the Semantic Engineering thesis stops being a claim and becomes a build step: the "living model" is the contractsLib, and every mechanism below — Envers, Producer/Consumer edges, Constellations — is how that model gets enforced, not just described.

The CI/CD Inversion

Conventional CI/CD versions artifacts — container images, Lambda zips, Helm charts — and discovers whether a new version is compatible with its neighbors by running them together. Staging is a compatibility-discovery mechanism dressed up as a QA gate.

ONDEMANDENV inverts this. The contractsLib versions the interfaces, and artifacts are derived from them. Services do not generate contracts; contracts generate the constraints that services must satisfy.

❌ Conventional CI/CD

  • Unit of versioning: Service artifact (image/zip)
  • Contract between services: Implicit, in READMEs
  • Compatibility discovered: At runtime in staging
  • Phase / environment: Separate axes that drift
  • Promotion model: Promote a bag across stages
  • Blue/green: Per environment, not per edge

✅ ONDEMANDENV

  • Unit of versioning: Interface (ContractsLib package)
  • Contract between services: Typed OdmdCrossRefProducer / Consumer with schema artifact
  • Compatibility discovered: At tsc / odmdValidate() — synth time
  • Phase / environment: Collapsed: phase = enver = revision
  • Promotion model: Add new graph nodes; consumers migrate per edge
  • Blue/green: Per producer/consumer edge — traffic shifts per edge, not per environment

What the inversion unlocks:

  • Compatibility is deductive, not observational. If the graph validates and every service compiled against its generated types, every producer/consumer pair is provably compatible. You don't need to run them together to find out.
  • Constellations coexist. Many constellations (mock, dev, main-v1, main-v2) can live in the same AWS accounts simultaneously. Cloning a constellation for a feature branch is cheap.
  • Contract errors surface early. Wrong cross-ref, missing schema, cross-region edge — odmdValidate() throws at synth, before any CloudFormation stack moves.

The cost is real: all distributed-systems complexity migrates into the ContractsLib. You are trading runtime surprise for design-time rigor.

1. The ContractsLib: A Legislature, Not a Registry

The contractsLib is a version-controlled TypeScript library that declares every service, every deployable version of every service, and every producer/consumer edge between them — with schema artifacts attached as children of the edges. This is the "living model" from the philosophy made literal: not a diagram of intent, but a compiled artifact that is the intent, and that fails to publish if the intent is inconsistent.

Think of it as the congress of your distributed system, not a service registry:

A service registry is passive: it records what services say about themselves. A legislature is active: it's where services negotiate, enact, and are bound. Your PRs to ContractsLib are legislation; its compiled output is law.

Hard constraints — enforced at construction, no opt-outs:

  • A build cannot consume from itself — intra-service coupling is plain TypeScript, not a producer/consumer pair.
  • ContractsLib envers cannot be consumers — the legislature cannot depend on the services whose laws it writes.
  • Cross-region consumers are forbidden — cross-region communication is modeled as distinct producers per region.
  • Container-image envers cannot be consumers — image-build envers are producer-only (they export an ECR image reference).
  • Every build and enver must have doc paths that resolveodmdValidate() fails if serviceOverviewMD, serviceContextMD, or enverContextMD point to missing files. Docs are part of the contract.

2. Enver (Environment Version): Phases Collapsed onto One Axis

An Enver is a complete, deployable version of a service's bounded context — its entire stack: infrastructure, dependencies, build pipeline, and monitoring. It is the unit of evolution: where the model, once compiled, becomes a running, disposable projection instead of a document about a system.

The core insight: development phases and deployment environments are the same axis. There is no separate "environment" concept. An enver is a phase.

Phase Enver (branch) Purpose
Phase 0 mock Contract verification — mocked responses, BDD validation, schema publishing. No real business logic.
Phase 1 dev MVP — real domain logic, cross-service integration, data persistence.
Phase 2 main Production — security hardening, observability, load testing, compliance.

Canonical progression: mock → dev → main. No forward references — a mock enver never consumes a dev producer.

Two kinds of enver:

Each enver provides a complete SDLC context: unique endpoints, isolated infrastructure, automated build and deploy, built-in BDD, and per-enver monitoring. Clone one with a single commit message to get a full isolated copy for a feature branch.

3. Producer / Consumer: Typed Edges with Schema Artifacts

Services declare what they publish and what they depend on using OdmdCrossRefProducer and OdmdCrossRefConsumer in ContractsLib. These are the edges of the contract graph.

// In ContractsLib — producer declares a base URL + schema artifact child
export class OrderEnver extends OdmdEnverCdk {
  readonly orderApiBaseUrl = new OdmdCrossRefProducer(
    this, 'orderApiBaseUrl',
    { children: [{ pathPart: 'schema-url', s3artifact: true }] }
  );
}

// Consumer declares its dependency on the producer
export class PaymentEnver extends OdmdEnverCdk {
  readonly orderApiBaseUrl = new OdmdCrossRefConsumer(
    this, 'orderApiBaseUrl', orderEnver.orderApiBaseUrl
  );
}

At deploy time: Producers publish their base URL and schema artifact via OdmdShareOut (backed by AWS SSM Parameter Store). Consumers read them via OdmdShareIn or getSharedValue() during CDK synth.

Schema artifacts are the mechanism that makes compatibility deductive. A producer attaches an OpenAPI 3.1 or AsyncAPI 2.x document as a child of its base URL producer. At build time, a consumer's build.sh:

  1. Downloads the upstream schema artifact from S3 via a SchemaTypeLoader utility (a platform-documented pattern your ContractsLib implements, not a class shipped in the base library).
  2. Generates Zod types into lib/handlers/src/__generated__/ via json-schema-to-zod.
  3. Compiles the handler against the generated types.

If the handler doesn't conform to the declared contract, tsc fails. The incompatibility is caught before any deployment.

Schema artifact kinds:

  • OpenAPI 3.1 — for REST-style APIs; includes paths and components.schemas. Consumers generate typed route helpers from operationId.
  • AsyncAPI 2.x — for topics, queues, and streams; includes channels and message schemas. Consumers generate typed channel helpers.
  • ODMD Bundle — a small envelope referencing multiple artifacts (e.g., { http: <openapi-url>, events: <asyncapi-url> }) while keeping a single schema-url address.

Consumers detect the artifact kind via a top-level discriminator: odmdKind: 'openapi' | 'asyncapi' | 'bundle'.

4. Constellation: Emergent, Not Declared

A Constellation is the subgraph of envers reachable by following producer/consumer edges from any starting enver. Constellations are emergent — they come into existence when ContractsLib wiring is enacted, not when anything is declared. They have no names, no registry, no enumeration. This is the closest thing on the platform to the model "coming alive": a constellation is what the living model looks like once it's running, and it is provably consistent because every edge in it already compiled.

How a constellation forms:

  1. Each service declares one or more envers in ContractsLib (mock, dev, main).
  2. Each enver declares producers and consumers.
  3. ContractsLib wires consumers to specific upstream producers (typically same-revision to same-revision).
  4. The transitive closure of those edges is a constellation.

"Mock constellation" is informal shorthand for the constellation rooted at mock-revision envers. It is not a class, type, or stack-name token. Multiple constellations coexist in the same AWS accounts, distinguished only by their SRC_Rev_REF (branch or tag).

Constellation rules:

  • No forward references. mock never consumes dev; dev never consumes main.
  • Account-agnostic. Revision→account mapping is an organizational choice, not part of the graph. The same constellation semantics work whether your org has one workspace account or ten.
  • Platform vs. application envers. Platform envers (__contracts, __user-auth, __networking) expose a single enver consumed across all constellations — one identity provider, one networking layer, shared. Application envers participate per-revision and evolve independently.
  • Do not encode revision labels in stack names. mock/dev/main belong to the enver's SRC_Rev_REF, not to resource names or stack IDs.

How It Works: The Contract-First Sequence

Bringing a new service onto the platform follows a contract-first sequence. Contracts are defined before a single line of implementation is written.

Step 1: ContractsLib

Define the service's OdmdBuild and envers (mock, dev, main). Declare each enver's producers (base URL + schema-url child) and consumers (upstream dependencies). Wire cross-build couplings after all builds exist.

Output: a compiled, validated contract graph. Every edge is type-checked. No service can deploy without a place in the graph.

Step 2: Service Scaffold

Each service repo initializes ContractsLib and resolves its target enver via ODMD_build_id + ODMD_rev_ref env vars. CDK stack names come from enver.getRevStackNames() — stable, revision-label-free. The stack publishes its base URL and schema via OdmdShareOut; it reads upstream values via OdmdShareIn.

Step 3: Build Orchestration

The platform runs .scripts/build.sh per repo. For consumers: download upstream schema artifacts → generate Zod types into __generated__/ → compile handler against generated types → build CDK stack. If the handler doesn't match its declared contract, tsc fails here, before any deployment.

Step 4: BDD Verification

Each enver ships a BDD stack deployed after the app stack. A Step Functions state machine calls service APIs using the master mock dataset and asserts schema-valid responses. An optional Playwright runner validates browser flows. BDD results are published via OdmdShareOut and gate promotion.

Step 5: Deployment Order

The platform deploys stacks in the order returned by getRevStackNames(). Producers deploy before consumers so SSM parameters are populated. Dependency changes automatically trigger downstream enver rebuilds — event-driven, not scheduled pipelines.

Phase Promotion

When mock contracts are verified, the service promotes to dev (real business logic). When MVP is validated, it promotes to main (production hardening). Each promotion is a graph evolution — new nodes added, consumers migrate per edge, old nodes retired when they have no remaining consumers.

Dynamic Cloning: Full Environments on Demand

Every feature branch can have its own complete, isolated enver — a full SDLC clone with unique endpoints, dedicated infrastructure, and independent lifecycle. Creating one requires a single commit message:

git commit -m "feat: new recommendation engine

odmd: create@dev"

The platform provisions a complete isolated environment. To tear it down: commit with odmd: delete.

Each cloned enver is resource-isolated — unique naming prevents conflicts. Static envers (mock, dev, main) are unaffected. Multiple developers and AI agents can run parallel experiments simultaneously, each with full infrastructure control, without shared-environment coordination.

A complete environment — VPC, database, load balancing, monitoring — provisions automatically from the graph, with no manual setup. The cost of experimentation drops to near zero.

Patterns in Practice

The platform's mechanics enable concrete solutions to recurring distributed-systems problems.

Pattern: Per-Branch Full SDLC Environments

Problem: Shared dev/QA environments create bottlenecks, contention, and configuration drift. Developers block each other. Integration failures are discovered late — in shared staging, where they affect everyone.

ONDEMANDENV Solution: Branch envers give each developer a complete, isolated copy of the system. Contracts are validated at tsc time — before anything is deployed — so integration failures surface on the developer's machine, not in shared staging. Staging becomes optional (or a dedicated performance-test environment), not the integration-discovery gate.

Pattern: Governed Sharing of Platform Infrastructure

Problem: Central teams manage shared infrastructure — VPCs, EKS clusters, transit gateways. Application teams need to consume these resources consistently across multiple accounts, but most IaC tools have no formal contract mechanism. Consumption is ad hoc, undocumented, and fragile.

ONDEMANDENV Solution: Platform envers (__networking, _default-vpc-rds, _default-kube-eks) publish their capabilities as formal OdmdCrossRefProducer outputs. Application envers declare typed OdmdCrossRefConsumer edges. The contract graph makes every dependency explicit and version-aware. When platform infrastructure changes, the graph identifies every affected consumer; the platform triggers their rebuilds automatically.

Pattern: AI Agents as First-Class Evolution Partners

Problem: AI code generators, lacking architectural context, produce code that violates domain boundaries, creates accidental cross-service coupling, and decays architectural integrity. Shared environments make AI experiments risky — a bad change can break everyone.

ONDEMANDENV Solution: The ContractsLib provides complete architectural context: declared interfaces, schema artifacts, hard constraints, and per-enver documentation paths (serviceContextMD, enverContextMD). Each AI agent gets its own cloned enver — full infrastructure isolation, no shared-environment risk. The platform enforces contracts at compile time regardless of who wrote the code. Successful experiments are promoted; failed ones are deleted. The graph retains the validated results.

Pattern: Per-Edge Blue/Green Without Environment Rebuilds

Problem: Traditional blue/green swaps an entire environment — every consumer gets the new version simultaneously. A breaking change requires coordinating all consumers before cutover, or spinning up a full parallel environment at significant cost.

ONDEMANDENV Solution: Interface versions are graph nodes, not states of a node. A service that needs a breaking API change publishes a new producer alongside the old one. Old consumers keep consuming the old producer; new consumers wire to the new one. Both run in the same account simultaneously. Traffic shifts per edge, not per environment. The old producer is retired only when no consumers point to it — retirement is visible in the graph.

Visualizing the Platform

These diagrams show the key structural contrasts and patterns in action.

Domain-First vs. X-Ops Flat World

The organized, domain-driven structure enabled by ONDEMANDENV contrasted with the chaotic, tool-centric "flat world" of traditional ops where every team manages its own pipeline silo.

View Diagram

The Branch Ecology

The "Walking on Many Feet" pattern — multiple envers evolving in parallel from a stable base, enabling safe concurrent development by humans and AI agents simultaneously.

View Diagram

Multi-Account Network Architecture

The governed sharing pattern for platform infrastructure — a central Transit Gateway published as a formal producer and consumed by application envers across multiple accounts via explicit contracts.

View Diagram

Where to Go Next?

Explore the Philosophy

Understand why interface-first, contract-enforced development is the right foundation for AI-native enterprises — and why the code-first era is ending.

Read the Vision

Read the Articles

Deep dives on specific topics: the CI/CD inversion, application-centric infrastructure, domain-driven design at the infrastructure layer, and the mathematical foundations of partitioning.

Browse the Library

Get Started

The quickstart sequence: set up your ContractsLib, scaffold your first service, publish your first schema artifact, and run your first BDD verification against the mock constellation.

View on GitHub