Skip to content

Platform Compiler — Projection Model

Document: 3 of 4 Status: Canonical Depends on: Core Object Model (arch_01), Contract Model (arch_02) Required by: Receipt & Provenance Model


Purpose

This document defines how the Platform Compiler transforms authoritative objects into generated artifacts. It specifies the compiler's internal pipeline stages, the Planner/Renderer separation that keeps the compiler runtime-agnostic, all defined projection types, and the rules governing generated repositories.


Core Principle

The Platform Compiler never knows Cloudflare. It never knows Docker. It never knows Terraform.

It knows:

  • Projection Types — abstract descriptions of what to generate
  • Renderers — pluggable implementations that emit a specific tool's artifact for a given projection type

Changing from Terraform to Pulumi to Crossplane means swapping a Renderer. The Planner, the Object Graph, and the Projection Types remain unchanged.


Compiler Internal Pipeline

Readers
    │  read contracts/, objects/, providers/
    │  produce typed in-memory representations
    ▼
Normalizers
    │  validate objects against schemas
    │  resolve $refs and cross-object relationships
    │  apply trust levels (owned vs vendor vs community)
    │  detect conflicts and drift
    ▼
Object Graph
    │  complete in-memory graph of all objects and relationships
    │  Authority → Capability → Contract
    │  Capability → Deployment → Runtime → Tunnel
    │  Provider → Contract
    ▼
Planners
    │  read the Object Graph
    │  produce ProjectionPlans — abstract, renderer-agnostic
    │  apply state filters (skip legacy, skip retired)
    │  detect duplicate projections
    │  validate intent (no two canonical deployments on same hostname)
    ▼
Generators
    │  select Renderer per (ProjectionPlan, target)
    │  Renderer emits the final artifact bytes
    │  Renderer is replaceable: Terraform ↔ Pulumi ↔ Crossplane ↔ YAML
    ▼
Emitters
    │  write artifacts to generated/ in the registry
    │  open MRs to generated repositories
    │  sign artifacts with hash
    ▼
Receipts
       record what was read, what was planned, what was generated
       stored in Beads → Dolt

Projection Types

A Projection Type is an abstract description of an artifact kind. It has no tool knowledge. A Renderer binds a Projection Type to a specific tool.

Exposure Projections

Projection Type Consumes Emits (abstract)
exposure:tunnel-ingress Deployment + Tunnel Tunnel ingress rules for all deployments routed through a tunnel
exposure:dns Deployment (exposed=true) DNS records pointing hostnames at tunnel endpoints
exposure:zero-trust-access Deployment (zeroTrust=true) Identity-aware access policies per hostname
exposure:tls Deployment + Tunnel TLS certificate and termination configuration

Runtime Projections

Projection Type Consumes Emits (abstract)
runtime:compose Deployment + Runtime (type=container) Container service definition with image, ports, volumes, env
runtime:k8s-manifest Deployment + Runtime (type=k8s) Kubernetes Deployment, Service, ConfigMap
runtime:systemd Deployment + Runtime (type=vm) systemd unit file
runtime:gascity-pack Capability + Contract Gas City Pack TOML definition
runtime:gascity-city Platform + Runtime + Pack refs Gas City City TOML definition

Network Projections

Projection Type Consumes Emits (abstract)
network:tailscale-acl Runtime (network=tailscale) + trust rules Tailscale ACL policy (HuJSON)
network:tailscale-tunnel Deployment + Runtime (type=nas) cloudflared tunnel config for NAS
network:subnet-route Runtime (subnet-router=true) Tailscale subnet route declaration

Security Projections

Projection Type Consumes Emits (abstract)
security:gitlab-policy Security policy objects GitLab security policy YAML
security:cedar-policy Authorization capability + resource definitions Cedar policy file
security:opa-policy Governance capability + rules Rego policy file

CI/CD Projections

Projection Type Consumes Emits (abstract)
cicd:gitlab-component CI component object GitLab CI component YAML
cicd:pipeline-template CI pipeline object GitLab CI include template

Catalog Projections

Projection Type Consumes Emits (abstract)
catalog:service-catalog All capabilities + deployments service-catalog.json
catalog:control-plane All capabilities + contracts control-plane.json
catalog:url-index All deployments urls.json (replaces ai.json)
catalog:endpoint-index All contracts (type=openapi) endpoints-index.json
catalog:typescript-types All contracts (type=openapi) *.types.ts

Renderers

A Renderer is a pluggable implementation that binds to one or more Projection Types and emits a specific tool's artifact format.

Renderer
  id:           renderer.<tool>.<projection-type>
  projection:   → ProjectionType (one or more)
  tool:         terraform | pulumi | crossplane | yaml | toml | hcl | json | typescript
  version:      which tool version this renderer targets
  stable:       boolean

Defined Renderers

