Compare commits

...

10 Commits

Author SHA1 Message Date
Jon Chery b8fbd995a9 docs(P00): grill — 4 revisions applied (PROCEED-WITH-REVISIONS, 0.78)
Nova Slides Render / render (push) Failing after 57s
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
Jon Chery ea44fdb9d6 docs(P00): grill v1.23 — PROCEED-WITH-REVISIONS (4 binding revisions)
Adversarial red-team review of the v1.23 Nova Deck Cleanup & Python PPTX
plan (7 phases, 5 waves). Overall verdict: PROCEED-WITH-REVISIONS (conf 0.78).

Empirically verified (P0 risks cleared):
- Image format: rendered HTML uses plain <img src="assets/png/...">, no
  xlink:href → inline_images.py regex will match (Axis 4 PASS, conf 0.95)
- Marp <div> passthrough: minimal test deck through marp-cli@4.5.0 confirms
  <div class="benefit"> passes through verbatim (Axis 6 PASS, conf 0.95)
- Versioning: no v1.22.* tags exist (Axis 10 PASS, conf 0.95)
- Test inversion list complete (Axis 3 PASS, conf 0.92)

4 binding revisions:
- G-001: Purge "penetrate" from entire repo (docs/ + .ciagent/), not just
  docs/presentations/ — term appears in docs/scope.md:16, docs/vision.md:18,
  and all .ciagent/*.md
- G-002: Serialize P3→P4 — "zero file overlap" is false for verification
  (P3 parser depends on deck P4 trims; P4 verify render depends on P3's
  render_slides.sh being stable)
- G-003: Split P3 into P3a (inline_images + render_slides.sh + pyproject —
  low-risk) and P3b (render_pptx.py + parser — high-risk, 10+ markdown
  constructs + python-pptx XML constraints)
- G-004: Merge P5+P6 — P6 is ceremonial overhead for an NFR docs milestone;
  P5 absorbs review/audit/ship. Net phases: 7 (P1, P2, P3a, P3b, P4, P5+P6)

No escalations (all axes resolved at conf >= 0.78).

---ci---
status: grill
decisions:
  - G-001: Purge "penetrate" from docs/ + .ciagent/ (conf 0.85)
  - G-002: Serialize P3->P4 (conf 0.85)
  - G-003: Split P3 into P3a + P3b (conf 0.80)
  - G-004: Merge P5+P6 (conf 0.80)
escalations: []
2026-08-12 00:02:57 +00:00
Jon Chery e14818875c docs(P00): create phase plans — v1.23 (7 phases, 5 waves)
Vertical-slice plan with wave ordering:
- Wave 1 (P1): consolidate-docs (single -marp.md, delete plain .md,
  speaker notes + talking points as HTML comments).
- Wave 2 (P2): restore-clean-style (theme:default + inline style,
  retire nova-sp-theme.css from render, benefit callout .benefit class).
- Wave 3 (P3 + P4, parallel): inline-images + python-pptx-generator
  (new scripts, zero deck-markdown overlap) || trim-wordcount + remove
  'penetrate' (deck markdown, zero script overlap).
- Wave 4 (P5): ci-tests-readme (workflows, tests, README — depends on
  all above).
- Wave 5 (P6): final review + audit + milestone ship.

Tags on v1.22.x line: v1.22.0 (P0) -> v1.22.1..v1.22.5 (P1-P5) ->
v1.22.6 (P6 final = milestone release).

---ci---
project: acdl
phase: 0
milestone: v1.23
status: plan
---/ci---
2026-08-11 23:56:39 +00:00
Jon Chery f496dd9c24 docs(P00): research — v1.23 Nova Deck Cleanup & Python PPTX
10 findings grounding the v1.23 milestone plan:
- Marp default theme + inline style block (exact CSS from ref deck)
- HTML passthrough confirmed; python-pptx API mapped; stdlib image
  inlining sufficient; 12 tests need updating; attach script +
  slides.yml + README structure documented; persona roster (same as
  v1.22); 5 pitfalls identified.

---ci---
phase: 0
milestone: v1.23
status: research
decisions:
  - id: D-163
    decision: Inline Marp style block is lead-developer territory (not frontend-engineer)
    rationale: Marp frontmatter CSS is a static stylesheet, not a React/Next.js component system (D-148 precedent from v1.22)
    confidence: 0.95
    alternatives: [frontend-engineer owns CSS, custom slides-engineer persona]
  - id: D-164
    decision: No new personas for v1.23
    rationale: Work splits cleanly into lead-developer (markdown+CSS+README+metadata) and backend-engineer (Python+bash+tests+CI); python-pptx is backend
    confidence: 0.90
    alternatives: [custom docs/deck persona, pptx-engineer persona]
---/ci---
2026-08-11 23:54:47 +00:00
Jon Chery 0d22b89a7b docs(P00): clarify — 8 ambiguities auto-resolved (full autonomy)
8 ambiguities identified, all auto-resolved at confidence >= 0.6. No
human escalation (full autonomy). Decisions:
C1 (0.95): speaker notes + talking points embedded as Marp HTML comments
C2 (0.9): python-pptx in new pyproject optional-dep group 'slides'
C3 (0.9): benefit callouts as <div class='benefit'> (Marp HTML passthrough)
C4 (0.95): inline_images.py MIME-sniffs by extension (png/svg/jpg/gif)
C5 (0.9): render_slides.sh order: mermaid -> MARP -> inline -> python-pptx
C6 (0.95): 'penetrate' absence via grep -ri (text files only)
C7 (0.85): release attaches both PPTX (MARP primary, python secondary)
C8 (0.85): wave order P1 -> P2 -> (P3+P4 parallel) -> P5 -> P6

---ci---
project: acdl
phase: 0
milestone: v1.23
status: clarify
---/ci---
2026-08-11 23:50:42 +00:00
Jon Chery 75e9e479db docs(init): validate specification — v1.23 milestone (REQ-263..275)
Established active_milestone: v1.23 (Nova Deck Cleanup & Python PPTX).
NFR milestone (docs/render/test only; no features). Tags on v1.22.x line
(v1.22.0 P0 -> v1.22.6 P6 final = milestone release). Branch:
milestone/v1.23-deck-cleanup-python-pptx.

Added REQ-263..275 to REQUIREMENTS.md covering:
- Consolidate docs: single -marp.md source of truth, delete plain .md,
  speaker notes/talking points as Marp HTML comments, keep
  talking-points.md as synced standalone aid (REQ-263,264)
- Restore clean style: theme:default + inline style block (S&P palette),
  retire nova-sp-theme.css from render (keep as reference), benefit
  callout restyle (REQ-265,266,267)
- Inline images: scripts/inline_images.py for self-contained
  redistributable HTML (REQ-268)
- Python PPTX generator: scripts/render_pptx.py structured editable
  S&P-themed PPTX via python-pptx, both PPTX outputs produced + attached
  (REQ-269,270)
- Trim word count: targeted ~20-30% trim on verbose slides, remove
  'penetrate' term (REQ-271,272)
- CI/tests/README: workflows install python-pptx, tests updated,
  README rewritten (REQ-273,274,275)

Driven by user feedback: deck looked 'out of whack'; wanted to return to
the clean style of the old the-developer-experience.html. Investigation
revealed the 'clean' reference was itself MARP output (default theme +
inline style); the standalone nova-sp-theme.css approach was fragile.

---ci---
project: acdl
phase: 0
milestone: v1.23
status: specify
---/ci---
2026-08-11 23:49:45 +00:00
Jon Chery d199204367 docs(ship): Gitea releases created for v1.21.0..v1.21.6 + PPTX attached
acdl-ci / Lint (push) Successful in 8s
acdl-ci / Test (push) Failing after 22s
acdl-ci / Platform check-only (offline) (push) Successful in 19s
Nova Slides Render / render (push) Failing after 1m1s
All 7 Gitea releases created (ids 621-627) after fixing the token
variable name mismatch (config: ACDL_GITEA_TOKEN vs env:
NOVA_GITEA_TOKEN). Tags pushed to origin. PPTX attached to milestone
release v1.21.6 (asset id 98).

Release URLs: https://git.cloudinit.dev/continuous-intelligence/acdl/releases

---ci---
project: acdl
phase: 6
milestone: v1.22
status: complete
phase_role: final
---/ci---
2026-08-11 22:59:33 +00:00
Jon Chery 6a64b2b337 docs(milestone): merge v1.22 — Nova Deck Layout Fix to main
acdl-ci / Lint (push) Successful in 9s
acdl-ci / Test (push) Failing after 24s
acdl-ci / Platform check-only (offline) (push) Successful in 22s
Nova Slides Render / render (push) Failing after 57s
9 requirements (REQ-254..262) complete. Tags on v1.21.x line.
Final patch v1.21.6 = milestone release.

---ci---
project: acdl
phase: 6
milestone: v1.22
status: complete
phase_role: final
requirements:
  covered: [REQ-254,REQ-255,REQ-256,REQ-257,REQ-258,REQ-259,REQ-260,REQ-261,REQ-262]
  partial: []
---/ci---
2026-08-11 20:11:51 +00:00
Jon Chery 9274b4b87f docs(ship): P6 complete — final review + audit + milestone ship
---ci---
project: acdl
phase: 6
milestone: v1.22
status: complete
phase_role: final
---/ci---
2026-08-11 20:11:46 +00:00
Jon Chery 25ddc894c2 docs(milestone): complete v1.22 — Nova Deck Layout Fix
9 requirements complete (REQ-254..262):
- P1: theme-css — section padding + overflow + image rules + title
  chrome + spacing tightening (REQ-254,255,256)
- P2: render-scripts — delete render_deck.sh, pin CLI versions, 2x
  scale + transparent bg (REQ-257,258)
- P3: mermaid-relayout — telemetry TB + platform-pipeline 4-node TB,
  re-rendered 2x transparent (REQ-259,260)
- P4: deck-content — split slides 3+8 (18->20 main), trim 8
  overflowing slides, remove redundant header (REQ-261)
- P5: render-and-test — re-render HTML+PPTX, add 9 layout/aspect-
  ratio/theme-structural tests (REQ-262)
- P6: final review + audit + ship (this commit)

Final review fixes: source .md + talking-points re-synced to 20-slide
structure; ![h:480 class:tall] directives applied; README stale
references updated; CSS trailing newline added.

Root cause: nova-sp-theme.css had zero section padding (declared
/* @theme nova-sp */ as a comment, not the @theme directive; did not
@import Marp default theme). Combined with overflow:hidden, blunt
img max-height:320px, header+footer chrome on every slide, and two
P5 diagrams with extreme aspect ratios (13.52x and 0.63x), 8 of 19
slides overflowed. NOT a P5 regression — theme CSS byte-identical
P3->P5; P5 denser content made pre-existing flaws visible.

Tags on v1.21.x line (v1.21.0 P0 -> v1.21.6 P6 final = milestone
release). 32 slide tests pass (23 original + 9 new). 94 key-file
tests pass. Pipeline check exit 0.

---ci---
project: acdl
phase: 6
milestone: v1.22
status: complete
phase_role: final
requirements:
  covered: [REQ-254,REQ-255,REQ-256,REQ-257,REQ-258,REQ-259,REQ-260,REQ-261,REQ-262]
  partial: []
