Commit Graph

19 Commits

Author SHA1 Message Date
Jon Chery 7a93a92c68 feat(P04): Phase 04 verification script + finalize_evidence URLError fix (T-4.4)
---ci---
phase: 4
milestone: v1.0
status: execute
persona: lead-developer
task: T-4.4
requirements:
  covered: [REQ-10, REQ-12]
review:
  p0: 1
  p1: 0
  p0_items:
    - id: P0-001
      location: scripts/finalize_evidence.py _request()
      issue: urllib.error.URLError (connection refused, DNS, timeout) was uncaught and stack-traced instead of returning clean JSON
      severity: P0 (the pipeline would crash on a Gitea outage instead of writing a clean failure event)
      fix: catch URLError in _request(); return (0, 'URLError: <reason>') so callers report cleanly
---/ci---

Wave 2, task T-4.4. scripts/verify_phase04.sh checks: (1) typecheck; (2)
pipeline.yml structure (3 inputs + 4 jobs + correct if: conditions +
finalize.needs=prod-gate); (3) pipeline.yml references all 5 core scripts
+ branch-pin doc; (4) issue-to-contract.yml structure (issues[opened] +
parse-and-trigger); (5) issue-to-contract.yml references (l3b_agent_stub
+ dispatch endpoint + contract-ref + issue number + GITEA_TOKEN +
new_branch); (6) finalize_evidence.py --help + missing file + missing
token (all exit 1 clean, no stack trace); (7) finalize_evidence.py
dead-host dry-run (exit 1, no stack trace). All 12 checks PASS.

The dead-host check caught a P0: finalize_evidence.py did not catch
urllib.error.URLError, so a connection-refused would stack-trace in the
pipeline. Fixed by catching URLError in _request() and returning
(0, 'URLError: <reason>') so callers report a clean JSON failure.
2026-07-21 13:40:50 +00:00
Jon Chery 2f0062c24d feat(P04): implement issue-to-contract.yml L3B trigger (T-4.3)
---ci---
phase: 4
milestone: v1.0
status: execute
persona: backend-engineer
task: T-4.3
requirements:
  covered: [REQ-12]
---/ci---

Wave 1, task T-4.3. Replaces the Phase 01 issue-to-contract.yml skeleton
with the real L3B trigger (D-030). On issue opened, the workflow checks out
the acdl repo at milestone/v1.0-initial (branch-pin rule) to obtain
l3b_agent_stub.py, parses the Issue body into contract.yaml, commits it to
a new branch contract/<issue-number> on acdl-contracts via the Gitea
file-contents API using the new_branch field (single POST creates the
branch + file), comments on and closes the Issue, then dispatches the
pipeline workflow on acdl via POST .../actions/workflows/pipeline.yml/
dispatches with inputs contract-ref=contract/<issue-number>
(cross-repo trigger per D-014). The `on:` key is quoted as "on": so
PyYAML parses it as a string key.
2026-07-21 13:39:06 +00:00
Jon Chery 1cb8d21315 feat(P04): implement pipeline.yml 3-dispatch approval-gate topology (T-4.2)
---ci---
phase: 4
milestone: v1.0
status: execute
persona: backend-engineer
task: T-4.2
requirements:
  covered: [REQ-10]
---/ci---

Wave 1, task T-4.2. Replaces the Phase 01 pipeline.yml skeleton with the
real 3-dispatch approval-gate topology (D-027/D-028). workflow_dispatch
inputs contract-ref/approve_qa/approve_prod drive four jobs: dev (policy +
confidence gate + mock_executor + evidence, persist via finalize_evidence),
qa-gate (records approval), prod-gate (records approval), finalize
(needs: prod-gate, commits final audit.json to acdl-evidence). Each stage
persists its audit.json to acdl-evidence via the file-contents API since
Gitea Actions artifacts do not survive re-dispatch. The `on:` key is quoted
as "on": so PyYAML parses it as a string key (it would otherwise be coerced
to the boolean True).
2026-07-21 13:38:35 +00:00
Jon Chery 3bcebd8d14 feat(P04): add finalize_evidence.py helper for D-028 state persistence (T-4.1)
---ci---
phase: 4
milestone: v1.0
status: execute
persona: backend-engineer
task: T-4.1
requirements:
  covered: [REQ-10]
---/ci---