Renderer Tool Projection Types Notes
renderer.terraform.cloudflare-dns Terraform + Cloudflare provider v5 exposure:dns Active
renderer.terraform.cloudflare-tunnel Terraform + Cloudflare provider v5 exposure:tunnel-ingress Blocked (token permission)
renderer.terraform.cloudflare-zero-trust Terraform + Cloudflare provider v5 exposure:zero-trust-access Active
renderer.terraform.oci Terraform + OCI provider v6 runtime:vm-provision Active
renderer.yaml.cloudflare-tunnel cloudflared YAML exposure:tunnel-ingress Active (current fallback)
renderer.yaml.tailscale-acl Tailscale HuJSON network:tailscale-acl Active
renderer.yaml.tailscale-tunnel cloudflared YAML (NAS) network:tailscale-tunnel Active
renderer.yaml.docker-compose Docker Compose v3 runtime:compose Active
renderer.toml.gascity-pack Gas City Pack v2 runtime:gascity-pack Active
renderer.toml.gascity-city Gas City City runtime:gascity-city Active
renderer.yaml.gitlab-policy GitLab Security Policy security:gitlab-policy Active
renderer.yaml.gitlab-component GitLab CI Component cicd:gitlab-component Active
renderer.typescript.types TypeScript (openapi-typescript) catalog:typescript-types Active
renderer.json.service-catalog JSON catalog:service-catalog Active

Swapping Terraform for Pulumi means registering renderer.pulumi.cloudflare-dns and removing renderer.terraform.cloudflare-dns. The Projection Type exposure:dns does not change. The Planner does not change. The Object Graph does not change.


Planner Output: ProjectionPlan

The Planner produces a ProjectionPlan — a declaration of what must be generated. The ProjectionPlan is itself an artifact that can be reviewed before Generators run.

# Example ProjectionPlan fragment
projections:
  - type: exposure:tunnel-ingress
    tunnel: tunnel.cloudflare.oracle-platform
    renderer: renderer.yaml.cloudflare-tunnel
    deployments:
      - deployment.compliance.oracle.production
      - deployment.authentication.oracle.production
      - deployment.mesh.oracle.production
      # ... all canonical deployments on this tunnel
    exclude:
      - deployment.compliance.oracle.legacy-3014   # state: legacy
      - deployment.adash.oracle.legacy-8081        # state: legacy
    output: generated/projections/cloudflare/tunnel-config.yml

  - type: exposure:dns
    renderer: renderer.terraform.cloudflare-dns
    deployments:
      - deployment.compliance.oracle.production
      # ...
    output: generated/projections/terraform/cloudflare/dns.tf

The ProjectionPlan makes the compiler's intent explicit and auditable. A human can review a ProjectionPlan before running Generators.


Generated Repository Ownership

Each generated repository receives artifacts from specific Projection Types:

Repository Receives projections of type Via
iac exposure:dns, exposure:tunnel-ingress, exposure:zero-trust-access, exposure:tls, runtime:vm-provision Terraform renderers
agent-docker runtime:compose, runtime:k8s-manifest Docker Compose + k8s YAML renderers
agent-tailscale network:tailscale-acl, network:tailscale-tunnel, network:subnet-route Tailscale YAML renderers
blucity-packs runtime:gascity-pack Gas City TOML renderer
bluefly-city runtime:gascity-city Gas City TOML renderer
security-policies security:gitlab-policy, security:cedar-policy, security:opa-policy YAML + Rego renderers
gitlab_components cicd:gitlab-component, cicd:pipeline-template GitLab CI YAML renderer

The compiler writes to these repositories via: 1. Compiler runs, emits artifacts to generated/projections/ within api-schema-registry 2. Compiler opens one MR per generated repository with the relevant artifact subset 3. CI in the generated repository runs terraform plan / docker compose config / gc formula list / etc. 4. Owner reviews the plan output, approves MR 5. MR merges → deploy pipeline runs 6. Deployment emits a Receipt


Compiler Trigger

Merge to api-schema-registry main
        │
        ▼
CI: api-schema-registry pipeline
        │
        ├── validate: schemas valid
        ├── validate: all objects conform to schemas
        ├── validate: no two canonical deployments on same hostname
        ├── validate: all provider manifests hash-verified
        │
        ▼
generate: run compiler
        │
        ├── emit ProjectionPlan (stored as artifact)
        ├── emit generated/ artifacts
        │
        ▼
open-mrs: one MR per generated repo
        │
        ▼
(human reviews ProjectionPlan + MR diff)
        │
        ▼
merge → deploy

Conflict Detection

The Planner detects and rejects the following before any artifact is generated:

Conflict Planner behavior
Two canonical deployments on the same hostname Fail — must resolve in objects before compile
A canonical deployment and a legacy deployment on the same hostname Warn — emit canonical only, legacy excluded from projections
A deployment on a tunnel not declared in objects/tunnels/ Fail
A deployment referencing a retired runtime Fail
Two tunnels routing to the same hostname Fail
A legacy deployment with no planned retirement date Warn

The current 27 Cloudflare route conflicts will cause Planner failures until each conflict is resolved in objects/deployments/ by classifying one as canonical and the other as legacy.


Enforcement in Generated Repositories

Once the compiler is the sole writer to a generated repository:

  1. CODEOWNERS: compiler service account owns all generated files; human ownership limited to README.md and CI config
  2. Branch protection: no direct push to main; only compiler-opened MRs merge
  3. CI drift detection: scheduled terraform plan or equivalent; alert if runtime diverges from generated state
  4. Pre-receive hook: reject any commit not authored by the compiler service account on compiler-owned files

Invariants

  1. The Planner produces a ProjectionPlan before any Generator runs.
  2. No artifact is emitted without a corresponding ProjectionPlan entry.
  3. No Renderer knows more than one target tool.
  4. Swapping a Renderer requires no changes to the Planner, Object Graph, or Projection Types.
  5. The compiler emits artifacts only to generated/ within api-schema-registry and to generated repository MRs — never directly to a runtime.
  6. A legacy deployment is never included in a Projection output.
  7. A Planner conflict causes the entire compilation to fail — no partial artifact emission.