Files
acdl/.ciagent/PLAN.md
T
grimacing 0672edfc3f ship: phase-05 evidence-ui-and-demo-dry-run (v1.0.5)
Squash merge of phase/05-evidence-ui-and-demo-dry-run; evidence-ui/index.html + run_demo.sh 4-act simulation + verify_phase05.sh; demo live at acdl-evidence raw URL.
2026-07-21 13:53:54 +00:00

7.6 KiB

phase, name, milestone, milestone_type, status, requirements, must_haves, verification
phase name milestone milestone_type status requirements must_haves verification
05 evidence-ui-and-demo-dry-run v1.0 feature planned
REQ-13
REQ-14
REQ-15
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
typecheck test build
bash -n scripts/*.sh && python3 -m py_compile scripts/*.py scripts/verify_phase05.sh no-op

Phase 05 — evidence-ui-and-demo-dry-run PLAN

Goal

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-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 — frontend-engineer (the UI)

Tasks:

  • T-5.1 Create evidence-ui/index.html — single HTML file with inline <style> + <script>. The JS fetches ./audit.json (relative URL), parses the JSON array, and renders a vertical timeline. Each event card shows: seq (badge), ts (timestamp), stage (color-coded chip: dev=blue, qa=yellow, prod=orange, finalize=green, genesis=gray, rejected=red), event text, and hash.slice(0, 12) + "…" (a 12-char preview). Includes a refresh button that re-fetches. Handles fetch failure with a "No audit data yet" message. No external resources (no CDN, no fetch libraries); vanilla JS only. The file is self-contained.

Files owned: evidence-ui/index.html

Commits: one commit, phase: 5, status: plan-as-execute, persona: frontend-engineer, task: T-5.1, requirements.covered: [REQ-14].

Wave 2 — backend-engineer (the dry-run script)

Tasks:

  • T-5.2 Create scripts/run_demo.sh — the Phase 05 dry-run simulation. It:

    1. Accepts an optional --no-upload flag (for testing without hitting Gitea).
    2. Creates a clean working directory under /tmp/acdl_demo_run/; sets AUDIT=/tmp/acdl_demo_run/audit.json.
    3. Initializes the audit log: python3 scripts/evidence_writer.py --stage genesis --event "audit log initialized" --audit "$AUDIT".
    4. Act 1 — Friction: write a single event --stage dev --event "Act 1 Friction: manual 2-week deployment (legacy process)".
    5. Act 2 — Developer Self-Service: write contracts/act2.yaml with stack: l2-commodity-price-feed, public-ingress: false. Run policy_checker.py + confidence_signal.py + mock_executor.sh. Write events: dev applied: l2-commodity-price-feed, qa approved, prod approved, finalize: audit.json committed.
    6. Act 3 — Citizen Developer: feed an Issue body ("We need to ingest natural gas prices from Platts...") to l3b_agent_stub.py -o contracts/act3.yaml. Run the same pipeline as Act 2 against the generated contract. Write 4 events.
    7. Act 4 — Safety Net: write contracts/act4.yaml with stack: l2-regulatory-reporting, public-ingress: true. Run policy_checker.py (fails) + confidence_signal.py (score 0.40). Since score < 0.50, write dev rejected: POLICY_VIOLATION:PUBLIC_INGRESS and skip QA/Prod/Finalize.
    8. Print a summary of all events.
    9. If --no-upload is NOT set: call python3 scripts/finalize_evidence.py --audit "$AUDIT" to upload audit.json to acdl-evidence, then call finalize_evidence.py --audit evidence-ui/index.html --path index.html --message "chore(ui): update index.html" to upload the UI. (Reuses finalize_evidence.py with --path override for index.html.)
    10. Exit 0 if all 4 acts produced the expected evidence events; non-zero otherwise.

    Cleanup: write contracts under contracts/ (gitignored) so the working tree stays clean.

Files owned: scripts/run_demo.sh

Commits: one commit, phase: 5, status: plan-as-execute, persona: backend-engineer, task: T-5.2, requirements.covered: [REQ-13, REQ-15].

Wave 3 — lead-developer (verify script + traceability)

Tasks:

  • T-5.3 Create scripts/verify_phase05.sh. Checks:
    1. evidence-ui/index.html exists, is a single file, contains <style> and <script> inline tags, contains fetch('./audit.json' (relative URL), no https:// external resource references (no CDN).
    2. scripts/run_demo.sh is bash -n clean.
    3. Run scripts/run_demo.sh --no-upload and confirm:
      • It exits 0.
      • It produces a non-empty audit.json with at least 14 events (genesis + act1 + act2[4] + act3[4] + act4[1] = 11 minimum, but with markers it may be more — use >= 11).
      • The audit chain is valid (re-run the hash check).
      • The Act 4 event contains "POLICY_VIOLATION:PUBLIC_INGRESS".
    4. If ACDL_GITEA_TOKEN is set: run scripts/run_demo.sh (with upload), then curl the raw URLs for audit.json and index.html on acdl-evidence and confirm HTTP 200 + that the audit.json matches the local one (or at least parses as JSON with the expected number of events) + that index.html contains "ACDL Evidence" or "audit.json" reference.
    5. If ACDL_GITEA_TOKEN is NOT set: skip the upload check with a clear "SKIP (no token)" message; the dry-run + structural checks are sufficient.
  • T-5.4 Update .ciagent/REQUIREMENTS.md (REQ-13/14/15 → covered pending VERIFY) and .ciagent/ROADMAP.md (Phase 05 → executing).

Files owned: scripts/verify_phase05.sh, .ciagent/REQUIREMENTS.md, .ciagent/ROADMAP.md

Commits: one per task, phase: 5, status: plan-as-execute, persona: lead-developer, task: T-5.3/5.4.

Wave ordering

  • Wave 1 (frontend) builds the UI.
  • Wave 2 (backend) builds the dry-run script.
  • Wave 3 (lead-developer) verifies + traceability.

Wave 1 and Wave 2 can run in parallel (no file overlap), but per execute.md the domain priority is coordination → backend → frontend → custom. Here frontend-engineer and backend-engineer have no territory overlap, so they can run sequentially in priority order: backend first (Wave 2), then frontend (Wave 1) — but for clarity I'll keep Wave 1 = frontend, Wave 2 = backend (the UI is the visible artifact; the script needs to upload it). Actually, run_demo.sh references evidence-ui/index.html, so the UI must exist before the script is tested end-to-end. Order: Wave 1 (UI) → Wave 2 (script) → Wave 3 (verify).

Dependencies

  • Depends on Phases 01-04 (all core scripts, workflows, and the acdl-evidence repo must exist).
  • This is the last phase in the milestone. After Phase 05 ships, the COMPLETE gate runs: review → ship(milestone v1.1.0) → audit.