Files
acdl/schemas/stack.schema.json
T
Jon Chery 895a2f3806 docs(P20): specify phase 20 — consumer happy path + reusable deploy workflow (v1.5)
---ci---
project: acdl
phase: 20
milestone: v1.5
status: specify
---/ci---

Add v1.5 milestone to ROADMAP.md + REQUIREMENTS.md. Phase 20 covers
REQ-46 (README consumer model + mermaid + L3B/spike scrub), REQ-47
(generic CONSUMER_GUIDE.md + versioned uses: + consumer-scoped prereqs
+ run-time platform fetch), REQ-48 (zero-trust OIDC/ABAC credentials +
static-key override + daily rotation), REQ-49 (reusable byte-identical
deploy.yml Gitea+GitHub implementing pipelines/deploy.yaml), REQ-50
(contracts/static-asset.yaml @v1.4), REQ-51 (deploy-workflow conformance
tests). Update config.json milestone to v1.5.
2026-07-22 17:09:23 +00:00

118 lines
5.4 KiB
JSON

{
"$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:<resourceId>.<outputName>')."
},
"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."
}
}
}
}
}