{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://acdl.cloudinit.dev/schemas/ir.schema.json", "title": "ACDL Target Stack IR", "description": "Substrate-neutral description of a target stack: resources with typed inputs/outputs/NFRs, relationships (single parent per child), composition tree (max depth 5), and policy hooks. The L1 registry, L2 thin-composition tree, contract YML, and PolicyCheckResult schema are all defined against this IR. Substrate adapters (the Terraform adapter in v1) are the only substrate-specific code.", "$comment": "v1 ships one adapter (Terraform). The IR is nearly isomorphic to Terraform in v1 (ARCHITECTURE.md §12.1); the adapter compiles resource.module -> module block, resource.inputs -> variable + arg, resource.outputs -> output, relationship.kind=uses_output -> interpolation, relationship.kind=parent -> composition ordering hint. As more adapters appear (v2+), the IR gains expressiveness; the L1 content + contract YML + thin-composition tree do not change. The schema body is substrate-agnostic: no Terraform block keywords (variable/output/resource as blocks) and no aws_ provider prefixes in the schema keywords; type values are IR types (aws:s3:bucket), not Terraform resource types (aws_s3_bucket).", "type": "object", "required": ["version", "stack", "resources"], "properties": { "version": { "type": "string", "description": "IR schema version (semver).", "pattern": "^\\d+\\.\\d+\\.\\d+$" }, "stack": { "type": "object", "description": "The L1/L2 stack identity this IR represents.", "required": ["name", "kind", "depth"], "properties": { "name": { "type": "string", "pattern": "^l[12]-[a-z][a-z0-9-]*$", "description": "Stack name matching the L1/L2 folder name." }, "kind": { "type": "string", "enum": ["l1", "l2"], "description": "l1 = primitive; l2 = thin-composition." }, "depth": { "type": "integer", "minimum": 1, "maximum": 5, "description": "Composition depth (ARCHITECTURE.md §3: max depth 5). L2->L1 is depth 1." } } }, "resources": { "type": "array", "minItems": 1, "items": {"$ref": "#/$defs/resource"} }, "relationships": { "type": "array", "description": "Optional in v1; present when the adapter needs explicit ordering/output wiring hints beyond parent composition.", "items": {"$ref": "#/$defs/relationship"} } }, "$defs": { "resource": { "type": "object", "required": ["id", "type", "module", "inputs"], "properties": { "id": { "type": "string", "pattern": "^[a-z][a-z0-9-]*$", "description": "Local IR resource id (unique within the stack)." }, "type": { "type": "string", "description": "IR-typed resource identifier (substrate-agnostic), e.g. 'aws:s3:bucket'. NOT a Terraform resource type ('aws_s3_bucket'); the adapter translates IR type -> substrate type." }, "module": { "type": "string", "pattern": "^l1-[a-z][a-z0-9-]*@\\d+\\.\\d+\\.\\d+$", "description": "L1 registry reference: name@semver (W3.D). MAJOR bumps require a new registry entry (immutable publication); old entry enters a 12-month deprecation window." }, "parent": { "type": "string", "description": "Parent resource id. Absent for the root. Single parent per child (ARCHITECTURE.md §12.1)." }, "inputs": { "type": "object", "description": "Input values keyed by the L1 module's declared inputs. Free-form in v1 (validated at contract->IR resolution against the L1 registry); typed per-L1 in v1.2.", "additionalProperties": {"type": ["string", "number", "boolean"]} }, "outputs": { "type": "object", "description": "Typed output contract. The adapter translates this to a substrate output block (e.g. Terraform output).", "additionalProperties": {"$ref": "#/$defs/outputSpec"} }, "nfrs": { "type": "object", "description": "Declared non-functional requirements (latency, throughput, error rate). Opaque to the adapter; consumed by the confidence signal's NFR input.", "additionalProperties": true } } }, "outputSpec": { "type": "object", "required": ["type"], "properties": { "type": { "type": "string", "description": "IR-typed output type: a primitive ('string', 'arn') or a reference ('ref:.')." }, "description": {"type": "string"} } }, "relationship": { "type": "object", "required": ["from", "to", "kind"], "properties": { "from": {"type": "string", "description": "Source resource id."}, "to": {"type": "string", "description": "Target resource id."}, "kind": { "type": "string", "enum": ["parent", "depends_on", "uses_output"], "description": "v1 uses 'parent' (composition ordering) + 'uses_output' (interpolation). 'depends_on' is reserved for v2 explicit-dependency cases." }, "shared_keyword": { "type": "string", "description": "Reserved for v2 multi-relationship dependencies. Unused in v1." } } } } }