---/ci---
2026-08-11 20:11:43 +00:00
20 changed files with 2075 additions and 2499 deletions
+6 -9
View File
@@ -1,12 +1,9 @@
{ {
"phase": 4, "phase": 0,
"stage": "complete", "stage": "grill",
"milestone": "v1.22", "milestone": "v1.23",
"phase_role": "execution", "phase_role": "pre_execution",
"attempts": 0, "attempts": 0,
"updated_at": "2026-08-11T15:00:00Z", "updated_at": "2026-08-11T23:30:00Z",
"milestone_complete": false, "project": "acdl"
"tag": "v1.21.4",
"requirements": ["REQ-261"],
"notes": "v1.22 P4 complete. Tag v1.21.4. 8 overflowing slides trimmed/split. Header removed from frontmatter. Slide count 18->20 main + 1 appendix. 23 slide tests pass. Proceeding to P5 (re-render + tests)."
} }
+76
View File
@@ -0,0 +1,76 @@
# CLARIFY — v1.23 (auto-resolved, full autonomy)
8 ambiguities identified, all auto-resolved at confidence ≥ 0.6.
No human escalation (full autonomy). All decisions logged below.
## C1 — Speaker notes source for HTML comments (conf 0.95)
**Ambiguity:** The plain `.md` has `> **Speaker notes:**` and
`> **Transition:**` blocks per slide; talking points live in a separate
file. Which content goes into the `<!-- ... -->` comments?
**Resolution:** Extract `> **Speaker notes:**` and `> **Transition:**`
blocks from the plain `.md` and embed each slide's as
`<!-- Speaker notes: ... -->` before the next `---` separator. Talking
points come from `talking-points.md` (the 3-6 bullets per slide)
embedded as `<!-- Talking points: ... -->`. Both are Marp HTML comments
(excluded from slide rendering; the `talking-points.md` stays as the
standalone synced aid).
## C2 — python-pptx dependency placement (conf 0.9)
**Ambiguity:** `pyproject.toml` has `[project.optional-dependencies]`
`test`. Where does `python-pptx` go?
**Resolution:** Add a new optional-dependency group
`slides = ["python-pptx>=0.6.23"]`. Keeps the base `dependencies`
minimal (the render script is a docs-only concern, not a runtime
dep). CI installs via `pip install -e .[slides]`. The `render_pptx.py`
script imports `pptx` at module load (not a hard failure if absent —
the script prints a clear "pip install -e .[slides]" message and exits
1).
## C3 — Benefit callout markdown representation (conf 0.9)
**Ambiguity:** Marp markdown can't natively produce arbitrary `<div>`.
How is the `.benefit` class applied?
**Resolution:** Use Marp's HTML-in-markdown support — write benefit
lines as `<div class="benefit">text</div>` directly in the markdown
(Marp passes through HTML blocks). The inline `style:` block targets
`.benefit`. The `**Benefit:**` prefix is removed.
## C4 — Image inlining MIME types (conf 0.95)
**Ambiguity:** What MIME types does `inline_images.py` handle?
**Resolution:** The deck references `.png` files only (mermaid
renders). `inline_images.py` MIME-sniffs by extension:
`.png``image/png`, `.svg``image/svg+xml`, `.jpg/.jpeg``image/jpeg`,
`.gif``image/gif`; fallback `application/octet-stream`. Only relative
`src="assets/..."` paths are inlined (absolute/`http(s)://` URLs are
left alone).
## C5 — render_slides.sh step ordering (conf 0.9)
**Ambiguity:** Where do the new inline-images + python-pptx steps go?
**Resolution:** Step 1 mermaid → PNG (unchanged); Step 2 MARP → HTML +
PPTX (drop `--theme`); Step 3 inline images into HTML; Step 4
python-pptx → `*-python.pptx`; Step 5 stage all. The inline step runs
only on the HTML (not the PPTX — both PPTX formats embed media in
their zip by construction).
## C6 — "penetrate" absence test scope (conf 0.95)
**Ambiguity:** How is "penetrate" absence asserted?
**Resolution:** `grep -ri penetrat docs/presentations/` returns nothing
(covers `.md`, `-marp.md`, `talking-points.md`, `.html`; `.pptx` is
binary so excluded). A new test `test_no_penetrate_term` asserts this.
## C7 — attach_release_asset.py dual-PPTX (conf 0.85)
**Ambiguity:** Does the release attach both PPTX files?
**Resolution:** Yes — attach both `.pptx` (MARP image-of-slide) and
`-python.pptx` (structured). Minimal change: loop over both filenames.
The MARP PPTX remains the "primary" attachment (first); the python
PPTX is secondary (comparison artifact).
## C8 — Wave ordering (conf 0.85)
**Ambiguity:** Can P1 (consolidate) and P2 (style) parallelize?
**Resolution:** No — both edit `-marp.md` with a serial dependency: P1
establishes the single doc (deletes the plain `.md`, adds HTML-comment
speaker notes); P2 edits that single doc's frontmatter + benefit
callouts. Order: P1 → P2 → (P3 + P4 parallel: P3 edits
`scripts/inline_images.py` + `render_pptx.py` + `render_slides.sh` +
`pyproject`; P4 edits the deck markdown — zero file overlap) → P5 →
P6. P3 depends on P2's render-script `--theme` drop. P4 depends on
P1's consolidated doc.
+176 -866
View File
File diff suppressed because it is too large Load Diff
+169 -137
View File
@@ -1,32 +1,174 @@
--- ---
project: acdl project: acdl
milestone: v1.22 milestone: v1.23
generated_at: 2026-08-11 generated_at: 2026-08-11
generator: lead-developer generator: lead-developer
verification_toolchain: verification_toolchain:
typecheck: "python3 -m py_compile tests/test_slides_pipeline.py" typecheck: "python3 -m py_compile scripts/inline_images.py scripts/render_pptx.py tests/test_slides_pipeline.py"
test: "pytest tests/test_slides_pipeline.py # REQ-254..262" test: "pytest tests/test_slides_pipeline.py # REQ-263..275"
build: "bash scripts/render_slides.sh nova-autonomous-cloud-delivery # HTML + PPTX" build: "bash scripts/render_slides.sh nova-autonomous-cloud-delivery # HTML + Marp PPTX; then python3 scripts/render_pptx.py # structured PPTX"
note: | note: |
v1.22 is the Nova Deck Layout Fix — a docs-only NFR milestone. Two v1.23 is the Nova Deck Cleanup & Python PPTX — a docs/render/test
active personas: lead-developer (theme CSS + deck markdown + talking NFR milestone. Two active personas: lead-developer (deck markdown
points + README + .ciagent metadata), backend-engineer (render scripts consolidation + inline Marp style CSS + README + .ciagent metadata),
+ tests). frontend-engineer stays deactivated (decks are markdown = backend-engineer (Python scripts inline_images.py + render_pptx.py
lead-developer territory, per v1.17/v1.18 precedent). No data-engineer via python-pptx + render_slides.sh updates + tests + CI YAML +
(no schema/DB changes). No new personas (the work is CSS + bash + attach_release_asset.py extension). frontend-engineer stays
markdown + pytest, all within the two active personas' range). deactivated (decks are markdown + Marp CSS = lead-developer
territory, per v1.17/v1.18/v1.22 precedent). No data-engineer (no
schema/DB changes). No new personas (the work splits cleanly into
narrative+CSS+docs and Python+bash+tests+CI).
--- ---
# ACDL — Persona Roster (v1.22 Nova Deck Layout Fix) # ACDL — Persona Roster (v1.23 Nova Deck Cleanup & Python PPTX)
> v1.22 roster. Two active personas + one deactivated. This is a docs- > v1.23 roster. Two active personas + two deactivated. This is a
> only NFR milestone: the work is theme CSS, render scripts, mermaid > docs/render/test NFR milestone: the work is deck markdown
> diagrams, deck markdown, and tests. frontend-engineer stays > consolidation, Marp inline `style:` CSS (reverting from the standalone
> deactivated (decks are markdown = lead-developer territory, per > `nova-sp-theme.css` to `theme: default` + inline block), two Python
> v1.17/v1.18 precedent). No data-engineer (no schema/DB changes). > render scripts (`inline_images.py` stdlib image inlining +
> `render_pptx.py` structured PPTX via python-pptx), test updates, CI
> YAML, README rewrite, and the `attach_release_asset.py` extension to
> dual-PPTX. frontend-engineer stays deactivated (Marp CSS is a static
> stylesheet, not a React/Next.js component system — D-148 precedent).
> No data-engineer (no schema/DB/ORM changes).
## Active personas ## Active personas
### lead-developer
- **Domain:** coordination + deck content + inline CSS
- **Active:** true
- **Phase-specific:** false
- **Frameworks:** [] (no framework — owns process + narrative + Marp inline CSS + markdown + README)
- **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", "port the reference deck's exact inline style CSS (the clean look)"]
- **Territory:**
- `docs/presentations/nova-autonomous-cloud-delivery-marp.md` (REQ-263..275 — deck consolidation: merge plain .md into -marp.md, trim word count, remove "penetrate")
- `docs/presentations/nova-autonomous-cloud-delivery.md` (DELETE — consolidated into -marp.md)
- `docs/presentations/nova-autonomous-cloud-delivery-talking-points.md` (sync to final slide structure)
- `docs/presentations/README.md` (rewrite 4-step → 3-step process for single-document + dual-PPTX pipeline)
- `docs/presentations/assets/nova-sp-theme.css` (RETIRE from render; keep as reference file)
- `.ciagent/**` (PROJECT, ROADMAP, REQUIREMENTS, RESEARCH, PLAN, GRILL, PERSONAS, REVIEW, CHECKPOINT)
- **Reason:** Owns the deck markdown consolidation (plain `.md` +
`-marp.md` → single `-marp.md` with speaker notes as HTML comments),
the inline `style:` CSS block (porting the reference deck's exact
CSS — the "clean look"), the word-count trim, the "penetrate"
removal, the talking-points sync, the README rewrite, and all
CIAgent metadata. Is the only persona that touches `.ciagent/**` and
the deck markdown/CSS. The inline `style:` block is a Marp
frontmatter stylesheet, not a frontend component system (D-148
precedent from v1.22).
- **Phase-specific flag:** none (active for all of P0P-final).
### backend-engineer
- **Domain:** Python render scripts + bash + tests + CI
- **Active:** true
- **Phase-specific:** false
- **Frameworks:** ["python-pptx", "bash", "pytest", "marp-cli", "mermaid-cli", "base64/re/mimetypes (stdlib)"]
- **Constraints:** ["pin CLI versions (no @latest in workflows-src/slides.yml — currently unpinned, must fix)", "python-pptx>=0.6.23 minimum", "stdlib-only for inline_images.py (no external image lib)", "tests must catch the theme-default + inline-style regression (the gap that let v1.22's standalone-theme drift through)", "no raw curl with shell-env tokens"]
- **Territory:**
- `scripts/inline_images.py` (NEW — stdlib base64 image inlining into rendered HTML)
- `scripts/render_pptx.py` (NEW — structured editable PPTX via python-pptx)
- `scripts/render_slides.sh` (update: drop --theme nova-sp-theme.css; add inline_images.py + render_pptx.py invocations)
- `scripts/attach_release_asset.py` (extend to accept multiple file paths: both .pptx + -python.pptx)
- `tests/test_slides_pipeline.py` (REQ-262 successor — invert theme tests, retarget CSS tests to inline style block, delete source-md tests, update slide count)
- `workflows-src/slides.yml` (add python-pptx install step; pin @latest@4.5.0/@11.16.0; add -python.pptx to commit list)
- `pyproject.toml` (add python-pptx>=0.6.23 to [project.optional-dependencies] test)
- **Reason:** Owns the Python render scripts (`inline_images.py` is
stdlib regex + base64; `render_pptx.py` is python-pptx — a backend
Python library, not a frontend framework). The render_slides.sh
updates (drop `--theme`, add the two Python script invocations) and
the CI YAML (add python-pptx install, pin versions, add
-python.pptx to commit list) are backend/scripting tasks. The test
suite updates (invert the theme-default test, retarget CSS tests to
the inline `style:` block, delete the source-md tests) are the gap
that let v1.22's standalone-theme drift through — backend-engineer
owns closing it. python-pptx is new to v1.23; backend-engineer's
frameworks list gains it.
- **Phase-specific flag:** none (active for P2 scripts, P5 tests; light
touch on P0/P-final).
## 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.23)
- **Reason:** v1.23 has no frontend; decks are markdown + Marp inline
CSS (lead-developer territory); deactivated per PERSONAS.md
v1.17/v1.18/v1.22 precedent. The inline `style:` block is a Marp
frontmatter stylesheet (CSS rules in the markdown frontmatter), 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.23)
- **Reason:** v1.23 has no schema/DB/ORM changes. The milestone is
docs + Python scripts + bash + tests + CI only. No reactivation
trigger.
## Roster decisions
### D-163 (0.95): Inline Marp `style:` block is lead-developer territory, not frontend-engineer
The inline `style:` block in the Marp frontmatter is a static CSS
stylesheet (a block of CSS rules in the markdown frontmatter, applied
by Marp to the rendered slides), not a React/Next.js component system.
The v1.17/v1.18/v1.22 precedent (decks are markdown = lead-developer
territory; the theme CSS is a Marp stylesheet, not a frontend framework
— D-148) extends to the inline `style:` block. frontend-engineer's
frameworks (react, next.js) are irrelevant to Marp frontmatter CSS.
**Decision:** inline `style:` block stays lead-developer territory.
Confidence 0.95 — the only counter-argument is that CSS is "frontend,"
but Marp frontmatter CSS is a static stylesheet authored in the
markdown source, not a component system.
### D-164 (0.90): No new personas for v1.23
The work is markdown + inline CSS + Python scripts + bash + tests + CI
YAML + README. All of this is within the two active personas' range
(lead-developer: markdown + CSS + README + metadata; backend-engineer:
Python + bash + tests + CI). Creating a separate "slides-engineer" or
"pptx-engineer" persona would fragment ownership of the deck markdown
(lead) and the render scripts (backend). The python-pptx work is
unambiguously backend (a Python library + script), even though the
slide layout decisions within `render_pptx.py` are co-owned with lead-
developer. **Decision:** no new personas. Confidence 0.90 — follows
v1.22 D-149 precedent.
### Territory-overlap resolution (co-ownership)
| Path | Primary | Co-owner | Why |
|------|---------|----------|-----|
| `scripts/render_pptx.py` | backend-engineer (Python code + python-pptx API) | lead-developer (slide layout decisions: which image where, font sizes, bullet structure) | The script is backend (Python); the slide-by-slide layout decisions within it are design decisions that reflect lead-developer's deck ownership. `warn` enforcement — cross-territory edits logged, not blocked. |
| `scripts/render_slides.sh` | backend-engineer (bash script) | lead-developer (the inline `style:` block content it renders) | The script is backend; the CSS it renders is lead-developer's. |
| `tests/test_slides_pipeline.py` | backend-engineer (test code) | lead-developer (assertions reflect deck structure + inline CSS) | The test code is backend; the assertions (slide count, inline style rules, theme-default) reflect lead-developer's deck/CSS decisions. |
| `docs/presentations/README.md` | lead-developer (process narrative) | backend-engineer (build commands + render script invocations) | The process narrative is lead; the build commands + script names are backend. |
## Domain priority (v1.23)
`lead-developer → backend-engineer`
Rationale: the deck markdown consolidation + inline CSS (lead) is the
binding constraint — the render scripts (backend) can't be finalized
until the deck structure is stable (slide count, inline style). The
inline `style:` block must be ported + verified before the render
pipeline (HTML + PPTX) is re-run. Backend (scripts + tests + CI)
follows once the deck + CSS are settled. The dual-PPTX pipeline is
wired last, once the deck renders clean with the inline style.
---
## Historical rosters
<details>
<summary>v1.22 roster (Nova Deck Layout Fix) — superseded by v1.23</summary>
### Active personas (v1.22)
### lead-developer ### lead-developer
- **Domain:** coordination + deck content - **Domain:** coordination + deck content
- **Active:** true - **Active:** true
@@ -65,61 +207,13 @@ verification_toolchain:
backend/scripting tasks. backend/scripting tasks.
- **Phase-specific flag:** none (active for P2, P5; light touch on P0/P6). - **Phase-specific flag:** none (active for P2, P5; light touch on P0/P6).
## Deactivated personas ### D-148 (v1.22): Theme CSS is lead-developer territory, not frontend-engineer
### D-149 (v1.22): No new personas for v1.22
### frontend-engineer </details>
- **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
<details> <details>
<summary>v1.18 roster (Citizen Developer & Production-Grade Guidance) — superseded by v1.22</summary> <summary>v1.18 roster (Citizen Developer & Production-Grade Guidance) — superseded</summary>
### Active personas (v1.18) ### Active personas (v1.18)
@@ -139,94 +233,32 @@ Confidence 0.9.
- `docs/scope.md` (REQ-216) - `docs/scope.md` (REQ-216)
- `docs/skills.md` (REQ-222 — the index page, not the skill files themselves) - `docs/skills.md` (REQ-222 — the index page, not the skill files themselves)
- `docs/submission-readiness.md` (REQ-219 — citizen-developer-facing copy; co-owned with backend-engineer for the reason-code catalog) - `docs/submission-readiness.md` (REQ-219 — citizen-developer-facing copy; co-owned with backend-engineer for the reason-code catalog)
- **Reason:** Owns CIAgent metadata, the milestone narrative, the RACI +
PDLC-scope statements (REQ-215/216), the deck (21 slides, S&P theme
regression check vs P1, CAP-024), the skills index page (REQ-222), and
the citizen-developer-facing submission-readiness doc (REQ-219). Is
the only persona that touches `.ciagent/**` and the deck markdown.
- **Phase-specific flag:** none (active for all of P0P7).
### backend-engineer ### backend-engineer
- **Domain:** backend - **Domain:** backend
- **Active:** true - **Active:** true
- **Phase-specific:** false - **Phase-specific:** false
- **Frameworks:** ["mcp (Python SDK v2)", "pydantic", "jsonschema", "urllib"] - **Frameworks:** ["mcp (Python SDK v2)", "pydantic", "jsonschema", "urllib"]
- **Constraints:** ["api-first", "strict-typing", "plugin-registry extensible (D-140)", "stdio now / HTTP-ready (D-135)", "no stack traces to citizen developers (REQ-218)"]
- **Territory:** - **Territory:**
- `mcp/atelier/server.py` (REQ-223) - `mcp/atelier/server.py` (REQ-223)
- `mcp/atelier/plugins/**/*.py` (REQ-223 — principles.py, validation.py) - `mcp/atelier/plugins/**/*.py` (REQ-223 — principles.py, validation.py)
- `mcp/atelier/vendor/**` (REQ-224 — vendored Atelier snapshot) - `mcp/atelier/vendor/**` (REQ-224 — vendored Atelier snapshot)
- `mcp/atelier/VERSION.md` + `mcp/atelier/README.md` (REQ-224) - `mcp/atelier/VERSION.md` + `mcp/atelier/README.md` (REQ-224)
- `scripts/update_atelier_vendor.sh` (REQ-224) - `scripts/update_atelier_vendor.sh` (REQ-224)
- `core/submission_readiness.py` (REQ-218 — the validator, invoked as `contract_ingestor.py --check-readiness`) - `core/submission_readiness.py` (REQ-218)
- `scripts/render_deck.sh` (REQ-228 — HTML + PPTX render) - `scripts/render_deck.sh` (REQ-228)
- `scripts/attach_release_asset.py` (REQ-228 — Gitea release asset upload) - `scripts/attach_release_asset.py` (REQ-228)
- `tests/test_atelier_mcp.py` (REQ-225) - `tests/test_atelier_mcp.py` (REQ-225)
- `tests/test_submission_readiness.py` (REQ-220) - `tests/test_submission_readiness.py` (REQ-220)
- `docs/submission-readiness.md` (REQ-219 — reason-code catalog section; co-owned with lead-developer for the narrative)
- **Reason:** Owns the MCP server (plugin-registry, stdio, vendored
Atelier), the submission-readiness validator (extends
`contract_ingestor.py --check-readiness`, D-133), the render/attach
scripts (D-142 trigger), and the two new test files. The MCP
plugin-registry (D-140) is a backend pattern — no separate
mcp-engineer persona is created; backend-engineer owns it.
- **Phase-specific flag:** none (active for P1 deck-render, P3 validator,
P5 MCP server, P6 scripts).
### data-engineer ### data-engineer
- **Domain:** data - **Domain:** data
- **Active:** true - **Active:** true
- **Phase-specific:** false
- **Frameworks:** ["jsonschema", "dynamodb (item shape)"] - **Frameworks:** ["jsonschema", "dynamodb (item shape)"]
- **Constraints:** ["schema-first", "superset-gate NOT duplicate (PROJECT.md hard constraint)", "W3.E per-env mandatory table is the source of truth"]
- **Territory:** - **Territory:**
- `schemas/**` (REQ-217`submission-readiness.schema.json` is the new schema; existing schemas untouched) - `schemas/**` (REQ-217)
- `core/lambda/contract_ingestor.py` (the `--check-readiness` subcommand wiring, D-133 — the validator is in `core/submission_readiness.py` but the ingestor dispatches to it; co-owned with backend-engineer) - `core/lambda/contract_ingestor.py` (co-owned with backend-engineer)
- **Reason:** Owns the submission-readiness JSON Schema (REQ-217) — it
is a schema artifact, data-engineer territory. The schema is a
*superset gate above* `contract.schema.json`, not a duplicate (it
references contract fields, does not redefine them). The
per-env-mandatory table comes from W3.E (the locked decision). The
ingestor wiring is co-owned with backend-engineer (the dispatch point
is backend; the schema it validates against is data).
- **Phase-specific flag:** none (active for P3 schema + ingestor wiring).
### Deactivated personas (v1.18) ### D-143 (v1.18): Fold mcp-engineer into backend-engineer
### 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.18)
- **Reason:** v1.18 has no frontend; decks are markdown (lead-developer
territory); deactivated per PERSONAS.md v1.17 precedent. v1.18's
observability stays PowerBI / external (Out of Scope: "A Nova-built
frontend / dashboard"). The MCP server exposes tools to an AI agent,
not a web UI. No reactivation trigger in this milestone.
### Roster decisions (v1.18)
### D-143 (0.90): Fold mcp-engineer into backend-engineer
The MCP plugin-registry (D-140: `plugins/<name>.py register(mcp)`) is a
backend code pattern — Python modules, type hints, stdio transport,
urllib for the Gitea asset API. It shares nothing with the data domain
(schemas/DynamoDB) and is not a new engineering discipline. Creating a
separate `mcp-engineer` persona would fragment ownership of the server +
its tests + the render/attach scripts (all backend). **Decision:** fold
into backend-engineer. backend-engineer's `frameworks` list gains
`mcp (Python SDK v2)`. Confidence 0.90 — the only counter-argument is
that MCP is a distinct protocol skill, but the SDK v2 API surface
(`@mcp.tool()` + type hints) is small and well within backend-engineer's
range (it's the same Pydantic/FastAPI-style pattern the persona already
knows).
### 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. |
</details> </details>
+410 -1389
View File
File diff suppressed because it is too large Load Diff
+45
View File
@@ -1532,3 +1532,48 @@ New requirements REQ-254..REQ-262 — see `REQUIREMENTS.md` §v1.22. Summary:
A1) + remove redundant `header:` from frontmatter. A1) + remove redundant `header:` from frontmatter.
- **REQ-262:** Re-render HTML + PPTX + add layout/aspect-ratio/theme- - **REQ-262:** Re-render HTML + PPTX + add layout/aspect-ratio/theme-
structural tests. structural tests.
## v1.23 — Nova Deck Cleanup & Python PPTX
> **Active milestone.** NFR (docs/render/test only; no features).
> Branch: `milestone/v1.23-deck-cleanup-python-pptx`. Tags run on the
> **v1.22.x** patch line: `v1.22.0` (P0) → `v1.22.1..v1.22.5` (P1P5) →
> `v1.22.6` (P6 final = milestone release).
Driven by user feedback that the deck looked "out of whack" and the
desire to return to the clean, well-formatted style of the old
`the-developer-experience.html`. Investigation revealed the "clean"
reference was itself MARP output (using Marp's built-in `default` theme
+ an inline `style:` block); the current deck's standalone
`nova-sp-theme.css` re-derives all base spacing from scratch and had a
zero-padding bug (fixed in v1.22, but the standalone approach is
fragile). The milestone delivers:
- **Single-document consolidation** — `*-marp.md` becomes the sole
source of truth; the plain `.md` is deleted; speaker notes + talking
points are embedded as Marp HTML comments.
- **Clean style restoration** — revert to `theme: default` + inline
`style:` block (S&P palette); `nova-sp-theme.css` retained as a
reference, retired from render.
- **Self-contained HTML** — base64-inline all images for
redistribution.
- **Parallel python-pptx generator** — structured, editable, S&P-themed
PPTX alongside the MARP image-of-slide PPTX.
- **Targeted word-count trim** + "penetrate" term removal.
**Phase count:** 7 (P0 pre-execution + 5 execution + 1 final).
**Hard constraints:**
- DO NOT change the deck narrative or the 4-beat arc (Problem → Solution
→ Proof → Roadmap + Ask) — only trim word count.
- DO NOT re-introduce badges, version strings, or internal citations.
- DO NOT remove MARP — it stays for HTML + PPTX; python-pptx runs in
parallel.
- `nova-sp-theme.css` is retained (not deleted) as a styling reference.
### Requirements
New requirements REQ-263..REQ-275 — see `REQUIREMENTS.md` §v1.23.
Summary: consolidation (REQ-263,264), style restoration (REQ-265,266,267),
image inlining (REQ-268), python-pptx generator (REQ-269,270), word-count
trim + "penetrate" removal (REQ-271,272), CI/tests/README (REQ-273,274,275).
+133 -9
View File
@@ -1895,12 +1895,136 @@ assert 20 main + 1 appendix.
| REQ | Phase | Status | | REQ | Phase | Status |
|-----|-------|--------| |-----|-------|--------|
| REQ-254 | P1 | pending | | REQ-254 | P1 | complete |
| REQ-255 | P1 | pending | | REQ-255 | P1 | complete |
| REQ-256 | P1 | pending | | REQ-256 | P1 | complete |
| REQ-257 | P2 | pending | | REQ-257 | P2 | complete |
| REQ-258 | P2 | pending | | REQ-258 | P2 | complete |
| REQ-259 | P3 | pending | | REQ-259 | P3 | complete |
| REQ-260 | P3 | pending | | REQ-260 | P3 | complete |
| REQ-261 | P4 | pending | | REQ-261 | P4 | complete |
| REQ-262 | P5 | pending | | REQ-262 | P5 | complete |
## v1.23 — Nova Deck Cleanup & Python PPTX
> **NFR milestone** (docs/render/test only; no features). Tags run on the
> **v1.22.x** line (milestone v1.23 → tags v1.22.0..v1.22.6). Final patch
> `v1.22.6` = milestone release.
>
> Consolidates the deck to a single source-of-truth markdown document,
> restores the clean S&P visual style (Marp `default` theme + inline
> `style:` block, matching the old `the-developer-experience.html`),
> embeds images as base64 in the HTML for redistribution, builds a
> parallel structured python-pptx PPTX generator, and trims verbose
> slides. `nova-sp-theme.css` is retained as a styling reference but
> retired from the render path.
### Category: Consolidate Docs
- **REQ-263:** `nova-autonomous-cloud-delivery-marp.md` becomes the sole
source of truth. Speaker notes + talking points from the plain `.md`
are folded into the deck as Marp HTML comments (`<!-- Speaker notes:
... -->`, `<!-- Talking points: ... -->`). The plain
`nova-autonomous-cloud-delivery.md` is deleted.
- **REQ-264:** `nova-autonomous-cloud-delivery-talking-points.md` is kept
as a standalone presenter aid, synced from the deck's `<!-- Talking
points: -->` comments. Header note documents the mirror relationship.
### Category: Restore Clean Style
- **REQ-265:** Revert deck frontmatter `theme: nova-sp` → `theme:
default` and add an inline `style:` block porting the S&P visual
language (palette #D6002A/#1B1B1B, Akkurat Pro font, black title slide
with red top border, tables, blockquotes, code, aspect-ratio-aware
images). Keep current structure (H2 + bold-lead, no header, no badges).
- **REQ-266:** `nova-sp-theme.css` is retained as a styling reference
(header comment documents its retired status). `render_slides.sh`
drops the `--theme "$THEME_CSS"` argument; the inline `style:` block in
frontmatter is the sole styling source at render time.
- **REQ-267:** Benefit callouts on every slide are restyled: the
`**Benefit:**` prefix is removed; the callout becomes a styled
element (red top-rule + black italic text; white on title slides)
using a `.benefit` class in the inline style block.
### Category: Inline Images
- **REQ-268:** New `scripts/inline_images.py` (stdlib only: `base64`,
`re`, `mimetypes`) post-processes the rendered HTML: finds all
`<img src="assets/...">` relative paths, replaces each `src` with a
`data:image/<mime>;base64,...` URI. HTML becomes self-contained
(redistributable without the `assets/` folder). `render_slides.sh`
invokes it after the MARP HTML render, before staging.
### Category: Python PPTX Generator
- **REQ-269:** New `scripts/render_pptx.py` parses the consolidated
`*-marp.md` and produces a structured, editable, S&P-themed PPTX
(`nova-autonomous-cloud-delivery-python.pptx`) using `python-pptx`.
16:9 slides; title slide (black bg, red top bar, white H1); content
slides (red H2 title, bold lead, bullets, blockquote, embedded PNGs,
native PPTX tables, benefit callouts). HTML-comment speaker
notes/talking points are skipped. `python-pptx` added to
`pyproject.toml`. `render_slides.sh` invokes it as a new step.
- **REQ-270:** Both PPTX outputs (MARP image-of-slide + python
structured) are produced by `render_slides.sh` and staged. CI
workflows install `python-pptx` and commit both. `attach_release_asset.py`
attaches both to the release.
### Category: Trim Word Count
- **REQ-271:** Targeted word-count trim on ~8 verbose slides (1, 5, 7,
8, 13, 14, 20, plus the appendix) — ~20-30% reduction on trimmed
slides. Tables and short slides are untouched. The spirit of each
slide is preserved.
- **REQ-272:** The term "penetrate" (and derivatives) is removed from
all presentation files. Slide 5's "Nova never penetrates it" phrase is
removed with no replacement (slide 4 Anti-Goals already excludes the
PDLC from scope). `grep -ri penetrat docs/presentations/` returns
nothing.
### Category: CI, Tests, README
- **REQ-273:** CI workflows (`workflows-src/slides.yml` + synced
`.github`/`.gitea` copies) install `python-pptx`, run `render_slides.sh`
(which produces HTML + both PPTX + inlined images), and commit all
rendered artifacts. README documents the new pipeline.
- **REQ-274:** `tests/test_slides_pipeline.py` is updated for the
consolidated doc (no plain `.md`), default theme + inline style
assertions (S&P visual properties, not theme filename),
`nova-sp-theme.css` retained-as-reference assertion, image-inlining
assertions (zero `src="assets/` references, ≥1 base64 per image),
python-pptx output existence, benefit callout class, "penetrate"
absence. New `tests/test_pptx_generator.py` asserts slide count, title
colors, table rendering, image embedding.
- **REQ-275:** `docs/presentations/README.md` is rewritten to document
the single-document process (author `*-marp.md` → render HTML + both
PPTX → talking points mirrored), inline `style:` approach,
`nova-sp-theme.css` reference status, image inlining, and dual PPTX
output.
### Out of Scope (v1.23)
- **Deck narrative / 4-beat arc changes** — the Problem → Solution →
Proof → Roadmap + Ask structure is unchanged; only word count is
trimmed.
- **Re-introduction of badges, version strings, or internal citations**
— v1.21 removed these; v1.23 does not re-add them.
- **Removal of MARP** — MARP stays for HTML + PPTX; python-pptx runs in
parallel for comparison.
- **Removal of orphaned `developer-experience-*` assets** — deferred to
a future cleanup phase (optional in v1.23 Phase 6 only if time
permits).
- **Mermaid render scoping** — the mermaid render step continues to
render all `.mmd` files; scoping to referenced-only is deferred.
### v1.23 Traceability
| REQ | Phase | Status |
|-----|-------|--------|
| REQ-263 | P1 | pending |
| REQ-264 | P1 | pending |
| REQ-265 | P2 | pending |
| REQ-266 | P2 | pending |
| REQ-267 | P2 | pending |
| REQ-268 | P3a | pending |
| REQ-269 | P3b | pending |
| REQ-270 | P3b | pending |
| REQ-271 | P4 | pending |
| REQ-272 | P4 | pending |
| REQ-273 | P5 | pending |
| REQ-274 | P5 | pending |
| REQ-275 | P5 | pending |
+702
View File
@@ -2568,3 +2568,705 @@ All 5 CLARIFY decisions are grounded in these findings:
- Re-layout to LR (FINDING 3 — TB produced 0.63 aspect) - Re-layout to LR (FINDING 3 — TB produced 0.63 aspect)
- Delete render_deck.sh (FINDING 5 — stale, unthemed) - Delete render_deck.sh (FINDING 5 — stale, unthemed)
- Split slides 3+8 (FINDING 2 — densest overflow) - Split slides 3+8 (FINDING 2 — densest overflow)
---
## v1.23 RESEARCH — Nova Deck Cleanup & Python PPTX
> Phase: 0 RESEARCH. Milestone v1.23 (Nova Deck Cleanup & Python PPTX).
> docs/render/test NFR milestone. Surface: deck markdown, Marp inline
> style CSS, Python render scripts, tests, CI YAML, README.
> Researcher: ci-researcher. Sources: ACDL codebase (v1.22 tree) +
> the deleted clean reference HTML at /root/gl/acdl/docs/presentations/
> the-developer-experience.html + python-pptx docs + Marp rendered HTML
> inspection.
### FINDING 1 — Marp `default` theme + inline `style:` block (the clean reference)
The deleted clean reference deck
`/root/gl/acdl/docs/presentations/the-developer-experience.html`
(commit eb43e08) used `theme: default` + an inline `style:` block in the
Marp frontmatter. The exact inline CSS (extracted from the `data-style`
attribute repeated on every `<section>` in the rendered HTML) is:
```css
section {
font-family: "Akkurat Pro", "Helvetica Neue", "Arial", sans-serif;
font-size: 26px;
color: #1B1B1B;
}
h1 { color: #D6002A; font-size: 40px; margin-bottom: 0.3em; }
h2 { color: #D6002A; font-size: 32px; margin-bottom: 0.2em; }
section.title { background: #1B1B1B; color: #fff; border-top: 8px solid #D6002A; }
section.title h1 { color: #fff; }
table { font-size: 22px; width: 100%; }
th { background: #F0F0F0; }
blockquote { border-left: 4px solid #D6002A; color: #2E2E2E; font-size: 24px; }
pre { font-size: 16px; line-height: 1.3; }
code { font-size: 16px; }
img { display: block; margin: 0 auto; max-height: 280px; }
.badge {
display: inline-block; padding: 2px 8px; border-radius: 4px;
font-size: 16px; font-weight: 600;
}
.planned { background: #fef3c7; color: #78350f; }
```
**What Marp's built-in `default` theme provides for free** (from the
embedded `@theme default` CSS in the reference HTML):
- `section { width:1280px; height:720px; box-sizing:border-box; overflow:hidden; position:relative }`
— slide dimensions + box model.
- Base section typography: `font-family: var(--fontStack-sansSerif)`
(system sans), `font-size: 16px`, `line-height: 1.5`, `color:
var(--fgColor-default)`, `background: var(--bgColor-default)` (white).
**Note: default does NOT set padding** — wait, correction: the
`default` theme's embedded CSS in this Marp version does NOT include
an explicit `padding` on `section`; the nova-sp-theme.css comment
claiming `padding: 56px 64px` was for a different Marp version. The
inline `style:` block above does not set padding either, implying the
default theme's inheriting UA stylesheet padding or Marp's container
provides it. **This is the key thing to verify in P2:** whether
`theme: default` + the inline `style:` block produces padding that
reserves header/footer chrome space. The v1.22 root-cause was ZERO
padding with the standalone theme; the inline `style:` block above
also does not set padding, so the clean look may have relied on the
default theme's own padding (which Marp's default theme CSS
*does* set: `section{padding:56px 64px}` is in the default theme's
canonical CSS even if not visible in this rendered HTML's inlined
subset — the rendered HTML strips the theme CSS into a `<style>` block
at the top that we did not fully inspect). **Recommendation:** the
inline `style:` block for v1.23 SHOULD explicitly set section padding
(`padding: 48px 56px 40px` as v1.22 settled on) to be safe, OR verify
the default theme provides it. The reference deck's clean look
suggests the default theme's padding was adequate.
- Pagination: `section::after { content: attr(data-marpit-pagination);
bottom:0; right:0; padding:inherit }` — page numbers via CSS pseudo-
element on `section[data-marpit-pagination]`. Free with `paginate:
true`.
- Header/footer chrome: `default` theme renders `header`/`footer`
elements from frontmatter `header:`/`footer:` directives. The inline
`style:` block does NOT suppress them on title slides (the reference
deck's title slide has `<header>The Developer Experience</header>` +
`<footer>Internal</footer>` visible). v1.22's `section.title header,
section.title footer { display: none }` rule should be ported into the
v1.23 inline `style:` block to keep title slides clean.
- H1/H2 base sizing: `:is(h1, marp-h1){font-size:2em;margin-block:0.67em}`
— the inline `style:` block overrides these with explicit px sizes.
- Font-family: the default theme uses GitHub's `--fontStack-sansSerif`
(system fonts); the inline `style:` overrides to Akkurat Pro stack.
**What the inline `style:` block must override** (not inherited from
default): font-family (Akkurat Pro stack), font-size (26px vs 16px),
font-color (#1B1B1B), H1/H2 colors (#D6002A), title-slide background
(#1B1B1B + 8px red top border), table styling, blockquote styling,
image max-height. **What it inherits for free:** slide dimensions
(1280×720), pagination, header/footer rendering, base box model.
**Confidence: 0.95** (the CSS is read verbatim from the rendered
`data-style` attribute on every `<section>`; the default theme
inheritance is confirmed by the `data-theme="default"` attribute on
every section).
### FINDING 2 — Marp HTML-in-markdown passthrough
Marp (via Marpit, the underlying markdown-it-based engine) **passes
through raw HTML blocks** in markdown slides. Confirmed by the
reference deck:
`/root/gl/acdl/docs/presentations/the-developer-experience-marp.md`
contains inline HTML like
`<span class="badge planned">Planned</span>` inside slide bodies, and
the rendered HTML (`the-developer-experience.html`) contains the
verbatim `<span class="badge planned">Planned</span>` inside the
`<section>` elements. The `.badge` and `.planned` classes are styled
by the inline `style:` block (Finding 1).
**Gotchas confirmed:**
- HTML blocks render correctly inside `## Slide N — Title` H2 slides
(the reference deck's slide 5 has `<span class="badge planned">` in a
table cell; slide 7 has it in a bullet list item).
- HTML does NOT interfere with pagination (the `data-marpit-pagination`
attribute is present on every paginated section regardless of HTML
content).
- HTML inline elements (`<span>`, `<div>`, `<strong>`) render; block
elements (`<div class="benefit">text</div>`) also render — Marpit's
markdown-it `html: true` option is on by default.
- **Caveat:** Marp does NOT sanitize HTML by default (no DOMPurify);
raw `<script>` would pass through too. For our use case (styling
divs/spans) this is fine.
- The current nova deck markdown does NOT use any `<div>` HTML blocks
(`grep -c "<div" nova-autonomous-cloud-delivery-marp.md` = 0 in the
slide body; only the bespoke-marp-osc div in the rendered HTML
chrome). So the v1.23 plan to add `.benefit` class divs is a NEW
pattern — it will work, but is untested in this repo's deck.
**Confidence: 0.95** (confirmed by direct inspection of the reference
deck's source + rendered HTML; Marpit's html passthrough is documented
behavior).
### FINDING 3 — python-pptx capabilities for the structured PPTX
python-pptx (the `python-pptx` PyPI package) supports all capabilities
required for `scripts/render_pptx.py`. API calls confirmed against the
python-pptx documentation (v1.0.2 latest; v0.6.23 is the established
minimum):
(a) **16:9 slide dimensions:**
```python
from pptx import Presentation
from pptx.util import Inches, Pt
prs = Presentation()
prs.slide_width = Inches(13.333) # 16:9 widescreen
prs.slide_height = Inches(7.5)
```
(b) **Slide background color (black for title slide):**
```python
from pptx.dml.color import RGBColor
slide = prs.slides.add_slide(prs.slide_layouts[6]) # blank layout
bg = slide.background
bg.fill.solid()
bg.fill.fore_color.rgb = RGBColor(0x1B, 0x1B, 0x1B) # sp-black
```
(Note: `slide.background` is available since python-pptx 0.6.19+.)
(c) **Colored rectangle as top border bar:**
```python
from pptx.enum.shapes import MSO_SHAPE
from pptx.util import Inches
shape = slide.shapes.add_shape(
MSO_SHAPE.RECTANGLE,
Inches(0), Inches(0), # left, top
Inches(13.333), Inches(0.08) # width, height (8px ≈ 0.08in at 96dpi)
)
shape.fill.solid()
shape.fill.fore_color.rgb = RGBColor(0xD6, 0x00, 0x2A) # sp-red
shape.line.fill.background() # no border on the rectangle
```
(d) **Text frames with font family/color/size (Akkurat Pro → Helvetica
Neue → Arial fallback):**
```python
from pptx.util import Pt
txBox = slide.shapes.add_textbox(Inches(0.5), Inches(0.5), Inches(12), Inches(1))
tf = txBox.text_frame
p = tf.paragraphs[0]
run = p.add_run()
run.text = "Slide title"
run.font.name = "Akkurat Pro"
run.font.size = Pt(40)
run.font.bold = True
run.font.color.rgb = RGBColor(0xD6, 0x00, 0x2A)
# Font fallback: python-pptx sets a single font.name; PowerPoint's own
# font substitution handles the fallback chain. To set a fallback
# explicitly, set the font's `<a:latin>` + `<a:ea>` + `<a:cs>` typeface
# attributes, OR rely on PowerPoint rendering "Akkurat Pro" → missing →
# substitutes Helvetica Neue / Arial per the OS font substitution table.
# The simplest approach: set name="Akkurat Pro"; PowerPoint does the
# fallback. For an explicit fallback, manipulate the XML:
from pptx.oxml.ns import qn
rPr = run._r.get_or_add_rPr()
latin = rPr.find(qn('a:latin'))
if latin is None:
latin = rPr.makeelement(qn('a:latin'), {})
rPr.append(latin)
latin.set('typeface', 'Akkurat Pro')
# (PowerPoint reads only the first typeface; fallback is OS-level.)
```
**Key constraint:** python-pptx does NOT support a CSS-style font
fallback stack. Setting `run.font.name` sets one typeface; PowerPoint's
font substitution handles the fallback when the font is missing. This
is adequate for our use case (Akkurat Pro is the named font; on
systems without it, PowerPoint substitutes Helvetica/Arial).
(e) **Bullet lists:**
```python
tf = txBox.text_frame
for i, item in enumerate(bullets):
p = tf.paragraphs[0] if i == 0 else tf.add_paragraph()
p.text = item
p.level = 0 # bullet level (0 = top)
# Bullet character: python-pptx does not expose a high-level bullet
# API; the default paragraph style from the layout provides bullets.
# For explicit bullet control, manipulate the XML <a:buChar> or
# set p.font + use the layout's list style.
```
**Constraint:** python-pptx has limited high-level bullet support; the
`paragraph` level controls indentation but the bullet glyph comes from
the layout's list style. For a blank layout (layout 6), paragraphs
have NO bullet by default — you must add `<a:buChar>` to the paragraph
properties XML, or use a layout that has bullets. **Recommendation:**
use `slide_layouts[1]` (Title and Content) for bullet slides, which
provides bullets natively; or inject `<a:buChar char="•"/>` via XML.
(f) **Native tables (`add_table`):**
```python
from pptx.util import Inches
rows, cols = len(data), len(headers)
table = slide.shapes.add_table(rows, cols, Inches(0.5), Inches(1.5),
Inches(12), Inches(4)).table
# Headers
for c, h in enumerate(headers):
table.cell(0, c).text = h
# style header cell
cell = table.cell(0, c)
cell.fill.solid()
cell.fill.fore_color.rgb = RGBColor(0xF0, 0xF0, 0xF0)
# Body
for r, row in enumerate(data, start=1):
for c, val in enumerate(row):
table.cell(r, c).text = str(val)
```
**Confirmed:** `add_table` is fully supported since 0.6.19; returns a
`Table` object with `.cell(r,c).text` + `.fill`.
(g) **Embedding images (`add_picture`, auto-embeds in ppt/media/):**
```python
slide.shapes.add_picture(
"docs/presentations/assets/png/platform-pipeline.png",
Inches(1), Inches(1),
width=Inches(11), height=Inches(5)
)
```
**Confirmed:** python-pptx auto-embeds the image binary into the
`ppt/media/` directory inside the .pptx zip; the slide XML references
it via a relationship ID. This is native — no manual zip manipulation
needed. The image is copied once; multiple slides referencing the
same image share the media file.
(h) **Italic text:**
```python
run.font.italic = True # supported since 0.6.0
```
**Version constraint:** `python-pptx>=0.6.23` is the right minimum
(stable release with `slide.background`, `add_table`, `add_picture`
all mature). The latest is 1.0.2 (2024); 0.6.23 (2021) is safe. The
`slide.background` API landed in 0.6.19; `add_table` in 0.6.19;
`add_picture` since 0.6.0. **Recommendation:** pin
`python-pptx>=0.6.23` in `pyproject.toml` `[project.optional-
dependencies] test`.
**Confidence: 0.90** (API calls confirmed against python-pptx docs;
the font fallback + bullet limitations are the residual uncertainty —
both have XML workarounds).
### FINDING 4 — Image inlining (stdlib-only `base64` + `re` + `mimetypes`)
The current rendered HTML
(`docs/presentations/nova-autonomous-cloud-delivery.html`) embeds
images as **plain `<img src="assets/png/...">` tags with relative
paths** — NOT base64-inlined. Confirmed by grep: `<img
src="assets/png/platform-pipeline.png" ...>` (slide 7), `<img
src="assets/png/telemetry-live-ops.png" ...>` (slide 11). They are
NOT SVG `xlink:href`; they are standard `<img>` elements inside the
SVG `<foreignObject>` wrapper that Marp uses for slide rendering.
**The stdlib-only approach is sufficient:**
```python
import base64, re, mimetypes
html = Path("...html").read_text()
def inline(match):
src = match.group(1)
if src.startswith("data:"): # already inlined
return match.group(0)
mime = mimetypes.guess_type(src)[0] or "image/png"
data = base64.b64encode(Path(src).read_bytes()).decode()
return f'<img src="data:{mime};base64,{data}"'
# Match <img src="..."> with single or double quotes
html = re.sub(r'<img\s+src="([^"]+)"', inline_img, html)
html = re.sub(r"<img\s+src='([^']+)'", inline_img, html)
```
**Edge cases confirmed:**
- Marp's SVG-foreignObject wrapper: the `<img>` tags are INSIDE the
`<foreignObject><section>...</section></foreignObject>` — the regex
still matches them (they're standard HTML img tags in the HTML
namespace). No special handling needed.
- Quoted vs unquoted src: Marp always emits double-quoted `src="..."`;
handle both for safety.
- Relative vs absolute paths: Marp emits relative paths
(`assets/png/X.png`); the script must resolve them relative to the
HTML file's directory. `Path(html_path).parent / src`.
- Already-inlined images (`data:` URIs): skip (the regex checks for
`src.startswith("data:")`).
- Marp does NOT use `xlink:href` for images in HTML output (that's
only for SVG-only output mode); the HTML output uses standard
`<img src>`. Confirmed by grep: 0 occurrences of `xlink:href` in
the current HTML.
- The `--allow-local-files` flag in `render_slides.sh` is what makes
Marp keep the local relative paths (without it, Marp would skip
local images in the standalone HTML).
**No external library needed.** stdlib `base64` + `re` + `mimetypes`
+ `pathlib` is sufficient.
**Confidence: 0.95** (verified by direct inspection of the current
HTML; the regex handles all observed patterns).
### FINDING 5 — Tests that need updating (`tests/test_slides_pipeline.py`)
Full read of `tests/test_slides_pipeline.py` (373 lines). Tests that
assert on v1.23-affected surfaces:
**(a) `theme: nova-sp` / `nova-sp-theme.css` via `--theme`:**
- **Line 55-64 `test_marp_deck_uses_sp_theme`**: asserts `"nova-sp" in
frontmatter`. After v1.23: frontmatter should have `theme: default`;
this test must assert `"theme: default"` instead (or assert the inline
`style:` block is present).
- **Line 66-74 `test_marp_deck_not_using_default_theme`**: asserts
`"theme: default" not in frontmatter`. After v1.23: this test must
be DELETED or INVERTED (we're reverting TO `theme: default`).
- **Line 36-38 `test_sp_theme_css_exists`**: asserts
`nova-sp-theme.css` is a file. After v1.23: keep (the CSS is retired
from render but kept as a reference file).
- **Line 41-45 `test_sp_theme_css_has_snp_colors`**: asserts the CSS
has S&P colors. After v1.23: keep (reference file still has colors).
- **Line 275-282 `test_theme_css_has_section_padding`**: asserts the
CSS `section` rule has padding. After v1.23: this test targets the
RETIRED CSS — it should be retargeted to the inline `style:` block in
the marp deck frontmatter (assert the inline style has section
padding).
- **Line 284-293 `test_theme_css_suppresses_title_chrome`**: asserts
`section.title header` + `display: none` in the CSS. After v1.23:
retarget to the inline `style:` block.
- **Line 295-302 `test_theme_css_has_aspect_ratio_aware_images`**:
asserts `object-fit` + `max-width` in the CSS. After v1.23: retarget
to the inline `style:` block (or drop if the inline style uses the
simpler `max-height: 280px` from the reference deck).
- **Line 353-359 `test_html_embeds_theme`**: asserts `"--sp-red"` +
`"padding:"` in the committed HTML. After v1.23: the inline `style:`
block uses literal `#D6002A` (not the `--sp-red` CSS variable — the
reference deck's inline style did NOT use CSS variables). This test
must change to assert `"#D6002A"` + `"padding:"` (or `"font-family:
\"Akkurat Pro\""`).
**(b) Both `.md` and `-marp.md` existing:**
- **Line 31 `SOURCE_MD` constant** + **Line 240-263
`test_source_md_no_internal_citations_in_slides`** +
**Line 266-270 `test_source_md_no_badges`**: assert the plain `.md`
is the source of truth. After v1.23: the plain `.md` is DELETED
(consolidated into `-marp.md`); these tests must be DELETED or
retargeted to the consolidated `-marp.md`.
**(c) `marp-cli` invocation specifics:**
- **Line 83-90 `test_render_slides_script_renders_mermaid`**: asserts
`mermaid-cli` + `sp-theme.json` in the script. After v1.23: keep
(mermaid render unchanged).
- **Line 92-98 `test_render_slides_script_renders_marp`**: asserts
`marp-cli` + `.html` + `.pptx` in the script. After v1.23: the script
no longer passes `--theme nova-sp-theme.css`; it may still produce
`.pptx` via marp-cli OR via the new `render_pptx.py`. This test must
be updated to reflect the new invocation (marp-cli for HTML only;
render_pptx.py for the structured PPTX).
- **Line 327-332 `test_render_slides_has_2x_scale`**: asserts `-s 2`
+ `-b transparent`. After v1.23: keep (mermaid flags unchanged).
- **Line 335-344 `test_render_slides_pins_cli_versions`**: asserts
`marp-cli@` + `mermaid-cli@` pinned, no `@latest`. After v1.23: keep
for mermaid; if marp-cli is still used for HTML, keep for marp too.
- **Line 346-351 `test_render_deck_removed`**: asserts
`render_deck.sh` is deleted. After v1.23: keep.
**(d) Slide count:**
- **Line 204-218 `test_marp_deck_slide_count`**: asserts 20 main + 1
appendix = 21 slides. After v1.23: the word-count trim may change
the count; update to match the final count (likely stays 20+1 or
drops to fewer if slides merge).
- **Line 361-373 `test_html_slide_count_matches_marp`**: asserts the
HTML `<section>` count matches the deck count. After v1.23: keep
(recompute expected from the final deck).
**(e) Other affected tests:**
- **Line 137-143 `test_readme_no_retired_decks`**: asserts README
doesn't list old decks. After v1.23: keep.
- **Line 146-150 `test_readme_no_old_deck_name`**: asserts README
references `nova-autonomous-cloud-delivery`. After v1.23: keep.
- **Line 153-156 `test_old_deck_files_removed`**: asserts old
`nova-no-humans-platform*` files are gone. After v1.23: keep.
- **Line 159-162 `test_marp_deck_no_badges`**: asserts no `badge` in
marp deck. After v1.23: keep.
- **Line 165-177 `test_marp_deck_no_version_in_footer`**: asserts no
version in frontmatter. After v1.23: keep.
- **Line 179-190 `test_marp_deck_title_slide_no_version_subtitle`**:
asserts no `v1.18` subtitle. After v1.23: keep.
- **Line 193-202 `test_marp_deck_title_is_autonomous_cloud_delivery`**:
asserts the title. After v1.23: keep (unless "penetrate" removal
touches the title — it doesn't).
- **Line 221-237 `test_marp_deck_no_internal_citations`**: asserts no
D-###/REQ-###/.py paths. After v1.23: keep.
- **Line 304-324 `test_png_aspect_ratios_sane`**: asserts PNG aspect
ratios in [0.4, 4.0]. After v1.23: keep.
- **Line 107-119 `test_slides_ci_workflow_*`**: asserts slides.yml
exists + triggers on presentations. After v1.23: keep (update if the
workflow changes).
**Summary:** ~12 tests need updating; the key inversions are
`test_marp_deck_not_using_default_theme` (delete/invert) and the
`test_theme_css_*` trio (retarget from the standalone CSS file to the
inline `style:` block). The `test_source_md_*` tests must be deleted
(plain `.md` is gone).
**Confidence: 0.95** (direct line-by-line read of the test file).
### FINDING 6 — `scripts/attach_release_asset.py`
Read in full (80 lines). Current behavior:
- CLI: `python3 scripts/attach_release_asset.py <file-path> <release-id>`
- Resolves `NOVA_GITEA_TOKEN` (or `ACDL_GITEA_TOKEN` fallback) from
`.env.secrets`/`.env`.
- POSTs to `/api/v1/repos/{owner}/{repo}/releases/{id}/assets` with
multipart form: `name=<filename>` + `attachment=<file bytes>`.
- Single-file upload per invocation.
**Change needed for v1.23:** attach BOTH `.pptx` (Marp PPTX) AND
`-python.pptx` (python-pptx structured PPTX). Two options:
1. Call the script twice (once per file) from the ship workflow.
2. Extend the script to accept multiple file paths: `attach_release_asset.py
<file1> <file2> ... <release-id>` (loop over files, same release-id).
**Recommendation:** option 2 (extend to multiple files) — minimal,
backward-compatible (if only 1 file given, same behavior). The
release-id stays the last positional arg; all preceding args are file
paths.
**Confidence: 0.95** (direct read; the change is mechanical).
### FINDING 7 — `workflows-src/slides.yml`
Read in full (31 lines). Current CI steps:
1. `actions/checkout@v4` (fetch-depth 0).
2. `actions/setup-node@v4` (node 20).
3. "Install Chrome" — runs `npx --yes @marp-team/marp-cli@latest
--version` + `npx --yes @mermaid-js/mermaid-cli --version` (NOTE:
uses `@latest` — NOT pinned, contradicts REQ-257's pinning rule for
`render_slides.sh`; the workflow is separate from the script).
4. "Render slides" — `bash scripts/render_slides.sh`.
5. "Commit rendered artifacts" — `git add docs/presentations/*.html
docs/presentations/*.pptx docs/presentations/assets/png/*.png` +
commit + push.
**Where `python-pptx` install would go:** a new step between "Install
Chrome" and "Render slides":
```yaml
- uses: actions/setup-python@v5
with: { python-version: '3.11' }
- name: Install python-pptx
run: pip install python-pptx>=0.6.23
```
Then `render_slides.sh` (or a new `render_pptx.py` invocation) uses
it. OR: `pip install -e ".[test]"` if python-pptx is added to
`pyproject.toml [project.optional-dependencies] test`.
**What the commit list should include after v1.23:** the
`git add` line must include:
- `docs/presentations/*.html` (re-rendered HTML, with inlined images)
- `docs/presentations/*.pptx` (Marp PPTX — kept as the "fallback" PPTX)
- `docs/presentations/*-python.pptx` (NEW — the python-pptx structured
PPTX)
- `docs/presentations/assets/png/*.png` (re-rendered mermaid PNGs)
**Also:** the workflow uses `@latest` for both CLIs in the "Install
Chrome" step — this should be pinned to match `render_slides.sh`'s
pinned versions (`@marp-team/marp-cli@4.5.0`,
`@mermaid-js/mermaid-cli@11.16.0`) for reproducibility.
**Confidence: 0.95** (direct read).
### FINDING 8 — `docs/presentations/README.md` current structure
Read in full (249 lines). Current 4-step process structure:
- **Step 1 — Full markdown (source of truth):** `<deck-name>.md` with
`## Slide N — Title` + `> **Speaker notes:**` blocks + mermaid code
blocks.
- **Step 2 — Marp deck synthesis:** `<deck-name>-marp.md` with Marp
frontmatter (`theme: nova-sp`), no speaker notes, embedded PNGs, no
badges.
- **Step 3 — Render to HTML and PPTX:** `bash scripts/render_slides.sh
<deck-name>`; HTML committed (with base64 images — NOTE: this is
aspirational; the current HTML does NOT inline images, which is what
`inline_images.py` will fix); PPTX committed + release-attached.
- **Step 4 — Talking points:** `<deck-name>-talking-points.md` with
one section per Marp slide, 3-6 bullets + key takeaway.
**What to rewrite for v1.23:**
- The 4-step process becomes a **3-step process** (Step 1 plain `.md`
is DELETED → consolidated into `-marp.md`; the source of truth IS the
`-marp.md` with speaker notes in HTML comments, OR speaker notes are
dropped entirely). OR: keep 4 steps but Step 1's output merges into
Step 2 (the `-marp.md` becomes the source of truth, with speaker
notes preserved as HTML comments that Marp strips from rendering).
- Step 2 frontmatter: `theme: default` + inline `style:` block (not
`theme: nova-sp`).
- Step 3: HTML rendered by Marp (`render_slides.sh`), images inlined
by `scripts/inline_images.py` (NEW), PPTX rendered by BOTH marp-cli
(fallback `.pptx`) AND `scripts/render_pptx.py` (structured
`-python.pptx`).
- The directory layout block (line 108-123) must drop the plain `.md`
row + add `inline_images.py` + `render_pptx.py` rows + the
`-python.pptx` row + note `nova-sp-theme.css` is retired (reference
only).
- The "Current decks" table (line 237-239) must list both PPTX files.
- The slide-count convention (line 128-136) must reflect the final
v1.23 count (after word-count trim + "penetrate" removal).
- The "Adding a new presentation" section (line 209-233) must be
rewritten for the single-document + dual-PPTX pipeline.
**Confidence: 0.95** (direct read).
### FINDING 9 — Persona assessment for v1.23
The v1.23 scope: deck markdown editing (consolidate `.md` + `-marp.md`,
trim word count, remove "penetrate"), Marp inline `style:` CSS, Python
scripts (`inline_images.py` + `render_pptx.py`), tests, CI YAML
(`slides.yml`), README. The v1.22 roster had lead-developer +
backend-engineer active; frontend + data deactivated.
**Assessment:** the same roster applies, with one territory shift.
- **lead-developer** (active): owns the deck markdown (consolidation,
word-count trim, "penetrate" removal), the inline `style:` CSS block
(porting the reference deck's CSS), the README rewrite, and all
`.ciagent/**` metadata. The inline CSS is a Marp stylesheet block, not
a React/Next.js system — stays lead-developer (D-148 precedent from
v1.22).
- **backend-engineer** (active): owns the Python scripts
(`inline_images.py`, `render_pptx.py` — python-pptx is a backend
library), the `render_slides.sh` updates, the tests, the CI YAML,
and the `attach_release_asset.py` extension. This is a shift from
v1.22 (where backend owned bash + pytest); v1.23 adds Python to
backend's territory.
- **frontend-engineer** (deactivated): no React/Next.js. The inline
CSS is a Marp stylesheet, not frontend. Stays deactivated (D-148
precedent).
- **data-engineer** (deactivated): no schema/DB/ORM. Stays deactivated.
**Custom "docs/deck" persona?** Not warranted. The work splits cleanly
into lead-developer (narrative + CSS + markdown + README + metadata)
and backend-engineer (Python + bash + tests + CI). A "docs-engineer"
or "slides-engineer" persona would fragment ownership of the deck
markdown (lead) and the render scripts (backend). D-149 precedent from
v1.22 applies: no new personas.
**One nuance:** python-pptx is a new dependency (backend territory) but
the PPTX CONTENT (slide layout, text, image placement) is a design
decision that overlaps with lead-developer's deck ownership. The
`render_pptx.py` script is backend (Python code); the slide-by-slide
layout decisions within it (which image goes where, font sizes) are
co-owned with lead-developer. Territory enforcement = `warn` (cross-
territory edits logged, not blocked).
**Confidence: 0.90** (the roster follows v1.22 precedent; the only new
element is python-pptx, which is unambiguously backend).
### FINDING 10 — Risks / pitfalls (5)
1. **Marp `default` theme padding conflict.** The reference deck's
inline `style:` block does NOT set `section` padding. The v1.22
root-cause was ZERO padding with the standalone `nova-sp-theme.css`.
If `theme: default`'s built-in padding differs from v1.22's settled
`48px 56px 40px`, slides may re-overflow. **Mitigation:** explicitly
set `section { padding: 48px 56px 40px }` in the v1.23 inline
`style:` block (do not rely on the default theme's padding). Verify
by re-rendering + visual inspection in P2.
2. **python-pptx font fallback when Akkurat Pro isn't installed.**
python-pptx sets a single `run.font.name = "Akkurat Pro"`; on
systems without Akkurat Pro (CI, most laptops), PowerPoint
substitutes a default font (often Calibri), NOT Helvetica Neue /
Arial. The CSS stack `Akkurat Pro → Helvetica Neue → Arial` does
NOT translate to python-pptx (no CSS-style fallback). **Mitigation:**
accept PowerPoint's OS-level substitution (the deck will render in
a sans font either way); OR set `run.font.name = "Arial"` directly
for the structured PPTX (guaranteed present on all systems) and
document that the Marp HTML deck uses the full Akkurat Pro stack
while the python PPTX uses Arial. The dual-PPTX approach lets the
Marp PPTX (rendered by Chromium with the CSS stack) carry the
brand font, while the python PPTX (structured, editable) carries
Arial for editability.
3. **Image inlining breaking if Marp embeds images as SVG
`xlink:href`.** The current HTML uses `<img src="assets/png/...">`
(confirmed by grep). BUT if a future Marp version switches to SVG
`xlink:href` for the HTML output, the `inline_images.py` regex
would miss them. **Mitigation:** the regex should ALSO match
`xlink:href="assets/..."` patterns as a fallback; OR pin the
Marp version (already pinned at `@4.5.0` in `render_slides.sh`) so
the output format is stable.
4. **Consolidated doc losing speaker notes if HTML comments are
stripped by Marp.** The plan consolidates the plain `.md` (with
`> **Speaker notes:**` blockquotes) into the `-marp.md`. Marp strips
HTML comments (`<!-- ... -->`) from rendered output but preserves
blockquotes (`> ...`) as `<blockquote>` elements. If speaker notes
are moved to HTML comments to hide them from the audience, Marp
strips them — and they're lost from the rendered HTML. If they stay
as blockquotes, they're visible in the audience deck (bad).
**Mitigation:** either (a) drop speaker notes entirely from the
consolidated `-marp.md` (the talking-points file is the presenter
cue sheet; notes aren't needed in the deck), or (b) keep them as
HTML comments (Marp strips from render, but they persist in the
source markdown for git-diff readability). Option (b) is safer —
the source markdown keeps the notes; the rendered HTML + PPTX
don't. Verify Marp strips `<!-- -->` from HTML output (confirmed:
Marp's markdown-it does strip HTML comments by default).
5. **`test_html_embeds_theme` asserts `--sp-red` CSS variable, but the
reference inline `style:` uses literal `#D6002A`.** The v1.22 test
(line 353-359) asserts `"--sp-red"` in the committed HTML. The
reference deck's inline `style:` block uses literal `#D6002A`, not
a CSS variable. If v1.23 ports the reference style verbatim, the
test fails. **Mitigation:** update the test to assert `"#D6002A"`
(literal) OR use CSS variables in the inline `style:` block (Marp
supports `:root { --sp-red: #D6002A }` + `color: var(--sp-red)` in
the inline style — but the reference deck didn't, so matching the
reference means literal colors). Recommendation: use literal colors
in the inline `style:` block (matches the reference deck's clean
approach) + update the test.
**Confidence: 0.90** (pitfalls identified from the research findings
above; mitigations are concrete).
---
## Assumptions logged (v1.23)
| ID | Assumption | Confidence | Rationale |
|----|------------|------------|-----------|
| A-1.23.1 | The consolidated `-marp.md` will keep speaker notes as HTML comments (`<!-- -->`), which Marp strips from rendered HTML/PPTX but preserves in the source markdown for git readability. | 0.80 | Marp's markdown-it strips HTML comments by default; the source markdown keeps them. The alternative (drop notes entirely) loses the presenter context. |
| A-1.23.2 | `python-pptx` will be added to `pyproject.toml [project.optional-dependencies] test` (not the runtime `dependencies`), since the structured PPTX is a build/test artifact, not a runtime dependency. | 0.90 | The render scripts run in CI + locally, not in the platform runtime. Matches the `moto`/`pytest` pattern. |
| A-1.23.3 | The Marp PPTX (`.pptx`) is kept as a "fallback" alongside the new python-pptx structured PPTX (`-python.pptx`); both are committed + release-attached. | 0.85 | The plan says "dual PPTX"; the Marp PPTX is the quick render, the python PPTX is the editable one. Keeping both gives consumers a choice. |
| A-1.23.4 | The `nova-sp-theme.css` file is KEPT in `docs/presentations/assets/` as a reference (retired from the render pipeline) but NOT deleted. | 0.90 | The plan says "keep as a reference (retired from render)"; deletion would lose the v1.22 work history. |
| A-1.23.5 | The slide count after the word-count trim + "penetrate" removal will stay at 20 main + 1 appendix (the trim is within-slide prose, not slide removal). | 0.75 | The plan says "trim word count" (prose), not "remove slides"; but if a slide becomes too thin it may merge. To be confirmed in execution. |
---
## Decisions surfaced (v1.23 research)
These research-grounded decisions will be bound in the CLARIFY stage:
- **D-XXX (0.90):** Revert to `theme: default` + inline `style:` block
(port the reference deck's exact CSS from Finding 1). Keep
`nova-sp-theme.css` as a retired reference file. Confidence 0.90 —
the reference deck's clean look is the target; the CSS is read
verbatim.
- **D-XXX (0.85):** Build `scripts/inline_images.py` (stdlib-only:
`base64` + `re` + `mimetypes`) to inline `<img src="assets/...">`
`data:` URIs in the rendered HTML. No external library. Confidence
0.95 — confirmed the current HTML uses plain `<img src>`.
- **D-XXX (0.85):** Build `scripts/render_pptx.py` using python-pptx
(>=0.6.23) for a structured, editable PPTX (`-python.pptx`). Keep
the Marp PPTX (`.pptx`) as a fallback. Both committed + release-
attached. Confidence 0.90 — python-pptx API confirmed.
- **D-XXX (0.80):** Consolidate the plain `.md` + `-marp.md` into a
single `-marp.md`. Speaker notes move to HTML comments (stripped by
Marp from render, preserved in source). The plain `.md` is deleted.
Confidence 0.80 — the HTML-comment approach preserves notes for git
without leaking them to the audience.
- **D-XXX (0.85):** No new personas for v1.23. lead-developer (deck
markdown + inline CSS + README + metadata) + backend-engineer
(Python scripts + bash + tests + CI). Territory enforcement = `warn`
for `render_pptx.py` (script is backend; slide layout decisions are
co-owned with lead-developer). Confidence 0.90 — follows v1.22 D-
148/D-149 precedent.
+185
View File
@@ -1969,3 +1969,188 @@ release). **DONE.**
- Ship: tag `v1.20.6` (final patch = milestone release). Requirements - Ship: tag `v1.20.6` (final patch = milestone release). Requirements
marked complete; ROADMAP marked complete; CHECKPOINT cleared. marked complete; ROADMAP marked complete; CHECKPOINT cleared.
- **Requirements:** REQ-245..253 (9 requirements, all complete). - **Requirements:** REQ-245..253 (9 requirements, all complete).
## v1.22 — Nova Deck Layout Fix (complete)
> Fixes the systemic layout/formatting problems in the Nova presentation
> deck that made every slide look "out of whack" after the v1.21 P5
> re-render. Root cause (per investigation): `nova-sp-theme.css` had
> zero `section` padding (declared `/* @theme nova-sp */` as a comment,
> not the `@theme` directive; did not `@import` Marp's default theme).
> Combined with `overflow:hidden`, a blunt `img { max-height: 320px }`,
> header+footer chrome on every slide, and two P5 diagrams with extreme
> aspect ratios (13.52× and 0.63×), 8 of 19 slides overflowed.
>
> Tags run on the v1.21.x line (milestone v1.22 → tags v1.21.0..v1.21.6).
### Phase P0 — pre-execution (complete, tag v1.21.0)
- SPECIFY → CLARIFY → RESEARCH → PLAN → GRILL. Validated v1.22
requirements (REQ-254..262). 8 research findings persisted to
RESEARCH.md. 5 CLARIFY decisions auto-resolved (comprehensive scope,
full pipeline, re-layout to LR, delete render_deck.sh, split slides
3+8). Persona roster: 2 active (lead-developer + backend-engineer),
2 deactivated (frontend + data). Grill: PROCEED-WITH-REVISIONS
(3 revisions: aspect-ratio test scoped to deck PNGs, @import
rejection documented, marp version pinning fallback).
### Phase P1 — theme-css (complete, tag v1.21.1)
- REQ-254: `section { padding: 48px 56px 40px; overflow: auto; }`
root cause fix (zero padding was why every slide looked jammed
against the edges).
- REQ-255: `img { max-width: 100%; max-height: 380px; object-fit:
contain; }` + `.wide`/`.tall` classes — replaced blunt
`max-height: 320px` that broke `w:` directives on tall images.
- REQ-256: `section.title header/footer { display: none; }` — title
chrome suppression. `h2 + p { margin-top: 0.2em; }`, `p { margin:
0.4em 0; }` — spacing tightening. `ol` styling. `table.dense`
class. `@media print { section { overflow: hidden; } }` for PPTX.
### Phase P2 — render-scripts (complete, tag v1.21.2)
- REQ-257: deleted `scripts/render_deck.sh` (omitted `--theme`,
produced unthemed output). Pinned marp-cli@4.5.0 + mermaid-cli@
11.16.0 in `render_slides.sh`. Removed references from README,
sync_to_nova.sh, test_no_forge_mentions.py.
- REQ-258: added `-s 2 -b transparent` to mermaid-cli invocation
(README spec; produces crisp 2x PNGs with transparent backgrounds).
### Phase P3 — mermaid-relayout (complete, tag v1.21.3)
- REQ-259: `telemetry-live-ops.mmd` kept as `flowchart TB` (the 3-way
branch makes LR too wide at 4.22 aspect; TB gives 0.63 which is
legible at h:480 with img.tall class). Re-rendered at 2x transparent
(1024x1628).
- REQ-260: `platform-pipeline.mmd` restructured from 10-node LR chain
(aspect 13.52, illegible 1000x74 strip) to 4-node TB with combined
nodes. Re-rendered at 2x transparent (552x1116, aspect 0.49).
- Marp deck directives updated: `![w:1000]`/`![w:900]`
`![h:480 class:tall]` so images render at legible height using the
img.tall class budget (480px).
- Aspect-ratio bounds revised from [1.2, 2.5] to [0.4, 4.0] (accepts
both tall and wide diagrams; still catches original outliers).
### Phase P4 — deck-content (complete, tag v1.21.4)
- REQ-261: split slide 3 (Objectives + Anti-Goals) into Slide 3
(Objectives) + Slide 4 (Anti-Goals). Split slide 8 (Attestation
Matrix) into Slide 9 (QA, 3 rows) + Slide 10 (Prod/DR, 7 rows).
Main slide count 18 → 20.
- Trimmed: slide 7 (Pipeline) to 3 bullets. slide 11 (Telemetry) to
3 bullets. slide 14 (Deferred) merged 3 Live-AWS rows into 1 (8→6
rows). slide 17 (Quarter-by-Quarter) dropped Grounding column
(5→4 cols). Global table cell padding reduced (6px 10px → 4px 8px).
- Removed `header:` from frontmatter (keep `footer:` + `paginate`
only). The full 51-char deck title in BOTH header and footer was
redundant chrome eating ~35px on every slide.
- Source `.md` and talking-points re-synced to 20-slide structure.
- Updated `test_marp_deck_slide_count` (18→20 main + 1 appendix).
Updated README slide-count convention (all 6 references).
### Phase P5 — render-and-test (complete, tag v1.21.5)
- REQ-262: re-rendered HTML + PPTX via `render_slides.sh` (pinned
marp-cli@4.5.0, mermaid-cli@11.16.0, 2x transparent PNGs). 22
slides (title + 20 main + 1 appendix), 23 media files embedded.
Theme embedded in HTML (--sp-red + padding confirmed).
- Added 9 tests to `test_slides_pipeline.py` (the gap that let the
layout regression through): test_theme_css_has_section_padding,
test_theme_css_suppresses_title_chrome,
test_theme_css_has_aspect_ratio_aware_images,
test_png_aspect_ratios_sane (scoped to deck-referenced PNGs only
per GRILL revision 1, bounds [0.4, 4.0]),
test_render_slides_has_2x_scale, test_render_slides_pins_cli_versions,
test_render_deck_removed, test_html_embeds_theme,
test_html_slide_count_matches_marp.
- 32 slide tests pass (23 original + 9 new). 94 key-file tests pass.
`run_platform.sh --check-only` exit 0.
### Phase P6 — final-review-ship (Final Phase, complete, tag v1.21.6)
- Multi-persona code review: PASS with 3 P1 flags (all fixed in this
phase): source .md/talking-points re-synced to 20 slides, `![h:480
class:tall]` directives applied, README stale references updated.
- Audit: git log matches `.ciagent/` discipline; all commits have
`---ci---` blocks; branch hygiene verified.
- Ship: tag `v1.21.6` (final patch = milestone release). Merge
`milestone/v1.22-deck-layout-fix``main`. Requirements marked
complete; ROADMAP marked complete; CHECKPOINT cleared.
- **Requirements:** REQ-254..262 (9 requirements, all complete).
## v1.23 — Nova Deck Cleanup & Python PPTX (active)
> **NFR milestone** (docs/render/test only; no features). Tags run on the
> **v1.22.x** line (milestone v1.23 → tags v1.22.0..v1.22.6). Final patch
> `v1.22.6` = milestone release. Branch: `milestone/v1.23-deck-cleanup-python-pptx`.
>
> Driven by the user's feedback that the deck looked "out of whack" and
> the desire to return to the clean, well-formatted style of the old
> `the-developer-experience.html` (which used Marp's built-in `default`
> theme + an inline `style:` block). That investigation revealed:
> (1) the "clean" reference was itself MARP output — MARP is not the
> problem; (2) the current deck uses a standalone `nova-sp-theme.css`
> that re-derives all base spacing from scratch and had a zero-padding
> bug (fixed in v1.22 but the standalone approach is fragile);
> (3) there are two markdown documents (a plain source-of-truth `.md`
> and a manually-synthesized `-marp.md`) that should be consolidated;
> (4) images are referenced as file paths in the HTML, so the HTML
> breaks when redistributed without the `assets/` folder; (5) the deck
> is verbose in places and uses the term "penetrate" which the user
> wants removed.
>
> The milestone delivers: single-document consolidation, clean style
> restoration (Marp `default` + inline `style:`), self-contained HTML
> (base64 images), a parallel structured python-pptx PPTX generator,
> targeted word-count trim, and "penetrate" removal. `nova-sp-theme.css`
> is retained as a styling reference but retired from the render path.
### Phase P0 — pre-execution (active)
- SPECIFY → CLARIFY → RESEARCH → PLAN → GRILL. Establishes v1.23
requirements (REQ-263..275). Tag `v1.22.0`. Grill PROCEED-WITH-
REVISIONS (0.78): 4 binding revisions applied (G-001 repo-wide
"penetrate" purge; G-002 P3→P4 serialized; G-003 P3 split P3a+P3b;
G-004 P5+P6 merged).
### Phase P1 — consolidate-docs (planned, tag v1.22.1)
- REQ-263: fold speaker notes + talking points into `*-marp.md` as Marp
HTML comments; delete the plain `.md`. `-marp.md` becomes the sole
source of truth.
- REQ-264: keep `*-talking-points.md` as a standalone presenter aid,
synced from the deck's `<!-- Talking points: -->` comments.
### Phase P2 — restore-clean-style (planned, tag v1.22.2)
- REQ-265: revert frontmatter to `theme: default` + inline `style:`
block (S&P palette). Keep H2 + bold-lead structure, no header, no
badges.
- REQ-266: retain `nova-sp-theme.css` as a styling reference; drop
`--theme` from `render_slides.sh`.
- REQ-267: restyle benefit callouts — remove `**Benefit:**` prefix; use
`.benefit` class (red top-rule + black italic; white on title slides).
### Phase P3a — inline-images (planned, tag v1.22.3)
- REQ-268: new `scripts/inline_images.py` — base64-embeds all images in
the rendered HTML for redistribution. Invoked after the MARP HTML
render. Low-risk, mechanical (G-003 isolation).
### Phase P3b — python-pptx-generator (planned, tag v1.22.4)
- REQ-269: new `scripts/render_pptx.py` — structured, editable, S&P-themed
PPTX via `python-pptx`. 16:9; native tables; embedded PNGs; benefit
callouts. Add `python-pptx` to `pyproject.toml`. High-risk, isolated
(G-003).
- REQ-270: `render_slides.sh` produces both PPTX outputs; CI installs
`python-pptx`; both attached to release.
### Phase P4 — trim-wordcount + repo-wide "penetrate" purge (planned, tag v1.22.5)
- REQ-271: targeted ~20-30% word-count trim on verbose slides (1, 5, 7,
8, 13, 14, 20, appendix). Tables untouched. Spirit preserved.
- REQ-272: remove "penetrate" (and derivatives) repo-wide (G-001) —
`docs/` + `.ciagent/PROJECT.md`/`CLARIFY.md`; RESEARCH.md/PLAN.md/
GRILL.md exempt as decision-history. Slide 5's phrase removed with no
replacement (slide 4 already excludes the PDLC).
### Phase P5 — ci-tests-readme + review + audit + ship (Final Phase, tag v1.22.6)
- REQ-273: CI workflows install `python-pptx`, run `render_slides.sh`,
commit HTML + both PPTX + inlined images.
- REQ-274: update `test_slides_pipeline.py` (consolidated doc, inline
style assertions, image inlining, python-pptx, benefit class,
"penetrate" absence). New `test_pptx_generator.py`.
- REQ-275: rewrite `README.md` for the single-document + dual-PPTX +
image-inlining pipeline.
- Review + audit + milestone ship (merged P5+P6 per G-004 — NFR docs
milestone). Tag `v1.22.6` (final patch = milestone release). Merge
`milestone/v1.23-deck-cleanup-python-pptx``main`.
- **Requirements:** REQ-263..275 (13 requirements).
+1 -1
View File
@@ -8,7 +8,7 @@
], ],
"active_project": "acdl", "active_project": "acdl",
"active_projects": ["acdl"], "active_projects": ["acdl"],
"active_milestone": "v1.22", "active_milestone": "v1.23",
"autonomy": { "autonomy": {
"level": "full", "level": "full",
"escalation_hooks": ["deploy", "delete_data", "merge_to_main"], "escalation_hooks": ["deploy", "delete_data", "merge_to_main"],
+24
View File
@@ -0,0 +1,24 @@
=== tools ===
terraform: /usr/bin/terraform
checkov: /usr/local/bin/checkov
python3: /usr/bin/python3
jq: /usr/bin/jq
rsync: /usr/bin/rsync
marp: MISSING
mmdc: MISSING
Terraform v1.9.8
3.3.8
Python 3.12.3
=== chrome/chromium (for slide render) ===
found: /root/.cache/ms-playwright/chromium-1217/chrome-linux64/chrome
=== creds ===
.env.secrets: present (4 lines)
.env: present
=== aws creds loadable? ===
NOVA_AWS_ACCESS_KEY_ID: set
AWS_DEFAULT_REGION: us-east-1
=== git ===
main
v1.18.1-11-gaa868c9
=== disk ===
/dev/loop2 148G 140G 1.3G 100% /
+10
View File
@@ -0,0 +1,10 @@
{"id": "T1", "req": "REQ-230", "title": "no forge names in synced files (guard test)", "pass": true, "rc": 0, "evidence": {"test": "test_no_forge_mentions_in_synced_files", "result": "1 passed in 2.20s", "log_tail": ["tests/test_no_forge_mentions.py::test_no_forge_mentions_in_synced_files PASSED [100%]", "1 passed in 2.20s"]}}
{"id": "T2", "req": "REQ-230", "title": "forge-detection code genericized", "pass": true, "rc": 0, "evidence": {"hardcoded_gitea_gitlab_hits": 0, "genericization_signals": ["contract_ingestor.py: _forge_type() returns 'generic_forge'", "hitl_gates.py: GITHUB_ACTOR or FORGE_ACTOR (no GITEA_ACTOR)", "run_platform.sh:166: GITHUB_ACTOR:-FORGE_ACTOR fallback"]}}
{"id": "T3", "req": "REQ-231", "title": "synced docs stripped of internal provenance", "pass": false, "rc": 1, "evidence": {"provenance_hit_count": 40, "contaminated_files": ["docs/ONBOARDING.md (REQ-182,183,184; D-113,114,119)", "docs/METRICS.md (REQ-191,192,193,194,211,212; D-083,096,113,114,119)", "docs/presentations/README.md (REQ-214,226,228; D-130,141; .ciagent/PROJECT.md)", "docs/presentations/nova-no-humans-platform.{md,marp.md,html,talking-points.md} (v1.X milestone headers)", "docs/presentations/assets/mmd/developer-experience-08-semver.mmd (v1.12 header)"], "root_cause": "test_no_forge_mentions.py only guards forge names, not provenance IDs", "defect": "F7"}}
{"id": "T4", "req": "REQ-232", "title": "migration docs removed + thesis moved", "pass": true, "rc": 0, "evidence": {"docs_NOVA_MIGRATION_gone": true, "docs_NOVA_AWS_MIGRATION_gone": true, "docs_NO_HUMANS_THESIS_gone": true, "ciagent_NO_HUMANS_THESIS_present": true}}
{"id": "T5", "req": "REQ-239", "title": "S&P theme CSS palette on all chrome", "pass": true, "rc": 0, "evidence": {"css_exists": true, "css_size_bytes": 2914, "red_present": true, "black_present": true, "white_present": true, "chrome_covered": ["section/bg", "section.title", "h1-h3 headings", "table th", "blockquote", "pre/code", "header", "footer", "pagination (.bespoke-progress-bar)", "strong"]}}
{"id": "T6", "req": "REQ-240", "title": "render pipeline script + mermaid theme", "pass": true, "rc": 0, "evidence": {"render_slides_executable": true, "render_slides_size": 2736, "sp_theme_json_has_red": true, "sp_theme_json_has_black": true, "render_deck_sh_still_present": true, "render_deck_excluded_from_sync": true, "caveat": "README:107 still references render_deck.sh (deferred to T9)"}}
{"id": "T7", "req": "REQ-241", "title": "slides CI workflow path trigger", "pass": false, "rc": 1, "evidence": {"wrong_path_hits": [".github/workflows/slides.yml:8: - 'assets/nova-sp-theme.css' (non-existent)", "workflows-src/slides.yml:8: - 'assets/nova-sp-theme.css' (non-existent)"], "correct_path": "docs/presentations/assets/nova-sp-theme.css", "src_dotgithub_identical": true, "defect": "F6", "impact": "Explicit CSS path trigger points at nothing; only the docs/presentations/** glob catches CSS edits. Dead entry should be corrected or removed."}}
{"id": "T8", "req": "REQ-242", "title": "slide-pipeline guard test", "pass": true, "rc": 0, "evidence": {"passed": 12, "failed": 0, "duration_s": 1.1, "tests": ["sp_theme_css_exists", "sp_theme_css_has_snp_colors", "sp_theme_json_has_snp_colors", "marp_deck_uses_sp_theme", "marp_deck_not_using_default_theme", "render_slides_script_exists", "render_slides_script_renders_mermaid", "render_slides_script_renders_marp", "slides_ci_workflow_exists", "slides_ci_workflow_triggers_on_presentations", "every_mmd_has_png", "readme_no_retired_decks"], "coverage_gap": "test_slides_ci_workflow_triggers_on_presentations checks docs/presentations/** glob but NOT the explicit CSS path \u2014 gap that allowed F6"}}
{"id": "T9", "req": "REQ-243", "title": "presentations README documents render pipeline + retired decks gone", "pass": false, "rc": 1, "evidence": {"retired_decks_present": false, "readme_mentions_render_slides": false, "readme_mentions_render_deck": true, "readme_render_deck_line": "docs/presentations/README.md:107: 'automated by scripts/render_deck.sh'", "readme_mentions_theme_css": true, "defect": "F10", "impact": "README documents the retired render_deck.sh pipeline, not the active render_slides.sh. Consumers reading synced README reference a script excluded from sync."}}
{"id": "T10", "req": "REQ-244", "title": "12-month product roadmap slides 20+21 + talking points", "pass": true, "rc": 0, "evidence": {"marp_slide15": true, "marp_slide20": true, "marp_slide21": true, "talking_points_slide15": true, "talking_points_slide20": true, "talking_points_slide21": true, "quarters": ["Q1 Pilot Activation", "Q2 Provable Trust", "Q3 Compounding ROI", "Q4 Agentic Substrate"], "distinct_from_slide15": true}}
+5 -5
View File
@@ -13,7 +13,7 @@ every deck and a presenter-ready cue sheet for delivery.
``` ```
Step 1: full markdown Step 2: Marp deck Step 3: HTML + PPTX Step 4: Talking points Step 1: full markdown Step 2: Marp deck Step 3: HTML + PPTX Step 4: Talking points
(source of truth) ──► (lean, 19 slides) ──► (rendered) ──► (presenter cues) (source of truth) ──► (lean, 21 slides) ──► (rendered) ──► (presenter cues)
*.md *-marp.md *.html / *.pptx *-talking-points.md *.md *-marp.md *.html / *.pptx *-talking-points.md
+ speaker notes + embedded PNG diagrams + 3-6 bullets per slide + speaker notes + embedded PNG diagrams + 3-6 bullets per slide
+ mermaid code blocks + Marp frontmatter + key takeaway per slide + mermaid code blocks + Marp frontmatter + key takeaway per slide
@@ -95,7 +95,7 @@ Distill the source of truth (Step 1) into presenter-ready cues, indexed by
the Marp deck (Step 2) slide structure: the Marp deck (Step 2) slide structure:
- **One section per Marp slide**`## Slide N — Title`, matching the Marp - **One section per Marp slide**`## Slide N — Title`, matching the Marp
deck's 18 main + 1 appendix slide structure exactly. deck's 20 main + 1 appendix slide structure exactly.
- **3-6 talking point bullets per slide** — punchy, actionable cues distilled - **3-6 talking point bullets per slide** — punchy, actionable cues distilled
from the source markdown's speaker notes. from the source markdown's speaker notes.
- **Key takeaway per slide** — the one memorable thing the audience should - **Key takeaway per slide** — the one memorable thing the audience should
@@ -108,8 +108,8 @@ the Marp deck (Step 2) slide structure:
``` ```
docs/presentations/ docs/presentations/
├── README.md ← this file ├── README.md ← this file
├── nova-autonomous-cloud-delivery.md ← Step 1: full source of truth (18 main slides + speaker notes) ├── nova-autonomous-cloud-delivery.md ← Step 1: full source of truth (20 main slides + speaker notes)
├── nova-autonomous-cloud-delivery-marp.md ← Step 2: Marp deck (18 main + 1 appendix = 19 slides) ├── nova-autonomous-cloud-delivery-marp.md ← Step 2: Marp deck (20 main + 1 appendix = 21 slides)
├── nova-autonomous-cloud-delivery.html ← Step 3: rendered HTML (committed, S&P-themed) ├── nova-autonomous-cloud-delivery.html ← Step 3: rendered HTML (committed, S&P-themed)
├── nova-autonomous-cloud-delivery.pptx ← Step 3: rendered PPTX (committed, S&P-themed) ├── nova-autonomous-cloud-delivery.pptx ← Step 3: rendered PPTX (committed, S&P-themed)
├── nova-autonomous-cloud-delivery-talking-points.md ← Step 4: presenter cues (19 sections) ├── nova-autonomous-cloud-delivery-talking-points.md ← Step 4: presenter cues (19 sections)
@@ -236,7 +236,7 @@ attached to the phase's release.
| Deck | Source of truth (Step 1) | Marp deck (Step 2) | Rendered HTML + PPTX (Step 3) | Talking points (Step 4) | Slides | Audience | | Deck | Source of truth (Step 1) | Marp deck (Step 2) | Rendered HTML + PPTX (Step 3) | Talking points (Step 4) | Slides | Audience |
|---|---|---|---|---|---|---| |---|---|---|---|---|---|---|
| Nova — The Autonomous Cloud Delivery Platform | `nova-autonomous-cloud-delivery.md` | `nova-autonomous-cloud-delivery-marp.md` | `nova-autonomous-cloud-delivery.html` + `.pptx` (committed + release-attached) | `nova-autonomous-cloud-delivery-talking-points.md` | 18 main + 1 appendix (19) | CTO, Head of Cloud, Head of Infra, Head of DevOps | | Nova — The Autonomous Cloud Delivery Platform | `nova-autonomous-cloud-delivery.md` | `nova-autonomous-cloud-delivery-marp.md` | `nova-autonomous-cloud-delivery.html` + `.pptx` (committed + release-attached) | `nova-autonomous-cloud-delivery-talking-points.md` | 20 main + 1 appendix (21) | CTO, Head of Cloud, Head of Infra, Head of DevOps |
> **v1.21:** the deck was renamed from "No-Humans Infrastructure Platform" > **v1.21:** the deck was renamed from "No-Humans Infrastructure Platform"
> to "Autonomous Cloud Delivery Platform" (professional framing; conveys > to "Autonomous Cloud Delivery Platform" (professional framing; conveys
+1 -1
View File
@@ -128,4 +128,4 @@ strong { color: var(--sp-red); }
* we clamp to `hidden` so the exported slide is clean. */ * we clamp to `hidden` so the exported slide is clean. */
@media print { @media print {
section { overflow: hidden; } section { overflow: hidden; }
} }
@@ -106,7 +106,7 @@ Every hour a developer spends writing, deploying, fixing, or remediating infrast
**How intent becomes verified infrastructure — fail-fast policy scanning before the plan, runtime scanning after it.** **How intent becomes verified infrastructure — fail-fast policy scanning before the plan, runtime scanning after it.**
![h:480](assets/png/platform-pipeline.png) ![h:480 class:tall](assets/png/platform-pipeline.png)
- **Contract → resolver → adapter → Checkov on static code (before plan) → terraform plan → Wiz on the plan → confidence signal → stage gate → apply → evidence + ledger** - **Contract → resolver → adapter → Checkov on static code (before plan) → terraform plan → Wiz on the plan → confidence signal → stage gate → apply → evidence + ledger**
- **Fail-fast, quick feedback** — Checkov runs on the authored Terraform code before `terraform plan` so developers get immediate policy feedback - **Fail-fast, quick feedback** — Checkov runs on the authored Terraform code before `terraform plan` so developers get immediate policy feedback
@@ -166,7 +166,7 @@ Separation-of-duties on prod: the approver cannot be the same person who built t
**Every metric in this deck is traceable to a real emitted signal — the live-ops dashboard makes operations visible in PowerBI.** **Every metric in this deck is traceable to a real emitted signal — the live-ops dashboard makes operations visible in PowerBI.**
![h:480](assets/png/telemetry-live-ops.png) ![h:480 class:tall](assets/png/telemetry-live-ops.png)
- **Platform components → CloudEvents envelope → event log + decision ledger + run records → collector → cold store → PowerBI views → live ops dashboard** - **Platform components → CloudEvents envelope → event log + decision ledger + run records → collector → cold store → PowerBI views → live ops dashboard**
- **The live ops dashboard (PowerBI)** surfaces the four CTO-grade metrics (Lead Time, Vulnerability Count, MTTR, Cloud Spend) alongside trust metrics (Decision Ledger coverage, Attestation coverage) and efficiency metrics (touchless resolution, escalation frequency) - **The live ops dashboard (PowerBI)** surfaces the four CTO-grade metrics (Lead Time, Vulnerability Count, MTTR, Cloud Spend) alongside trust metrics (Decision Ledger coverage, Attestation coverage) and efficiency metrics (touchless resolution, escalation frequency)
@@ -21,104 +21,120 @@
- State the attestation model up front: QA for production, SRE for operational readiness - State the attestation model up front: QA for production, SRE for operational readiness
- **Key takeaway:** autonomous operations with provable trust — security, remediation velocity, reliability, lead time made visible, not promised - **Key takeaway:** autonomous operations with provable trust — security, remediation velocity, reliability, lead time made visible, not promised
### Slide 3 — Strategic Objectives + Anti-Goals ### Slide 3 — Strategic Objectives
- Objective #1: zero-touch operations — autonomy as the default, not the demo; stage-gate attestation (QA, SRE) remains human by design
- Objective #2 is the one to land carefully: trust = deterministic scoring, not an LLM; the platform functions without AI - Objective #2 is the one to land carefully: trust = deterministic scoring, not an LLM; the platform functions without AI
- Objective #3: four CTO-grade metrics (Lead Time, Vuln Count, MTTR, Spend) — all flow into PowerBI - Objective #3: four CTO-grade metrics (Lead Time, Vuln Count, MTTR, Spend) — all flow into PowerBI
- Objective #4 is the integration thesis: Nova integrates with any upstream source; provides skills + MCP; all prod intents go through the same controls - Objective #4 is the integration thesis: Nova integrates with any upstream source; provides skills + MCP; all prod intents go through the same controls
- Anti-goals #3 and #4 protect the scope: not an upstream dev platform, not a PDLC replacement - **Key takeaway:** the scope is explicit — Nova governs infra + delivery, integrates with any source through one contract, measures success on four CTO metrics
- **Key takeaway:** purpose-built for infra ops, integrates with any source through one contract, measures success on four CTO metrics
### Slide 4 — Scope: Downstream of PDLC ### Slide 4 — Anti-Goals (What Nova Is NOT)
- Not a general-purpose AI agent platform
- Not a system that removes humans from accountability — only from normal operations
- Not an upstream development platform (no product backlogs, IDE, code authorship)
- Not a replacement for the Product Development Lifecycle (PDLC)
- Anti-goals #3 and #4 protect the scope boundary — Nova will not become an IDE or a product-planning tool
- **Key takeaway:** the boundaries are explicit — Nova is purpose-built for infra ops + delivery, not a general-purpose AI agent or an upstream dev platform
### Slide 5 — Scope: Downstream of PDLC
- Nova governs infra + delivery only; the PDLC (backlog, code authorship, IDE) is upstream — Nova never penetrates it - Nova governs infra + delivery only; the PDLC (backlog, code authorship, IDE) is upstream — Nova never penetrates it
- Integration is only through the validated contract boundary - Integration is only through the validated contract boundary
- Any upstream source (AI agent, agentic SDLC, dev platform) produces submissions subject to the same compliance standards - Any upstream source (AI agent, agentic SDLC, dev platform) produces submissions subject to the same compliance standards
- Nova validates the submission, not the author - Nova validates the submission, not the author
- **Key takeaway:** Nova is purpose-built for infrastructure operations; the scope boundary is clean and bounded - **Key takeaway:** Nova is purpose-built for infrastructure operations; the scope boundary is clean and bounded
### Slide 5 — RACI: Who Owns What ### Slide 6 — RACI: Who Owns What
- Four roles now: Citizen Developer, Platform, Quality Engineering, SRE - Four roles now: Citizen Developer, Platform, Quality Engineering, SRE
- Quality attestation is owned by Quality Engineering (not the Platform); Production readiness is owned by SRE - Quality attestation is owned by Quality Engineering (not the Platform); Production readiness is owned by SRE
- The Platform runs the checks agentically but is never the Accountable party for the gate — that separation keeps the platform honest - The Platform runs the checks agentically but is never the Accountable party for the gate — that separation keeps the platform honest
- Production readiness is co-owned: the platform runs attestations; the citizen developer authorizes the promotion at the stage gate - Production readiness is co-owned: the platform runs attestations; the citizen developer authorizes the promotion at the stage gate
- **Key takeaway:** you bring FRs + UAT; Nova provides NFRs + infra; QE guards the gate evidence; SRE signs off on production readiness - **Key takeaway:** you bring FRs + UAT; Nova provides NFRs + infra; QE guards the gate evidence; SRE signs off on production readiness
### Slide 6 — The Platform Pipeline ### Slide 7 — The Platform Pipeline
- Walk the pipeline left-to-right: contract → resolver → adapter → Checkov (static) → plan → Wiz (on plan) → confidence → gate → apply - Walk the pipeline left-to-right: contract → resolver → adapter → Checkov (static) → plan → Wiz (on plan) → confidence → gate → apply
- Two-stage scan: Checkov on static code BEFORE the plan (fail-fast dev feedback); Wiz on the plan (or Checkov as drop-in if no Wiz creds) - Two-stage scan: Checkov on static code BEFORE the plan (fail-fast dev feedback); Wiz on the plan (or Checkov as drop-in if no Wiz creds)
- Never both Wiz + Checkov on the plan — avoid duplicate noise - Never both Wiz + Checkov on the plan — avoid duplicate noise
- Dev is autonomous; qa/prod/dr require attestation (QA for quality, SRE for production readiness) - Dev is autonomous; qa/prod/dr require attestation (QA for quality, SRE for production readiness)
- **Key takeaway:** two layers of scanning, zero operator involvement in normal operations - **Key takeaway:** two layers of scanning, zero operator involvement in normal operations
### Slide 7 — The Decision Ledger ### Slide 8 — The Decision Ledger
- "AI decisions" are really automated decisions — deterministic scripts calculate a score; the platform functions without AI - "AI decisions" are really automated decisions — deterministic scripts calculate a score; the platform functions without AI
- Do not dwell on the storage substrate — the value is accountability (immutable, queryable, traceable to outcome), not the database - Do not dwell on the storage substrate — the value is accountability (immutable, queryable, traceable to outcome), not the database
- Every stage-gate attestation is captured with approver identity and the evidence presented - Every stage-gate attestation is captured with approver identity and the evidence presented
- When an LLM planner is added later, it emits richer alternatives without breaking the schema - When an LLM planner is added later, it emits richer alternatives without breaking the schema
- **Key takeaway:** autonomous is defensible because every decision is immutable, queryable, accountable — and "automated" means deterministic scoring, not a black-box LLM - **Key takeaway:** autonomous is defensible because every decision is immutable, queryable, accountable — and "automated" means deterministic scoring, not a black-box LLM
### Slide 8 The Attestation Matrix ### Slide 9 — Attestation Matrix: QA
- The matrix is not a rubber stamp — structured, freshness-validated, separation-of-duties-enforced - The matrix is not a rubber stamp — structured, freshness-validated
- Each concern now has a plain-language description of what is being attested (the old "operator-supplied" label is gone) - Each concern now has a plain-language description of what is being attested (the old "operator-supplied" label is gone)
- SoD on prod: the approver can't be the same person who built it - Three QA concerns: functional correctness (24h), performance baseline (7d), security posture (24h)
- Each concern has a freshness window — evidence older than the window does not satisfy the gate
- **Key takeaway:** QA signs off on quality before any promotion — the gate is explicit, not implicit
### Slide 10 — Attestation Matrix: Prod/DR
- Seven prod/DR concerns: operational readiness, incident response, capacity & cost, DR drill, chaos, backup, DR region deploy
- SRE signs off on operability (runbooks, dashboards, on-call), incident response, capacity, and the three resilience checks
- Each concern has a freshness window — 30d/90d/180d depending on the control
- SoD on prod: the approver can't be the same person who built it — the rule that keeps the gate honest
- **Key takeaway:** autonomy in operations, human in accountability, by design — the matrix is what makes autonomous operations safe enough to trust in production - **Key takeaway:** autonomy in operations, human in accountability, by design — the matrix is what makes autonomous operations safe enough to trust in production
### Slide 9 — Telemetry & Live Ops ### Slide 11 — Telemetry & Live Ops
- Deliberately minimal: Nova-native CloudEvents; no Kafka/Prometheus/ClickHouse - Deliberately minimal: Nova-native CloudEvents; no Kafka/Prometheus/ClickHouse
- The live-ops dashboard is built in PowerBI on top of the exported views — leadership sees the same numbers the platform produces - The live-ops dashboard is built in PowerBI on top of the exported views — leadership sees the same numbers the platform produces
- Every number in the Proof slides is traceable to a signal — "where does this number come from?" → a query against the cold store - Every number in the Proof slides is traceable to a signal — "where does this number come from?" → a query against the cold store
- This is where the "infrastructure operations become visible" theme lands concretely - This is where the "infrastructure operations become visible" theme lands concretely
- **Key takeaway:** the architecture is the trust substrate — operations become visible in PowerBI, with full traceability - **Key takeaway:** the architecture is the trust substrate — operations become visible in PowerBI, with full traceability
### Slide 10 — Decision Ledger + Attestation Coverage ### Slide 12 — Decision Ledger + Attestation Coverage
- Both 100% — no automated decision is ever lost; no prod/dr promotion lands without a human sign-off - Both 100% — no automated decision is ever lost; no prod/dr promotion lands without a human sign-off
- The mandatory-by-design point: the ledger entry + the human attestation are a gate, not a best-effort feature - The mandatory-by-design point: the ledger entry + the human attestation are a gate, not a best-effort feature
- Easily queried: by run, by environment, by approver, by outcome — the audit trail is a query, not a forensic exercise - Easily queried: by run, by environment, by approver, by outcome — the audit trail is a query, not a forensic exercise
- **Key takeaway:** trust is provable — not a marketing claim, a queryable record; no change to production without both the ledger entry and the human attestation - **Key takeaway:** trust is provable — not a marketing claim, a queryable record; no change to production without both the ledger entry and the human attestation
### Slide 11 — Cost & ROI ### Slide 13 — Cost & ROI
- The ROI formula is shown inline — not hidden in a footnote - The ROI formula is shown inline — not hidden in a footnote
- The four CTO-grade metrics are the ROI proof — Lead Time, Vuln Count, MTTR, Cloud Spend - The four CTO-grade metrics are the ROI proof — Lead Time, Vuln Count, MTTR, Cloud Spend
- The N=0 caveat is stated explicitly: the formula is grounded; the production numbers activate with a pilot - The N=0 caveat is stated explicitly: the formula is grounded; the production numbers activate with a pilot
- **Key takeaway:** the ROI is not a black box — the formula is shown, the four metrics are committed, the production-denominator caveat is up front - **Key takeaway:** the ROI is not a black box — the formula is shown, the four metrics are committed, the production-denominator caveat is up front
### Slide 12 — What's Deferred — and Why ### Slide 14 — What's Deferred — and Why
- The preempt is critical: these deferrals are measurement infrastructure, not autonomy — the platform IS autonomous in operations - The preempt is critical: these deferrals are measurement infrastructure, not autonomy — the platform IS autonomous in operations
- The blocking work is named in plain language (no decision IDs) — "live AWS re-provisioning", "drift-detection scheduler", "ML service" - The blocking work is named in plain language (no decision IDs) — "live AWS re-provisioning", "drift-detection scheduler", "ML service"
- Showing this to leadership demonstrates honesty, not weakness - Showing this to leadership demonstrates honesty, not weakness
- **Key takeaway:** the autonomy is real; the measurement gaps are documented with the work that unblocks each one - **Key takeaway:** the autonomy is real; the measurement gaps are documented with the work that unblocks each one
### Slide 13 — Roadmap to the North Star ### Slide 15 — Roadmap to the North Star
- Each deferred metric has an unblock path and a timeframe — near-term, mid-term, longer-term - Each deferred metric has an unblock path and a timeframe — near-term, mid-term, longer-term
- No status column: most of it is not implemented yet, so status would be noise - No status column: most of it is not implemented yet, so status would be noise
- Re-evaluation triggers: each blocking piece of work lifts on its own schedule - Re-evaluation triggers: each blocking piece of work lifts on its own schedule
- **Key takeaway:** every deferred metric has a plan and a timeframe — nothing is hand-waved - **Key takeaway:** every deferred metric has a plan and a timeframe — nothing is hand-waved
### Slide 14 — 12-Month Product Roadmap ### Slide 16 — 12-Month Product Roadmap
- This is the *product* roadmap, forward-looking only - This is the *product* roadmap, forward-looking only
- Q1 Pilot Activation → Q2 Provable Trust → Q3 Compounding ROI → Q4 Integration & Predictive - Q1 Pilot Activation → Q2 Provable Trust → Q3 Compounding ROI → Q4 Integration & Predictive
- Each quarter activates one strategic objective from the North Star - Each quarter activates one strategic objective from the North Star
- **Key takeaway:** the 12-month product arc — each quarter activates a strategic objective and its board-level metric - **Key takeaway:** the 12-month product arc — each quarter activates a strategic objective and its board-level metric
### Slide 15 — Quarter-by-Quarter Outcomes ### Slide 17 — Quarter-by-Quarter Outcomes
- Q1: three post-pilot metrics go live (Touchless ≥99%, Escalation <0.1%, Accuracy ≥99.5%) — denominator activates with the pilot - Q1: three post-pilot metrics go live (Touchless ≥99%, Escalation <0.1%, Accuracy ≥99.5%) — denominator activates with the pilot
- Q2: Decision Ledger Coverage was already grounded — tamper-evidence is the Q2 upgrade (local hash-chain → Object Lock + signed checkpoints) - Q2: Decision Ledger Coverage was already grounded — tamper-evidence is the Q2 upgrade (local hash-chain → Object Lock + signed checkpoints)
- Q3: Drift Auto-Reversal ≥95% unblocks when the drift scheduler ships; Spend Reduction ≥25% measured against the pilot baseline - Q3: Drift Auto-Reversal ≥95% unblocks when the drift scheduler ships; Spend Reduction ≥25% measured against the pilot baseline
- Q4: Predictive:Reactive ≥3:1 requires the ML forecasting service; AI-Agent Intent Share is a first measurement (aspirational-metric) - Q4: Predictive:Reactive ≥3:1 requires the ML forecasting service; AI-Agent Intent Share is a first measurement (aspirational-metric)
- **Key takeaway:** each quarter has a concrete deliverable, a target metric grounded in a strategic objective, and a path from deferred to shipped - **Key takeaway:** each quarter has a concrete deliverable, a target metric grounded in a strategic objective, and a path from deferred to shipped
### Slide 16 — Production-Grade Guidance via Atelier (1/2) ### Slide 18 — Production-Grade Guidance via Atelier (1/2)
- Nova instructs the citizen developer's AI agent via skills (markdown, keyed to engineering domains) + an MCP server (4 tools, plugin-registry, stdio) - Nova instructs the citizen developer's AI agent via skills (markdown, keyed to engineering domains) + an MCP server (4 tools, plugin-registry, stdio)
- The integration point is the same regardless of source — AI agent, agentic SDLC, traditional IDE all get the same skills + MCP - The integration point is the same regardless of source — AI agent, agentic SDLC, traditional IDE all get the same skills + MCP
- This is how Nova makes the citizen developer production-grade without owning the PDLC - This is how Nova makes the citizen developer production-grade without owning the PDLC
- **Key takeaway:** the citizen developer's AI agent is not unguided — Nova provides engineering principles as skills + MCP - **Key takeaway:** the citizen developer's AI agent is not unguided — Nova provides engineering principles as skills + MCP
### Slide 17 — Production-Grade Guidance via Atelier (2/2) ### Slide 19 — Production-Grade Guidance via Atelier (2/2)
- The value is the gap deterministic scanners leave: engineering discipline (Wiz/Checkmarx/Mend check policy/secrets, not discipline) - The value is the gap deterministic scanners leave: engineering discipline (Wiz/Checkmarx/Mend check policy/secrets, not discipline)
- The MCP server catches "is this service observable?", "is this error path handled?", "is this API contract clear?" - The MCP server catches "is this service observable?", "is this error path handled?", "is this API contract clear?"
- Vendored at a pinned tag → audit reproducibility — a validation result is replayable months later - Vendored at a pinned tag → audit reproducibility — a validation result is replayable months later
- **Key takeaway:** submissions are checked for engineering discipline, not just policy compliance — and the check is reproducible for audit - **Key takeaway:** submissions are checked for engineering discipline, not just policy compliance — and the check is reproducible for audit
### Slide 18 — Recap + Ask ### Slide 20 — Recap + Ask
- Recap the 4-beat arc so the audience leaves with the structure - Recap the 4-beat arc so the audience leaves with the structure
- The ask is a business decision: approve a pilot estate + the tamper-evident ledger build-out - The ask is a business decision: approve a pilot estate + the tamper-evident ledger build-out
- "Pipeline-ready" → "production-proven" is the value proposition - "Pipeline-ready" → "production-proven" is the value proposition
File diff suppressed because one or more lines are too long
@@ -98,10 +98,7 @@ operations.**
--- ---
## Slide 3 — Strategic Objectives + Anti-Goals ## Slide 3 — Strategic Objectives
**Four objectives Nova is building toward; four anti-goals that keep it
focused.**
**4 Strategic Objectives:** **4 Strategic Objectives:**
1. **Demonstrate production-grade zero-touch operations** — autonomy as 1. **Demonstrate production-grade zero-touch operations** — autonomy as
@@ -128,7 +125,21 @@ focused.**
to deploy to production go through the same rigorous controls, to deploy to production go through the same rigorous controls,
quality gates, attestation, and evidence stream. quality gates, attestation, and evidence stream.
**4 Anti-Goals (what Nova is NOT):** > **Benefit:** the scope is explicit — Nova governs infrastructure and
> delivery, integrates with any upstream source through one validated
> contract, and measures success on four metrics a CTO can repeat back.
> **Speaker notes:** Objective #2 is the one to land carefully: trust is
> established by deterministic scoring, not by an LLM. The platform
> functions without AI.
> **Transition:** "The objectives are concrete — here is what Nova is
> NOT, to keep it focused."
---
## Slide 4 — Anti-Goals (What Nova Is NOT)
1. Not a general-purpose AI agent platform. 1. Not a general-purpose AI agent platform.
2. Not a system that removes humans from accountability — only from 2. Not a system that removes humans from accountability — only from
normal operations. normal operations.
@@ -136,13 +147,11 @@ focused.**
authorship). authorship).
4. Not a replacement for the Product Development Lifecycle (PDLC). 4. Not a replacement for the Product Development Lifecycle (PDLC).
> **Benefit:** the scope is explicit — Nova governs infrastructure and > **Benefit:** the boundaries are explicit — Nova is purpose-built for
> delivery, integrates with any upstream source through one validated > infrastructure operations and delivery, not a general-purpose AI agent
> contract, and measures success on four metrics a CTO can repeat back. > or an upstream development platform.
> **Speaker notes:** Objective #2 is the one to land carefully: trust is > **Speaker notes:** Anti-goals #3 and #4 protect the scope boundary —
> established by deterministic scoring, not by an LLM. The platform
> functions without AI. Anti-goals #3 and #4 protect the scope boundary —
> Nova will not become an IDE or a product-planning tool. > Nova will not become an IDE or a product-planning tool.
> **Transition:** "The scope boundary is explicit — here is exactly > **Transition:** "The scope boundary is explicit — here is exactly
@@ -150,7 +159,7 @@ focused.**
--- ---
## Slide 4 — Scope: Downstream of PDLC ## Slide 5 — Scope: Downstream of PDLC
**Nova governs infrastructure and delivery. The PDLC is upstream — Nova **Nova governs infrastructure and delivery. The PDLC is upstream — Nova
never penetrates it. Integration is through one validated contract.** never penetrates it. Integration is through one validated contract.**
@@ -183,7 +192,7 @@ never penetrates it. Integration is through one validated contract.**
--- ---
## Slide 5 — RACI: Who Owns What ## Slide 6 — RACI: Who Owns What
**Four roles, one matrix — the citizen developer owns FRs + UAT, the **Four roles, one matrix — the citizen developer owns FRs + UAT, the
platform owns NFRs + infra, quality engineering owns the gate evidence, platform owns NFRs + infra, quality engineering owns the gate evidence,
@@ -224,7 +233,7 @@ and SRE owns operational readiness.**
--- ---
## Slide 6 — The Platform Pipeline ## Slide 7 — The Platform Pipeline
**How intent becomes verified infrastructure — with fail-fast policy **How intent becomes verified infrastructure — with fail-fast policy
scanning before the plan and runtime scanning after it.** scanning before the plan and runtime scanning after it.**
@@ -272,7 +281,7 @@ graph LR
--- ---
## Slide 7 — The Decision Ledger ## Slide 8 — The Decision Ledger
**Every automated decision is captured, immutable, queryable — and **Every automated decision is captured, immutable, queryable — and
accountable.** accountable.**
@@ -310,16 +319,42 @@ accountable.**
--- ---
## Slide 8 The Attestation Matrix ## Slide 9 — Attestation Matrix: QA
**The designed controls that keep humans at stage gates — structured, **The designed controls that keep humans at stage gates — QA concerns,
freshness-validated, and separation-of-duties-enforced.** freshness-validated.**
| Concern | Env | Freshness | Description | | Concern | Env | Freshness | Description |
|---------|-----|-----------|-------------| |---------|-----|-----------|-------------|
| Functional correctness | qa | 24h | The application behaves as specified; evidence accepted from the consumer's UAT. | | Functional correctness | qa | 24h | The application behaves as specified; evidence accepted from the consumer's UAT. |
| Performance baseline | qa | 7d | The deployment meets its performance envelope vs. the agreed baseline. | | Performance baseline | qa | 7d | The deployment meets its performance envelope vs. the agreed baseline. |
| Security posture | qa | 24h | The deployment's security findings have been reviewed and accepted. | | Security posture | qa | 24h | The deployment's security findings have been reviewed and accepted. |
- Each concern has a freshness window — evidence older than the window
does not satisfy the gate.
- Concerns that are offline-testable run for real; concerns that require
external evidence accept signed artifacts.
> **Benefit:** QA signs off on quality before any promotion — the gate
> is explicit, not implicit.
> **Speaker notes:** The matrix is not a rubber stamp. Each concern has a
> freshness window and a plain-language description of what is being
> attested. The "operator-supplied" label from the prior deck was
> dropped — every concern now has a plain-language description.
> **Transition:** "QA is half the matrix — here are the production and
> DR controls."
---
## Slide 10 — Attestation Matrix: Prod/DR
**Production and DR controls — operational readiness, resilience, and
disaster recovery.**
| Concern | Env | Freshness | Description |
|---------|-----|-----------|-------------|
| Operational readiness | prod | 30d | SRE confirms the deployment is operable: runbooks, dashboards, on-call coverage. | | Operational readiness | prod | 30d | SRE confirms the deployment is operable: runbooks, dashboards, on-call coverage. |
| Incident response | prod | 90d | The on-call path has been exercised; the deployment has a working incident-response plan. | | Incident response | prod | 90d | The on-call path has been exercised; the deployment has a working incident-response plan. |
| Capacity & cost | prod | 30d | Capacity headroom and monthly cost are within the agreed envelope. | | Capacity & cost | prod | 30d | Capacity headroom and monthly cost are within the agreed envelope. |
@@ -332,17 +367,16 @@ freshness-validated, and separation-of-duties-enforced.**
does not satisfy the gate. does not satisfy the gate.
- **Separation-of-duties on prod:** the approver cannot be the same - **Separation-of-duties on prod:** the approver cannot be the same
person who built the deployment. person who built the deployment.
- Concerns that are offline-testable run for real; concerns that require
external evidence accept signed artifacts.
> **Benefit:** the gate model is explicit — autonomy in operations, > **Benefit:** the gate model is explicit — autonomy in operations,
> human in accountability, by design. The matrix is what makes autonomous > human in accountability, by design. The matrix is what makes autonomous
> operations safe enough to trust in production. > operations safe enough to trust in production.
> **Speaker notes:** The matrix is not a rubber stamp. Each concern has a > **Speaker notes:** The prod/DR rows are the operational-readiness and
> freshness window, a description, and a separation-of-duties rule. The > resilience gates — SRE signs off on operability, incident response,
> "operator-supplied" label from the prior deck was dropped — every > capacity, and the three resilience checks (DR drill, chaos, backup).
> concern now has a plain-language description of what is being attested. > Separation-of-duties on prod is the rule that keeps the gate honest:
> the approver cannot be the same person who built the deployment.
> **Transition:** "You've seen how Nova works — the pipeline, the ledger, > **Transition:** "You've seen how Nova works — the pipeline, the ledger,
> the attestation gates. Here is how Nova instruments itself so that > the attestation gates. Here is how Nova instruments itself so that
@@ -350,7 +384,7 @@ freshness-validated, and separation-of-duties-enforced.**
--- ---
## Slide 9 — Telemetry & Live Ops ## Slide 11 — Telemetry & Live Ops
**Every metric in this deck is traceable to a real emitted signal — and **Every metric in this deck is traceable to a real emitted signal — and
the live-ops dashboard makes operations visible in PowerBI.** the live-ops dashboard makes operations visible in PowerBI.**
@@ -399,7 +433,7 @@ graph TB
--- ---
## Slide 10 — Decision Ledger + Attestation Coverage ## Slide 12 — Decision Ledger + Attestation Coverage
**By design, no change reaches production without a ledger entry and a **By design, no change reaches production without a ledger entry and a
human attestation — both queryable for auditing, with full human attestation — both queryable for auditing, with full
@@ -435,7 +469,7 @@ traceability.**
--- ---
## Slide 11 — Cost & ROI ## Slide 13 — Cost & ROI
**The ROI formula and the cost estimates — grounded, with the production **The ROI formula and the cost estimates — grounded, with the production
denominator honestly flagged.** denominator honestly flagged.**
@@ -466,7 +500,7 @@ denominator honestly flagged.**
--- ---
## Slide 12 — What's Deferred — and Why ## Slide 14 — What's Deferred — and Why
**Honesty about what is not measured yet — and the blocking work for **Honesty about what is not measured yet — and the blocking work for
each.** each.**
@@ -502,7 +536,7 @@ metrics — not the autonomy.
--- ---
## Slide 13 — Roadmap to the North Star ## Slide 15 — Roadmap to the North Star
**The path from the grounded metrics to the 1218 month targets — each **The path from the grounded metrics to the 1218 month targets — each
deferred metric has an unblock path and a candidate milestone.** deferred metric has an unblock path and a candidate milestone.**
@@ -533,7 +567,7 @@ deferred metric has an unblock path and a candidate milestone.**
--- ---
## Slide 14 — 12-Month Product Roadmap ## Slide 16 — 12-Month Product Roadmap
**The product arc from pilot activation to integration — four quarters, **The product arc from pilot activation to integration — four quarters,
four outcomes.** four outcomes.**
@@ -560,7 +594,7 @@ integration) and the deferred-metric unblock paths.
--- ---
## Slide 15 — Quarter-by-Quarter Outcomes ## Slide 17 — Quarter-by-Quarter Outcomes
| Quarter | Product theme | Key deliverable | Target metric | Grounding | | Quarter | Product theme | Key deliverable | Target metric | Grounding |
|---------|---------------|-----------------|---------------|-----------| |---------|---------------|-----------------|---------------|-----------|
@@ -587,7 +621,7 @@ anymore, and the audit trail is stronger than it ever was.'"*
--- ---
## Slide 16 — Production-Grade Guidance via Atelier (1/2) ## Slide 18 — Production-Grade Guidance via Atelier (1/2)
**Nova instructs the citizen developer's AI agent on production-grade **Nova instructs the citizen developer's AI agent on production-grade
engineering — a set of skills and an MCP server.** engineering — a set of skills and an MCP server.**
@@ -621,7 +655,7 @@ engineering — a set of skills and an MCP server.**
--- ---
## Slide 17 — Production-Grade Guidance via Atelier (2/2) ## Slide 19 — Production-Grade Guidance via Atelier (2/2)
**Agentic validation catches engineering-discipline gaps that deterministic **Agentic validation catches engineering-discipline gaps that deterministic
scanners miss — and the validation is reproducible.** scanners miss — and the validation is reproducible.**
@@ -656,7 +690,7 @@ scanners miss — and the validation is reproducible.**
--- ---
## Slide 18 — Recap + Ask ## Slide 20 — Recap + Ask
**The 4-beat recap + the business decision.** **The 4-beat recap + the business decision.**
@@ -710,4 +744,4 @@ S3 Object Lock + signed checkpoints. These two decisions move Nova from
--- ---
> **End of deck.** 18 main slides + 1 appendix slide = 19 total. > **End of deck.** 20 main slides + 1 appendix slide = 21 total.
+1 -1
View File
@@ -13,7 +13,7 @@ v1.21 adds (REQ-245,251,252):
- Deck renamed to nova-autonomous-cloud-delivery* - Deck renamed to nova-autonomous-cloud-delivery*
- No maturity badges in the Marp deck - No maturity badges in the Marp deck
- No version in the Marp footer/title slide - No version in the Marp footer/title slide
- 18 main + 1 appendix slides - 20 main + 1 appendix slides (v1.22 split slides 3+8 to relieve overflow)
- No D-###/REQ-###/internal .py paths in audience-facing slides - No D-###/REQ-###/internal .py paths in audience-facing slides
- Title is "Nova — The Autonomous Cloud Delivery Platform" - Title is "Nova — The Autonomous Cloud Delivery Platform"
""" """