Files
acdl/schemas/ir.schema.json
T
Jon Chery f8e99ed906 phase: 7, status: plan-as-execute, persona: platform-engineer+backend-engineer, task: T-7.2+T-7.3
---ci---
project: acdl
phase: 7
milestone: v1.1
status: plan-as-execute
persona: platform-engineer+backend-engineer
task: [T-7.2, T-7.3]
requirements.covered: [REQ-17, REQ-22]
---/ci---

Wave 2 (parallel): two independent JSON Schemas, different owners.

- T-7.2 (platform-engineer): schemas/ir.schema.json — Target Stack IR
  (JSON Schema draft 2020-12). Resources with typed inputs/outputs/NFRs,
  relationships (single parent per child), composition tree max-depth-5,
  policy hooks. Substrate-agnostic (no Terraform block keywords, no aws_
  provider prefixes; type values are IR types like aws:s3:bucket). module
  pins L1 by name@semver (W3.D). shared_keyword reserved for v2. Validates
  as Draft 2020-12; minimal l2-static-asset IR instance validates.

- T-7.3 (backend-engineer): schemas/contract.schema.json — consumer
  contract (JSON Schema draft 2020-12). Per-env mandatory (W3.E): dev
  stack+environment; qa adds validation.e2eSuite+loadTest; prod adds
  runbook+dashboard+oncall; dr adds drDrillRef. inputs always optional.
  profile: agentic marker; naturalLanguageIntent required when agentic
  (fixed: if-condition requires profile to be present before checking
  const). environment enum has no staging. Validates as Draft 2020-12;
  spike dev contract validates; qa/prod/dr/agentic negative cases reject.
2026-07-21 18:43:33 +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."
}
}
}
}
}