Wave 1, task T-4.1. Adds scripts/finalize_evidence.py, a stdlib-only helper
that uploads a local audit.json to the acdl-evidence Gitea repo via the
file-contents API. It GETs the existing file to discover its sha (update
mode) and falls back to create mode on 404, then PUTs/POSTs the base64-encoded
content with the Authorization: token <token> header. This is the per-stage
state-persistence mechanism (D-028) used by the pipeline jobs between
re-dispatches, and the finalize-step writer (D-029).
2026-07-21 13:37:51 +00:00
Jon Chery 88945fed71 docs(P04): create 2-wave phase plan (REQ-10/12)
---ci---
phase: 4
milestone: v1.0
status: plan
plan:
  waves: 2
  wave_1_backend: [T-4.1 finalize_evidence.py, T-4.2 pipeline.yml real, T-4.3 issue-to-contract.yml real]
  wave_2_coordination: [T-4.4 verify_phase04.sh, T-4.5 traceability]
  requirements_covered: [REQ-10, REQ-12]
  must_haves: 7
  verification:
    typecheck: bash -n + py_compile + yaml load both workflows
    test: scripts/verify_phase04.sh (structure + syntax + finalize_evidence dry-run; full end-to-end run is Phase 05)
  risk: full pipeline cannot be exercised without an act_runner; verify_phase04 validates structure + syntax + dry-run only
---/ci---

PLAN.md replaced with Phase 04 plan. Wave 1 (backend) builds the pipeline
real implementation + finalize_evidence.py helper + issue-to-contract.yml
real implementation. Wave 2 (lead-developer) wires verify_phase04.sh +
traceability. Full end-to-end run is deferred to Phase 05 (act_runner
not registered in this environment).
2026-07-21 13:36:26 +00:00
Jon Chery 60e3fbaa29 docs(P04): research findings — pipeline topology, gates, state persistence
---ci---
phase: 4
milestone: v1.0
status: research
research:
  gitea_actions_capabilities:
    upload_artifact_v3: supported (v4 NOT supported by act_runner)
    artifacts_cross_dispatch: NOT preserved (re-dispatch starts a new run)
    workflow_dispatch_api: POST /actions/workflows/{filename}.yml/dispatches
    workflow_call: supported; uses: <owner>/<repo>/.gitea/workflows/<file>@<ref>
    checkout_cross_repo: actions/checkout@v4 with repository + ref + token
    secrets: ${{ secrets.GITEA_TOKEN }} must be a manually-created PAT (auto-token is current-repo only)
    approval_gate: workflow_dispatch input (approve_qa, approve_prod); no native pause-and-wait
  pipeline_design:
    topology: single pipeline.yml with workflow_dispatch inputs (contract-ref, approve_qa, approve_prod)
    stages: 3 separate dispatches (initial dev, qa-approve, prod-approve+finalize)
    state_persistence: each stage writes evidence to acdl-evidence via file-contents API (PUT audit.json)
    job_if_conditions: dev runs when !approve_qa && !approve_prod; qa-gate when approve_qa && !approve_prod; prod-gate+finalize when approve_prod
  personas: no change; backend-engineer owns the workflow YAML + finalize + issue trigger; lead-developer owns verify_phase04.sh
---/ci---

ARCHITECTURE.md gains a 'Phase 04 pipeline topology (research)' section:
the artifact-vs-re-dispatch limitation forces 3-dispatch topology with
evidence persisted to acdl-evidence (PUT audit.json) between dispatches.
PERSONAS.md is unchanged for Phase 04 (backend-engineer + lead-developer
active; infra-stub-engineer idle; frontend-engineer still off).
2026-07-21 13:35:45 +00:00
Jon Chery c2767fa3a5 decision(P04): clarification — pipeline topology, gates, finalize, issue trigger
---ci---
phase: 4
milestone: v1.0
status: clarify
decisions:
  - id: D-027
    decision: Two workflows: pipeline.yml (workflow_call + workflow_dispatch) and issue-to-contract.yml (issues.opened); gates via workflow_dispatch approve_qa/approve_prod inputs
    rationale: Gitea has no environment reviewers, no repository_dispatch, no native approval UI; D-013 fallback
    confidence: 0.85
    alternatives: [single long-running workflow that polls, external approval bot]
  - id: D-028
    decision: All 4 stages in one workflow run; state passed via upload/download-artifact; gates re-dispatched with approve inputs
    rationale: Gitea supports upload/download-artifact; alternative is committing state between jobs (heavier)
    confidence: 0.80
    alternatives: [commit state.json + audit.json to a state branch between jobs]
  - id: D-029
    decision: Finalize commits audit.json to acdl-evidence main via the Gitea file-contents API (same mechanism as Phase 01 index.html push)
    rationale: D-012 raw-URL requires the file to be on main; the API is the only way to put it there from a step
    confidence: 0.90
    alternatives: [clone acdl-evidence in the step, copy file, commit, push]
  - id: D-030
    decision: Issue-to-contract workflow checks out l3b_agent_stub from acdl, parses Issue, commits contract.yaml to contract/<issue-number> branch on acdl-contracts, then dispatches pipeline via workflow_dispatch API
    rationale: Gitea Actions cannot trigger cross-repo without an explicit API call; the branch carries the contract ref
    confidence: 0.85
    alternatives: [push contract to a sentinel branch on the acdl repo itself]
