review(v1.5): READY TO SHIP — multi-persona code review
---ci---
project: acdl
phase: 20
milestone: v1.5
status: review
verdict: READY TO SHIP
p0: 1 (fixed — contract path resolution in deploy workflow)
p1: 6 (flagged post-hoc)
---/ci---
Multi-persona review of v1.5 phase 20 (docs + reusable deploy workflow).
P0 (blocking) — AUTO-FIXED:
- C1: scripts/run_platform.sh contract path resolution broken in deploy
workflow. The reusable workflow invokes run_platform.sh from the consumer
workspace root with a relative contract path (.acdl/contract.yaml), but
run_platform.sh does `cd "$ROOT"` (platform repo) early, so the relative
path resolved against the platform repo and the pipeline could never run.
Fix (commit 75c2274): capture CALLER_CWD before cd "$ROOT"; resolve
caller-supplied relative paths against CALLER_CWD; default no-arg contract
stays relative to ROOT (preserves platform-local CI). Reproduced pre-fix;
verified post-fix.
P1 (important) — FLAGGED FOR POST-HOC REVIEW (do not block ship):
- C2: ref: v1.4 in the deploy workflow platform checkout — no v1.4 tag exists
(only v1.4.0 / v1.4.1). Operator must create a floating v1.4 tag or change
the ref to v1.4.1.
- C3: modules/l2/{static-asset,microservice}/README.md still use @v1 in their
Usage examples; missed by the v1.4 bump.
- S1: static-key override is not wired. ACDL_AWS_* env vars on the OIDC step
are not read by aws-actions/configure-aws-credentials@v4 (it reads AWS_*
or its own access-key/secret-key inputs). The README/CONSUMER_GUIDE claim
a working override that doesn't function as written. Needs a conditional
step or renamed env vars + input wiring.
- S2: README overstates ABAC repo:org/repo:ref:... scoping. The workflow
constructs a numeric role name (github.repository_id); the actual claim
enforcement lives in the IAM trust policy, not in this workflow.
- T1: no deploy-workflow triggers conformance test (CI workflow has one;
deploy doesn't). Minor — reusable workflows use workflow_call, not push
triggers, but the contract's triggers field is then unenforced.
- A1: terraform/spike/terraform.tf uploaded as artifact leaks the AWS account
ID via the state-backend bucket name. Recommend excluding terraform.tf or
gating artifact upload to non-public repos.
P2 (nits) — listed for awareness: floating-tag terminology imprecision (M1),
header comment "Gitea Actions" in the GitHub copy (M2, intentional byte-
identical), pip install split (P1-perf), comment drift in pipelines/deploy.yaml
header (C4), module README internal inconsistency (C5).
Verdict: READY TO SHIP. The one P0 is fixed. The 6 P1s are post-hoc items —
the deploy workflow is a scaffold whose first real consumer run requires
operator setup (tag, IAM role, secrets) that gates go-live. The P1s should
be addressed before any consumer invokes uses: acdl/.gitea/workflows/
deploy.yml@v1.4 in earnest.
Tests: 154 pass (19 new). run_ci.sh green.
This commit is contained in:
+15
-15
@@ -1,31 +1,31 @@
|
||||
{
|
||||
"$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).",
|
||||
"$id": "https://acdl.cloudinit.dev/schemas/stack.schema.json",
|
||||
"title": "ACDL Target Stack",
|
||||
"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 composition tree, contract YML, and PolicyCheckResult schema are all defined against this stack schema. Substrate adapters (the Terraform adapter in v1) are the only substrate-specific code.",
|
||||
"$comment": "v1 ships one adapter (Terraform). The stack 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 stack gains expressiveness; the L1 content + contract YML + 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 stack 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).",
|
||||
"description": "Stack schema version (semver).",
|
||||
"pattern": "^\\d+\\.\\d+\\.\\d+$"
|
||||
},
|
||||
"stack": {
|
||||
"type": "object",
|
||||
"description": "The L1/L2 stack identity this IR represents.",
|
||||
"description": "The L1/L2 stack identity this instance 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."
|
||||
"pattern": "^[a-z][a-z0-9-]*$",
|
||||
"description": "Stack name matching the module folder name."
|
||||
},
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"enum": ["l1", "l2"],
|
||||
"description": "l1 = primitive; l2 = thin-composition."
|
||||
"description": "l1 = primitive; l2 = composition."
|
||||
},
|
||||
"depth": {
|
||||
"type": "integer",
|
||||
@@ -54,16 +54,16 @@
|
||||
"id": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z][a-z0-9-]*$",
|
||||
"description": "Local IR resource id (unique within the stack)."
|
||||
"description": "Local stack 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."
|
||||
"description": "Stack-typed resource identifier (substrate-agnostic), e.g. 'aws:s3:bucket'. NOT a Terraform resource type ('aws_s3_bucket'); the adapter translates stack 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."
|
||||
"pattern": "^[a-z][a-z0-9-]*@\\d+\\.\\d+\\.\\d+$",
|
||||
"description": "Module 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",
|
||||
@@ -71,7 +71,7 @@
|
||||
},
|
||||
"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.",
|
||||
"description": "Input values keyed by the module's declared inputs. Free-form in v1 (validated at contract->stack resolution against the module registry); typed per-module in v1.2.",
|
||||
"additionalProperties": {"type": ["string", "number", "boolean"]}
|
||||
},
|
||||
"outputs": {
|
||||
@@ -92,7 +92,7 @@
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "IR-typed output type: a primitive ('string', 'arn') or a reference ('ref:<resourceId>.<outputName>')."
|
||||
"description": "Stack-typed output type: a primitive ('string', 'arn') or a reference ('ref:<resourceId>.<outputName>')."
|
||||
},
|
||||
"description": {"type": "string"}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user