Files
acdl/.ciagent/PLAN.md
T
Jon Chery b8fbd995a9
Nova Slides Render / render (push) Failing after 57s
docs(P00): grill — 4 revisions applied (PROCEED-WITH-REVISIONS, 0.78)
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---
2026-08-12 00:05:34 +00:00

22 KiB
Raw Blame History

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 (P1P4) → 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.

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

  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 <!-- 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.
  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 <!-- Talking points: ... --> (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 <!-- Talking points: --> 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 "<!-- Speaker notes:" nova-autonomous-cloud-delivery-marp.md returns ≥20 (one per main slide).
    • grep -c "<!-- Talking points:" ... returns ≥20.
    • The plain .md no longer exists.
    • talking-points.md still 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

  1. Revert frontmatter to theme: default + inline style: (REQ-265):

    • In nova-autonomous-cloud-delivery-marp.md frontmatter:
      • theme: nova-sptheme: 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:, no header:.
  2. Retire nova-sp-theme.css from 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 Marp default theme + inline style: block in the -marp.md frontmatter. Not loaded at render time."
    • scripts/render_slides.sh: remove THEME_CSS variable usage and the --theme "$THEME_CSS" argument from both marp-cli invocations (lines 70, 73). Keep --allow-local-files.
  3. Restyle benefit callouts (REQ-267):

    • In nova-autonomous-cloud-delivery-marp.md, convert every **Benefit:** text line → <div class="benefit">text</div>.
    • This applies to all 20 main slides + appendix (21 callouts).
    • The **Benefit:** prefix is removed; the .benefit class (defined in the inline style: block) provides the visual emphasis.
  4. Verify (must-have):

    • bash scripts/render_slides.sh renders; 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.md returns 1.
    • grep -c "theme: nova-sp" ... returns 0.
    • grep -c 'class="benefit"' ... returns ≥21.
    • grep -c "\\*\\*Benefit:\\*\\*" ... returns 0.
    • nova-sp-theme.css still exists (reference).
    • grep "Not loaded at render" nova-sp-theme.css returns 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

  1. 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 src with data:image/<mime>;base64,<base64>.
    • MIME by extension: .pngimage/png, .svgimage/svg+xml, .jpg/.jpegimage/jpeg, .gifimage/gif; fallback application/octet-stream.
    • Writes HTML back in place; prints count inlined to stderr.
    • Usage: python scripts/inline_images.py <html-path>.
  2. 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.
  3. Verify (must-have):

    • bash scripts/render_slides.sh produces .html with inlined base64 images.
    • Open the HTML from a different directory (no assets/ folder) — images display.
    • grep -c 'src="assets/' nova-autonomous-cloud-delivery.html returns 0 (all inlined).
    • grep -c 'data:image' nova-autonomous-cloud-delivery.html returns ≥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

  1. 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).
      • ![alt](path)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).
    • 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]:
      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 <!-- 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 .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/05milestone/v1.23-deck-cleanup-python-pptx.
    • Merge milestone/v1.23-deck-cleanup-python-pptxmain.
    • 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.