From d8240588c95cf229d46d028bbc0b299233616ae8 Mon Sep 17 00:00:00 2001 From: Jon Chery Date: Wed, 12 Aug 2026 14:23:24 +0000 Subject: [PATCH] =?UTF-8?q?docs(P00):=20create=20phase=20plans=20=E2=80=94?= =?UTF-8?q?=20v1.24=20(4=20phases,=204=20waves)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ---ci--- project: acdl phase: 0 milestone: v1.24 status: plan ---/ci--- --- .ciagent/CHECKPOINT.json | 7 +- .ciagent/PLAN.md | 636 +++++++++++---------------------------- 2 files changed, 173 insertions(+), 470 deletions(-) diff --git a/.ciagent/CHECKPOINT.json b/.ciagent/CHECKPOINT.json index 6d53ae7..c01c8bc 100644 --- a/.ciagent/CHECKPOINT.json +++ b/.ciagent/CHECKPOINT.json @@ -1,13 +1,14 @@ { "phase": 0, - "stage": "research", + "stage": "plan", "milestone": "v1.24", "phase_role": "pre_execution", "attempts": 0, - "updated_at": "2026-08-12T02:10:00Z", + "updated_at": "2026-08-12T02:15:00Z", "project": "acdl", "milestone_complete": false, "tag_line": "v1.23.x", "requirements": ["REQ-276","REQ-277","REQ-278","REQ-279","REQ-280","REQ-281","REQ-282","REQ-283","REQ-284","REQ-285","REQ-286","REQ-287","REQ-288","REQ-289","REQ-290"], - "decisions": ["D-201","D-202","D-203","D-204","D-205","D-206","D-207","D-208"] + "phases": ["P1:consumer-guide-fixes","P2:env-transition-detect-and-destroy","P3:env-transition-tests","P4:final-review-ship"], + "waves": 4 } \ No newline at end of file diff --git a/.ciagent/PLAN.md b/.ciagent/PLAN.md index a380082..04f9752 100644 --- a/.ciagent/PLAN.md +++ b/.ciagent/PLAN.md @@ -1,478 +1,180 @@ -# PLAN — v1.23 (Nova Deck Cleanup & Python PPTX) +# PLAN — v1.24 (Consumer Guide Accuracy & Env-Promotion Lifecycle Enforcement) -> NFR milestone (docs/render/test only). Tags on v1.22.x line: -> v1.22.0 (P0) → v1.22.1..v1.22.4 (P1–P4) → v1.22.5 (P5 final = milestone -> release). 13 requirements (REQ-263..275), 6 phases. -> -> **GRILL revisions applied** (G-001..G-004, conf 0.78-0.85): -> - G-001: "penetrate" purge covers the whole repo (`docs/` + -> `.ciagent/`), not just `docs/presentations/`. -> - G-002: P3→P4 serialized (not parallel) — P4's parser depends on -> P3's stable `render_slides.sh`; P4's trimmed deck is what P3b's -> parser consumes. -> - G-003: P3 split into P3a (inline_images + render_slides.sh + -> pyproject — low-risk) + P3b (render_pptx.py + parser + -> attach_release_asset.py — high-risk, isolated). -> - G-004: P5+P6 merged — NFR docs milestone; dedicated review/ship -> phase is ceremonial overhead. P5 absorbs review/audit/ship. Tag -> v1.22.5 = milestone release. +> Feature milestone (one `feat` phase: env-transition destroy enforcement; +> the rest are `fix`/`docs`/`test`). Tags on the **v1.23.x** line: +> v1.23.0 (P0) → v1.23.1 (P1) → v1.23.2 (P2) → v1.23.3 (P3) → v1.23.4 (P4 +> final = milestone release). 15 requirements (REQ-276..290), 4 phases + +> P0 pre-execution. -## Wave Ordering +## Phase breakdown + +### Phase P1 — consumer-guide-fixes (Wave 1, lead-developer) + +**Type:** `docs` + `fix` + `test` (consumer guide accuracy + guide test updates) + +**Requirements:** REQ-276, REQ-277, REQ-278, REQ-279, REQ-280, REQ-281, REQ-290 + +**Must-haves:** +- `docs/consumer-guide.md` Step 3 contract fields table corrected (REQ-276) +- `docs/consumer-guide.md` Step 4 caller consistent with Step 2 (REQ-277) +- `docs/consumer-guide.md` Step 5 stage 8 "(dev only)" → "(autonomous in dev; higher environments apply after HITL attestation)" (REQ-278) +- `docs/consumer-guide.md` Step 8 rewritten with destroy-then-rebuild semantics + cross-ref to Shape B (REQ-279) +- `docs/consumer-guide.md` Per-env section gains Shape B lead sentence (REQ-280) +- `docs/consumer-guide.md` Reference table `@v1.19` wording corrected (REQ-281) +- `tests/test_consumer_guide_per_env_section.py` updated: rename `test_consumer_guide_states_no_field_editing` → `test_consumer_guide_documents_both_promotion_shapes`; add `test_consumer_guide_documents_destroy_on_env_change` (REQ-290) + +**Vertical slice:** A reader of `docs/consumer-guide.md` can promote via +either shape (A: edit environment + platform destroys prior; B: per-env +caller workflow) without contradiction. The guide's field table, caller +examples, and stage descriptions match the actual schema and platform +behavior. All consumer-guide tests pass. + +**Files touched:** +- `docs/consumer-guide.md` +- `tests/test_consumer_guide_per_env_section.py` + +**Verification:** `pytest tests/test_consumer_guide_per_env_section.py -v` +(all 7 tests pass). Manual read of `docs/consumer-guide.md` end-to-end +for internal consistency. + +--- + +### Phase P2 — env-transition-detect-and-destroy (Wave 2, backend-engineer) + +**Type:** `feat` (new platform feature: env-transition detect-and-destroy) + +**Requirements:** REQ-282, REQ-283, REQ-284, REQ-285, REQ-286, REQ-287 + +**Must-haves:** +- `core/env_transition.py` new module: `detect_prior_env()` + `record_applied_env()` with boto3 DynamoDB queries (REQ-282, REQ-283) +- `scripts/run_platform.sh` Step 0b: environment-transition check — detect prior env, re-resolve with `environment_override=prior_env` + `deletion_protection=false`, `terraform init -reconfigure` + `terraform destroy -auto-approve` against prior state key, emit `nova.env.destroyed` evidence event, fail closed on destroy failure (REQ-284) +- `scripts/run_platform.sh` records applied env after successful apply (REQ-285) +- `.github/workflows/deploy.yml` passes `NOVA_CONSUMER_REPO=${{ github.repository }}` to `run_platform.sh` (REQ-286) +- `adapters/terraform/adapter.py` state-key block gains doc comment (REQ-287) + +**Vertical slice:** When a consumer changes `environment:` on a stable +`contract.id`, the pipeline detects the prior env from DynamoDB, destroys +the prior env's Terraform state (with `deletion_protection=false`), emits +an evidence event, and only then applies the new env. If the destroy +fails, the pipeline exits non-zero (no orphan path). If no prior env +exists (first deploy or Shape B), the pipeline proceeds normally. + +**Files touched:** +- `core/env_transition.py` (NEW) +- `scripts/run_platform.sh` +- `.github/workflows/deploy.yml` +- `adapters/terraform/adapter.py` (doc comment only) + +**Verification:** `python3 -m py_compile core/env_transition.py`. +`pytest tests/test_pipeline.py tests/test_deploy_workflow_env_input.py -v` +(existing tests still pass). The new tests in P3 validate the behavior. + +**Key implementation notes (from RESEARCH §5 pitfalls):** +1. The destroy step must re-resolve with `environment_override=prior_env` + so the emitted TF matches the prior env's resources. +2. `terraform init -reconfigure` is required when switching state backends. +3. `deletion_protection: false` must be injected (same as decommission + Step 2 in `scripts/run_decommission.sh:34-37`) or `prevent_destroy` + blocks the destroy. +4. DynamoDB unreachable in local/CI → log warning + return `None` + (conservative, no prior env assumed). +5. The state key `spike/{id}/{env}/terraform.tfstate` stays as-is — the + env segment is what lets the destroy target the prior env. + +--- + +### Phase P3 — env-transition-tests (Wave 3, backend-engineer + lead-developer) + +**Type:** `test` (new test coverage for env-transition + pipeline integration) + +**Requirements:** REQ-288, REQ-289 + +**Must-haves:** +- `tests/test_env_transition.py` (NEW): `detect_prior_env` returns `None` when no record; returns prior env when record differs; returns `None` when record matches; `record_applied_env` writes record. Uses moto for DynamoDB (REQ-288) +- `tests/test_run_platform_env_transition.py` (NEW): asserts `run_platform.sh` has Step 0b; calls `env_transition.py detect`; calls `terraform destroy` on prior env; fails closed on destroy failure; records applied env after success (REQ-289) + +**Vertical slice:** The env-transition detect-and-destroy behavior is +fully covered by automated tests. The DynamoDB query logic is unit-tested +with moto. The pipeline orchestration is tested via shell-text assertions +(pattern from `tests/test_pipeline.py:79-95`). + +**Files touched:** +- `tests/test_env_transition.py` (NEW) +- `tests/test_run_platform_env_transition.py` (NEW) + +**Verification:** `pytest tests/test_env_transition.py tests/test_run_platform_env_transition.py -v` (all new tests pass). Full suite: `pytest tests/ -k "env_transition or consumer_guide or pipeline or adapter or deploy_workflow" -v`. + +--- + +### Phase P4 — final-review-ship (Wave 4, lead-developer) + +**Type:** `docs` (review + audit + milestone ship) + +**Requirements:** (none new — milestone completion) + +**Must-haves:** +- Multi-persona code review across P1-P3 changes (ci-code-reviewer) +- Project health audit (ci-doc-verifier + ci-audit) +- Milestone ship: tag v1.23.4 (final phase patch = milestone release), merge to main, Gitea release +- Update REQUIREMENTS.md traceability (all REQ-276..290 → complete) +- Update ROADMAP.md (v1.24 → complete) + +--- + +## Wave ordering ``` -Wave 1 (P1): consolidate-docs (edits -marp.md, deletes plain .md) - ↓ -Wave 2 (P2): restore-clean-style (edits -marp.md frontmatter + - ↓ benefit callouts; edits render_slides.sh; retires - ↓ nova-sp-theme.css from render) - ↓ -Wave 3 (P3a): inline-images (inline_images.py + render_slides.sh - ↓ step + pyproject — low-risk, mechanical) - ↓ -Wave 4 (P3b): python-pptx-generator (render_pptx.py + parser + - ↓ attach_release_asset.py — high-risk, isolated) - ↓ -Wave 5 (P4): trim-wordcount + remove "penetrate" (edits -marp.md + - ↓ talking-points.md + docs/scope.md + docs/vision.md + - ↓ .ciagent/*.md "penetrate" purge) - ↓ -Wave 6 (P5): ci-tests-readme + review + audit + milestone ship - (merged P5+P6 per G-004) +Wave 1 (P1): consumer-guide-fixes [lead-developer] + ↓ +Wave 2 (P2): env-transition-detect-and-destroy [backend-engineer] + ↓ +Wave 3 (P3): env-transition-tests [backend-engineer + lead-developer] + ↓ +Wave 4 (P4): final-review-ship [lead-developer] ``` -**Rationale (C8 revised by G-002/G-003/G-004):** P1→P2 serial (both -edit `-marp.md`). P3a→P3b serial (P3b's parser benefits from P3a's -stable `render_slides.sh`). P4 serial after P3b (P4's trimmed deck is -what P3b's parser must handle; P4's verify render depends on P3a's -stable script). P5 final (merged review/audit/ship per G-004 — NFR docs -milestone doesn't warrant a dedicated P6). +**Dependencies:** +- P2 depends on P1: the Step 8 rewrite in P1 documents the destroy + semantics that P2 implements. Doing P1 first ensures the docs and code + land in the right order (docs describe the intended behavior, then code + implements it). +- P3 depends on P2: the tests validate the env-transition module and + pipeline Step 0b that P2 creates. +- P4 depends on P1+P2+P3: the final review covers all changes. ---- +**Parallelization:** P1 and P2 could run in parallel (different +territories: docs vs code), but the wave ordering is sequential for +safety — if P1's Step 8 rewrite reveals a design issue, P2's +implementation should follow the corrected design. With +`parallelization.enabled=true` and `min_plans_for_parallel=2`, the +orchestrator *could* run them concurrently; however, the dependency +(P2 follows P1's design) makes sequential the safer choice. P3 must +follow P2 (tests validate the code). P4 must follow all. -## Phase P1 — consolidate-docs (tag v1.22.1) +## Requirement → Phase mapping -**Requirements:** REQ-263, REQ-264 -**Persona:** lead-developer (deck markdown + .ciagent) -**Branch:** `phase/01-consolidate-docs` +| REQ | Phase | Type | Description | +|-----|-------|------|-------------| +| REQ-276 | P1 | docs | Contract fields table corrected | +| REQ-277 | P1 | docs | Step 4 caller consistent with Step 2 | +| REQ-278 | P1 | docs | Step 5 stage 8 "dev only" corrected | +| REQ-279 | P1 | docs | Step 8 rewritten with destroy semantics | +| REQ-280 | P1 | docs | Per-env section Shape B lead sentence | +| REQ-281 | P1 | docs | Reference table @v1.19 wording corrected | +| REQ-282 | P2 | feat | env_transition.py detect_prior_env() | +| REQ-283 | P2 | feat | env_transition.py record_applied_env() | +| REQ-284 | P2 | feat | run_platform.sh Step 0b detect-and-destroy | +| REQ-285 | P2 | feat | run_platform.sh records applied env | +| REQ-286 | P2 | feat | deploy.yml passes NOVA_CONSUMER_REPO | +| REQ-287 | P2 | docs | adapter.py state-key doc comment | +| REQ-288 | P3 | test | test_env_transition.py | +| REQ-289 | P3 | test | test_run_platform_env_transition.py | +| REQ-290 | P1 | test | consumer guide test updates | -### Tasks +## Tag plan -1. **Fold speaker notes into the deck** (REQ-263): - - Read `docs/presentations/nova-autonomous-cloud-delivery.md` (the - plain source-of-truth, 747 lines). - - For each `## Slide N — Title` section, extract the - `> **Speaker notes:**` and `> **Transition:**` blockquote blocks. - - In `docs/presentations/nova-autonomous-cloud-delivery-marp.md`, - insert `` (and `` - where present) as a Marp HTML comment immediately after the - slide's content, before the next `---` separator. - - The slide's visible content is unchanged. - -2. **Fold talking points into the deck** (REQ-264): - - Read `docs/presentations/nova-autonomous-cloud-delivery-talking-points.md` - (145 lines, 3-6 bullets per slide + key takeaway). - - For each slide, insert `` (the bullets - joined) as a Marp HTML comment after the speaker-notes comment. - - Update the `talking-points.md` header (line 4): change "distilled - from the source of truth (`nova-autonomous-cloud-delivery.md`)" → - "mirrors the `` comments in - `nova-autonomous-cloud-delivery-marp.md` (the sole source of - truth)". - -3. **Delete the plain `.md`** (REQ-263): - - `git rm docs/presentations/nova-autonomous-cloud-delivery.md`. - -4. **Verify** (must-have): - - `bash scripts/render_slides.sh` still renders (22 slides: - title + 20 main + 1 appendix — unchanged). - - HTML slide count unchanged (test_marp_deck_slide_count passes). - - `grep -c "` HTML comments → skipped (speaker notes/talking - points). - - `- `/`* ` bullets → bullet list. - - `**bold lead**` (first paragraph after title) → bold lead. - - `> blockquote` → blockquote-styled paragraph. - - ` ```lang ... ``` ` → code block (monospace text frame). - - `![alt](path)` → `add_picture` (embedded in ppt/media/). - - `| ... |` tables → native PPTX table (`add_table`). - - `
text
` → benefit callout - (italic text frame with red top border accent). - - Produces 16:9 PPTX (`prs.slide_width = Inches(13.333)`, - `prs.slide_height = Inches(7.5)`): - - Title slide: black background, red top bar - (`MSO_SHAPE.RECTANGLE`, fill `#D6002A`, height ~0.4"), white H1 - (Arial — Akkurat Pro not installed; PowerPoint does OS - substitution). - - Content slides: blank layout; red H2 title text box at top; - bold lead paragraph (red `**strong**`); bullets; blockquote - (indent + red left accent via thin rectangle); embedded PNGs - (centered, scaled to fit content area); native tables (grey - header, red bottom border); benefit callout (italic, red - top-rule accent). - - Font: "Akkurat Pro" (PowerPoint falls back to OS default if - absent — acceptable; the HTML is the pixel-perfect artifact). - - Output: `docs/presentations/nova-autonomous-cloud-delivery-python.pptx`. - - Usage: `python scripts/render_pptx.py [deck-name]` (defaults to - `nova-autonomous-cloud-delivery`). - -2. **`pyproject.toml`** (REQ-269): - - Add to `[project.optional-dependencies]`: - ```toml - slides = ["python-pptx>=0.6.23"] - ``` - -3. **`scripts/render_slides.sh`** (REQ-270): - - Add Step 4: python-pptx render → `*-python.pptx`. - - Update Step 5 (stage): add `*-python.pptx`. - - Final order: Step 1 mermaid → Step 2 MARP HTML+PPTX → Step 3 - inline images → Step 4 python-pptx → Step 5 stage. - -4. **`scripts/attach_release_asset.py`** (REQ-270): - - Extend to accept multiple asset paths (both `.pptx` + - `-python.pptx`). Backward-compatible (single arg still works; or - accept a list). MARP PPTX is the primary attachment (first). - -5. **Verify** (must-have): - - `bash scripts/render_slides.sh` produces 3 artifacts: `.html` - (with inlined base64 images), `.pptx` (MARP), `-python.pptx` - (structured). - - Open `-python.pptx` — 16:9, title slide black with red bar, content - slides with red titles + bullets + tables + images. - - `-python.pptx` is a valid zip (PPTX signature). - ---- - -## Phase P4 — trim-wordcount + repo-wide "penetrate" purge (tag v1.22.5) - -**Requirements:** REQ-271, REQ-272 -**Persona:** lead-developer (deck markdown + talking-points + docs + -.ciagent) -**Branch:** `phase/04-trim-wordcount` -**Depends on:** P3b (stable render_slides.sh; trimmed deck is what P3b's -parser already handles — P4 does not break P3b's parser because the -parser handles the pre-trim structure and P4 trims prose, not -structure) - -### Tasks - -1. **Targeted word-count trim** (REQ-271) on ~8 verbose slides: - - **Slide 1 (The Problem)**: cut the "Every hour a developer - spends..." restatement paragraph (lines 29-ish); tighten bullet - sub-clauses. Target ~25% reduction. - - **Slide 5 (Scope)**: collapse bullets 1 + 3 (both say "PDLC is - upstream") to 3 bullets. - - **Slide 7 (Pipeline)**: condense bullet 1's pipe-chain; deduplicate - bullet 3's "Wiz on the plan" repetition. - - **Slide 8 (Decision Ledger)**: tighten the "AI decisions" bullet - from a paragraph to one sentence. - - **Slide 13 (Cost & ROI)**: collapse the "Honest caveat" bullet to - one line. - - **Slide 14 (Deferred)**: cut the preamble paragraph to one line. - - **Slide 20 (Recap + Ask)**: split the 60-word ask run-on into two - short sentences. - - **Appendix A1**: tighten the benefit callout to one line. - - Tables (slides 6, 9, 10, 15, 16, 17, A1) untouched. - - Short slides (2, 3, 4, 11, 12, 18, 19) untouched. - - Benefit callouts (all slides): already restyled in P2; here just - tighten each to one short sentence (preserve the spirit). - -2. **Remove "penetrate" — repo-wide purge** (REQ-272, G-001): - - `docs/presentations/nova-autonomous-cloud-delivery-marp.md` slide 5: - "Nova never penetrates it. Integration is through one validated - contract." → "Integration is through one validated contract." - - `docs/presentations/nova-autonomous-cloud-delivery-talking-points.md:40`: - "Nova never penetrates it" → match slide 5's trimmed wording. - - `docs/scope.md`: reword "Nova never penetrates the PDLC" → - "Nova never reaches into the PDLC" (or restructure — the scope - boundary is already established by "downstream of PDLC"). - - `docs/vision.md`: reword "It does not penetrate upstream product or - software development lifecycles" → "It does not reach into upstream - product or software development lifecycles". - - `.ciagent/PROJECT.md`: reword the 3 "penetrate" occurrences in the - Core Tenets #2 + Scope sections. - - Note: `.ciagent/RESEARCH.md` + `.ciagent/PLAN.md` meta-references - to "penetrate removal" are NOT purged (they describe the removal; - purging them would erase the decision history). - -3. **Verify** (must-have): - - `grep -ri penetrat docs/ .ciagent/PROJECT.md .ciagent/CLARIFY.md` - returns nothing (the term is gone from all audience-facing + - project-spec docs; RESEARCH.md/PLAN.md/GRILL.md meta-references - are exempt as decision-history). - - Slide count unchanged (22). - - `bash scripts/render_slides.sh` renders; no broken slides. - - Word count of trimmed slides reduced ~20-30% (manual spot-check). - ---- - -## Phase P5 — ci-tests-readme + review + audit + ship (Final Phase, tag v1.22.6) - -**Requirements:** REQ-273, REQ-274, REQ-275 (+ review/audit/ship for all REQ-263..275) -**Persona:** backend-engineer (CI + tests) + lead-developer (README + review coordination) -**Branch:** `phase/05-ci-tests-readme-ship` -**Depends on:** P1, P2, P3a, P3b, P4 (asserts the final state; merged -P5+P6 per G-004 — NFR docs milestone doesn't warrant a dedicated -review/ship phase) - -### Tasks - -1. **CI workflows** (REQ-273): - - `workflows-src/slides.yml`: add `setup-python` step + `pip install - -e .[slides]` (or `pip install python-pptx>=0.6.23`). Pin - `@marp-team/marp-cli@4.5.0` + `@mermaid-js/mermaid-cli@11.16.0` - (match render_slides.sh). Update `git add` commit list: add - `*-python.pptx`. - - Sync to `.github/workflows/slides.yml` + `.gitea/workflows/slides.yml` - via `scripts/sync_workflows.py`. - -2. **Tests** (REQ-274): - - `tests/test_slides_pipeline.py` updates (per research finding 5): - - Delete/invert `test_marp_deck_not_using_default_theme` (we now - USE `theme: default`). - - `test_marp_deck_uses_sp_theme` → rewrite to assert the inline - `style:` block has S&P properties (`#D6002A`, `#1B1B1B`, - `section.title`). - - `test_theme_css_*` trio → retarget from standalone CSS file to - inline `style:` block (or delete if the inline-style assertion - covers it). - - `test_html_embeds_theme` → assert literal `#D6002A` (not - `--sp-red`). - - `test_source_md_*` → delete (plain `.md` is gone). - - `test_render_slides_pins_cli_versions` → keep, extend to assert - `python-pptx` is in `pyproject.toml`. - - `test_no_penetrate_term` (new, G-001): assert - `grep -ri penetrat docs/ .ciagent/PROJECT.md .ciagent/CLARIFY.md` - returns nothing (RESEARCH.md/PLAN.md/GRILL.md meta-references - exempt as decision-history). - - `test_html_images_inlined_as_base64` (new): assert rendered - HTML has zero `src="assets/` references and ≥1 - `data:image/png;base64` per image the deck uses. - - `test_python_pptx_exists` (new): assert - `nova-autonomous-cloud-delivery-python.pptx` exists + is a valid - zip (PPTX signature). - - `test_nova_sp_theme_css_retained_as_reference` (new): assert - the file exists + has the "Not loaded at render" comment. - - `test_benefit_callouts_use_class` (new): assert `-marp.md` has - `class="benefit"` and no `**Benefit:**` prefix. - - New `tests/test_pptx_generator.py`: - - `test_slide_count`: python PPTX slide count == 22 (title + 20 + - appendix). - - `test_title_slide_colors`: title slide background black, red bar - present. - - `test_expected_slide_titles`: spot-check 3-5 slide titles match - the markdown. - - `test_table_rendering`: a slide with a table (e.g., RACI) has a - native PPTX table shape. - - `test_image_embedding`: a slide with an image has a picture - shape. - - `test_benefit_callout_present`: ≥1 slide has italic benefit text. - -3. **README** (REQ-275): - - Rewrite `docs/presentations/README.md` process section: - - 3-step process (was 4): 1) author `*-marp.md` (sole source of - truth, with `` + `` - comments); 2) render HTML + dual PPTX (`render_slides.sh`: - mermaid → MARP HTML+PPTX → inline images → python-pptx); 3) - talking points (mirrored from deck comments). - - Drop the plain `.md` row from the decks table. - - Add `inline_images.py` + `render_pptx.py` + `-python.pptx` rows - to the tooling section. - - Note `nova-sp-theme.css` retired (reference only; inline `style:` - is the live styling). - - Document the dual-PPTX output (MARP image-of-slide primary + - python structured for comparison/editing). - -4. **Multi-persona code review** (`ciagent-review`): - - Review all changes in `milestone/v1.23-deck-cleanup-python-pptx`. - - Auto-apply P0 fixes; flag P1+ for post-hoc review. - - If P1+ found: fix in this phase. - -5. **Audit** (`ciagent-audit`): - - Reconstruction test: git log matches `.ciagent/` files. - - `.ciagent/` file discipline + branch hygiene + commit discipline. - -6. **Ship** (`ciagent-ship` — milestone ship): - - Merge `phase/05` → `milestone/v1.23-deck-cleanup-python-pptx`. - - Merge `milestone/v1.23-deck-cleanup-python-pptx` → `main`. - - Tag `v1.22.6` (final patch = milestone release). - - Create release with full milestone summary (all phases, all 13 - requirements). - - Attach both PPTX files (MARP + python) to the release. - - Delete all milestone branches (local + remote). Tags preserve - history. - -7. **Complete the milestone**: - - Update `REQUIREMENTS.md` — mark all v1.23 requirements complete. - - Update `ROADMAP.md` — mark v1.23 complete. - - Commit: `docs(milestone): complete v1.23 — Nova Deck Cleanup & Python PPTX`. - -8. **Verify** (must-have): - - `pytest tests/test_slides_pipeline.py tests/test_pptx_generator.py` - all pass. - - CI workflow YAML is valid. - - README reflects the new pipeline. - ---- - -## Versioning - -- NFR milestone → progressive patches on v1.22.x line. -- `v1.22.0` (P0) → `v1.22.1` (P1) → `v1.22.2` (P2) → `v1.22.3` (P3a) → - `v1.22.4` (P3b) → `v1.22.5` (P4) → `v1.22.6` (P5 final = milestone - release). No separate minor tag. 6 phases total (was 7; P5+P6 merged - per G-004, P3 split into P3a+P3b per G-003). - -## Risk Mitigations (from RESEARCH + GRILL) - -1. **Default theme padding** — explicitly set - `section { padding: 48px 56px 40px }` in the inline `style:` block - (don't rely on default's `56px 64px` which doesn't reserve - header/footer space). -2. **python-pptx font fallback** — use "Akkurat Pro" in the PPTX - (PowerPoint does OS substitution); the HTML is the pixel-perfect - artifact, the python PPTX is for comparison/editing. -3. **Marp version drift** — marp-cli pinned at 4.5.0 (already). -4. **Speaker notes stripped** — Marp strips HTML comments from rendered - slides but they persist in the source `-marp.md` (acceptable; they're - for authors, not the audience). -5. **`test_html_embeds_theme`** — update to assert literal `#D6002A` - (not `--sp-red`). -6. **P3b parser overflow** (G-003) — isolated in its own phase so a - parser setback doesn't block inline-images (P3a) or trim (P4). -7. **"penetrate" purge scope** (G-001) — repo-wide, not just - `docs/presentations/`; RESEARCH.md/PLAN.md/GRILL.md exempt as - decision-history. \ No newline at end of file +- P0 (this phase): `v1.23.0` — pre-execution patch +- P1: `v1.23.1` — consumer guide fixes +- P2: `v1.23.2` — env-transition detect-and-destroy +- P3: `v1.23.3` — env-transition tests +- P4: `v1.23.4` — final review + ship = **milestone release** \ No newline at end of file