diff --git a/.ciagent/PROJECT.md b/.ciagent/PROJECT.md index ee8266d..d2c65a6 100644 --- a/.ciagent/PROJECT.md +++ b/.ciagent/PROJECT.md @@ -691,6 +691,22 @@ New requirements REQ-354..REQ-369 + REQ-371 + REQ-363b — full text in - **Decisions:** `D-241..D-243` (3 decisions, authored in CLARIFY). Max existing D = D-240 (v1.29). Next free: D-244. + - **D-241** — Leadership deck is a single-shot, discrete, hand- + authored artifact (NOT a compression of the existing citizen- + developer pitch `nova-autonomous-cloud-delivery-marp.md`). + Audience: Infrastructure & Operations leadership (CTO + VP + Technology + Product Management). August 2026 presentation + anchor + November 2026 runway anchor. The existing citizen- + developer deck remains untouched. Overrides the post-v1.29 + STATE.md intake assumption 3. + - **D-242** — Narrow `scripts/render_pptx.py` extension: accept an + explicit source `.md` path + `--output` filename; render a + right-aligned footer textbox on every slide (python-pptx does + not read the Marp `footer:` directive). Non-REQ-372 prerequisite + per spec §3.3 Edge 2. + - **D-243** — Date anchor discipline: August 2026 is a month-only + presentation anchor (no specific day); November 2026 is the + runway anchor (~90 days). - **Capabilities:** `CAP-042` (1 capability, appended at ship). Max existing CAP = CAP-041 (v1.29). Next free: CAP-043. diff --git a/.ciagent/STATE.md b/.ciagent/STATE.md index 5275aee..946cf30 100644 --- a/.ciagent/STATE.md +++ b/.ciagent/STATE.md @@ -357,6 +357,7 @@ | CAP-039 | Platform ops reposplit | v1.29 / `v1.28.6` | `nova-platform-ops` (out-of-band), `docs/operator-guide-platform-ops.md`, `docs/archive/nova-idp-cfn-v1.28.md` | REQ-369, REQ-OPS-GUIDE, D-232, D-235 | covered-reference | engineering (`acdl/acdl`, GitHub) ends at the artifact; operations (`nova-platform-ops`, Gitea-private, OPER-PRIV) begins at the live platform; tag-pin handoff; CFN archived; covered-reference REQs tracked via cutover gates | | CAP-040 | KJ substrate lockstep | v1.29 / `v1.28.6` | `nova-platform-ops` (out-of-band), `platform/abac/kj-version.txt`, `.github/workflows/publish.yml` | REQ-371, REQ-363, REQ-363b, D-238, D-239 | covered-reference | one ECR image digest shared by Lambda `image_uri` + Fargate task `image`; `lifecycle.precondition` on both resources at `terraform plan`; KJ-STATIC (`CGO_ENABLED=0`, `file(1)` asserts `statically linked`); no second pipeline, no second SHA pin | | CAP-041 | JWKS edge-only | v1.29 / `v1.28.6` | `nova-platform-ops` (out-of-band), `docs/operator-guide-platform-ops.md` | REQ-364, REQ-365, REQ-366, INV-18, D-233 | covered-reference | JWKS is the only public read surface; CloudFront + OAC (`AuthType: AWS_IAM`, NOT `NONE`, `OriginAccessControlOriginType: lambda`, `SigningBehavior: always`); direct Function URL → 403, via-CloudFront → 200; WAF rate-limit 3000/5min + AWSManagedRulesCommonRuleSet; ACM DNS-validated in us-east-1; Route53 A-alias | +| CAP-042 | Leadership presentation deck (single-shot) | v1.30 / `v1.29.3` | `docs/presentations/nova-leadership-deck-marp.md`, `docs/presentations/nova-leadership-deck.pptx`, `scripts/check_leadership_deck.sh` | REQ-372.1..REQ-372.12, D-241, D-242, D-243 | local | Single-shot 7-slide PPTX deck for Infrastructure & Operations leadership (CTO + VP Technology + Product Management); presented August 2026; November 2026 runway anchor; discrete hand-authored artifact (NOT a compression of the citizen-developer pitch per D-241); rendered via existing `scripts/render_pptx.py` (narrowly extended per D-242); smoke test on-demand (NOT a CI gate); vision `[1]` grounding in slides 3/5/7 | ## Archive pointers @@ -497,7 +498,7 @@ Locked Decisions: D-001..D-240 (full ledger in PROJECT.md + CLAR Active Invariants: INV-1..INV-18 (full text above). New in v1.28: INV-12 (mode observability), INV-13 (mode determinism), INV-14 (credential type encodes role), INV-15 (no AWS-managed identity), INV-16 (Argon2id password storage), INV-17 (ABAC discipline fail-closed). New in v1.29: INV-18 (JWKS-EDGE-ONLY) + 10 NFR constraints (KJ-STATIC, KJ-LOCKSTEP, KJ-WARMUP-HEALTH, OPER-PRIV, IAM-NARROW, DRIFT-DETECT, IMPORT-IDEMPOTENT, TFM-HITL, JWKS-SLO, JWKS-ROTATION) -Standing Capability Gate: CAP-001..CAP-041 — all Verified (32 from v1.0..v1.27 + 6 from v1.28 + 3 from v1.29 covered-reference). Gate enforced by `core/regression_verify.py` + CI merge gates. CAP-033..038 added v1.28 (CLI surface, delegation AST, layer/wheel match, auth flow, KMS sign, PAT revocation). CAP-039..041 added v1.29 (platform-ops-reposplit, kj-substrate-lockstep, jwks-edge-only — covered-reference, live cutover pending operator action in nova-platform-ops). +Standing Capability Gate: CAP-001..CAP-042 — all Verified (32 from v1.0..v1.27 + 6 from v1.28 + 3 from v1.29 covered-reference + 1 from v1.30 single-shot deck). Gate enforced by `core/regression_verify.py` + CI merge gates. CAP-033..038 added v1.28 (CLI surface, delegation AST, layer/wheel match, auth flow, KMS sign, PAT revocation). CAP-039..041 added v1.29 (platform-ops-reposplit, kj-substrate-lockstep, jwks-edge-only — covered-reference, live cutover pending operator action in nova-platform-ops). CAP-042 added v1.30 (leadership-deck — single-shot, on-demand smoke test, NOT a CI gate). Anti-Goals Touched: `docs/vision.md` §7 / `NORTH_STAR.md` §Anti-Goals — (1) not an upstream dev platform; (2) not a general-purpose AI; (3) not a legacy infra bridge; (4) not a permissive delivery highway; (5) not a mutable audit log. v1.29 honored all 5 (no PDLC reach, narrow CLI autonomy, no VMs, ABAC fail-closed + HITL gates intact, immutable outbox). diff --git a/docs/presentations/nova-leadership-deck.pptx b/docs/presentations/nova-leadership-deck.pptx new file mode 100644 index 0000000..20774fb Binary files /dev/null and b/docs/presentations/nova-leadership-deck.pptx differ diff --git a/scripts/render_pptx.py b/scripts/render_pptx.py index f1cc942..79391ef 100644 --- a/scripts/render_pptx.py +++ b/scripts/render_pptx.py @@ -70,13 +70,21 @@ def parse_frontmatter(md_text: str): (no nested structures) — sufficient for Marp deck frontmatter (marp, theme, footer, paginate, size). The `style:` block (multi- line `|`) is skipped (not needed by the python-pptx renderer). + Skips leading HTML comments before the frontmatter fence. """ - if not md_text.lstrip().startswith("---"): + text = md_text.lstrip() + # Skip leading HTML comments before frontmatter. + while text.startswith("") + if end == -1: + return {} + text = text[end + 3 :].lstrip() + if not text.startswith("---"): return {} - end = md_text.find("\n---", 3) + end = text.find("\n---", 3) if end == -1: return {} - fm_text = md_text[3:end] + fm_text = text[3:end] fm = {} in_multiline = False for line in fm_text.splitlines(): @@ -104,14 +112,26 @@ def parse_frontmatter(md_text: str): def split_slides(md_text: str): - """Strip YAML frontmatter, then split the deck into slide source strings.""" + """Strip leading HTML comments + YAML frontmatter, then split into slides. + + A Marp deck may carry a header HTML comment before the frontmatter + (e.g. the REQ-372 related-artifacts comment). Skip leading comments + before detecting the `---` frontmatter fence. + """ + text = md_text.lstrip() + # Skip leading HTML comments () before frontmatter. + while text.startswith("") + if end == -1: + break + text = text[end + 3 :].lstrip() # Strip YAML frontmatter (between first pair of `---` lines). - if md_text.lstrip().startswith("---"): - end = md_text.find("\n---", 3) + if text.startswith("---"): + end = text.find("\n---", 3) if end != -1: - md_text = md_text[end + 4 :] + text = text[end + 4 :] # Normalize slide separators. Marp uses `\n---\n` on its own line. - parts = re.split(r"\n---\s*\n", md_text) + parts = re.split(r"\n---\s*\n", text) slides = [] for p in parts: p = p.strip("\n")