From e85041d67c1de596588ccdf2a8a3697f1ef2c131 Mon Sep 17 00:00:00 2001 From: Jon Chery Date: Tue, 21 Jul 2026 13:20:48 +0000 Subject: [PATCH] docs(P03): create 3-wave phase plan (REQ-04/05/06/07/08/11) ---ci--- phase: 3 milestone: v1.0 status: plan plan: waves: 3 wave_1_infra_stub: [T-3.1..T-3.4 create 4 L2 manifests] wave_2_backend: [T-3.5 policy_checker, T-3.6 confidence_signal, T-3.7 evidence_writer, T-3.8 mock_executor, T-3.9 l3b_agent_stub] wave_3_coordination: [T-3.10 verify_phase03, T-3.11 traceability] requirements_covered: [REQ-04, REQ-05, REQ-06, REQ-07, REQ-08, REQ-11] must_haves: 9 verification: typecheck: bash -n + python -m py_compile + yaml load test: scripts/verify_phase03.sh build: no-op ---/ci--- PLAN.md replaced with Phase 03 plan. Wave 1 (infra-stub-engineer) creates the 4 L2 manifests. Wave 2 (backend-engineer) creates the 5 core scripts. Wave 3 (lead-developer) wires the verify script + traceability. --- .ciagent/PLAN.md | 115 +++++++++++++++++++++++++++-------------------- 1 file changed, 66 insertions(+), 49 deletions(-) diff --git a/.ciagent/PLAN.md b/.ciagent/PLAN.md index e8482b3..f8d91ce 100644 --- a/.ciagent/PLAN.md +++ b/.ciagent/PLAN.md @@ -1,85 +1,102 @@ --- -phase: 02 -name: l1-modules +phase: 03 +name: l2-modules-and-core-scripts milestone: v1.0 milestone_type: feature status: planned -requirements: [REQ-02, REQ-03] +requirements: [REQ-04, REQ-05, REQ-06, REQ-07, REQ-08, REQ-11] must_haves: - - "All 8 L1 module folders exist under modules/l1/ with the exact names from REQ-02" - - "Each L1 has a manifest.yaml matching the schema in ARCHITECTURE.md (name, kind: l1, description, inputs: map of string keys)" - - "Each L1 has a mock_apply.sh that echoes '[L1: ] applying...', sleeps 1s, echoes '[L1: ] OK', exits 0 (D-007)" - - "All mock_apply.sh are executable (chmod +x) and bash -n clean" - - "All manifest.yaml files parse as valid YAML" - - "scripts/verify_phase02.sh passes: enumerates 8 L1s, validates each manifest, runs each mock_apply.sh, confirms exit 0 + expected output" + - "4 L2 module folders exist under modules/l2/ with exact names: l2-invoice-service, l2-commodity-price-feed, l2-energy-analytics-api, l2-regulatory-reporting" + - "Each L2 has a manifest.yaml matching the D-020 schema (name, kind: l2, description, l1s: list of {name, inputs: map})" + - "Each L2 references 5 L1s by name; all referenced L1 names exist in modules/l1/" + - "mock_executor.sh reads a contract.yaml, resolves the L2, invokes each L1 mock_apply.sh, writes state.json per D-022" + - "policy_checker.py exits 1 with 'POLICY_VIOLATION:PUBLIC_INGRESS' on public-ingress:true; exits 0 with 'POLICY_PASS' otherwise (D-025)" + - "confidence_signal.py prints {score, reason} JSON; score 0.90 on pass, 0.40 on policy fail (D-024)" + - "evidence_writer.py appends an event to audit.json with a valid canonical-JSON SHA-256 hash chain (D-023)" + - "l3b_agent_stub.py maps the Act 3 example issue text to l2-commodity-price-feed and emits a valid contract.yaml (D-026/D-008)" + - "scripts/verify_phase03.sh passes: validates all 4 L2s, runs each core script with a sample contract, confirms hash chain integrity" verification: - typecheck: "bash -n modules/l1/*/mock_apply.sh scripts/*.sh && python3 -c 'import yaml; [yaml.safe_load(open(f)) for f in glob.glob(\"modules/l1/*/manifest.yaml\")]'" - test: "scripts/verify_phase02.sh" + typecheck: "bash -n scripts/*.sh && python3 -m py_compile scripts/*.py && python3 -c 'import yaml, glob; [yaml.safe_load(open(f)) for f in glob.glob(\"modules/l2/*/manifest.yaml\")]'" + test: "scripts/verify_phase03.sh" build: no-op --- -# Phase 02 — l1-modules PLAN +# Phase 03 — l2-modules-and-core-scripts PLAN ## Goal -Create the 8 L1 stub modules under `modules/l1/`. Each module has a -`manifest.yaml` (declared inputs, flat string map per D-017) and a uniform -`mock_apply.sh` (echo + 1s sleep + exit 0 per D-007/D-018). After this phase, -Phase 03 can compose L1s into L2 modules and `mock_executor.sh` can iterate -over an L2's L1 references. +Create the 4 L2 composition modules and the 5 core scripts. After this +phase, the demo has every primitive needed for Phase 04 to wire the +pipeline and Phase 05 to render the evidence UI. ## Requirements covered -- REQ-02: 8 L1 module folders exist (exact names) -- REQ-03: each L1 has manifest.yaml + mock_apply.sh with the uniform behavior +- REQ-04: 4 L2 modules under modules/l2/ composing L1s +- REQ-05: L2s compose L1s, max depth 5 +- REQ-06: mock_executor.sh reads L2 + invokes L1s + writes state.json +- REQ-07: policy_checker.py fails on public-ingress:true +- REQ-08: confidence_signal.py 0.90/0.40 + gate ≥ 0.50 +- REQ-11: evidence_writer.py SHA-256 hash chain -## Waves (vertical slices) +## Waves (vertical slices, domain priority order) -### Wave 1 — infra-stub-engineer (creates the 8 L1s) +### Wave 1 — infra-stub-engineer (4 L2 manifests) **Tasks:** -- **T-2.1** Create `modules/l1/l1-eks-fargate/{manifest.yaml, mock_apply.sh}` -- **T-2.2** Create `modules/l1/l1-iam-role/{manifest.yaml, mock_apply.sh}` -- **T-2.3** Create `modules/l1/l1-lambda/{manifest.yaml, mock_apply.sh}` -- **T-2.4** Create `modules/l1/l1-api-gateway/{manifest.yaml, mock_apply.sh}` -- **T-2.5** Create `modules/l1/l1-eventbridge/{manifest.yaml, mock_apply.sh}` -- **T-2.6** Create `modules/l1/l1-sqs/{manifest.yaml, mock_apply.sh}` -- **T-2.7** Create `modules/l1/l1-s3/{manifest.yaml, mock_apply.sh}` -- **T-2.8** Create `modules/l1/l1-cloudwatch/{manifest.yaml, mock_apply.sh}` +- **T-3.1** Create `modules/l2/l2-invoice-service/manifest.yaml` (L1s: l1-eks-fargate, l1-iam-role, l1-lambda, l1-sqs, l1-s3) +- **T-3.2** Create `modules/l2/l2-commodity-price-feed/manifest.yaml` (L1s: l1-eks-fargate, l1-lambda, l1-api-gateway, l1-eventbridge, l1-s3) +- **T-3.3** Create `modules/l2/l2-energy-analytics-api/manifest.yaml` (L1s: l1-eks-fargate, l1-api-gateway, l1-lambda, l1-s3, l1-cloudwatch) +- **T-3.4** Create `modules/l2/l2-regulatory-reporting/manifest.yaml` (L1s: l1-eks-fargate, l1-iam-role, l1-lambda, l1-sqs, l1-s3) -Each L1's `manifest.yaml` declares 1-3 plausible inputs for that primitive -(e.g., `l1-s3` declares `bucket_name`, `region`, `retention_days`; `l1-iam-role` -declares `role_name`, `trust_policy`). Each `mock_apply.sh` follows the exact -uniform template from ARCHITECTURE.md. +Each manifest declares plausible `inputs` per L1 (string map per D-017). +Remove `modules/l2/.gitkeep` in T-3.1. -**Files owned (territory):** `modules/l1/**` +**Files owned:** `modules/l2/**` -**Commits:** one per task, `---ci---` block has `phase: 2, status: plan-as-execute, persona: infra-stub-engineer, task: T-2.x, requirements.covered: [REQ-02, REQ-03]`. +**Commits:** one per task, `phase: 3, status: plan-as-execute, persona: infra-stub-engineer, task: T-3.x, requirements.covered: [REQ-04, REQ-05]`. -### Wave 2 — lead-developer (verification script + traceability) +### Wave 2 — backend-engineer (5 core scripts) **Tasks:** -- **T-2.9** Create `scripts/verify_phase02.sh`. It: - 1. Enumerates `modules/l1/*/` and confirms exactly 8 folders with the 8 expected names. - 2. For each L1: confirms `manifest.yaml` exists and parses as YAML with `name` matching the folder, `kind: l1`, and an `inputs:` map. - 3. For each L1: confirms `mock_apply.sh` is executable, `bash -n` clean, runs in <2s, exits 0, and its stdout contains the `[L1: ] applying...` and `[L1: ] OK` markers. - 4. Prints a PASS/FAIL summary; exits 0 on full success. -- **T-2.10** Update `.ciagent/REQUIREMENTS.md` (REQ-02/03 → covered pending VERIFY) and `.ciagent/ROADMAP.md` (Phase 02 → executing). No README change. +- **T-3.5** Create `scripts/policy_checker.py` — reads contract.yaml (argv[1]); if `public-ingress: true`, print `POLICY_VIOLATION:PUBLIC_INGRESS` and exit 1; else print `POLICY_PASS` and exit 0. Use only stdlib (yaml is available). Idempotent, no side effects. +- **T-3.6** Create `scripts/confidence_signal.py` — reads contract.yaml (argv[1]); calls policy_checker as a subprocess; if pass → `{"score": 0.90, "reason": "POLICY_PASS"}`, if fail → `{"score": 0.40, "reason": "POLICY_VIOLATION:PUBLIC_INGRESS"}`. Print JSON to stdout. Exit 0 always. +- **T-3.7** Create `scripts/evidence_writer.py` — argv flags `--stage`, `--event`, `--audit ` (default `./audit.json`). Loads audit.json (or empty list), computes the new event with canonical-JSON SHA-256 hash chain per D-023, appends, writes back atomically (write tmp + rename). Prints `{"seq": N, "hash": "..."}` to stdout. Genesis event automatically inserted if the file is empty/missing. +- **T-3.8** Create `scripts/mock_executor.sh` — argv[1] = contract.yaml path. Reads contract.stack, resolves `modules/l2//manifest.yaml`, iterates `l1s`, invokes `modules/l1//mock_apply.sh` for each, captures exit code, writes `state.json` per D-022. Exit 0 if all L1s exit 0; non-zero otherwise. +- **T-3.9** Create `scripts/l3b_agent_stub.py` — argv[1] = issue body (or read stdin if absent); optional `-o ` (default stdout). Applies the D-008 keyword map; writes a contract.yaml (D-021 schema) with `stack` set to the mapped L2 name and a fixed `inputs:` map per stack. Exit 0 on success, 1 on empty input. -**Files owned (territory):** `scripts/verify_phase02.sh`, `.ciagent/REQUIREMENTS.md`, `.ciagent/ROADMAP.md` +**Files owned:** `scripts/policy_checker.py`, `scripts/confidence_signal.py`, `scripts/evidence_writer.py`, `scripts/mock_executor.sh`, `scripts/l3b_agent_stub.py` -**Commits:** one per task, `---ci---` block has `phase: 2, status: plan-as-execute, persona: lead-developer, task: T-2.9/2.10`. +**Commits:** one per task, `phase: 3, status: plan-as-execute, persona: backend-engineer, task: T-3.x, requirements.covered: [REQ-06/07/08/11/12]`. + +### Wave 3 — lead-developer (verify script + traceability) + +**Tasks:** + +- **T-3.10** Create `scripts/verify_phase03.sh`. Checks: + 1. Exactly 4 L2 folders with the expected names. + 2. Each L2 manifest.yaml parses, name matches folder, kind=l2, l1s is a list of 5 entries, all referenced L1 names exist in modules/l1/. + 3. policy_checker.py on a passing contract → exit 0 + `POLICY_PASS`; on `public-ingress: true` contract → exit 1 + `POLICY_VIOLATION:PUBLIC_INGRESS`. + 4. confidence_signal.py on passing contract → `{"score": 0.90, ...}`; on failing contract → `{"score": 0.40, ...}`. Both exit 0. + 5. mock_executor.sh on a sample contract → writes state.json with l2 + l1s (all applied=true, exit_code=0) + contract fields. + 6. evidence_writer.py: append 3 events to a temp audit.json; verify seq increments 0/1/2, prev_hash chain links, each hash matches a recompute. + 7. l3b_agent_stub.py on the Act 3 example issue text ("We need to ingest natural gas prices from Platts...") → emits a contract.yaml with `stack: l2-commodity-price-feed`. +- **T-3.11** Update `.ciagent/REQUIREMENTS.md` (REQ-04/05/06/07/08/11 → covered pending VERIFY) and `.ciagent/ROADMAP.md` (Phase 03 → executing). + +**Files owned:** `scripts/verify_phase03.sh`, `.ciagent/REQUIREMENTS.md`, `.ciagent/ROADMAP.md` + +**Commits:** one per task, `phase: 3, status: plan-as-execute, persona: lead-developer, task: T-3.10/3.11`. ## Wave ordering -- Wave 1 (infra-stub-engineer) creates all 8 L1s. A single subagent gets all 8 tasks; it commits per task. -- Wave 2 (lead-developer) adds the verify script and traceability after the L1s exist. +- Wave 1 (infra-stub-engineer) creates the 4 L2 manifests first so mock_executor.sh has something to resolve. +- Wave 2 (backend-engineer) builds the 5 core scripts. policy_checker + confidence_signal have no L2 dependency; mock_executor depends on Wave 1; l3b_agent_stub is independent. +- Wave 3 (lead-developer) wires the verify script after both Waves 1 and 2 are complete. -`backend-engineer`, `data-engineer`, `frontend-engineer` have 0 tasks this phase. +`data-engineer` and `frontend-engineer` have 0 tasks this phase. ## Dependencies -- Depends on Phase 01 (the `modules/l1/.gitkeep` from T-1.1 is replaced by real folders). -- Phase 03 depends on this phase for L1 references in L2 compositions. \ No newline at end of file +- Depends on Phase 02 (L1 modules exist so mock_executor can invoke them and verify_phase03 can confirm L2 references resolve). +- Phase 04 depends on this phase for the pipeline to call policy_checker, mock_executor, confidence_signal, evidence_writer, and for the issue workflow to call l3b_agent_stub. \ No newline at end of file