# Nova — Phase Plan v1.21 (Nova Deck Refinement & Pipeline Hardening) > **Milestone:** v1.21 — Nova Deck Refinement & Pipeline Hardening > **Branch:** `milestone/v1.21-deck-refinement` (flat workflow: commits on > main, tags on the v1.20.x line per branch-strategy) > **Tag line:** `v1.20.x` patch line — `v1.20.0` (P0) → `v1.20.1..v1.20.5` > (P1–P5) → `v1.20.6` (P6 final = milestone release). v1.21 is an NFR > milestone (all phases are docs/test/chore/refactor) → progressive patches. > **Phase count:** 7 (P0 pre-execution [DONE] + 5 execution + 1 final). > **Source of truth for requirements:** `.ciagent/REQUIREMENTS.md` §v1.21 > (REQ-245..253, 9 requirements). > **Source of truth for decisions:** the 33 review notes in the v1.21 > run context (encoded as REQ-245..253). > **Source of truth for research:** existing deck + pipeline + strategic > docs (the domain is known; no new research needed at full autonomy). ## Wave Ordering All 5 execution phases are **sequenced** (flat workflow). The theoretical parallelism is documented for future parallelization-enabled runs. | Wave | Phases | Rationale | |------|--------|-----------| | Wave 1 | P1, P2, P4 (**parallelizable**) | P1 (strategic docs: NORTH_STAR, AUTONOMY_THESIS, PROJECT, scope, raci), P2 (slides source-of-truth rewrite + rename), P4 (pipeline hardening: Checkov/Wiz flow). Zero file overlap: P1 touches `.ciagent/` + `docs/scope.md` + `docs/raci.md`; P2 touches `docs/presentations/*.md`; P4 touches `scripts/run_*.sh` + `adapters/wiz/` + `tests/test_pipeline*.py`. In a parallelization-enabled run these three could execute concurrently. | | Wave 2 | P3 | Marp deck + talking points + README synthesis. Depends on P2's updated source-of-truth. Re-renders HTML+PPTX via `render_slides.sh`. Also fixes theme CSS A1 table + footer cleanup (REQ-251). | | Wave 3 | P5 | Render + verify. Depends on P2 (source), P3 (marp), P4 (pipeline). Re-renders mermaid PNGs (slide 1 new diagram, slide 9 expand, Atelier split), HTML, PPTX. Runs `test_slides_pipeline.py`, `test_no_forge_mentions.py`, full `pytest`, `run_platform.sh --check-only`. | | Wave 4 | P6 | Final review + audit + milestone ship. Merge to main, tag `v1.20.6`, create release, attach PPTX. | ## Phase Summaries ### Phase P0 — pre-execution (DONE) SPECIFY → CLARIFY → RESEARCH → PLAN. Validated v1.21 requirements (REQ-245..253). Established `active_milestone: "v1.21"`. Synced PROJECT.md strategic-direction pillar. No new research (domain known). ### Phase P1 — strategic-docs (Wave 1) - `NORTH_STAR.md`: vision polish (item 11); obj #2 deterministic-scoring reword (item 13); obj #3 four CTO metrics (item 14); obj #4 replaced with integration objective (item 17); drop anti-goals 1,4,5; add 2 new anti-goals (item 16); anti-goal #3 reworded (item 7). - `git mv .ciagent/NO_HUMANS_THESIS.md .ciagent/AUTONOMY_THESIS.md` + reframe content (items 7, 8). - `PROJECT.md`: mission/scope sync for item 17 (already partially done in P0; finalize here). - `docs/scope.md`: light sync. - `docs/raci.md`: rename Release Mgmt → SRE; add Quality Engineering role. - **REQs:** REQ-246, REQ-247 (partial). ### Phase P2 — slides source-of-truth (Wave 1) - `git mv` all 5 deck files `nova-no-humans-platform*` → `nova-autonomous-cloud-delivery*`. - Rewrite `nova-autonomous-cloud-delivery.md` (source of truth): - Slide 1 "The Problem" (items 3,4,5,7,9): broader problem (devs writing terraform, destructive changes, AI-era 0-day pace, bandwidth gaps, tribal knowledge/rockstar operator); no arc; no "18 capabilities verified"; not "humans are the problem". - Slide 2 "Nova's Vision" (item 11): polish for technical audience; "infrastructure operations become visible" as recurring theme. - Slide 3 "Strategic Objectives + Anti-Goals" (items 12,13,14,15,16,17, 18): only Obj+Anti-Goals; provable trust = deterministic scripts (functions without AI); ROI = Lead Time + Vuln Trend + MTTR + Spend; drop anti-goals 1,4,5; add "not upstream dev platform", "not PDLC replacement"; replace obj #4 with integration objective; reword benefit. - Slide 4 "Scope" (item 29): refine (moved up). - Slide 5 "RACI" (item 30): add QE column; reassign A from Platform → QA/SRE; rename Release Mgmt → SRE; split release attestation (SRE = Production Readiness); shrink to fit (moved up). - Slide 6 "Pipeline" (item 20): Checkov on static code before plan; Wiz on plan; no Wiz → Checkov on plan; never both. - Slide 7 "Decision Ledger" (items 21,22): drop D-121/122/132; "AI decisions = automated decisions"; focus on value (immutable, queryable, accountable), not sqlite/hash-chain implementation. - Slide 8 "Attestation Matrix" (item 23): drop bullets below table; add Description column per concern; rethink "operator-supplied" label; reword benefit. - Slide 9 "Telemetry & Live Ops" (item 25): expand on value; keep metric flow; drop D-120/125/126; expand on PowerBI live ops dashboard; reword benefit. - Slide 10 "Decision Ledger + Attestation Coverage" (item 27): mandatory by design; no prod change without ledger + human attestation; queryable for auditing; full traceability; improve benefit. - Slide 11 "Cost & ROI": minor polish. - Slide 12 "What's Deferred — and Why" (items 10,19): remove all D-IDs; plain-language blockers. - Slide 13 "Roadmap to the North Star" (items 10,19): drop D-IDs; no status column; roadmap with timelines. - Slide 14 "12-Month Product Roadmap" (item 24): drop `planned` badges. - Slide 15 "Quarter-by-Quarter Outcomes" (item 24): drop badges. - Slide 16 "Production-Grade Guidance via Atelier (1/2)" (item 31): split — Skills + MCP server overview. - Slide 17 "Production-Grade Guidance via Atelier (2/2)" (item 31): split — agentic validation beyond deterministic scanners + vendoring. - Slide 18 "Recap + Ask": refresh recap to match new structure. - Appendix A1 "Metrics Glossary" (item 32): table readability fixed in P3 theme CSS. - Global (items 6,10,24,2): tech-leadership benefits; no D-###/REQ-###/ .py paths in audience slides; no badges; no version in footer; final "less is more / no fluff" prose pass. - **REQs:** REQ-245, REQ-248, REQ-249, REQ-252 (partial). ### Phase P3 — marp deck + talking points + README (Wave 2) - `nova-autonomous-cloud-delivery-marp.md`: synthesize from updated source; frontmatter — title "Nova — The Autonomous Cloud Delivery Platform", footer without version + without "Act N/5", title-slide subtitle "Product Development & Citizen Developer Overview", no badges. - `nova-autonomous-cloud-delivery-talking-points.md`: re-distill to 18-slide structure. - `docs/presentations/README.md`: update deck title, audience, slide count (18 main + 1 appendix), directory layout, remove badge docs, update deck table + render commands + filenames. - `docs/presentations/assets/nova-sp-theme.css`: fix Appendix A1 table background (item 32); footer chrome no version. - Update `scripts/render_slides.sh`, `scripts/render_deck.sh`, `workflows-src/slides.yml`, `.github/workflows/slides.yml`, `tests/test_slides_pipeline.py` filename refs. - **REQs:** REQ-251, REQ-252 (partial). ### Phase P4 — pipeline hardening (Wave 1) - `scripts/run_platform.sh` + `scripts/run_postapply.sh`: item 20 flow — 1. Checkov on static code (`main.tf`/TF dir) **before** `terraform plan` → fail-fast dev feedback. 2. After plan: if `WIZ_API_TOKEN`+`WIZ_API_URL` → **Wiz against plan**; else **Checkov against plan** (drop-in). **Never both.** - `adapters/wiz/wiz_adapter.py`: support plan-mode input if needed. - Tests: `tests/test_pipeline.py`, `tests/test_pipeline_contract.py`, `tests/test_slides_pipeline.py`, checkov/wiz tests. - `docs/scope.md` policy-enforcement line + slide 6 reflect new flow. - `docs/METRICS.md` policy-stage description if changed. - **REQs:** REQ-250. ### Phase P5 — render + verify (Wave 3) - Re-render changed/new mermaid diagrams (slide 1 new diagram, slide 9 expand, Atelier split) via `scripts/render_slides.sh`. - Render HTML + PPTX. - `tests/test_slides_pipeline.py` passes: 18 main + 1 appendix; no badges; no version in footer; no D-###/REQ-###/.py paths in audience slides; filename refs updated. - `tests/test_no_forge_mentions.py` passes. - Full `pytest` passes (pipeline-hardening tests green). - `run_platform.sh --check-only` passes. - **REQs:** REQ-253 (partial). ### Phase P6 — final-review-ship (Final Phase, Wave 4) - Multi-persona code review across P1–P5. - Audit: git log vs `.ciagent/` discipline. - Ship: merge to main, tag `v1.20.6` (final patch = milestone release), create release, attach PPTX. - Update `REQUIREMENTS.md` (v1.21 REQs complete) + `ROADMAP.md` (v1.21 complete). Clear `CHECKPOINT.json`. - **REQs:** REQ-253 (complete). --- # Nova — Phase Plan v1.18 (Citizen Developer & Production-Grade Guidance) > **Milestone:** v1.18 — Citizen Developer & Production-Grade Guidance > **Branch:** `milestone/v1.18-citizen-developer-guidance` > **Tag line:** `v1.17.x` patch line — `v1.17.0` (P0) → `v1.17.1..v1.17.6` > (P1–P6) → `v1.17.7` (P7 final = milestone release). Previous minor per > branch-strategy (v1.17 shipped on the v1.16.x line; v1.18 is a Feature > milestone → tags run on the previous minor's patch line = v1.17.x). > **Phase count:** 8 (P0 pre-execution [DONE] + 6 execution + 1 final). > **Source of truth for requirements:** `.ciagent/REQUIREMENTS.md` §v1.18 > (REQ-214..228, 15 requirements). > **Source of truth for decisions:** `.ciagent/PROJECT.md` §"Key Decisions > (v1.18)" (D-133..D-142). > **Source of truth for research:** `.ciagent/RESEARCH.md` §v1.18 (Atelier > skill mapping, MCP SDK skeleton, submission-readiness gap analysis, Marp > PPTX fidelity). ## Wave Ordering All 6 execution phases are **sequenced** for this run (the repo uses a flat `/ci-run` workflow — one phase at a time). The theoretical parallelism is documented for future parallelization-enabled runs. | Wave | Phases | Rationale | |------|--------|-----------| | Wave 1 | P1 | Theme restoration + render/attach scripts. P2/P6 depend on the render scripts existing. P6 depends on the S&P theme. Foundation — nothing else can ship a re-rendered deck without this. | | Wave 2 | P2 | RACI + PDLC-scope docs + 2 deck slides → 20 slides. Depends on P1's `render_deck.sh` + `attach_release_asset.py` + restored S&P theme. Re-renders HTML+PPTX. | | Wave 3 | P3, P4 (**parallelizable**) | P3 (submission-readiness schema+validator+doc+tests) and P4 (Atelier skills + index) have NO dependency on each other. P3 touches `schemas/`, `core/`, `tests/`, `docs/submission-readiness.md`. P4 touches `skills/`, `docs/skills.md`, `PROJECT.md` BA.A. Zero file overlap. In a parallelization-enabled run these two could execute concurrently. | | Wave 4 | P5 | Atelier MCP server (plugin-registry, vendored Atelier, tests). Depends on P4's skill catalog being present (the MCP `atelier.list_domains` tool returns the Nova-relevance table that P4 codifies in `docs/skills.md`; the server reads the vendored Atelier snapshot that P5 itself vendors — but the skill provenance in `docs/skills.md` is the cross-reference). Strictly P5 vendors Atelier independently of P4; the dependency is narrative consistency (the MCP server's domain list should match the skills index). | | Wave 5 | P6 | 3 new deck slides (scope/RACI/atelier) → 21 slides + README update + talking-points sync + HTML+PPTX re-render. Depends on P1 (theme + scripts), P2 (scope + RACI content + 2-slide precedent), P4 (atelier skills content for the Atelier slide), P5 (MCP server content for the Atelier slide). The deck slide that introduces Atelier must reflect what P4 + P5 actually shipped. | | Wave 6 | P7 | Final review + audit + milestone ship (merge to main, tag v1.17.7, delete branches). | **Execution order for this run:** P1 → P2 → P3 → P4 → P5 → P6 → P7 (sequential). The Wave 3 parallelism (P3‖P4) is noted for future runs but NOT exercised here. --- ## Phase P1 — sp-theme-restoration (feat) - **Wave:** 1 - **Requirements covered:** REQ-214, REQ-228 - **Persona assignment:** lead-developer (deck `style:` block restoration + HTML re-render verification) + backend-engineer (`scripts/render_deck.sh` + `scripts/attach_release_asset.py`) - **Description:** Restore the S&P Global Energy Marp `style:` block (from commit `ae0cb58`, v1.9.2 / P45) to the unified deck. The v1.17 P5 deck rebuild lost the S&P visual identity when it consolidated the two decks into one; the mermaid `sp-theme.json` survived but the Marp CSS theme was replaced with a generic dark-navy theme. Create the deck-automation scripts (`render_deck.sh` + `attach_release_asset.py`) that become the reusable render+commit+attach pipeline for P2 and P6. Re-render HTML. Commit the PPTX binary. Attach to the phase's Gitea release. ### Tasks 1. **Edit `docs/presentations/nova-no-humans-platform-marp.md`** — replace the current `style: |` block (lines 8–15, the generic dark-navy theme: `#1a1a2e` / `#16213e`) with the S&P Global Energy `style:` block from commit `ae0cb58` (`docs/presentations/how-the-platform-works-marp.md` frontmatter). The restored block must contain: - `section { font-family: "Akkurat Pro", "Helvetica Neue", "Arial", sans-serif; font-size: 22px; color: #1B1B1B; }` - `h1 { color: #D6002A; font-size: 34px; margin-bottom: 0.3em; }` - `h2 { color: #D6002A; font-size: 26px; margin-bottom: 0.2em; }` - `section.title { background: #1B1B1B; color: #fff; border-top: 8px solid #D6002A; }` - `section.title h1 { color: #fff; }` - `table { font-size: 18px; width: 100%; }` - `th { background: #F0F0F0; }` - `blockquote { border-left: 4px solid #D6002A; color: #2E2E2E; font-size: 20px; }` - `img { display: block; margin: 0 auto; max-height: 320px; }` - `.badge { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 14px; font-weight: 600; }` - `.today { background: #c6f6d5; color: #22543d; }` - `.planned { background: #fef3c7; color: #78350f; }` - Preserve the current Nova header text (`Nova — The No-Humans Infrastructure Platform`) and the `footer: 'Act %{page}/5 — v1.17'` line — the rebrand is NOT touched (REQ-214: "the current Nova header/footer text is preserved"). Only the visual theme (colors + font + accent bar) is restored. 2. **Create `scripts/render_deck.sh`** (executable, `set -euo pipefail`) — renders HTML + PPTX from a Marp deck markdown file. Usage: `render_deck.sh `. Implementation per RESEARCH §4.1: - Reads the deck path from `$1` (required; fails with usage message if absent). - Derives the output basename (strip `-marp.md` suffix → bare name; e.g. `nova-no-humans-platform-marp.md` → `nova-no-humans-platform`). - Output paths: `.html` and `.pptx` in the same directory as the input deck. - HTML render: `npx --yes @marp-team/marp-cli@latest --allow-local-files -o .html` (self-contained HTML, base64-embedded images). - PPTX render: `CHROME_PATH= npx --yes @marp-team/marp-cli@latest --allow-local-files -o .pptx` (standard image-based PPTX, NOT `--pptx-editable` — per RESEARCH §4.1 the inline `style:` CSS survives the rasterization path). The `CHROME_PATH` is resolved from `~/.cache/ms-playwright/chromium-*/chrome-linux64/chrome` (the existing path documented in `docs/presentations/README.md` line 96). - Exit 0 on success; non-zero on render failure (the `set -e` propagates). - Prints `rendered: ` and `rendered: `. 3. **Create `scripts/attach_release_asset.py`** (executable Python, stdlib-only per RESEARCH §3.5) — uploads a file to a Gitea release via the API. Usage: `attach_release_asset.py --tag --file [--name ]`. Implementation per RESEARCH §3.5: - Reads `NOVA_GITEA_TOKEN` from `.env.secrets` (same source as `scripts/ship_phase.sh` line 35) — load via a small helper that reads `.env.secrets` key=value lines. - Resolves tag → release ID: `GET https://git.cloudinit.dev/api/v1/repos/continuous-intelligence/acdl/releases/tags/{tag}` with `Authorization: token ` → response JSON `id`. - Uploads the asset: `POST https://git.cloudinit.dev/api/v1/repos/continuous-intelligence/acdl/releases/{id}/assets` with `multipart/form-data` (`name` = display filename, `attachment` = file binary) + `Authorization: token `. - Constructs the multipart body manually via `urllib` (stdlib-only, per RESEARCH §3.5 — a ~30-line `multipart_encode(fields, files)` helper with a generated boundary; no `requests` dependency). - Prints `asset_id: release: file: ` on success. - Exits non-zero on API error (HTTP non-2xx) with a clear message (not a stack trace — C2 Clarity). 4. **Run `scripts/render_deck.sh docs/presentations/nova-no-humans-platform-marp.md`** — regenerates `nova-no-humans-platform.html` (committed) + creates `nova-no-humans-platform.pptx` (committed, D-141 — no LFS). 5. **Commit** the updated deck markdown, the regenerated HTML, and the new PPTX binary to the phase branch. 6. **Attach** the PPTX to the phase's Gitea release (after `ship_phase.sh` creates the `v1.17.1` tag + release): `python3 scripts/attach_release_asset.py --tag v1.17.1 --file docs/presentations/nova-no-humans-platform.pptx`. 7. **Update `docs/presentations/README.md`** — document the new `render_deck.sh` + `attach_release_asset.py` scripts in the deck-build process section; note that PPTX is now a committed binary (D-141) + attached to every phase's release (D-142). ### Must-haves (verification gate) - [ ] `docs/presentations/nova-no-humans-platform-marp.md` frontmatter `style:` block contains `#D6002A` (S&P red-core), `#1B1B1B` (grey-90), `8px solid #D6002A` (top accent bar), `'Akkurat Pro'` (font). A grep for `#D6002A` in the deck markdown returns ≥4 hits (h1, h2, title-bg border, blockquote border). - [ ] The Nova header (`Nova — The No-Humans Infrastructure Platform`) and footer (`Act %{page}/5 — v1.17`) text are UNCHANGED (rebrand preserved — REQ-214). - [ ] `scripts/render_deck.sh` exists, is executable, and exits 0 when run against the unified deck. - [ ] `scripts/attach_release_asset.py` exists, is executable, and `python3 -m py_compile scripts/attach_release_asset.py` succeeds. - [ ] `docs/presentations/nova-no-humans-platform.html` is regenerated (mtime newer than the deck markdown) and opens in a browser showing the S&P red accent bar + dark title-slide background. - [ ] `docs/presentations/nova-no-humans-platform.pptx` exists (binary, committed, no LFS) and is attached to the `v1.17.1` Gitea release. - [ ] `docs/presentations/README.md` documents the two new scripts. - [ ] CAP-024 deck structure regression passes (the S&P theme restoration must not break the 18-slide structure — slide count, x3 arc, per-slide benefit callouts all preserved). ### Ship tag `v1.17.1` --- ## Phase P2 — pdlc-scope-raci (docs) - **Wave:** 2 - **Requirements covered:** REQ-215, REQ-216, REQ-228 - **Persona assignment:** lead-developer (RACI matrix + PDLC-scope statement in PROJECT.md + `docs/raci.md` + `docs/scope.md` + 2 deck slides + HTML/PPTX re-render) - **Description:** Promote Core Tenet #2 + Anti-Goal #1 from buried tenets to a dedicated, unmissable scope statement: the PDLC is upstream of Nova; Nova governs infra + delivery only; integration is through the validated contract boundary. Author a three-role RACI matrix clarifying who owns what across the citizen-developer → platform → release-management boundary. Add 2 deck slides (scope + RACI) → 20 slides. Re-render HTML + PPTX using P1's scripts; commit PPTX; attach to release. ### Tasks 1. **Edit `PROJECT.md`** — add a new `## Scope: Nova is Downstream of PDLC` subsection under `## Domain Boundaries` (after the existing "Interface:" bullet). Content (per REQ-216): - State that the PDLC (Product Development Lifecycle — product backlog, code authorship, IDE) is upstream of Nova. - State that Nova governs infra + delivery only. - State that integration is through the validated contract boundary (the contract is the only ingress; Nova does not penetrate upstream product/SDLC). - Promote Core Tenet #2 ("The Delivery Lifecycle is a Sovereign Boundary") + Anti-Goal #1 ("Not an upstream development platform") from buried tenets to this dedicated, unmissable statement. 2. **Edit `PROJECT.md`** — add a new `## RACI Matrix` section (after the `## Scope: Nova is Downstream of PDLC` subsection, before `## Core Tenets` or at the end of the Domain Boundaries cluster). Content (per REQ-215, D-139): - Three roles (columns): **Citizen Developer**, **Platform**, **Release Management** (co-owned). - Rows = work categories: Functional Requirements, User Acceptance Testing, NFRs, Infrastructure, QA, Production Deploy, Release Attestation. - Cells = R/A/C/I per role per category. The assignment per REQ-215: - **Citizen Developer:** Responsible for all Functional Requirements + User Acceptance Testing (via their AI coding agent / upstream agentic SDLC / upstream development platform — the source does not matter as all are subject to the same compliance standards). - **Platform:** Responsible for all NFRs + Infrastructure + QA + Production deployments to cloud. - **Release Management:** co-owned — QA + SRE attestations required by the actual release, performed agentically but overseen & triggered by the Citizen Developer. - Render as a markdown table. - Include the compliance-standard-equivalence note: regardless of the source (AI agent, agentic SDLC, dev platform), the citizen developer's output is subject to the same compliance standards. 3. **Create `docs/scope.md`** — citizen-developer-facing copy of the PDLC-upstream scope statement. Cross-references PROJECT.md §Scope as the source of truth. Plain-language prose (no CIAgent metadata references — REQ-52 precedent). 4. **Create `docs/raci.md`** — citizen-developer-facing copy of the RACI matrix. Renders the same table as PROJECT.md §RACI Matrix. Explains the three roles in plain language. Cross-references PROJECT.md §RACI Matrix as the source of truth. Includes the compliance-standard equivalence note. 5. **Edit `docs/presentations/nova-no-humans-platform-marp.md`** — add 2 new slides after the existing Slide 16 (Recap + Ask), before the appendix slides: - **Slide 19 — Scope: Downstream of PDLC.** States the PDLC is upstream; Nova governs infra + delivery only; integration is through the contract boundary. Benefit callout: "you now know exactly where Nova's boundary is — infrastructure and delivery, not product development." - **Slide 20 — RACI: Who Owns What.** Renders the 3-role × 7-category RACI table. Benefit callout: "you now know who is responsible for what — citizen developer owns FRs + UAT, platform owns NFRs + infra + deploy, release management is co-owned attestation." - The 5-act arc (D-130) is preserved — these are append-only context slides, not a new act (per D-134: "no act restructure"). - Update the **Slide 1 — Arc Preview** text to reflect the 20-slide count (change "18 slides" / "5-act arc" references if they cite a count; the slide count is now 20 main + appendix). Update the footer `Act %{page}/5 — v1.17` → `Act %{page}/5 — v1.18` (the deck now reflects the v1.18 milestone content). 6. **Run `scripts/render_deck.sh docs/presentations/nova-no-humans-platform-marp.md`** — regenerates HTML + PPTX (S&P theme preserved — regression check vs P1). 7. **Commit** the updated PROJECT.md, `docs/scope.md`, `docs/raci.md`, the updated deck markdown, the regenerated HTML, and the regenerated PPTX binary. 8. **Attach** the PPTX to the `v1.17.2` Gitea release via `scripts/attach_release_asset.py --tag v1.17.2 --file docs/presentations/nova-no-humans-platform.pptx`. ### Must-haves (verification gate) - [ ] `PROJECT.md` has a `## Scope: Nova is Downstream of PDLC` section under Domain Boundaries. - [ ] `PROJECT.md` has a `## RACI Matrix` section with a 3-column (Citizen Developer / Platform / Release Management) × 7-row table. - [ ] `docs/scope.md` exists, is citizen-developer-facing (no `.ciagent/` references), and cross-references PROJECT.md §Scope. - [ ] `docs/raci.md` exists, is citizen-developer-facing, renders the RACI table, and cross-references PROJECT.md §RACI Matrix. - [ ] The deck has 20 main slides (Slide 19 = Scope, Slide 20 = RACI) + the appendix slides. Slide 1 Arc Preview reflects 20 slides. - [ ] `scripts/render_deck.sh` re-renders HTML + PPTX successfully; the S&P theme is preserved (grep `#D6002A` in the deck markdown still returns ≥4 hits — P1 regression check). - [ ] `docs/presentations/nova-no-humans-platform.pptx` is committed (binary) and attached to the `v1.17.2` Gitea release. - [ ] CAP-024 deck structure regression passes (20 slides, x3 arc, per-slide benefits on the 2 new slides). ### Ship tag `v1.17.2` --- ## Phase P3 — submission-readiness (feat) - **Wave:** 3 - **Requirements covered:** REQ-217, REQ-218, REQ-219, REQ-220 - **Persona assignment:** data-engineer (schema: `schemas/submission-readiness.schema.json` + the ingestor dispatch wiring co-owned with backend-engineer) + backend-engineer (validator `core/submission_readiness.py` + CLI mode in `contract_ingestor.py` + `tests/test_submission_readiness.py` + reason-code catalog in `docs/submission-readiness.md`) - **Description:** Define what is "acceptable to start" as a machine- checkable contract — a superset gate above `contract.schema.json` validity. The schema adds required Nova tags, per-env mandatory metadata (W3.E), declared policy preconditions, the `developer`/`agentic` profile (with agentic markers per REQ-22/W3.E), and an `appSource` pointer. The validator runs as `contract_ingestor.py --check-readiness` (D-133), returns a structured `ReadinessResult` with reason codes, and on fail emits a citizen-developer-facing error (not a stack trace). ### Tasks 1. **Create `schemas/submission-readiness.schema.json`** (JSON Schema draft 2020-12) — per REQ-217 + RESEARCH §3.3. This is a **superset gate ABOVE `contract.schema.json`**, NOT a duplicate (PROJECT.md hard constraint). It references but does not redefine contract fields. Schema fields: - `contractId`: string, non-empty, required (promoted from the Lambda envelope to a contract-level required field). - `environment`: enum `["dev", "qa", "prod", "dr"]`, required (references `contract.schema.json`'s environment — does not redefine; uses it to select the per-env mandatory set). - `tags`: object, required. Required keys: `nova:owner`, `nova:contract`, `nova:environment`, `nova:cost-center` (`nova:ref` optional). References `schemas/tagging-standard.json`'s `required_tags` shape (D-054). - `policyPreconditions`: object (map of string→boolean/string), required. Declared policy expectations the platform will enforce (e.g. `{"public-ingress": false}`). - `profile`: enum `["developer", "agentic"]`, required (REQ-217 / W3.E). - `appSource`: object `{repo: string, ref: string}`, required (REQ-217 — repo + ref pointer for runtime fetch). - **Per-env mandatory (W3.E) — conditional `allOf` / `if-then`:** - `dev` requires `stack` + `environment` (base contract fields). - `qa` adds `validation.e2eSuite` + `validation.loadTest`. - `prod` adds `runbook` + `dashboard` + `oncall`. - `dr` adds `drDrillRef`. - `inputs` map: optional everywhere (W3.E). - `profile: agentic` → conditionally requires `naturalLanguageIntent` (string), `confidenceAtSubmission` (number 0–1), `agentTrace` (object/string) per REQ-22 / W3.E. - `additionalProperties: false` at the top level (the gate is strict — no undocumented fields, per the v1.14 REQ-145 precedent). - `$id`: `https://nova.cloudinit.dev/schemas/submission-readiness.schema.json` (D-110 brand consistency). - `$schema`: `https://json-schema.org/draft/2020-12/schema`. 2. **Create `core/submission_readiness.py`** — the validator (REQ-218, D-133). Invoked as `contract_ingestor.py --check-readiness`. Returns a structured `ReadinessResult`. Implementation per RESEARCH §3.2 + §3.4: - `ReadinessResult` dataclass/Pydantic model: `{passed: bool, checks: list[{name, passed, reason_code}], contract_id: str}`. - `validate_readiness(contract: dict) -> ReadinessResult` — the main entry point. - **Validation order (two-layer gate, RESEARCH §3.2):** 1. Call `contract_ingestor._validate_contract_schema(contract)` first (the shape gate — reuses the existing function in `core/lambda/contract_ingestor.py` line 57; if shape fails, return early with a `CONTRACT_SHAPE_INVALID` reason code). 2. Validate against `schemas/submission-readiness.schema.json` via `jsonschema` (the gate — loads the schema from disk; if jsonschema unavailable, fail loud with `SCHEMA_UNAVAILABLE`). 3. Run the readiness checks that produce the citizen-developer-facing reason codes (REQ-218): - `MISSING_TAGS` — the 5 required Nova tags are not all present. - `ENV_MISSING_MANDATORY::` — the per-env mandatory field is absent (e.g. `ENV_MISSING_MANDATORY:qa:validation.e2eSuite`). - `AGENTIC_MISSING_INTENT` — profile is `agentic` but `naturalLanguageIntent` / `confidenceAtSubmission` / `agentTrace` is missing. - `MISSING_APP_SOURCE` — `appSource` is missing or incomplete. - `POLICY_PRECONDITION_MISSING` — `policyPreconditions` is empty or missing. 4. Return all reason codes at once (not one-at-a-time — C2 Clarity: the citizen developer sees the full scope of fixes needed). - On fail → the caller (CLI or Lambda) emits a citizen-developer-facing error (not a stack trace — REQ-218). On pass → proceeds to existing ingestion. 3. **Edit `core/lambda/contract_ingestor.py`** — add the `--check-readiness` CLI mode (D-133, RESEARCH §3.4 A-7). The ingestor is currently Lambda-only (no `__main__` block); P3 adds one: - Add `if __name__ == "__main__":` block at the bottom that parses `sys.argv` (argparse). Subcommand: `--check-readiness ` (reads a YAML/JSON contract file path; also supports `--stdin` to read from stdin). - The `--check-readiness` subcommand calls `core.submission_readiness.validate_readiness(contract)` and prints the `ReadinessResult` as JSON to stdout. - On fail → exit non-zero with the citizen-developer-facing error (the reason codes, not a stack trace). On pass → exit 0 with `READY: `. - The Lambda path is NOT changed by this task (the readiness gate is a pre-flight CLI surface; whether the Lambda also gates on readiness is a separate decision — REQ-218 says "On pass → proceeds to existing contract ingestion," which the CLI path satisfies). - Co-ownership: backend-engineer owns the dispatch wiring; data-engineer owns the schema it validates against (PERSONAS.md territory-overlap table). 4. **Create `docs/submission-readiness.md`** — citizen-developer-facing doc (REQ-219). Explains what is acceptable to start. Sections: - **What this checks** — the 5 readiness dimensions (tags, per-env mandatory, policy preconditions, profile, appSource). - **Good example** — a complete, passing contract (annotated with which checks it satisfies). - **Rejected examples** — one per reason code (a contract missing tags → `MISSING_TAGS`; a qa contract missing `validation.e2eSuite` → `ENV_MISSING_MANDATORY:qa:validation.e2eSuite`; an agentic contract missing intent → `AGENTIC_MISSING_INTENT`; a contract missing `appSource` → `MISSING_APP_SOURCE`; a contract with empty `policyPreconditions` → `POLICY_PRECONDITION_MISSING`). - **Reason-code catalog** — the 5 reason codes with their meaning + how to fix (co-owned: lead-developer writes the narrative, backend-engineer writes the reason-code catalog that mirrors the validator's return codes — PERSONAS.md territory-overlap table). - References `schemas/submission-readiness.schema.json` as the source of truth. 5. **Create `tests/test_submission_readiness.py`** (REQ-220) — covers: - Good contract passes (all checks green, `ReadinessResult.passed == True`). - Missing tags fail with `MISSING_TAGS`. - Missing env mandatory fails with `ENV_MISSING_MANDATORY::` (test at least qa + prod + dr cases). - Agentic profile missing intent fails with `AGENTIC_MISSING_INTENT`. - Missing appSource fails with `MISSING_APP_SOURCE`. - Missing policyPreconditions fails with `POLICY_PRECONDITION_MISSING`. - The CLI mode (`contract_ingestor.py --check-readiness`) works end-to-end: a good contract file → exit 0 + `READY:`; a bad contract file → exit non-zero + the reason codes in stdout. 6. **Run the test suite** — `pytest tests/test_submission_readiness.py` passes; the existing suite (`pytest`) still passes (no regressions). ### Must-haves (verification gate) - [ ] `schemas/submission-readiness.schema.json` exists, is valid JSON Schema draft 2020-12, and `python3 -c "import jsonschema; jsonschema.Draft202012Validator.check_schema(json.load(open('schemas/submission-readiness.schema.json')))"` succeeds. - [ ] The schema references `contract.schema.json` (via `$ref` or by delegating the shape check to the validator) — it does NOT redefine `id`/`name`/`environment`/`infrastructure` (superset gate, not duplicate — PROJECT.md hard constraint). - [ ] `core/submission_readiness.py` exists, `python3 -m py_compile core/submission_readiness.py` succeeds, and `validate_readiness(good_contract)` returns `ReadinessResult(passed=True)`. - [ ] `core/lambda/contract_ingestor.py` has a `__main__` block; `python3 core/lambda/contract_ingestor.py --check-readiness ` exits 0; `python3 core/lambda/contract_ingestor.py --check-readiness ` exits non-zero with a citizen-developer-facing reason code (not a stack trace). - [ ] `docs/submission-readiness.md` exists, has a good example + 5 rejected examples (one per reason code), and references the schema as source of truth. - [ ] `tests/test_submission_readiness.py` passes (all 5+ reason-code cases + the CLI end-to-end case). - [ ] The full test suite passes (`pytest` — no regressions from the ingestor edit). ### Ship tag `v1.17.3` --- ## Phase P4 — atelier-skills (docs) - **Wave:** 3 (parallelizable with P3 in a parallelization-enabled run) - **Requirements covered:** REQ-221, REQ-222 - **Persona assignment:** lead-developer (9 skill files + `docs/skills.md` index + PROJECT.md BA.A extension) - **Description:** Create 9 Atelier-derived skill files under `skills/` keyed to Atelier domain paths, extending the BA.A 5-skill citizen- developer catalog. Each skill names the Atelier source path, distills the first-principles to the citizen-developer-relevant subset, links to agent-checklist triggers, and maps to the BA.A catalog. Create a `docs/skills.md` index page. The research (RESEARCH §1.3) confirmed the exact 9-skill list — no adjustment needed. ### Tasks 1. **Create `skills/` directory** with 9 Atelier-derived skill files (REQ-221, D-138). Each file is markdown, structured as: - **Atelier source path** (e.g. `domains/security/`). - **P-rules distilled** (the citizen-developer-relevant subset — see RESEARCH §1.3 table for the exact P-rules per skill). - **First-principles distillation** (plain language; no Atelier-internal jargon; the citizen-developer-relevant subset, not the full domain). - **Agent-checklist triggers** (links to `review/agent-checklist.md` sections the citizen developer's AI agent runs before finishing a task). - **BA.A catalog mapping** (which of the 5 BA.A skills this extends: web API, worker, scheduled job, static asset, basic observability bootstrap — per RESEARCH §1.3). The 9 files (per REQ-221 + RESEARCH §1.3): - `skills/api.md` — Atelier `domains/api/`. P-rules: P1 Contract Fidelity, P2 Clarity, P5 Versioning, P6 Idempotency, P8 Security, P9 Error Transparency. Extends: web API. - `skills/security.md` — Atelier `domains/security/`. P-rules: P1 Zero Trust, P2 Least Privilege, P4 Input Validation, P6 Crypto Correctness, P8 Fail Securely, P9 Secret Hygiene. Extends: all 5 (cross-cutting). - `skills/data.md` — Atelier `domains/data/`. P-rules: P1 Truth, P3 Invariants in Schema, P4 Migration Safety, P7 Type Fidelity, P9 Referential Integrity. Extends: web API, worker, scheduled job. - `skills/testing.md` — Atelier `domains/testing/`. P-rules: P1 Tests as Specification, P3 Determinism, P5 Coverage of Behavior, P9 Edge Case Coverage, P10 No Test Theater. Extends: all 5 (UAT is a citizen- developer RACI responsibility). - `skills/observability.md` — Atelier `domains/observability/`. P-rules: P1 Structured by Default, P2 Correlation, P6 No Secrets in Obs, P7 Actionable Alerts. Extends: basic observability bootstrap. - `skills/errors.md` — Atelier `domains/errors/`. P-rules: P1 Errors are Data, P2 Fail Loudly, P3 Fail Specifically, P4 Preserve Context, P5 Recoverable When Possible. Extends: web API, worker, scheduled job. - `skills/devops.md` — Atelier `domains/devops/`. P-rules: P1 Reproducibility, P4 Rollback First, P5 Progressive Delivery, P6 Config as Code, P8 Security at Every Layer. Extends: scheduled job, worker (deploy/release is co-owned Release Mgmt). - `skills/infrastructure-as-code.md` — Atelier `domains/infrastructure-as-code/`. P-rules: P1 Declarative Intent, P2 Idempotence, P4 Plan Before Apply, P5 Version Everything, P10 Secrets Never in Code. Extends: static asset (the contract→Terraform path). - `skills/compliance.md` — Atelier `domains/compliance/`. P-rules: P1 Audit Logs Append-Only, P2 Every Significant Action Logged, P4 Policy is Code, P5 Policy is Evaluated as a Gate, P9 Secrets Redacted in Audit. Extends: all 5 (cross-cutting; Nova's compliance posture). 2. **Create `docs/skills.md`** (REQ-222) — the index page. Sections: - **Skill catalog** — a table listing the 9 skills with their Atelier source path + BA.A catalog mapping. - **Atelier provenance** — explains the skills are derived from `coreci/atelier` (the first-principles docs-as-code engineering framework — 8 core principles, 19 domains, 190 P-rules); the 9 skills are the citizen-developer-relevant subset of the 13 relevant domains (RESEARCH §1.2 — 6 domains excluded: UI/UX, Kubernetes, GitOps, i18n, Edge, Messaging). - **How the citizen developer's AI agent consumes them** — read the relevant skill before completing a task; run the Atelier `review/agent-checklist.md` before finishing. The agent-checklist will be exposed as an MCP tool in P5 (`atelier.validate_against_principles`). - **The 4 "reference-only" domains** (Performance, Documentation, Concurrency, AI/ML) — their principles are cited inside the 9 skills + this index but do NOT get their own skill file (RESEARCH §1.2 — a citizen developer's first production-grade service does not need a standalone Concurrency or AI/ML skill). - No `.ciagent/` references (consumer-facing — REQ-52 precedent). 3. **Edit `PROJECT.md`** — extend the BA.A decision (W3.E resolution table, line ~886) with a reference to the Atelier-derived skill catalog. Add a note that the BA.A 5-skill catalog (web API, worker, scheduled job, static asset, basic observability bootstrap) is extended by the 9 Atelier-derived skills under `skills/`, indexed at `docs/skills.md`. ### Must-haves (verification gate) - [ ] `skills/` directory exists with exactly 9 markdown files: `api.md`, `security.md`, `data.md`, `testing.md`, `observability.md`, `errors.md`, `devops.md`, `infrastructure-as-code.md`, `compliance.md`. - [ ] Each skill file names its Atelier source path (e.g. `domains/security/`), distills ≥4 P-rules, links to agent-checklist triggers, and maps to a BA.A catalog skill. - [ ] `docs/skills.md` exists, has a skill-catalog table (9 rows), an Atelier-provenance section, a "how the AI agent consumes them" section, and the 4 reference-only domains note. - [ ] `docs/skills.md` has no `.ciagent/` references (consumer-facing). - [ ] `PROJECT.md` BA.A decision is extended with the Atelier-derived skill catalog reference. - [ ] The full test suite still passes (`pytest` — no code changes, docs only, but verify no regressions). ### Ship tag `v1.17.4` --- ## Phase P5 — atelier-mcp (feat) - **Wave:** 4 - **Requirements covered:** REQ-223, REQ-224, REQ-225 - **Persona assignment:** backend-engineer (MCP server + plugin-registry + vendored Atelier + tests) - **Description:** Build the Atelier MCP server (`mcp/atelier/server.py`) with a plugin-registry architecture (D-140): `plugins/.py` modules each expose `register(mcp) -> None` and call `@mcp.tool()` for their tools. The server scans `plugins/` and calls `register` on each. Initial plugins: `principles.py` (`atelier.lookup_principle`, `atelier.list_domains`, `atelier.matrix_lookup`) and `validation.py` (`atelier.validate_against_principles` — agentic validation against the Atelier agent-checklist). Uses the MCP Python SDK v2 (D-137). stdio transport (D-135). Vendor the Atelier snapshot at pinned tag `v0.3.6` (D-136) for audit reproducibility. ### Tasks 1. **Create `mcp/atelier/vendor/`** — vendored Atelier snapshot at tag `v0.3.6` (REQ-224, D-136, RESEARCH §1.6). The vendored content is a clean copy of the Atelier repo at tag `v0.3.6` (the `core/`, `domains/`, `matrix/`, `review/` directories — the docs the MCP tools read; `examples/` and `languages/` are optional but included for completeness). Mechanics per RESEARCH §1.6: - Fetch `https://git.cloudinit.dev/coreci/atelier/archive/v0.3.6.tar.gz`. - Extract the doc directories into `mcp/atelier/vendor/`. - Verify the matrix is at the complete state: 19 domains, 190 P-rules (the Coverage Summary in `matrix/principles-matrix.md` confirms this). 2. **Create `mcp/atelier/vendor/VERSION.md`** — records the pinned tag + provenance (REQ-224, RESEARCH §1.6): - Tag: `v0.3.6` - Commit: `66b4767d25` - Date: 2026-08-05 - Milestone: "v0.4 Edge + Messaging + Language-Derived Docs" - P-rule count: 190 - Domain count: 19 - Source URL: `https://git.cloudinit.dev/coreci/atelier` 3. **Create `scripts/update_atelier_vendor.sh`** (executable, `set -euo pipefail`) — helper for intentional upgrades (REQ-224). Takes a tag arg, fetches the tarball from `https://git.cloudinit.dev/coreci/atelier/archive/.tar.gz`, extracts the doc directories into `mcp/atelier/vendor/`, and updates `VERSION.md`. Intentional upgrades only (re-run + re-audit). 4. **Create `mcp/atelier/server.py`** (REQ-223, D-135, D-137, D-140, RESEARCH §2.2) — the MCP server. Implementation per the RESEARCH §2.2 skeleton: - `from mcp.server import MCPServer` (v2 high-level server — NOT `FastMCP`, which was v1; RESEARCH §2.1 A-2). - `mcp = MCPServer("atelier")` — one arg = server name. - **Plugin-registry (D-140):** scan `plugins/`, import each module via `importlib.import_module(f".plugins.{p.stem}", __package__)`, call `register(mcp)` on each. `sorted(pathlib.Path(__file__).parent.glob("plugins/*.py"))` makes load order deterministic (audit reproducibility — RESEARCH §2.2 notes). - `@mcp.tool()` for the server-level tool `atelier_list_domains` (or delegate to a plugin — the skeleton shows it inline; the implementation may move it to `plugins/principles.py` for consistency with the plugin-registry pattern). - `if __name__ == "__main__": mcp.run()` — stdio transport is the default (D-135; RESEARCH §2.1 A-3). HTTP-ready on the same object (future milestone — Out of Scope for v1.18). 5. **Create `mcp/atelier/plugins/__init__.py`** — empty init (makes `plugins/` a package). 6. **Create `mcp/atelier/plugins/principles.py`** (REQ-223, RESEARCH §1.5) — the principles plugin. `register(mcp: MCPServer) -> None` containing `@mcp.tool()` calls for: - `atelier_lookup_principle(domain: str, principle_id: str) -> PrincipleLookup` — resolves a principle reference to its full text + core derivation + checklist items. Resolution path per RESEARCH §1.5: load `vendor/core/first-principles.md` (if domain=="core") or `vendor/domains//first-principles.md`, parse the principle section; cross-reference `vendor/matrix/principles-matrix.md` for the core derivation; cross-reference `vendor/review/agent-checklist.md` for checklist items; check non-tradeable status in `vendor/domains//first-principles.md` §3. Return the `PrincipleLookup` Pydantic model (RESEARCH §1.5). - `atelier_list_domains() -> list[DomainInfo]` — returns the 19 domain names + P-rule counts + Nova-relevance flag (the plugin hardcodes the Nova-relevance table from RESEARCH §1.2 so the citizen developer's agent can filter to the 13 relevant / 9 skill-bearing domains). - `atelier_matrix_lookup(domain: str) -> DomainMatrix` — returns the full domain→core mapping for one domain (all 10 P-rules → their core C-rule(s)), used by `validate_against_principles` to set `severity` and by conflict resolution when two findings collide. - Lazily load + cache the vendored markdown in module-level dicts (C8 Economy — don't re-parse the matrix on every lookup; RESEARCH §2.2 notes). 7. **Create `mcp/atelier/plugins/validation.py`** (REQ-223, RESEARCH §1.4) — the validation plugin. `register(mcp: MCPServer) -> None` containing: - `atelier_validate_against_principles(snippet: str, language: str, domains: list[str], run_core: bool = True) -> ValidateResult` — agentic validation against the Atelier agent-checklist, beyond Wiz/Checkmarx/Mend. Input/output models per RESEARCH §1.4 (`ValidateInput`, `Violation`, `ValidateResult` Pydantic models). The plugin reads the vendored `review/agent-checklist.md` (frozen at the pinned tag — RESEARCH §1.4) and maps each checklist line to a predicate function keyed by `(language, principle)`. The validation catches C1 (correctness) + C7 (observability) violations in a known-bad snippet and passes a known-good snippet (REQ-225 test case). 8. **Create `mcp/atelier/README.md`** (REQ-224) — documents the server: - How to run (`python3 mcp/atelier/server.py` — stdio transport; the citizen developer's AI agent spawns the server as a subprocess). - Transport: stdio now (D-135); HTTP-ready on the same object (future milestone — Out of Scope). - Tool catalog: the 4 tools (`atelier.lookup_principle`, `atelier.list_domains`, `atelier.matrix_lookup`, `atelier.validate_against_principles`) with their input/output schemas. - Plugin-authoring guide: how to add a new plugin (`plugins/.py` with `register(mcp)` — D-140; no `server.py` edits). - Vendoring policy: pinned tag `v0.3.6` for audit reproducibility (D-136); `scripts/update_atelier_vendor.sh` for intentional upgrades; live-fetch is NOT implemented (Out of Scope). 9. **Create `tests/test_atelier_mcp.py`** (REQ-225) — covers: - **Tool registration** — all 4 tools discoverable via `tools/list` (the MCP protocol's tool-discovery call; the test spawns the server in-process or uses the SDK's test harness). - `atelier.lookup_principle("security", "P4")` returns the principle text ("Input Validation") + core C-rule (`C1`) + checklist items (RESEARCH §1.5 example). - `atelier.validate_against_principles` catches a planted C1 (correctness) + C7 (observability) violation in a known-bad snippet and passes a known-good snippet (REQ-225 explicit case). - `atelier.matrix_lookup("security")` returns the domain→core mapping (all 10 P-rules → their core C-rule(s)). - **Plugin discovery** — the server loads all plugins in `plugins/` (the test verifies `plugins/principles.py` + `plugins/validation.py` are both loaded; the `register` function was called on each). 10. **Add the MCP Python SDK v2 dependency** to `requirements-test.txt` (or `pyproject.toml` test dependencies): `mcp>=2.0` (the `modelcontextprotocol/python-sdk` package; D-137). Pin per the project's dependency convention. 11. **Run the test suite** — `pytest tests/test_atelier_mcp.py` passes; the existing suite still passes. ### Must-haves (verification gate) - [ ] `mcp/atelier/server.py` exists, `python3 -m py_compile mcp/atelier/server.py` succeeds, and imports `from mcp.server import MCPServer` (v2 high-level server — NOT `FastMCP`). - [ ] `mcp/atelier/plugins/principles.py` + `mcp/atelier/plugins/validation.py` exist; each has a `register(mcp)` function containing `@mcp.tool()` calls. - [ ] `mcp/atelier/vendor/` exists with `core/`, `domains/`, `matrix/`, `review/` directories vendored from Atelier tag `v0.3.6`. - [ ] `mcp/atelier/vendor/VERSION.md` records tag `v0.3.6`, commit `66b4767d25`, 190 P-rules, 19 domains. - [ ] `scripts/update_atelier_vendor.sh` exists, is executable, and takes a tag arg. - [ ] `mcp/atelier/README.md` documents how to run, transport, tool catalog, plugin-authoring guide, vendoring policy. - [ ] `tests/test_atelier_mcp.py` passes: 4 tools discoverable, `lookup_principle` returns the principle + core rule, `validate_against_principles` catches C1+C7 violations in a known-bad snippet + passes a known-good snippet, `matrix_lookup` returns the domain→core mapping, plugin discovery loads all plugins. - [ ] The full test suite passes (`pytest` — no regressions from the new dependency). ### Ship tag `v1.17.5` --- ## Phase P6 — deck-slides-atelier (docs) - **Wave:** 5 - **Requirements covered:** REQ-226, REQ-227, REQ-228 - **Persona assignment:** lead-developer (3 new deck slides + README update + talking-points sync + HTML/PPTX re-render) - **Description:** Add the 21st deck slide to the unified deck → 21 slides total. P2 added slides 19 (Scope) + 20 (RACI); P6 adds slide 21 (Atelier). Update the Arc Preview slide to reflect 21 slides. Sync the talking-points file for the 3 new slides (Scope, RACI, Atelier). Re-render HTML + PPTX (S&P theme preserved — regression check vs P1). Update the README slide count + deck table. ### Tasks 1. **Edit `docs/presentations/nova-no-humans-platform-marp.md`** — add the 21st slide (REQ-226, D-134): - **Slide 21 — Production-Grade Guidance via Atelier.** Content: - The 9 Atelier-derived skills (under `skills/`, indexed at `docs/skills.md`) extend the BA.A 5-skill catalog. - The Atelier MCP server (`mcp/atelier/server.py`, stdio transport) exposes 4 tools: `atelier.lookup_principle`, `atelier.list_domains`, `atelier.matrix_lookup`, `atelier.validate_against_principles`. - Agentic validation goes beyond deterministic scanners (Wiz/Checkmarx/Mend) by catching correctness/clarity/simplicity/ observability gaps (C1/C2/C3/C7) against the Atelier agent-checklist. - Vendored Atelier (pinned tag `v0.3.6`) for audit reproducibility (D-136) — an agentic validation result is replayable against the exact principles that produced it. - Benefit callout: "you now know the citizen developer is not unguided — production-grade engineering principles are machine-checkable, and the validation goes beyond SAST to correctness, clarity, simplicity, and observability." - Slides 19 (Scope) + 20 (RACI) were added in P2; P6 confirms they are still present and renumbers if needed so the slide order is Scope → RACI → Atelier (19 → 20 → 21). - Update **Slide 1 — Arc Preview** to reflect 21 slides (change the slide-count reference; the 5-act arc is preserved — D-134: the 3 new slides are append-only context, not a new act). 2. **Edit `docs/presentations/nova-no-humans-platform-talking-points.md`** (REQ-226) — sync the talking points for the 3 new slides (Scope, RACI, Atelier). Each new slide gets a talking-points section with 3–6 punchy, actionable cues + a key takeaway per slide (per the v1.9.7 talking-points format). 3. **Edit `docs/presentations/README.md`** (REQ-227) — update: - The slide count (21 slides + appendix). - The deck table (add the 3 new slide titles: "Scope: Downstream of PDLC", "RACI: Who Owns What", "Production-Grade Guidance via Atelier"). 4. **Run `scripts/render_deck.sh docs/presentations/nova-no-humans-platform-marp.md`** (REQ-228) — regenerates HTML + PPTX. The S&P theme is preserved (regression check vs P1 — grep `#D6002A` in the deck markdown still returns ≥4 hits). 5. **Commit** the updated deck markdown, talking-points, README, the regenerated HTML, and the regenerated PPTX binary. 6. **Attach** the PPTX to the `v1.17.6` Gitea release via `scripts/attach_release_asset.py --tag v1.17.6 --file docs/presentations/nova-no-humans-platform.pptx`. ### Must-haves (verification gate) - [ ] The deck has 21 main slides: Slide 19 = Scope, Slide 20 = RACI, Slide 21 = Atelier (+ appendix slides). - [ ] Slide 1 Arc Preview reflects 21 slides. - [ ] Slide 21 (Atelier) mentions the 9 skills, the 4 MCP tools, agentic validation beyond SAST, and the vendored pinned tag `v0.3.6`. - [ ] `docs/presentations/nova-no-humans-platform-talking-points.md` has talking-points sections for all 3 new slides (Scope, RACI, Atelier). - [ ] `docs/presentations/README.md` reflects 21 slides + the 3 new titles in the deck table. - [ ] `scripts/render_deck.sh` re-renders HTML + PPTX successfully; the S&P theme is preserved (grep `#D6002A` — P1 regression check). - [ ] `docs/presentations/nova-no-humans-platform.pptx` is committed (binary) and attached to the `v1.17.6` Gitea release. - [ ] CAP-024 deck structure regression passes (21 slides, x3 arc, per-slide benefits on all 3 new slides). ### Ship tag `v1.17.6` --- ## Phase P7 — final-review-ship (final) - **Wave:** 6 - **Requirements covered:** all (REQ-214..228) — verification that every requirement is complete; milestone ship. - **Persona assignment:** lead-developer (review coordination + audit + milestone ship) + backend-engineer (regression gate + technical verification) + data-engineer (schema audit) - **Description:** Multi-persona review of all v1.18 phases, audit of the requirement coverage, regression gate run (CAP-023 metrics collector + CAP-024 deck structure + the existing 22 capabilities), and milestone ship: merge to main, tag `v1.17.7`, delete phase branches. ### Tasks 1. **Review** — multi-persona review of P1–P6. Lead-developer verifies the deck (21 slides, S&P theme, x3 arc, talking-points sync), RACI + scope docs, and skills index. Backend-engineer verifies the MCP server (4 tools, plugin-registry, vendored Atelier), the submission-readiness validator (reason codes, CLI mode), and the render/attach scripts. Data-engineer verifies the submission-readiness schema (superset gate, per-env mandatory, no duplication of contract fields). Findings recorded in `.ciagent/REVIEW.md`. 2. **Audit** — requirement coverage audit. Every REQ-214..228 is checked against the shipped artifacts. The traceability table in `REQUIREMENTS.md` §v1.18 is updated: all 15 requirements move from `pending` → `complete (v1.17.x)`. Gaps are fixed before ship (no partial shipments). 3. **Regression gate** — `bash scripts/run_regression.sh` (D-091) runs all auto-verifiable capabilities. CAP-023 (metrics collector) + CAP-024 (deck structure: 21 slides, x3 present, per-slide benefit present) must pass. The existing 22 capabilities must stay Verified (no regressions from v1.18's schema/code additions). 4. **Milestone ship:** - Merge the milestone branch `milestone/v1.18-citizen-developer-guidance` to `main`. - Tag `v1.17.7` (the milestone release tag — final patch on the v1.17.x line = the v1.18 milestone release per the tag-line decision). - Force-move the floating `v1.17` + `v1` tags to `v1.17.7` (D-057 precedent — consumers on `@v1.17` or `@v1` receive the update). - Create the Gitea release for `v1.17.7` with an auto-generated body (the v1.18 milestone summary). - Attach the final PPTX to the `v1.17.7` release via `scripts/attach_release_asset.py`. - Delete the phase branches (`phase/01-sp-theme-restoration` through `phase/06-deck-slides-atelier`) after merge. 5. **Update `.ciagent/` metadata** — ROADMAP.md §v1.18 marked complete; PROJECT.md §v1.18 objective marked complete with the ship tag; CAPABILITY_INVENTORY.md gains CAP-025 (submission-readiness gate) + CAP-026 (Atelier MCP server) if the regression gate certifies them; REVIEW.md updated with the v1.18 review content. ### Must-haves (verification gate) - [ ] All 15 requirements (REQ-214..228) are `complete` in the `REQUIREMENTS.md` §v1.18 traceability table. - [ ] `bash scripts/run_regression.sh` passes (all capabilities Verified; CAP-024 deck structure regression passes at 21 slides). - [ ] The milestone branch is merged to `main`. - [ ] Tag `v1.17.7` exists; floating tags `v1.17` + `v1` point at it. - [ ] The `v1.17.7` Gitea release exists with the PPTX attached. - [ ] Phase branches are deleted. - [ ] `.ciagent/ROADMAP.md` §v1.18 marked complete. - [ ] `.ciagent/REVIEW.md` updated with v1.18 review content. ### Ship tag `v1.17.7` (milestone release) --- ## Plan-Level Risks + Notes 1. **Atelier tag drift (A-1, conf 0.92).** The vendored tag is `v0.3.6` (fetched 2026-08-05). If a v0.5 milestone lands before P5 ships, the pin is stale — but the VERSION.md + `update_atelier_vendor.sh` model makes a future upgrade a deliberate, audited action, not silent drift. P5 should re-verify the latest Atelier tag at execution time and document any divergence in VERSION.md. 2. **MCP Python SDK v2 import name (A-2, conf 0.88).** The high-level server class is `MCPServer` (NOT `FastMCP`, which was v1). If a future SDK patch restores a `FastMCP` alias, both imports would work, but the v2 canonical name is `MCPServer`. P5 should verify the import against the installed SDK version at execution time. 3. **`mcp.run()` stdio entry point (A-3, conf 0.85).** The exact `run()` signature for stdio vs HTTP is not fully spelled out on the SDK landing page. P5 should verify the exact run call from the "Running your server" docs page before finalizing `server.py`. If stdio requires an explicit transport argument, the fix is a one-line change in `server.py` (D-135 — the server object is transport-agnostic). 4. **Submission-readiness validator wiring (A-7, conf 0.80).** D-133 places the readiness gate as `contract_ingestor.py --check-readiness` (a CLI pre-flight). REQ-218 says "On pass → proceeds to existing contract ingestion" — this is satisfied by the CLI path (the citizen developer runs `--check-readiness` before submitting). Whether the Lambda path ALSO gates on readiness (a pre-write gate in `_submit_contract`) is a P3 implementation decision. The plan defaults to CLI-only (the Lambda path is unchanged) to avoid changing the Lambda's behavior mid-milestone; the Lambda gate can be added in a future milestone if desired. 5. **PPTX binary in git (D-141).** Committing the PPTX binary directly (no LFS) is the decision. Decks are small (~1–5 MiB); git handles binary blobs. Binary diffs are not delta-friendly, but deck changes are infrequent (3 times this milestone). If the repo grows significantly, a future milestone may reconsider LFS — but only if git.cloudinit.dev confirms LFS server-side support. 6. **Wave 3 parallelism (P3‖P4) is theoretical.** This run executes sequentially (P3 then P4). The parallelism is noted for future parallelization-enabled runs. The two phases have zero file overlap (P3: `schemas/`, `core/`, `tests/`, `docs/submission-readiness.md`; P4: `skills/`, `docs/skills.md`, `PROJECT.md` BA.A) so they COULD run concurrently without conflict. 7. **Deck slide numbering.** P2 adds slides 19 + 20 (scope + RACI) → 20 slides. P6 adds slide 21 (Atelier) → 21 slides. The Arc Preview slide is updated in both P2 (to 20) and P6 (to 21). The 5-act arc (D-130) is preserved throughout — the new slides are append-only context, not a new act (D-134). 8. **No new frontend (frontend-engineer deactivated).** v1.18 has no frontend; decks are markdown (lead-developer territory); the MCP server exposes tools to an AI agent, not a web UI. The frontend-engineer persona stays deactivated (PERSONAS.md v1.18 roster). No reactivation trigger in this milestone. --- # Nova — Phase Plan v1.22 (Nova Deck Layout Fix) > **Milestone:** v1.22 — Nova Deck Layout Fix > **Branch:** `milestone/v1.22-deck-layout-fix` → merge to `main` at P6. > Phase branches: `phase/00-pre-execution`, `phase/01-theme-css`, > `phase/02-render-scripts`, `phase/03-mermaid-relayout`, > `phase/04-deck-content`, `phase/05-render-and-test`, > `phase/06-final-review-ship`. > **Tag line:** `v1.21.x` patch line — `v1.21.0` (P0) → > `v1.21.1..v1.21.5` (P1–P5) → `v1.21.6` (P6 final = milestone release). > v1.22 is an NFR milestone (all phases are fix/docs/test) → > progressive patches. > **Phase count:** 7 (P0 pre-execution + 5 execution + 1 final). > **Source of truth for requirements:** `.ciagent/REQUIREMENTS.md` §v1.22 > (REQ-254..262, 9 requirements). > **Source of truth for research:** `.ciagent/RESEARCH.md` §v1.22 (8 > findings, 5 assumptions, 5 CLARIFY decisions). > **Source of truth for personas:** `.ciagent/PERSONAS.md` v1.22 roster > (2 active: lead-developer + backend-engineer; 2 deactivated: > frontend + data). ## Wave Ordering | Wave | Phases | Rationale | |------|--------|-----------| | Wave 1 | P1, P2 (**parallel**) | P1 (theme CSS: padding, overflow, image, title chrome) + P2 (render scripts: delete render_deck.sh, pin versions, 2x scale). Zero file overlap: P1 touches `docs/presentations/assets/nova-sp-theme.css`; P2 touches `scripts/render_slides.sh` + deletes `scripts/render_deck.sh`. P1 establishes the padding/overflow/image budget that P4's content trimming relies on; P2 fixes the render pipeline that P3's PNG re-render depends on. | | Wave 2 | P3, P4 (**parallel**) | P3 (mermaid re-layout: telemetry LR, platform-pipeline 2-row wrap) + P4 (deck content: trim/split 8 overflowing slides, remove header). P3 depends on P2 (2x scale flag); P4 depends on P1 (padding budget). Zero file overlap: P3 touches `docs/presentations/assets/mmd/*.mmd` + PNGs; P4 touches `docs/presentations/nova-autonomous-cloud-delivery-marp.md` + source `.md` + talking-points + README. | | Wave 3 | P5 | Re-render HTML + PPTX + add tests. Depends on all above (P1 theme, P2 scripts, P3 diagrams, P4 content). Re-renders via the fixed `render_slides.sh`; adds the layout/aspect-ratio/theme-structural tests (the gap that let this through). | | Wave 4 | P6 | Final review + audit + milestone ship. Merge to main, tag `v1.21.6`, create release, attach PPTX. | ## Phase P0 — pre-execution (DONE) SPECIFY → CLARIFY → RESEARCH → PLAN. Validated v1.22 requirements (REQ-254..262). Established `active_milestone: "v1.22"`. Root-cause investigation persisted to RESEARCH.md (8 findings). Persona roster updated (2 active, 2 deactivated). 5 CLARIFY decisions auto-resolved. ## Phase P1 — theme-css (fix) — lead-developer **Requirements:** REQ-254, REQ-255, REQ-256 **Branch:** `phase/01-theme-css` **Territory:** `docs/presentations/assets/nova-sp-theme.css` ### Tasks 1. **REQ-254 — section padding + overflow:** - Add `section { padding: 48px 56px 40px; }` (top reserves header space; bottom reserves footer). - Add `section { overflow: auto; }` as an authoring-time signal (dense content scrolls instead of silently clipping). Document that the real fix is content trimming (P4), not runtime scroll. 2. **REQ-255 — aspect-ratio-aware image rules:** - Replace `img { display: block; margin: 0 auto; max-height: 320px }` with `img { display: block; margin: 0 auto; max-width: 100%; max-height: 380px; object-fit: contain; }`. - Add `.wide` class: `img.wide { max-height: 280px; }` (for ultra-wide diagrams). - Add `.tall` class: `img.tall { max-height: 480px; }` (for tall diagrams that need more vertical room). 3. **REQ-256 — title chrome + spacing tightening:** - Add `section.title header, section.title footer { display: none; }`. - Add `section h2 + p { margin-top: 0.2em; }`. - Add `section p { margin: 0.4em 0; }`. - Add `ol` styling: `ol { margin-top: 0.3em; }` (match `ul`). - Add `table.dense td, table.dense th { padding: 4px 8px; }` (for tables with ≥8 rows). - Add `@media print { section { overflow: hidden; } }` (PPTX export fidelity — no scrollbars in exported slides). ### Verify (inline) - `python3 -c "from pathlib import Path; css = Path('docs/presentations/assets/nova-sp-theme.css').read_text(); assert 'padding:' in css and 'section.title header' in css and 'object-fit' in css and 'table.dense' in css; print('theme CSS OK')"` - `pytest tests/test_slides_pipeline.py -k "theme" -q` (existing theme color tests still pass). ### Ship - Tag `v1.21.1`, merge `phase/01-theme-css` → `milestone/v1.22-deck-layout-fix`. ## Phase P2 — render-scripts (fix) — backend-engineer **Requirements:** REQ-257, REQ-258 **Branch:** `phase/02-render-scripts` **Territory:** `scripts/render_slides.sh`, `scripts/render_deck.sh` (DELETE) ### Tasks 1. **REQ-257 — delete render_deck.sh + pin CLI versions:** - `git rm scripts/render_deck.sh` (the README already documents `render_slides.sh` as canonical; `render_deck.sh` omits `--theme` and produces unthemed output). - Pin marp-cli and mermaid-cli versions in `render_slides.sh`: replace `@marp-team/marp-cli@latest` with a pinned version (e.g. `@marp-team/marp-cli@4.0.0` — determine the working version by testing during execution) and `@mermaid-js/mermaid-cli@latest` with a pinned version (e.g. `@mermaid-js/mermaid-cli@10.9.1`). - Remove any references to `render_deck.sh` from `.github/workflows/slides.yml`, `docs/presentations/README.md`, and `tests/test_slides_pipeline.py` (if any test references it). 2. **REQ-258 — 2x scale + transparent bg for mermaid:** - In `render_slides.sh` lines 51-55, add `-s 2 -b transparent` to the mermaid-cli invocation (matches README line 193 spec). ### Verify (inline) - `test ! -f scripts/render_deck.sh && echo "render_deck.sh deleted OK"` - `grep -q "marp-cli@" scripts/render_slides.sh && grep -q "mermaid-cli@" scripts/render_slides.sh && echo "versions pinned OK"` - `grep -q -- "-s 2" scripts/render_slides.sh && grep -q -- "-b transparent" scripts/render_slides.sh && echo "2x + transparent OK"` - `pytest tests/test_slides_pipeline.py -k "render" -q` (existing render-script tests still pass; update if they reference `render_deck.sh`). ### Ship - Tag `v1.21.2`, merge `phase/02-render-scripts` → `milestone/v1.22-deck-layout-fix`. ## Phase P3 — mermaid-relayout (fix) — lead-developer **Requirements:** REQ-259, REQ-260 **Branch:** `phase/03-mermaid-relayout` **Territory:** `docs/presentations/assets/mmd/telemetry-live-ops.mmd`, `docs/presentations/assets/mmd/platform-pipeline.mmd`, PNG re-render (via `render_slides.sh` — backend-engineer co-owns the script invocation). ### Tasks 1. **REQ-259 — telemetry-live-ops.mmd TB → LR:** - Rewrite `docs/presentations/assets/mmd/telemetry-live-ops.mmd` from `flowchart TB` to `flowchart LR` with subgraph row-wrapping (per README line 168). Target aspect ratio ∈ [1.2, 2.5]. - Re-render PNG: `bash scripts/render_slides.sh nova-autonomous-cloud-delivery` (now with 2x scale + transparent bg from P2). - Update the Marp deck's `![w:900]` directive on slide 9 to match the new dimensions (or replace with `![h:320]` if the diagram remains taller than wide after re-layout — but LR should produce a wide diagram). 2. **REQ-260 — platform-pipeline.mmd 2-row wrap:** - Rewrite `docs/presentations/assets/mmd/platform-pipeline.mmd` to wrap the 10-node LR chain into 2 rows via mermaid subgraphs (or split into two stages: static-scan row + runtime-scan row). Target aspect ratio ∈ [1.2, 2.5]. - Re-render PNG (same command as above). ### Verify (inline) - `python3 -c "from PIL import Image; import os; d='docs/presentations/assets/png'; [print(f, Image.open(os.path.join(d,f)).size) for f in os.listdir(d) if f.endswith('.png')]"` (check aspect ratios — or use a stdlib-only check if PIL unavailable). - Verify both re-rendered PNGs have aspect ratio ∈ [1.2, 2.5]. ### Ship - Tag `v1.21.3`, merge `phase/03-mermaid-relayout` → `milestone/v1.22-deck-layout-fix`. ## Phase P4 — deck-content (fix) — lead-developer **Requirements:** REQ-261 **Branch:** `phase/04-deck-content` **Territory:** `docs/presentations/nova-autonomous-cloud-delivery-marp.md`, `docs/presentations/nova-autonomous-cloud-delivery.md`, `docs/presentations/nova-autonomous-cloud-delivery-talking-points.md`, `docs/presentations/README.md`. ### Tasks 1. **Split slide 3** (Objectives + Anti-Goals) into: - Slide 3a — Strategic Objectives (4 objectives + nested sub-list). - Slide 3b — Anti-Goals (4 anti-goals + benefit). Main slide count 18 → 19. 2. **Split slide 8** (Attestation Matrix) into: - Slide 8a — Attestation: QA (3 qa rows + separation-of-duties note). - Slide 8b — Attestation: Prod/DR (7 prod/dr rows + benefit). Main slide count 19 → 20. 3. **Trim slide 5** (RACI): apply `table.dense` class (from P1) to reduce cell padding; keep 8 rows. 4. **Trim slide 6** (Pipeline): reduce to 3 bullets (the 4th is covered by the diagram, now legible after P3). 5. **Trim slide 9** (Telemetry): reduce to 3 bullets; image now legible after P3. 6. **Trim slide 12** (Deferred): reduce to 6 rows (merge the 3 "Live AWS re-provisioning" blockers into one row). 7. **Trim slide 15** (Quarter-by-Quarter): drop the "Grounding" column (redundant with strategic objectives); 4 columns fit better. 8. **Trim Appendix A1** (Glossary): apply `table.dense` class (16px font); keep 13 rows. 9. **Remove `header:` from frontmatter** (keep `footer:` + `paginate: true` only). The full 51-char deck title in BOTH header and footer is redundant chrome; the footer alone suffices. 10. **Update talking-points.md** to match the new 20 main + 1 appendix slide structure. 11. **Update README.md** "18 main + 1 appendix" convention (line 130) → "20 main + 1 appendix". 12. **Update `test_marp_deck_slide_count`** in `tests/test_slides_pipeline.py` to assert 20 main + 1 appendix (this test is co-owned with backend-engineer per PERSONAS.md, but the assertion value reflects lead-developer's deck structure decision — lead-developer makes the edit here). ### Verify (inline) - `pytest tests/test_slides_pipeline.py -k "slide_count" -q` (updated test passes with 20 main + 1 appendix). - `grep -c "## Slide " docs/presentations/nova-autonomous-cloud-delivery-marp.md` → 20. - `grep -c "## Appendix " docs/presentations/nova-autonomous-cloud-delivery-marp.md` → 1. - `grep -q "^header:" docs/presentations/nova-autonomous-cloud-delivery-marp.md && echo "FAIL: header still present" || echo "header removed OK"`. ### Ship - Tag `v1.21.4`, merge `phase/04-deck-content` → `milestone/v1.22-deck-layout-fix`. ## Phase P5 — render-and-test (test) — backend-engineer **Requirements:** REQ-262 **Branch:** `phase/05-render-and-test` **Territory:** `tests/test_slides_pipeline.py` (test code — backend), re-render invocation (backend). Assertions reflect lead-developer's deck/theme decisions (co-owned). ### Tasks 1. **Re-render HTML + PPTX:** - `bash scripts/render_slides.sh nova-autonomous-cloud-delivery` → re-renders all mermaid PNGs (2x transparent) + HTML + PPTX. - Verify slide count (20 main + 1 appendix = 21 `
` elements in the HTML + 1 title = 22 total — or however Marp counts the title slide; verify against the marp deck). - Verify media embedding (PPTX has embedded PNGs). 2. **Add tests to `tests/test_slides_pipeline.py`:** - `test_theme_css_has_section_padding` — assert `section` rule in `nova-sp-theme.css` contains `padding`. - `test_theme_css_suppresses_title_chrome` — assert `section.title header` and `section.title footer` have `display: none`. - `test_png_aspect_ratios_sane` — for every PNG in `assets/png/`, assert aspect ratio ∈ [1.2, 2.5] (catches the 13.52× and 0.63× outliers). Use `struct`/`imghdr` or a minimal PNG header parser (no PIL dependency if possible). - `test_render_slides_has_2x_scale` — assert `render_slides.sh` contains `-s 2` and `-b transparent`. - `test_render_deck_removed` — assert `scripts/render_deck.sh` does not exist. - `test_html_embeds_theme` — assert committed HTML contains `--sp-red` and `padding` in the inline `