From 8437a51c6cc577bd1709ba90b295e0f1f6ad7ffd Mon Sep 17 00:00:00 2001 From: Jon Chery Date: Tue, 21 Jul 2026 19:33:31 +0000 Subject: [PATCH] phase: 10, status: plan-as-execute, persona: platform-engineer, task: T-10.1..T-10.3+T-10.6 ---ci--- project: acdl phase: 10 milestone: v1.1 status: plan-as-execute persona: platform-engineer task: [T-10.1, T-10.2, T-10.3, T-10.6] requirements.covered: [REQ-25] ---/ci--- Wave 1: L2 thin-composition + registry extension + adapter L2 handling. - T-10.1: modules-ir/l2/l2-static-asset/composition.json (kind=l2, depth=1, one child l1-s3@1.0.0, wires passthrough). - T-10.2: modules-ir/registry.json extended with l2-static-asset@1.0.0. - T-10.3: modules-ir/l2/l2-static-asset/README.md (D-P10-1 doc). - T-10.6: adapters/terraform/adapter.py - backend key now derived from the stack name (spike//terraform.tfstate). The resources array handling is unchanged; a resolved L2 IR instance has the L1 resource as resources[0], so the existing TYPE_MAP + resource emission handle it (the adapter is shape-driven, not kind-driven). --- adapters/terraform/adapter.py | 4 ++- modules-ir/l2/l2-static-asset/README.md | 31 +++++++++++++++++++ .../l2/l2-static-asset/composition.json | 17 ++++++++++ modules-ir/registry.json | 7 +++++ 4 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 modules-ir/l2/l2-static-asset/README.md create mode 100644 modules-ir/l2/l2-static-asset/composition.json diff --git a/adapters/terraform/adapter.py b/adapters/terraform/adapter.py index bf0a591..a54cfe3 100644 --- a/adapters/terraform/adapter.py +++ b/adapters/terraform/adapter.py @@ -82,6 +82,8 @@ def adapt(ir_instance, out_dir): ) # --- terraform.tf: required_version + required_providers + S3 backend (no DynamoDB lock per D-P09-1) --- + # The backend key is derived from the stack name so l1 vs l2 spikes use separate state keys (D-P10-1). + stack_name = stack.get("name", "spike") terraform_tf = ( 'terraform {\n' ' required_version = ">= 1.9, < 1.10"\n' @@ -93,7 +95,7 @@ def adapt(ir_instance, out_dir): ' }\n' ' backend "s3" {\n' ' bucket = "acdl-tfstate-581513795199-us-east-1"\n' - ' key = "spike/l1-s3/terraform.tfstate"\n' + f' key = "spike/{stack_name}/terraform.tfstate"\n' ' region = "us-east-1"\n' ' }\n' '}\n' diff --git a/modules-ir/l2/l2-static-asset/README.md b/modules-ir/l2/l2-static-asset/README.md new file mode 100644 index 0000000..f13dc00 --- /dev/null +++ b/modules-ir/l2/l2-static-asset/README.md @@ -0,0 +1,31 @@ +# l2-static-asset — thin-composition (S3 static asset) + +The v1.1 spike's L2. A thin-composition that references `l1-s3` only +(depth 1). The contract's inputs (`bucket_name`, `region`) map 1:1 +through the wires to the L1's inputs. + +## Composition (the IR-typed thin-composition tree) + +See `composition.json`: `kind=l2`, `depth=1`, one child `l1-s3@1.0.0`, +wires `{bucket_name → s3.inputs.bucket_name, region → s3.inputs.region}` +(passthrough). + +## IR → Terraform mapping (D-P10-1) + +The Terraform adapter consumes the *resolved IR instance* (which has +`kind=l2` + the L1 resource `s3` in its `resources` array). For a +depth-1 thin-composition, the L2 root module **IS** the L1's resource — +no separate `module "l1_s3" { source = "..." }` block. The existing +adapter `TYPE_MAP` + resource emission handle both l1 and l2 instances +(the resources array is the same shape). The `relationships` array is +ignored at the Terraform level for the spike (composition ordering is +implicit in the single resource). + +v1.2 may emit a real `module "l1_s3" { source = "..." }` block when L1s +become published Terraform modules rather than inline resources. + +## Versioning (W3.D) + +`1.0.0` — interface MAJOR, behavior MINOR, lifecycle PATCH. MAJOR bumps +require a new registry entry (immutable publication); old entries enter +a 12-month deprecation window. \ No newline at end of file diff --git a/modules-ir/l2/l2-static-asset/composition.json b/modules-ir/l2/l2-static-asset/composition.json new file mode 100644 index 0000000..e24f092 --- /dev/null +++ b/modules-ir/l2/l2-static-asset/composition.json @@ -0,0 +1,17 @@ +{ + "name": "l2-static-asset", + "version": "1.0.0", + "kind": "l2", + "depth": 1, + "description": "Thin-composition: a single S3 bucket for static asset hosting. References l1-s3 only (depth 1).", + "children": [ + { + "id": "s3", + "module": "l1-s3@1.0.0" + } + ], + "wires": { + "bucket_name": {"target": "s3", "input": "bucket_name"}, + "region": {"target": "s3", "input": "region"} + } +} \ No newline at end of file diff --git a/modules-ir/registry.json b/modules-ir/registry.json index 9c480bd..444da98 100644 --- a/modules-ir/registry.json +++ b/modules-ir/registry.json @@ -5,5 +5,12 @@ "published_at": "2026-07-21T19:00:00Z", "deprecated": false } + }, + "l2-static-asset": { + "1.0.0": { + "composition": "modules-ir/l2/l2-static-asset/composition.json", + "published_at": "2026-07-21T19:30:00Z", + "deprecated": false + } } } \ No newline at end of file