Squash merge of phase/02-l1-modules into milestone/v1.0-initial; 8 L1 stub modules created; verify_phase02.sh green.
9.5 KiB
ACDL — Architecture (initial)
Initial architecture for the ACDL demo. May be incomplete; refined at phase boundaries.
Overview
The demo is a three-repo, stub-driven system that simulates an autonomous cloud delivery platform. No real cloud or AI is used; every "infrastructure" action is a bash/Python stub that emits structured evidence. The platform is driven by either a developer-supplied contract.yaml (L3A) or a natural-language GitHub Issue parsed by a keyword script (L3B), then flows through an autonomous Dev stage, manual QA and Prod approval gates, and finally publishes a hash-chained audit trail to a Pages site.
┌──────────────── acdl-contracts ─────────────────┐
Developer ───▶ │ commit contract.yaml Issue (NL intent) │
└────────────┬───────────────────┬────────────────┘
│ (push) │ (issue opened)
▼ ▼
┌─────────────────┐ ┌──────────────────────┐
│ reusable │ │ issue workflow → │
│ pipeline │ │ l3b_agent_stub.py → │
│ (acdl repo) │ │ contract.yaml → push │
└────────┬────────┘ └──────────────────────┘
│
┌────────────────────┼────────────────────┐
▼ ▼ ▼
Dev (autonomous) QA (approval) Prod (approval)
mock_executor.sh environment gate environment gate
policy_checker.py
confidence_signal.py
│
▼
evidence_writer.py ──▶ audit.json (hash-chained) ──▶ acdl-evidence
│
▼
index.html (Pages)
timeline UI
Components
| Name | Description | Boundaries | Depends On |
|---|---|---|---|
acdl repo |
Platform meta repo: reusable workflows, L1/L2 stub modules, core scripts | Owns workflows + stubs; does not hold contracts or evidence | — |
| L1 modules | Single-purpose infra primitives (EKS Fargate, IAM, Lambda, API Gateway, EventBridge, SQS, S3, CloudWatch) | One folder per L1; manifest.yaml + mock_apply.sh; do not compose with other L1s |
acdl repo |
| L2 modules | Composed stacks (invoice, commodity-price-feed, energy-analytics-api, regulatory-reporting) | Reference L1s by name; max depth 5; expressed as a composition manifest | L1 modules |
mock_executor.sh |
Reads an L2 composition, invokes each L1 mock_apply.sh, writes state.json |
Bash; reads L2 manifest + L1 manifests | L1/L2 modules |
policy_checker.py |
Reads contract.yaml; fails on forbidden keys (e.g. public-ingress: true) |
Python; emits POLICY_VIOLATION:<REASON> or pass |
contract.yaml |
confidence_signal.py |
Base 0.90; on policy failure drops to 0.40 and echoes reason | Python; calls policy_checker | policy_checker.py |
evidence_writer.py |
Appends an event to audit.json, links to previous event via SHA-256 chain |
Python; canonical-JSON hashing | audit.json |
l3b_agent_stub.py |
Parses Issue text by keywords, emits contract.yaml |
Python keyword map; no external APIs | contract.yaml schema |
acdl-contracts repo |
Developer + agentic entry surface; holds contracts + issue workflow | Triggers main pipeline on push | acdl reusable workflow |
acdl-evidence repo |
Pages host for audit.json + index.html timeline |
Read-only for the pipeline; written at finalize stage | evidence_writer.py output |
| Reusable pipeline workflow | Dev → QA → Prod → Finalize stages with environment gates | Gitea Actions; calls core scripts | All core scripts |
Data Flow
- A
contract.yamlarrives either by direct push (L3A) or by the issue workflow runningl3b_agent_stub.py(L3B). - Push to
acdl-contractstriggers the reusable pipeline in theacdlrepo. - Dev stage:
policy_checker.pyvalidates the contract;mock_executor.shapplies the L2 composition's L1s;confidence_signal.pycomputes the score;evidence_writer.pyrecords each step. If score < 0.50, the stage fails and evidence records the rejection. - QA stage: the workflow pauses on the
qaenvironment; a human approves. - Prod stage: same gate on the
prodenvironment. - Finalize: the workflow commits the updated
audit.jsontoacdl-evidence; Pages republishesindex.html, which fetches and renders the timeline.
Build Order
- Repo scaffolding: create
acdl-contractsandacdl-evidencein the org; seedacdldirectory layout. - L1 modules (8 stubs).
- L2 modules (4 compositions).
- Core scripts (
mock_executor.sh,policy_checker.py,confidence_signal.py,evidence_writer.py,l3b_agent_stub.py). - Reusable pipeline workflow (Dev → QA → Prod → Finalize) + environment gates.
- Issue-triggered L3B workflow in
acdl-contracts. - Evidence UI (
index.html+ Pages config). - Demo dry-run + the four scripted acts.
Gitea API Surface (Phase 01 research)
Authoritative findings from the Gitea docs (added in RESEARCH; supersedes any GitHub-Pages / GitHub-Environments assumptions carried over from the spec):
| Capability | Gitea support | ACDL approach |
|---|---|---|
| Org-scoped repo create | POST /api/v1/orgs/{org}/repos (CreateRepoOption) |
Used to create acdl-contracts + acdl-evidence |
| Native Pages | None (no [pages] config section) |
Serve acdl-evidence via raw file URLs: https://git.cloudinit.dev/continuous-intelligence/acdl-evidence/raw/branch/main/index.html; index.html fetches audit.json from the same raw path. Requires [cors] ENABLED=true on the server if the UI is loaded cross-origin. |
| Environments API | None; jobs.<id>.environment is ignored by act_runner |
Model QA/Prod gates as workflow_dispatch approval inputs (D-004 / D-013); optionally create qa and prod branches as a visible stand-in |
repository_dispatch trigger |
Not supported | Cross-repo trigger via workflow_dispatch API: POST /api/v1/repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches called from a step using $GITEA_TOKEN |
Reusable workflows (workflow_call) |
Supported | acdl/.gitea/workflows/pipeline.yml called via uses: continuous-intelligence/acdl/.gitea/workflows/pipeline.yml@milestone/v1.0-initial |
workflow_dispatch |
Supported (trigger + API) | Used for the manual-approval fallback and the issue workflow's cross-repo trigger |
issues.opened trigger |
Supported | Drives the L3B issue-trigger workflow in acdl-contracts |
act_runner labels |
Single label only (runs-on: ubuntu-latest) |
All workflows use runs-on: ubuntu-latest |
| Context | ${{ gitea.* }} and ${{ github.* }} both work |
Workflows use gitea.* for clarity |
Branch pinning rule
The reusable workflow in the acdl repo lives on milestone/v1.0-initial
(that is the repo's default branch). uses: references from acdl-contracts
must pin to @milestone/v1.0-initial, not @main (the acdl repo has no
main branch). The new repos acdl-contracts and acdl-evidence use
default_branch: "main" (D-015) so their default branch exists immediately
for pushes.
Default verification toolchain
There is no package.json; ACDL is bash + python stubs. The verification gate
substitutes bash -n and python -m py_compile for npm run typecheck, and
per-phase scripts/verify_phaseNN.sh for npm test. npm run build is a
no-op (no build step). See PERSONAS.md / VERIFICATION note.
L1 module schema (Phase 02 research)
Each L1 module lives at modules/l1/<name>/ with exactly two files:
manifest.yaml— declares the L1's identity + a flatinputs:map. Schema (D-017):name: l1-eks-fargate # matches the folder name kind: l1 # literal "l1"; substrate-agnostic description: <one-line> inputs: <key>: description: <one-line> type: string # only "string" allowed (flat, max-depth-1)mock_apply.sh— uniform stub per D-007 + D-018:#!/usr/bin/env bash set -euo pipefail echo "[L1: <name>] applying..." sleep 1 echo "[L1: <name>] OK" exit 0mock_apply.shdoes NOT read input values; the manifest is for traceability and for Phase 03'smock_executor.shto enumerate the L1s in an L2.
L1 list (fixed per REQ-02 / D-019)
| Folder | Description |
|---|---|
l1-eks-fargate |
Serverless container compute substrate |
l1-iam-role |
Identity and access role primitive |
l1-lambda |
Event-driven function primitive |
l1-api-gateway |
HTTP routing primitive |
l1-eventbridge |
Event bus primitive |
l1-sqs |
Queue primitive |
l1-s3 |
Object store primitive |
l1-cloudwatch |
Observability primitive |
L1 modules are single-purpose, substrate-agnostic, max-depth-1 (per PROJECT.md Constraints). They do not compose with other L1s.