Files
acdl/.ciagent/ARCHITECTURE.md
T
grimacing 00d0043866 ship: phase-02 l1-modules (v1.0.2)
Squash merge of phase/02-l1-modules into milestone/v1.0-initial; 8 L1 stub modules created; verify_phase02.sh green.
2026-07-21 13:18:12 +00:00

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

  1. A contract.yaml arrives either by direct push (L3A) or by the issue workflow running l3b_agent_stub.py (L3B).
  2. Push to acdl-contracts triggers the reusable pipeline in the acdl repo.
  3. Dev stage: policy_checker.py validates the contract; mock_executor.sh applies the L2 composition's L1s; confidence_signal.py computes the score; evidence_writer.py records each step. If score < 0.50, the stage fails and evidence records the rejection.
  4. QA stage: the workflow pauses on the qa environment; a human approves.
  5. Prod stage: same gate on the prod environment.
  6. Finalize: the workflow commits the updated audit.json to acdl-evidence; Pages republishes index.html, which fetches and renders the timeline.

Build Order

  1. Repo scaffolding: create acdl-contracts and acdl-evidence in the org; seed acdl directory layout.
  2. L1 modules (8 stubs).
  3. L2 modules (4 compositions).
  4. Core scripts (mock_executor.sh, policy_checker.py, confidence_signal.py, evidence_writer.py, l3b_agent_stub.py).
  5. Reusable pipeline workflow (Dev → QA → Prod → Finalize) + environment gates.
  6. Issue-triggered L3B workflow in acdl-contracts.
  7. Evidence UI (index.html + Pages config).
  8. 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 flat inputs: 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 0
    
    mock_apply.sh does NOT read input values; the manifest is for traceability and for Phase 03's mock_executor.sh to 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.