---/ci---

Phase 04 has real pipeline-topology ambiguities (Gitea's gaps vs the spec's
approval-gate intent). Four decisions logged: D-027 two-workflow topology
+ dispatch-input gates, D-028 artifact-based state passing, D-029 finalize
commits via file-contents API, D-030 issue workflow checks out
l3b_agent_stub from acdl and dispatches the pipeline.
2026-07-21 13:34:00 +00:00
Jon Chery 711b61d63e docs(P03): post-ship traceability + roadmap update (v1.0.3)
---ci---
phase: 3
milestone: v1.0
status: shipped
requirements:
  complete: [REQ-04, REQ-05, REQ-06, REQ-07, REQ-08, REQ-11]
  partial: [REQ-12]
release:
  tag: v1.0.3
  pr: 3
---/ci---

ROADMAP Phase 03 -> complete (v1.0.3). REQUIREMENTS: REQ-04/05/06/07/08/11
-> complete; REQ-12 -> partial (full issue-trigger wiring in Phase 04).
2026-07-21 13:33:18 +00:00
grimacing 3ea36ef3ab ship: phase-03 l2-modules-and-core-scripts (v1.0.3)
Squash merge of phase/03-l2-modules-and-core-scripts; 4 L2s + 5 core scripts; verify_phase03.sh green.
v1.0.3
2026-07-21 13:32:21 +00:00
Jon Chery 6e27df7404 docs(P02): post-ship traceability + roadmap update (v1.0.2)
---ci---
phase: 2
milestone: v1.0
status: shipped
requirements:
  complete: [REQ-02, REQ-03]
release:
  tag: v1.0.2
  pr: 2
---/ci---

ROADMAP Phase 02 -> complete (v1.0.2). REQUIREMENTS REQ-02/03 -> complete.
2026-07-21 13:18:51 +00:00
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.
v1.0.2
2026-07-21 13:18:12 +00:00
Jon Chery fd423e2df1 docs(P01): post-ship traceability + roadmap update (v1.0.1)
---ci---
phase: 1
milestone: v1.0
status: shipped
requirements:
  complete: [REQ-01, REQ-09]
  partial: [REQ-10, REQ-12]
release:
  tag: v1.0.1
  url: https://git.cloudinit.dev/continuous-intelligence/acdl/releases/tag/v1.0.1
  pr: 1
---/ci---

ROADMAP Phase 01 -> complete (v1.0.1). REQUIREMENTS REQ-01/09 -> complete;
REQ-10/12 -> partial (full impl in Phase 04).
2026-07-21 13:12:01 +00:00
grimacing 8947e89d7b ship: phase-01 repo-scaffolding (v1.0.1)
Squash merge of phase/01-repo-scaffolding into milestone/v1.0-initial; tagged v1.0.1.
2026-07-21 13:11:02 +00:00
Jon Chery b953fd4a8e docs(P01): complete repo-scaffolding phase
---ci---
phase: 1
milestone: v1.0
status: complete
requirements:
  covered: [REQ-01, REQ-09]
  partial: [REQ-10, REQ-12]
---/ci---

