diff --git a/.ciagent/CHECKPOINT.json b/.ciagent/CHECKPOINT.json index 273b809..5fa69ba 100644 --- a/.ciagent/CHECKPOINT.json +++ b/.ciagent/CHECKPOINT.json @@ -1,12 +1,12 @@ { - "phase": 6, - "stage": "complete", - "milestone": "v1.21", - "phase_role": "final", + "phase": 0, + "stage": "plan", + "milestone": "v1.22", + "phase_role": "pre_execution", "attempts": 0, - "updated_at": "2026-08-11T00:30:00Z", - "milestone_complete": true, - "tag": "v1.20.6", - "requirements": ["REQ-245","REQ-246","REQ-247","REQ-248","REQ-249","REQ-250","REQ-251","REQ-252","REQ-253"], - "notes": "v1.21 milestone complete. 9 requirements (REQ-245..253) across 6 execution phases + P0 pre-execution. P1 strategic-docs (thesis rename + NORTH_STAR objectives + RACI restructure); P2 slides source-of-truth (rename + restructure + rewrite, 18 main + 1 appendix); P3 marp deck + talking points + README + theme CSS fix; P4 pipeline hardening (Checkov before plan, Wiz-or-Checkov on plan, never both); P5 render + verify (new diagrams, HTML, PPTX, 686 tests pass + 1 pre-existing attestation env failure). Deck renamed nova-no-humans-platform* -> nova-autonomous-cloud-delivery*. Title: 'Nova — The Autonomous Cloud Delivery Platform'. 4-beat arc (Problem -> Solution -> Proof -> Roadmap + Ask). All 33 review notes applied. Tags on v1.20.x line (v1.20.0 P0 -> v1.20.6 P6 final). Next milestone starts fresh." + "updated_at": "2026-08-11T14:38:00Z", + "milestone_complete": false, + "tag": null, + "requirements": ["REQ-254","REQ-255","REQ-256","REQ-257","REQ-258","REQ-259","REQ-260","REQ-261","REQ-262"], + "notes": "v1.22 PLAN complete. 7 phases, 4 waves. Plan persisted to PLAN.md. Tags on v1.21.x line." } \ No newline at end of file diff --git a/.ciagent/PERSONAS.md b/.ciagent/PERSONAS.md index 652e384..1bda1d1 100644 --- a/.ciagent/PERSONAS.md +++ b/.ciagent/PERSONAS.md @@ -1,34 +1,128 @@ --- project: acdl -milestone: v1.18 -generated_at: 2026-08-06 +milestone: v1.22 +generated_at: 2026-08-11 generator: lead-developer verification_toolchain: - typecheck: "python3 -m py_compile core/submission_readiness.py mcp/atelier/server.py && python3 -m jsonschema schemas/submission-readiness.schema.json" - test: "pytest tests/test_submission_readiness.py tests/test_atelier_mcp.py # REQ-220 + REQ-225" - build: "bash scripts/render_deck.sh docs/presentations/nova-no-humans-platform-marp.md # HTML + PPTX (D-142)" + typecheck: "python3 -m py_compile tests/test_slides_pipeline.py" + test: "pytest tests/test_slides_pipeline.py # REQ-254..262" + build: "bash scripts/render_slides.sh nova-autonomous-cloud-delivery # HTML + PPTX" note: | - v1.18 adds the Citizen Developer & Production-Grade Guidance surface: - submission-readiness gate, Atelier-derived skills, the Atelier MCP server - (plugin-registry, stdio), and PPTX-as-first-class-artifact deck automation. - Three active personas: lead-developer (coordination + decks + RACI/scope - docs), backend-engineer (MCP server + submission-readiness validator + - render/attach scripts), data-engineer (submission-readiness schema if it - touches contract storage / DynamoDB shape). frontend-engineer stays - deactivated (v1.18 has no frontend; decks are markdown = lead-developer - territory). The MCP plugin-registry is a backend pattern, so a separate - mcp-engineer persona is NOT added — it folds into backend-engineer. + v1.22 is the Nova Deck Layout Fix — a docs-only NFR milestone. Two + active personas: lead-developer (theme CSS + deck markdown + talking + points + README + .ciagent metadata), backend-engineer (render scripts + + tests). frontend-engineer stays deactivated (decks are markdown = + lead-developer territory, per v1.17/v1.18 precedent). No data-engineer + (no schema/DB changes). No new personas (the work is CSS + bash + + markdown + pytest, all within the two active personas' range). --- -# ACDL — Persona Roster (v1.18 Citizen Developer & Production-Grade Guidance) +# ACDL — Persona Roster (v1.22 Nova Deck Layout Fix) -> v1.18 roster. Three active personas + one deactivated. The MCP server -> plugin-registry (D-140) is a backend pattern, not a new persona — it -> folds into backend-engineer. v1.17 precedent (frontend-engineer -> deactivated, decks are markdown = lead-developer territory) is upheld. +> v1.22 roster. Two active personas + one deactivated. This is a docs- +> only NFR milestone: the work is theme CSS, render scripts, mermaid +> diagrams, deck markdown, and tests. frontend-engineer stays +> deactivated (decks are markdown = lead-developer territory, per +> v1.17/v1.18 precedent). No data-engineer (no schema/DB changes). ## Active personas +### lead-developer +- **Domain:** coordination + deck content +- **Active:** true +- **Phase-specific:** false +- **Frameworks:** [] (no framework — owns process + narrative + CSS + markdown) +- **Constraints:** ["pragmatic", "battle-tested defaults", "no fabrication (NORTH_STAR honesty model)", "do not change the 4-beat arc", "do not re-introduce badges/version/internal citations"] +- **Territory:** + - `docs/presentations/assets/nova-sp-theme.css` (REQ-254,255,256 — theme CSS) + - `docs/presentations/nova-autonomous-cloud-delivery-marp.md` (REQ-261 — deck content) + - `docs/presentations/nova-autonomous-cloud-delivery.md` (REQ-261 — source of truth) + - `docs/presentations/nova-autonomous-cloud-delivery-talking-points.md` (REQ-261) + - `docs/presentations/README.md` (REQ-261 — slide-count convention) + - `docs/presentations/assets/mmd/*.mmd` (REQ-259,260 — mermaid re-layout) + - `.ciagent/**` (PROJECT, ROADMAP, REQUIREMENTS, RESEARCH, PLAN, GRILL, PERSONAS, REVIEW, CHECKPOINT) +- **Reason:** Owns the theme CSS (the root cause), the deck markdown + (trim/split overflowing slides), the mermaid re-layout, the talking + points, the README, and all CIAgent metadata. Is the only persona + that touches `.ciagent/**` and the deck markdown/CSS. +- **Phase-specific flag:** none (active for all of P0–P6). + +### backend-engineer +- **Domain:** render scripts + tests +- **Active:** true +- **Phase-specific:** false +- **Frameworks:** ["bash", "pytest", "marp-cli", "mermaid-cli"] +- **Constraints:** ["pin CLI versions (no @latest)", "2x scale + transparent bg for mermaid", "tests must catch layout regressions", "no raw curl with shell-env tokens"] +- **Territory:** + - `scripts/render_slides.sh` (REQ-257,258 — pin versions, 2x scale) + - `scripts/render_deck.sh` (REQ-257 — DELETE) + - `tests/test_slides_pipeline.py` (REQ-262 — layout/aspect-ratio/theme-structural tests) + - `.github/workflows/slides.yml` (if references to render_deck.sh need removal) +- **Reason:** Owns the render pipeline (bash scripts) and the test + suite. The layout/aspect-ratio/theme-structural tests (REQ-262) are + the gap that let this regression through — backend-engineer owns + closing that gap. Pinning CLI versions and adding 2x scale are + backend/scripting tasks. +- **Phase-specific flag:** none (active for P2, P5; light touch on P0/P6). + +## Deactivated personas + +### frontend-engineer +- **Active:** false +- **Domain:** frontend +- **Frameworks:** ["react", "next.js"] (inert — no territory) +- **Constraints:** ["component-first", "server-components", "minimal-client-js"] (inert) +- **Territory:** [] (no territory in v1.22) +- **Reason:** v1.22 has no frontend; decks are markdown (lead-developer + territory); deactivated per PERSONAS.md v1.17/v1.18 precedent. The + theme CSS is a Marp stylesheet, not a React/Next.js component system + — it stays lead-developer territory. No reactivation trigger. + +### data-engineer +- **Active:** false +- **Domain:** data +- **Frameworks:** [] (inert) +- **Constraints:** [] (inert) +- **Territory:** [] (no territory in v1.22) +- **Reason:** v1.22 has no schema/DB/ORM changes. The milestone is + docs + scripts + tests only. No reactivation trigger. + +## Roster decisions + +### D-148 (0.95): Theme CSS is lead-developer territory, not frontend-engineer +The `nova-sp-theme.css` is a Marp stylesheet (CSS for a markdown-to- +slide renderer), not a React/Next.js component system. The v1.17/v1.18 +precedent (decks are markdown = lead-developer territory) extends to +the deck's CSS theme. frontend-engineer's frameworks (react, next.js) +are irrelevant to Marp CSS. **Decision:** theme CSS stays lead-developer +territory. Confidence 0.95 — the only counter-argument is that CSS is +"frontend," but Marp CSS is a static stylesheet, not a component system. + +### D-149 (0.9): No new personas for v1.22 +The work is CSS + bash + markdown + mermaid + pytest. All of this is +within the two active personas' range (lead-developer: CSS + markdown + +mermaid; backend-engineer: bash + pytest). Creating a separate "css- +engineer" or "slides-engineer" persona would fragment ownership of the +theme CSS + deck markdown (both lead-developer) and the render scripts ++ tests (both backend-engineer). **Decision:** no new personas. +Confidence 0.9. + +### Territory-overlap resolution (co-ownership) + +| Path | Primary | Co-owner | Why | +|------|---------|----------|-----| +| `docs/presentations/assets/mmd/*.mmd` | lead-developer (mermaid re-layout) | backend-engineer (re-render via render_slides.sh) | The .mmd content is lead-developer (diagram narrative); the PNG re-render is backend-engineer (script invocation). | +| `tests/test_slides_pipeline.py` | backend-engineer (test code) | lead-developer (assertions reflect deck structure) | The test code is backend; the assertions (slide count, theme rules, aspect ratios) reflect lead-developer's deck/theme decisions. | + +--- + +## Historical rosters + +
+v1.18 roster (Citizen Developer & Production-Grade Guidance) — superseded by v1.22 + +### Active personas (v1.18) + ### lead-developer - **Domain:** coordination - **Active:** true @@ -97,7 +191,7 @@ verification_toolchain: is backend; the schema it validates against is data). - **Phase-specific flag:** none (active for P3 schema + ingestor wiring). -## Deactivated personas +### Deactivated personas (v1.18) ### frontend-engineer - **Active:** false @@ -111,7 +205,7 @@ verification_toolchain: frontend / dashboard"). The MCP server exposes tools to an AI agent, not a web UI. No reactivation trigger in this milestone. -## Roster decisions +### Roster decisions (v1.18) ### D-143 (0.90): Fold mcp-engineer into backend-engineer The MCP plugin-registry (D-140: `plugins/.py register(mcp)`) is a @@ -127,10 +221,12 @@ that MCP is a distinct protocol skill, but the SDK v2 API surface range (it's the same Pydantic/FastAPI-style pattern the persona already knows). -### Territory-overlap resolution (co-ownership) +### Territory-overlap resolution (v1.18) | Path | Primary | Co-owner | Why | |------|---------|----------|-----| | `docs/submission-readiness.md` | lead-developer (narrative + examples) | backend-engineer (reason-code catalog, REQ-218 codes) | The doc is citizen-developer-facing copy (lead) but the reason-code catalog (MISSING_TAGS, ENV_MISSING_MANDATORY, AGENTIC_MISSING_INTENT, MISSING_APP_SOURCE, POLICY_PRECONDITION_MISSING) is backend (it mirrors the validator's return codes). | | `core/lambda/contract_ingestor.py` | backend-engineer (dispatch wiring) | data-engineer (the schema it validates against) | D-133 places the `--check-readiness` subcommand on the ingestor (backend dispatch), but the readiness schema it loads is data-engineer territory. | -| `schemas/submission-readiness.schema.json` | data-engineer (schema artifact) | backend-engineer (the validator must match it) | The schema is data-engineer's; the validator (REQ-218) is backend-engineer's and must stay in sync with it. | \ No newline at end of file +| `schemas/submission-readiness.schema.json` | data-engineer (schema artifact) | backend-engineer (the validator must match it) | The schema is data-engineer's; the validator (REQ-218) is backend-engineer's and must stay in sync with it. | + +
\ No newline at end of file diff --git a/.ciagent/PLAN.md b/.ciagent/PLAN.md index 0ce4f1f..9d265ce 100644 --- a/.ciagent/PLAN.md +++ b/.ciagent/PLAN.md @@ -1098,5 +1098,360 @@ NOT exercised here. 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. \ No newline at end of file + 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 `