diff --git a/.ciagent/PLAN.md b/.ciagent/PLAN.md index cb0f5de..4bb20fc 100644 --- a/.ciagent/PLAN.md +++ b/.ciagent/PLAN.md @@ -1,88 +1,100 @@ --- -phase: 04 -name: pipeline-and-approval-gates +phase: 05 +name: evidence-ui-and-demo-dry-run milestone: v1.0 milestone_type: feature status: planned -requirements: [REQ-10, REQ-12] +requirements: [REQ-13, REQ-14, REQ-15] must_haves: - - ".gitea/workflows/pipeline.yml is a real workflow (no placeholders) with workflow_dispatch inputs (contract-ref, approve_qa, approve_prod) and 4 jobs (dev, qa-gate, prod-gate, finalize) with correct if: conditions per D-027/D-028" - - "The dev job checks out acdl + acdl-contracts@contract-ref, runs policy_checker.py + confidence_signal.py + mock_executor.sh, and writes a dev_applied or dev_rejected evidence event to acdl-evidence via the file-contents API" - - "The qa-gate job (approve_qa=true) writes a qa_approved evidence event" - - "The prod-gate + finalize jobs (approve_prod=true) write prod_approved + finalize evidence events, committing the final audit.json to acdl-evidence main" - - "contracts-repo/.gitea/workflows/issue-to-contract.yml is a real workflow (no placeholders) that checks out l3b_agent_stub.py from acdl, parses the Issue body, commits contract.yaml to contract/ on acdl-contracts, and dispatches pipeline.yml with contract-ref=contract/" - - "scripts/finalize_evidence.py helper exists: given an audit.json file path, GETs the current file sha from acdl-evidence, PUTs the new content via the file-contents API. Used by the workflow steps to commit evidence updates." - - "scripts/verify_phase04.sh passes: validates the workflow YAML syntax, confirms job if: conditions, confirms issue-to-contract.yml references the dispatch API, runs a dry-run of finalize_evidence.py against a temp audit.json (mock API)" + - "evidence-ui/index.html exists: single HTML file with inline CSS + JS, no external resources, no frameworks (D-032, REQ-14)" + - "index.html fetches ./audit.json (relative URL) and renders events as a vertical timeline with stage color-coding (dev/qa/prod/finalize/genesis) + 12-char hash preview" + - "scripts/run_demo.sh exists: simulates all 4 acts (Friction, Dev Self-Service, Citizen Developer, Safety Net) by calling the Phase 03 core scripts + evidence_writer.py + finalize_evidence.py; writes a final audit.json; uploads audit.json + evidence-ui/index.html to acdl-evidence main via the Gitea file-contents API (D-031/D-033)" + - "scripts/run_demo.sh is idempotent: re-running overwrites both files on acdl-evidence and produces the same audit.json (deterministic hash chain)" + - "Act 4 produces a 'dev rejected: POLICY_VIOLATION:PUBLIC_INGRESS' evidence event with score 0.40 (the Safety Net)" + - "scripts/verify_phase05.sh passes: validates index.html structure (single file, inline, fetch call), runs run_demo.sh, fetches the raw audit.json + index.html URLs from acdl-evidence and confirms HTTP 200" verification: - typecheck: "bash -n scripts/*.sh && python3 -m py_compile scripts/*.py && python3 -c 'import yaml; yaml.safe_load(open(\".gitea/workflows/pipeline.yml\")); yaml.safe_load(open(\"contracts-repo/.gitea/workflows/issue-to-contract.yml\"))'" - test: "scripts/verify_phase04.sh" + typecheck: "bash -n scripts/*.sh && python3 -m py_compile scripts/*.py" + test: "scripts/verify_phase05.sh" build: no-op --- -# Phase 04 — pipeline-and-approval-gates PLAN +# Phase 05 — evidence-ui-and-demo-dry-run PLAN ## Goal -Replace the Phase 01 workflow skeletons with real implementations. Wire -the Dev → QA → Prod → Finalize pipeline with the 3-dispatch approval-gate -pattern (D-027/D-028), and the issue-to-contract trigger (D-030). +Build the vanilla-JS timeline UI and run the 4 demo acts as a local dry +run that produces a real `audit.json` and publishes it (plus the UI) to +`acdl-evidence` main. This is the milestone's capstone phase. ## Requirements covered -- REQ-10: reusable pipeline runs Dev (autonomous), QA (approval), Prod (approval), Finalize (commits audit.json to acdl-evidence) -- REQ-12: opening an Issue in acdl-contracts runs l3b_agent_stub.py, commits a contract.yaml to a new branch, closes the Issue, and triggers the main pipeline +- REQ-13: `acdl-evidence` is Pages-enabled and serves `audit.json` plus `index.html` (substituted by D-012: raw-URL 200 on both files) +- REQ-14: `index.html` uses vanilla JS to fetch `audit.json` and render events as a timeline +- REQ-15: All four demo acts reproduce deterministically in a dry run ## Waves (vertical slices, domain priority order) -### Wave 1 — backend-engineer (pipeline + finalize helper + issue trigger) +### Wave 1 — frontend-engineer (the UI) **Tasks:** -- **T-4.1** Create `scripts/finalize_evidence.py` — a helper that takes `--audit ` `--owner ` `--repo ` `--branch ` (defaults: continuous-intelligence, acdl-evidence, main) and `--token-env ` (default ACDL_GITEA_TOKEN). It GETs the current `audit.json` from the repo (to get the sha if it exists), reads the local `` file, PUTs (or POSTs if 404) the new content via the Gitea file-contents API with base64 + commit message "finalize: update audit.json (run )". Exit 0 on success, 1 on API failure. Used by the pipeline finalize + each stage to persist evidence to acdl-evidence. -- **T-4.2** Replace `.gitea/workflows/pipeline.yml` with the real implementation: - - `on: workflow_dispatch` with inputs `contract-ref` (string, default `main`), `approve_qa` (boolean, default `false`), `approve_prod` (boolean, default `false`). - - Job `dev`: `if: inputs.approve_qa != true && inputs.approve_prod != true`. Steps: checkout `acdl` (current repo) at `milestone/v1.0-initial`; checkout `acdl-contracts` at `inputs.contract-ref` into a sibling dir using `actions/checkout@v4` with `repository: continuous-intelligence/acdl-contracts`, `ref: ${{ inputs.contract-ref }}`, `token: ${{ secrets.GITEA_TOKEN }}`; run `python3 scripts/policy_checker.py ../acdl-contracts/contract.yaml`; run `python3 scripts/confidence_signal.py ../acdl-contracts/contract.yaml` and capture the score; if score < 0.50, run `python3 scripts/evidence_writer.py --stage dev --event "dev rejected: confidence < 0.50"` and `python3 scripts/finalize_evidence.py --audit audit.json` and `exit 1`; else run `bash scripts/mock_executor.sh ../acdl-contracts/contract.yaml`, then `python3 scripts/evidence_writer.py --stage dev --event "dev applied: "`, then `python3 scripts/finalize_evidence.py --audit audit.json`. - - Job `qa-gate`: `if: inputs.approve_qa == true && inputs.approve_prod != true`. Steps: checkout acdl; run `python3 scripts/evidence_writer.py --stage qa --event "qa approved"`; `python3 scripts/finalize_evidence.py --audit audit.json`. - - Job `prod-gate`: `if: inputs.approve_prod == true`. Steps: checkout acdl; run `python3 scripts/evidence_writer.py --stage prod --event "prod approved"`; `python3 scripts/finalize_evidence.py --audit audit.json`. - - Job `finalize`: `needs: prod-gate`. Steps: checkout acdl; run `python3 scripts/evidence_writer.py --stage finalize --event "pipeline complete: audit.json committed to acdl-evidence"`; `python3 scripts/finalize_evidence.py --audit audit.json`. - - All jobs `runs-on: ubuntu-latest`. Use `gitea.*` context where relevant. -- **T-4.3** Replace `contracts-repo/.gitea/workflows/issue-to-contract.yml` with the real implementation: - - `on: issues` with `types: [opened]`. - - Job `parse-and-trigger`: `runs-on: ubuntu-latest`. Steps: checkout `acdl` (to get `l3b_agent_stub.py`) at `milestone/v1.0-initial`; run `python3 scripts/l3b_agent_stub.py "${{ gitea.event.issue.body }}" -o contract.yaml`; parse the contract to confirm a stack was set; commit `contract.yaml` to a new branch `contract/${{ gitea.event.issue.number }}` on `acdl-contracts` via the file-contents API (POST); comment on the Issue with the contract summary; close the Issue via the issues API; dispatch the pipeline workflow via `POST /api/v1/repos/continuous-intelligence/acdl/actions/workflows/pipeline.yml/dispatches` with body `{ "ref": "milestone/v1.0-initial", "inputs": { "contract-ref": "contract/${{ gitea.event.issue.number }}" } }` using `secrets.GITEA_TOKEN`. +- **T-5.1** Create `evidence-ui/index.html` — single HTML file with inline `