Squash merge of phase/01-repo-scaffolding into milestone/v1.0-initial.
Phase 01 ships the three-repo scaffold (acdl, acdl-contracts, acdl-evidence),
the placeholder index.html on acdl-evidence (D-012/D-016 raw-URL substitute
for unsupported Gitea Pages), the qa + prod branches on acdl-contracts
(D-013 stand-in for unsupported Gitea environments), the workflow skeletons
(pipeline.yml + issue-to-contract.yml), and the idempotent setup + verify
scripts. REQ-10/12 remain partial pending Phase 04 full implementation.
v1.0.1
2026-07-21 13:10:50 +00:00
Jon Chery 38eaec9337 docs(P01): create 3-wave phase plan (REQ-01/09/10)
---ci---
phase: 1
milestone: v1.0
status: plan
plan:
  waves: 3
  wave_1_coordination: [T-1.1 gitignore+layout+README, T-1.2 verify_phase01.sh]
  wave_2_backend: [T-2.1 gitea_setup.sh, T-2.2 pipeline.yml skeleton, T-2.3 issue-to-contract.yml skeleton]
  wave_3_coordination: [T-3.1 wire verify + traceability update]
  requirements_covered: [REQ-01, REQ-09, REQ-10]
  must_haves: 6
  verification:
    typecheck: bash -n scripts/*.sh
    test: scripts/verify_phase01.sh
    build: no-op
---/ci---

PLAN.md defines 3 vertical-slice waves: coordination (skeleton + verify
script), backend (Gitea setup + workflow skeletons), coordination (wiring +
traceability). infra-stub-engineer and frontend-engineer have 0 tasks this
phase. Branch for EXECUTE will be phase/01-repo-scaffolding.
2026-07-21 12:59:27 +00:00
Jon Chery 6691974445 docs(P01): research findings — Gitea API surface + persona roster
---ci---
phase: 1
milestone: v1.0
status: research
research:
  gitea_capabilities:
    pages: not_supported
    environments_api: not_supported
    repository_dispatch: not_supported
    workflow_call: supported
    workflow_dispatch: supported
    issues_opened: supported
  workarounds:
    - D-012 raw file URLs in place of Pages
    - D-013 workflow_dispatch approval inputs in place of environments
    - D-014 workflow_dispatch API in place of repository_dispatch
  verification_toolchain:
    typecheck: bash -n + python -m py_compile (no package.json)
    test: per-phase scripts/verify_phaseNN.sh
    build: no-op
---/ci---

ARCHITECTURE.md gains a Gitea API surface table and a branch-pinning rule.
PERSONAS.md is the canonical project-level persona roster: lead-developer
and backend-engineer always active; infra-stub-engineer custom persona owns
L1 stubs; data-engineer deactivated (no DB); frontend-engineer deactivated
until Phase 05.
2026-07-21 12:58:35 +00:00
Jon Chery e5f5604319 decision(P01): clarification — project mode, pages fallback, env gates
---ci---
phase: 1
milestone: v1.0
status: clarify
decisions:
  - id: D-011
    decision: Single-project mode explicitly enforced via config.json mode=single
    rationale: run.md Step 0 reads projects[] length as multi-project trigger; explicit flag disambiguates from D-010
    confidence: 0.95
    alternatives: [move acdl into .ciagent/acdl/ subdirectory and adopt multi-project paths]
  - id: D-012
    decision: Gitea has no native Pages; serve acdl-evidence via raw file URLs + CORS note
    rationale: Research confirms Gitea has no [pages] section; raw URLs work without server config
    confidence: 0.85
    alternatives: [sidecar static server, external Pages host]
  - id: D-013
    decision: QA/Prod gates modeled as workflow_dispatch approval inputs (D-004 fallback) instead of Gitea environments
    rationale: Research confirms Gitea ignores environment: blocks and exposes no environments API
    confidence: 0.90
    alternatives: [external approval bot, drop approval gates entirely]
  - id: D-014
    decision: Cross-repo triggering uses workflow_dispatch API from inside a step (no repository_dispatch)
    rationale: Gitea Actions does not support repository_dispatch
    confidence: 0.85
    alternatives: [push-based trigger with a sentinel file, polling]
  - id: D-015
    decision: New repos acdl-contracts and acdl-evidence use default_branch=main with auto_init=true
    rationale: Matches Gitea DEFAULT_BRANCH=main; required for the default branch to exist before any push
    confidence: 0.95
    alternatives: [use milestone/v1.0-initial as default_branch]
  - id: D-016
    decision: Pages placeholder for Phase 01 is a minimal HTML stub; full timeline UI deferred to Phase 05
    rationale: Phase 01 success criterion is the URL returns 200 with placeholder; full UI is Phase 05
    confidence: 0.90
    alternatives: [build a minimal timeline now]
---/ci---

Clarifications accepted at full autonomy per clarify.md Step 4. Three requirements
re-stated: REQ-09 (new repos default_branch=main), REQ-10 Pages (raw-URL 200
substitute), REQ-10 environments (workflow_dispatch inputs + qa/prod branches).
See .ciagent/REQUIREMENTS.md Clarifications table.
2026-07-21 12:57:50 +00:00
Jon Chery 5222a460e5 chore(config): rotate Gitea token to env-var reference (security)
---ci---
phase: 0
milestone: v1.0
status: specify
security:
  - id: SEC-001
    type: info_disclosure
    disposition: mitigated
    summary: Literal API token was committed in config.json gitea.api_token_env field
    fix: Replaced literal with env var name 'ACDL_GITEA_TOKEN'; token supplied via shell env at runtime
    severity: high
    stride: Information Disclosure
---/ci---

The 40-char value previously stored in .ciagent/config.json was a live Gitea
API token. Per the spec constraint 'no secrets in repo', the field now holds
an env var name. The token itself is exported in the shell session at runtime
and is never written to disk. Treat the prior value as already-leaked and
rotate it via the Gitea UI before any external disclosure.
2026-07-21 12:55:29 +00:00
Jon Chery e3416f8e77 docs(init): initialize Agentic Cloud Delivery Platform (5 phases)
---ci---
phase: 0
milestone: v1.0
status: specify
decisions:
  - id: D-001
    decision: Use Gitea org continuous-intelligence for all ACDL repos
    rationale: User-specified target org; already exists at git.cloudinit.dev
    confidence: 0.95
    alternatives: [new dedicated demo org]
  - id: D-002
    decision: Map "GitHub Actions" to Gitea Actions (act_runner) using same workflow YAML
    rationale: Environment is Gitea; syntax-compatible with act_runner
    confidence: 0.85
    alternatives: [migrate to GitHub.com, raw shell scripts]
  - id: D-003
    decision: Collapse acdl-platform into the existing empty acdl repo
    rationale: acdl already exists at org root; avoids a 4th repo
    confidence: 0.90
    alternatives: [create separate acdl-platform repo]
  - id: D-004
    decision: Use Gitea environment blocks + required reviewers for QA/Prod; fallback to manual workflow_dispatch with approval input
    rationale: Spec mandates approval gates; forge supports environment protection
    confidence: 0.80
    alternatives: [external approval bot, no approval gates]
  - id: D-005
    decision: Hash-chained ledger (prev_hash + own hash via SHA-256 of canonical JSON) for evidence; declared demonstrative not adversarially secure
    rationale: Spec asks for simple JSON; chain gives visible tamper-evidence
    confidence: 0.85
    alternatives: [signed commits only, full Merkle tree]
  - id: D-006
    decision: Confidence gate threshold = 0.50 exactly (base 0.90, fail drops to 0.40)
    rationale: Explicit in spec
    confidence: 0.99
    alternatives: []
  - id: D-007
    decision: Each mock_apply.sh echoes "[L1: <name>] applying..." + "OK", sleeps 1s, exits 0
    rationale: Spec literal; uniformity aids timeline parsing
    confidence: 0.95
    alternatives: [randomized sleep durations]
  - id: D-008
    decision: L3B keyword->stack mapping: gas/price/ingest/data-lake->commodity-price-feed; invoice/billing->invoice-service; analytics/historical/query->energy-analytics-api; regulatory/compliance/reporting/trading->regulatory-reporting; fallback->invoice-service
    rationale: Mirrors the 4 L2 modules + Act 3 example issue text
    confidence: 0.85
    alternatives: [single default stack, ML classifier (forbidden by no-AI constraint)]
  - id: D-009
    decision: Init milestone = v1.0, branch milestone/v1.0-initial
    rationale: init.md Step 5 mandates milestone/v1.0-initial
    confidence: 0.99
    alternatives: []
  - id: D-010
    decision: Single-project mode for the acdl checkout; ---ci--- blocks omit project field
    rationale: User chose standalone single-project; no other projects in this checkout
    confidence: 0.90
    alternatives: [register acdl in /root multi-project config]
---/ci---

Specification: 30-minute executive demo of the Agentic Cloud Delivery Platform proving automatic, safe, audited infra delivery via local stubs on Gitea Actions (no cloud, no AI APIs).
Requirements: [3 repos under continuous-intelligence org, 8 L1 stub modules, 4 L2 composed modules mirroring S&P Global Energy use cases, 5 core scripts (mock_executor.sh, policy_checker.py, confidence_signal.py, evidence_writer.py, l3b_agent_stub.py), reusable Dev->QA->Prod pipeline with approval gates, issue-triggered L3B agent, Pages evidence timeline UI, 4 scripted demo acts]
Constraints: [local Linux OS, Gitea Actions + Environments, no AWS/GCP/Azure, no external LLM APIs, state in flat JSON/artifacts, EKS Fargate + serverless primitives (no VPC module), L1 single-purpose substrate-agnostic max-depth-1, L2 max-depth-5]
Out of scope: [real cloud provisioning, real LLM inference, production-grade infrastructure, adversarial tamper-proofing of evidence]
2026-07-21 12:46:33 +00:00