f8e99ed906
---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.
118 lines
5.4 KiB
JSON
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."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |