10 axes reviewed. 6 PASS, 4 REVISE. Overall: PROCEED-WITH-REVISIONS. Empirically cleared (not assumed): image format (plain <img src>, conf 0.95) + Marp <div> passthrough (rendered test, conf 0.95). Versioning clean (no v1.22.* tags, conf 1.0). Test inversion risk fully enumerated (conf 0.9). Revisions (binding): G-001 (0.85): purge 'penetrate' repo-wide (docs/ + .ciagent/), not just docs/presentations/. RESEARCH.md/PLAN.md/GRILL.md exempt as decision- history. P4 verify becomes grep -ri penetrat docs/ .ciagent/PROJECT.md .ciagent/CLARIFY.md -> nothing. G-002 (0.85): serialize P3->P4 (not parallel). P4's parser depends on P3's stable render_slides.sh; P4's trimmed deck is what P3b's parser consumes. C8 parallelization overruled. G-003 (0.80): split P3 into P3a (inline_images.py + render_slides.sh + pyproject — low-risk) + P3b (render_pptx.py + parser + attach_release_asset.py — high-risk, isolated). Both serial in Wave 3. G-004 (0.80): merge P5+P6. NFR docs milestone; dedicated review/ship phase is ceremonial. P5 absorbs review/audit/ship. Net phases 7->6. Revised phase/tag plan: 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). ---ci--- project: acdl phase: 0 milestone: v1.23 status: grill ---/ci---
22 KiB
PLAN — v1.23 (Nova Deck Cleanup & Python PPTX)
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 justdocs/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.
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)
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).
Phase P1 — consolidate-docs (tag v1.22.1)
Requirements: REQ-263, REQ-264
Persona: lead-developer (deck markdown + .ciagent)
Branch: phase/01-consolidate-docs
Tasks
-
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 — Titlesection, extract the> **Speaker notes:**and> **Transition:**blockquote blocks. - In
docs/presentations/nova-autonomous-cloud-delivery-marp.md, insert<!-- Speaker notes: ... -->(and<!-- Transition: ... -->where present) as a Marp HTML comment immediately after the slide's content, before the next---separator. - The slide's visible content is unchanged.
- Read
-
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
<!-- Talking points: ... -->(the bullets joined) as a Marp HTML comment after the speaker-notes comment. - Update the
talking-points.mdheader (line 4): change "distilled from the source of truth (nova-autonomous-cloud-delivery.md)" → "mirrors the<!-- Talking points: -->comments innova-autonomous-cloud-delivery-marp.md(the sole source of truth)".
- Read
-
Delete the plain
.md(REQ-263):git rm docs/presentations/nova-autonomous-cloud-delivery.md.
-
Verify (must-have):
bash scripts/render_slides.shstill renders (22 slides: title + 20 main + 1 appendix — unchanged).- HTML slide count unchanged (test_marp_deck_slide_count passes).
grep -c "<!-- Speaker notes:" nova-autonomous-cloud-delivery-marp.mdreturns ≥20 (one per main slide).grep -c "<!-- Talking points:" ...returns ≥20.- The plain
.mdno longer exists. talking-points.mdstill exists with updated header.
Phase P2 — restore-clean-style (tag v1.22.2)
Requirements: REQ-265, REQ-266, REQ-267
Persona: lead-developer (deck markdown + CSS) + backend-engineer
(render_slides.sh)
Branch: phase/02-restore-clean-style
Depends on: P1 (consolidated doc)
Tasks
-
Revert frontmatter to
theme: default+ inlinestyle:(REQ-265):- In
nova-autonomous-cloud-delivery-marp.mdfrontmatter:theme: nova-sp→theme: default.- Add
style: |block porting the S&P visual language (from the research-extracted reference CSS +nova-sp-theme.css):style: | section { font-family: "Akkurat Pro", "Helvetica Neue", "Arial", sans-serif; font-size: 22px; color: #1B1B1B; padding: 48px 56px 40px; overflow: auto; } h1 { color: #D6002A; font-size: 34px; margin-bottom: 0.3em; } h2 { color: #D6002A; font-size: 26px; margin-bottom: 0.2em; } h3 { color: #D6002A; font-size: 22px; margin-bottom: 0.2em; } section.title { background: #1B1B1B; color: #fff; border-top: 8px solid #D6002A; } section.title h1, section.title h2 { color: #fff; } section.title header, section.title footer { display: none; } table { font-size: 18px; width: 100%; border-collapse: collapse; } th { background: #F0F0F0; border-bottom: 2px solid #D6002A; padding: 4px 8px; text-align: left; } td { border-bottom: 1px solid #F0F0F0; padding: 4px 8px; } blockquote { border-left: 4px solid #D6002A; color: #2E2E2E; font-size: 20px; padding-left: 12px; } pre { background: #1B1B1B; color: #fff; border-radius: 4px; padding: 12px; font-size: 16px; } code { background: #F0F0F0; color: #1B1B1B; border-radius: 2px; padding: 1px 4px; font-size: 18px; } pre code { background: transparent; color: inherit; } img { display: block; margin: 0 auto; max-width: 100%; max-height: 380px; object-fit: contain; } strong { color: #D6002A; } .benefit { margin-top: 0.6em; padding-top: 0.4em; border-top: 1px solid #D6002A; color: #1B1B1B; font-size: 20px; font-style: italic; } section.title .benefit { color: #fff; } @media print { section { overflow: hidden; } }
- Keep:
paginate: true,size: 16x9,footer:, noheader:.
- In
-
Retire
nova-sp-theme.cssfrom render (REQ-266):- Add header comment to
docs/presentations/assets/nova-sp-theme.css: "Retained as the S&P visual-language reference for future styling work. The live deck uses Marpdefaulttheme + inlinestyle:block in the -marp.md frontmatter. Not loaded at render time." scripts/render_slides.sh: removeTHEME_CSSvariable usage and the--theme "$THEME_CSS"argument from both marp-cli invocations (lines 70, 73). Keep--allow-local-files.
- Add header comment to
-
Restyle benefit callouts (REQ-267):
- In
nova-autonomous-cloud-delivery-marp.md, convert every**Benefit:** textline →<div class="benefit">text</div>. - This applies to all 20 main slides + appendix (21 callouts).
- The
**Benefit:**prefix is removed; the.benefitclass (defined in the inlinestyle:block) provides the visual emphasis.
- In
-
Verify (must-have):
bash scripts/render_slides.shrenders; HTML opens with S&P red h1s, black title slide with red top border, benefit callouts with red top-rule + italic.grep -c "theme: default" nova-autonomous-cloud-delivery-marp.mdreturns 1.grep -c "theme: nova-sp" ...returns 0.grep -c 'class="benefit"' ...returns ≥21.grep -c "\\*\\*Benefit:\\*\\*" ...returns 0.nova-sp-theme.cssstill exists (reference).grep "Not loaded at render" nova-sp-theme.cssreturns a match.
Phase P3a — inline-images (tag v1.22.3)
Requirements: REQ-268
Persona: backend-engineer (scripts + pyproject)
Branch: phase/03a-inline-images
Depends on: P2 (render_slides.sh --theme drop)
Tasks
-
scripts/inline_images.py(REQ-268):- Stdlib only (
base64,re,mimetypes,sys,pathlib). - Reads the rendered HTML path (argv[1]).
- Finds all
<img ... src="(assets/...)" ...>(relative paths only; skip absolute/http(s)://). - Reads each referenced file, replaces
srcwithdata:image/<mime>;base64,<base64>. - MIME by extension:
.png→image/png,.svg→image/svg+xml,.jpg/.jpeg→image/jpeg,.gif→image/gif; fallbackapplication/octet-stream. - Writes HTML back in place; prints count inlined to stderr.
- Usage:
python scripts/inline_images.py <html-path>.
- Stdlib only (
-
scripts/render_slides.sh(REQ-268):- After Step 2 (MARP render), add Step 3: inline images into HTML
(
python scripts/inline_images.py "$HTML"). - Update Step 5 (stage): no change yet (python-pptx is P3b).
- Order now: Step 1 mermaid → Step 2 MARP HTML+PPTX → Step 3 inline images → Step 4 stage.
- After Step 2 (MARP render), add Step 3: inline images into HTML
(
-
Verify (must-have):
bash scripts/render_slides.shproduces.htmlwith inlined base64 images.- Open the HTML from a different directory (no
assets/folder) — images display. grep -c 'src="assets/' nova-autonomous-cloud-delivery.htmlreturns 0 (all inlined).grep -c 'data:image' nova-autonomous-cloud-delivery.htmlreturns ≥2 (the deck's 2 images).
Phase P3b — python-pptx-generator (tag v1.22.4)
Requirements: REQ-269, REQ-270
Persona: backend-engineer (scripts + pyproject) + lead-developer
(deck structure consultation)
Branch: phase/03b-python-pptx
Depends on: P3a (stable render_slides.sh with inline step)
Tasks
-
scripts/render_pptx.py(REQ-269):- Dependency:
python-pptx>=0.6.23(import at module load; if absent, print "pip install -e .[slides]" and exit 1). - Parses
nova-autonomous-cloud-delivery-marp.md:- Frontmatter (skip YAML between
---markers). ---slide separators.#/##headings → slide title.<!-- ... -->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).→add_picture(embedded in ppt/media/).| ... |tables → native PPTX table (add_table).<div class="benefit">text</div>→ benefit callout (italic text frame with red top border accent).
- Frontmatter (skip YAML between
- 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).
- Title slide: black background, red top bar
(
- Output:
docs/presentations/nova-autonomous-cloud-delivery-python.pptx. - Usage:
python scripts/render_pptx.py [deck-name](defaults tonova-autonomous-cloud-delivery).
- Dependency:
-
pyproject.toml(REQ-269):- Add to
[project.optional-dependencies]:slides = ["python-pptx>=0.6.23"]
- Add to
-
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.
- Add Step 4: python-pptx render →
-
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).
- Extend to accept multiple asset paths (both
-
Verify (must-have):
bash scripts/render_slides.shproduces 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.pptxis 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
-
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).
-
Remove "penetrate" — repo-wide purge (REQ-272, G-001):
docs/presentations/nova-autonomous-cloud-delivery-marp.mdslide 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.mdmeta-references to "penetrate removal" are NOT purged (they describe the removal; purging them would erase the decision history).
-
Verify (must-have):
grep -ri penetrat docs/ .ciagent/PROJECT.md .ciagent/CLARIFY.mdreturns 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.shrenders; 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
-
CI workflows (REQ-273):
workflows-src/slides.yml: addsetup-pythonstep +pip install -e .[slides](orpip 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). Updategit addcommit list: add*-python.pptx.- Sync to
.github/workflows/slides.yml+.gitea/workflows/slides.ymlviascripts/sync_workflows.py.
-
Tests (REQ-274):
tests/test_slides_pipeline.pyupdates (per research finding 5):- Delete/invert
test_marp_deck_not_using_default_theme(we now USEtheme: default). test_marp_deck_uses_sp_theme→ rewrite to assert the inlinestyle:block has S&P properties (#D6002A,#1B1B1B,section.title).test_theme_css_*trio → retarget from standalone CSS file to inlinestyle: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.mdis gone).test_render_slides_pins_cli_versions→ keep, extend to assertpython-pptxis inpyproject.toml.test_no_penetrate_term(new, G-001): assertgrep -ri penetrat docs/ .ciagent/PROJECT.md .ciagent/CLARIFY.mdreturns nothing (RESEARCH.md/PLAN.md/GRILL.md meta-references exempt as decision-history).test_html_images_inlined_as_base64(new): assert rendered HTML has zerosrc="assets/references and ≥1data:image/png;base64per image the deck uses.test_python_pptx_exists(new): assertnova-autonomous-cloud-delivery-python.pptxexists + 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.mdhasclass="benefit"and no**Benefit:**prefix.
- Delete/invert
- 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.
-
README (REQ-275):
- Rewrite
docs/presentations/README.mdprocess section:- 3-step process (was 4): 1) author
*-marp.md(sole source of truth, with<!-- Speaker notes: -->+<!-- Talking points: -->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
.mdrow from the decks table. - Add
inline_images.py+render_pptx.py+-python.pptxrows to the tooling section. - Note
nova-sp-theme.cssretired (reference only; inlinestyle:is the live styling). - Document the dual-PPTX output (MARP image-of-slide primary + python structured for comparison/editing).
- 3-step process (was 4): 1) author
- Rewrite
-
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.
- Review all changes in
-
Audit (
ciagent-audit):- Reconstruction test: git log matches
.ciagent/files. .ciagent/file discipline + branch hygiene + commit discipline.
- Reconstruction test: git log matches
-
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.
- Merge
-
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.
- Update
-
Verify (must-have):
pytest tests/test_slides_pipeline.py tests/test_pptx_generator.pyall 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)
- Default theme padding — explicitly set
section { padding: 48px 56px 40px }in the inlinestyle:block (don't rely on default's56px 64pxwhich doesn't reserve header/footer space). - 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.
- Marp version drift — marp-cli pinned at 4.5.0 (already).
- 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). test_html_embeds_theme— update to assert literal#D6002A(not--sp-red).- P3b parser overflow (G-003) — isolated in its own phase so a parser setback doesn't block inline-images (P3a) or trim (P4).
- "penetrate" purge scope (G-001) — repo-wide, not just
docs/presentations/; RESEARCH.md/PLAN.md/GRILL.md exempt as decision-history.