Files
acdl/.ciagent/PLAN.md
T
Jon Chery d61a3d1a2f docs(P00): create phase plans — v1.18 8 phases, 6 waves, 15 requirements
Vertical-slice plan for v1.18 Citizen Developer & Production-Grade Guidance.
Wave order: W1=P1, W2=P2, W3=P3+P4 (parallelizable), W4=P5, W5=P6, W6=P7.
Sequential execution this run. 8 plan-level risks documented (conf 0.80-0.92).

---ci---
project: acdl
phase: 0
milestone: v1.18
status: plan
---/ci---
2026-08-06 15:02:53 +00:00

53 KiB
Raw Permalink Blame History

Nova — Phase Plan v1.18 (Citizen Developer & Production-Grade Guidance)

Milestone: v1.18 — Citizen Developer & Production-Grade Guidance Branch: milestone/v1.18-citizen-developer-guidance Tag line: v1.17.x patch line — v1.17.0 (P0) → v1.17.1..v1.17.6 (P1P6) → v1.17.7 (P7 final = milestone release). Previous minor per branch-strategy (v1.17 shipped on the v1.16.x line; v1.18 is a Feature milestone → tags run on the previous minor's patch line = v1.17.x). Phase count: 8 (P0 pre-execution [DONE] + 6 execution + 1 final). Source of truth for requirements: .ciagent/REQUIREMENTS.md §v1.18 (REQ-214..228, 15 requirements). Source of truth for decisions: .ciagent/PROJECT.md §"Key Decisions (v1.18)" (D-133..D-142). Source of truth for research: .ciagent/RESEARCH.md §v1.18 (Atelier skill mapping, MCP SDK skeleton, submission-readiness gap analysis, Marp PPTX fidelity).

Wave Ordering

All 6 execution phases are sequenced for this run (the repo uses a flat /ci-run workflow — one phase at a time). The theoretical parallelism is documented for future parallelization-enabled runs.

Wave Phases Rationale
Wave 1 P1 Theme restoration + render/attach scripts. P2/P6 depend on the render scripts existing. P6 depends on the S&P theme. Foundation — nothing else can ship a re-rendered deck without this.
Wave 2 P2 RACI + PDLC-scope docs + 2 deck slides → 20 slides. Depends on P1's render_deck.sh + attach_release_asset.py + restored S&P theme. Re-renders HTML+PPTX.
Wave 3 P3, P4 (parallelizable) P3 (submission-readiness schema+validator+doc+tests) and P4 (Atelier skills + index) have NO dependency on each other. P3 touches schemas/, core/, tests/, docs/submission-readiness.md. P4 touches skills/, docs/skills.md, PROJECT.md BA.A. Zero file overlap. In a parallelization-enabled run these two could execute concurrently.
Wave 4 P5 Atelier MCP server (plugin-registry, vendored Atelier, tests). Depends on P4's skill catalog being present (the MCP atelier.list_domains tool returns the Nova-relevance table that P4 codifies in docs/skills.md; the server reads the vendored Atelier snapshot that P5 itself vendors — but the skill provenance in docs/skills.md is the cross-reference). Strictly P5 vendors Atelier independently of P4; the dependency is narrative consistency (the MCP server's domain list should match the skills index).
Wave 5 P6 3 new deck slides (scope/RACI/atelier) → 21 slides + README update + talking-points sync + HTML+PPTX re-render. Depends on P1 (theme + scripts), P2 (scope + RACI content + 2-slide precedent), P4 (atelier skills content for the Atelier slide), P5 (MCP server content for the Atelier slide). The deck slide that introduces Atelier must reflect what P4 + P5 actually shipped.
Wave 6 P7 Final review + audit + milestone ship (merge to main, tag v1.17.7, delete branches).

Execution order for this run: P1 → P2 → P3 → P4 → P5 → P6 → P7 (sequential). The Wave 3 parallelism (P3‖P4) is noted for future runs but NOT exercised here.


Phase P1 — sp-theme-restoration (feat)

  • Wave: 1
  • Requirements covered: REQ-214, REQ-228
  • Persona assignment: lead-developer (deck style: block restoration + HTML re-render verification) + backend-engineer (scripts/render_deck.sh
    • scripts/attach_release_asset.py)
  • Description: Restore the S&P Global Energy Marp style: block (from commit ae0cb58, v1.9.2 / P45) to the unified deck. The v1.17 P5 deck rebuild lost the S&P visual identity when it consolidated the two decks into one; the mermaid sp-theme.json survived but the Marp CSS theme was replaced with a generic dark-navy theme. Create the deck-automation scripts (render_deck.sh + attach_release_asset.py) that become the reusable render+commit+attach pipeline for P2 and P6. Re-render HTML. Commit the PPTX binary. Attach to the phase's Gitea release.

Tasks

  1. Edit docs/presentations/nova-no-humans-platform-marp.md — replace the current style: | block (lines 815, the generic dark-navy theme: #1a1a2e / #16213e) with the S&P Global Energy style: block from commit ae0cb58 (docs/presentations/how-the-platform-works-marp.md frontmatter). The restored block must contain:
    • section { font-family: "Akkurat Pro", "Helvetica Neue", "Arial", sans-serif; font-size: 22px; color: #1B1B1B; }
    • h1 { color: #D6002A; font-size: 34px; margin-bottom: 0.3em; }
    • h2 { color: #D6002A; font-size: 26px; margin-bottom: 0.2em; }
    • section.title { background: #1B1B1B; color: #fff; border-top: 8px solid #D6002A; }
    • section.title h1 { color: #fff; }
    • table { font-size: 18px; width: 100%; }
    • th { background: #F0F0F0; }
    • blockquote { border-left: 4px solid #D6002A; color: #2E2E2E; font-size: 20px; }
    • img { display: block; margin: 0 auto; max-height: 320px; }
    • .badge { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 14px; font-weight: 600; }
    • .today { background: #c6f6d5; color: #22543d; }
    • .planned { background: #fef3c7; color: #78350f; }
    • Preserve the current Nova header text (Nova — The No-Humans Infrastructure Platform) and the footer: 'Act %{page}/5 — v1.17' line — the rebrand is NOT touched (REQ-214: "the current Nova header/footer text is preserved"). Only the visual theme (colors + font + accent bar) is restored.
  2. Create scripts/render_deck.sh (executable, set -euo pipefail) — renders HTML + PPTX from a Marp deck markdown file. Usage: render_deck.sh <deck-marp.md>. Implementation per RESEARCH §4.1:
    • Reads the deck path from $1 (required; fails with usage message if absent).
    • Derives the output basename (strip -marp.md suffix → bare name; e.g. nova-no-humans-platform-marp.mdnova-no-humans-platform).
    • Output paths: <basename>.html and <basename>.pptx in the same directory as the input deck.
    • HTML render: npx --yes @marp-team/marp-cli@latest --allow-local-files <deck> -o <basename>.html (self-contained HTML, base64-embedded images).
    • PPTX render: CHROME_PATH=<chromium-path> npx --yes @marp-team/marp-cli@latest --allow-local-files <deck> -o <basename>.pptx (standard image-based PPTX, NOT --pptx-editable — per RESEARCH §4.1 the inline style: CSS survives the rasterization path). The CHROME_PATH is resolved from ~/.cache/ms-playwright/chromium-*/chrome-linux64/chrome (the existing path documented in docs/presentations/README.md line 96).
    • Exit 0 on success; non-zero on render failure (the set -e propagates).
    • Prints rendered: <html-path> and rendered: <pptx-path>.
  3. Create scripts/attach_release_asset.py (executable Python, stdlib-only per RESEARCH §3.5) — uploads a file to a Gitea release via the API. Usage: attach_release_asset.py --tag <release-tag> --file <path> [--name <display-name>]. Implementation per RESEARCH §3.5:
    • Reads NOVA_GITEA_TOKEN from .env.secrets (same source as scripts/ship_phase.sh line 35) — load via a small helper that reads .env.secrets key=value lines.
    • Resolves tag → release ID: GET https://git.cloudinit.dev/api/v1/repos/continuous-intelligence/acdl/releases/tags/{tag} with Authorization: token <NOVA_GITEA_TOKEN> → response JSON id.
    • Uploads the asset: POST https://git.cloudinit.dev/api/v1/repos/continuous-intelligence/acdl/releases/{id}/assets with multipart/form-data (name = display filename, attachment = file binary) + Authorization: token <NOVA_GITEA_TOKEN>.
    • Constructs the multipart body manually via urllib (stdlib-only, per RESEARCH §3.5 — a ~30-line multipart_encode(fields, files) helper with a generated boundary; no requests dependency).
    • Prints asset_id: <id> release: <tag> file: <name> on success.
    • Exits non-zero on API error (HTTP non-2xx) with a clear message (not a stack trace — C2 Clarity).
  4. Run scripts/render_deck.sh docs/presentations/nova-no-humans-platform-marp.md — regenerates nova-no-humans-platform.html (committed) + creates nova-no-humans-platform.pptx (committed, D-141 — no LFS).
  5. Commit the updated deck markdown, the regenerated HTML, and the new PPTX binary to the phase branch.
  6. Attach the PPTX to the phase's Gitea release (after ship_phase.sh creates the v1.17.1 tag + release): python3 scripts/attach_release_asset.py --tag v1.17.1 --file docs/presentations/nova-no-humans-platform.pptx.
  7. Update docs/presentations/README.md — document the new render_deck.sh + attach_release_asset.py scripts in the deck-build process section; note that PPTX is now a committed binary (D-141) + attached to every phase's release (D-142).

Must-haves (verification gate)

  • docs/presentations/nova-no-humans-platform-marp.md frontmatter style: block contains #D6002A (S&P red-core), #1B1B1B (grey-90), 8px solid #D6002A (top accent bar), 'Akkurat Pro' (font). A grep for #D6002A in the deck markdown returns ≥4 hits (h1, h2, title-bg border, blockquote border).
  • The Nova header (Nova — The No-Humans Infrastructure Platform) and footer (Act %{page}/5 — v1.17) text are UNCHANGED (rebrand preserved — REQ-214).
  • scripts/render_deck.sh exists, is executable, and exits 0 when run against the unified deck.
  • scripts/attach_release_asset.py exists, is executable, and python3 -m py_compile scripts/attach_release_asset.py succeeds.
  • docs/presentations/nova-no-humans-platform.html is regenerated (mtime newer than the deck markdown) and opens in a browser showing the S&P red accent bar + dark title-slide background.
  • docs/presentations/nova-no-humans-platform.pptx exists (binary, committed, no LFS) and is attached to the v1.17.1 Gitea release.
  • docs/presentations/README.md documents the two new scripts.
  • CAP-024 deck structure regression passes (the S&P theme restoration must not break the 18-slide structure — slide count, x3 arc, per-slide benefit callouts all preserved).

Ship tag

v1.17.1


Phase P2 — pdlc-scope-raci (docs)

  • Wave: 2
  • Requirements covered: REQ-215, REQ-216, REQ-228
  • Persona assignment: lead-developer (RACI matrix + PDLC-scope statement in PROJECT.md + docs/raci.md + docs/scope.md + 2 deck slides + HTML/PPTX re-render)
  • Description: Promote Core Tenet #2 + Anti-Goal #1 from buried tenets to a dedicated, unmissable scope statement: the PDLC is upstream of Nova; Nova governs infra + delivery only; integration is through the validated contract boundary. Author a three-role RACI matrix clarifying who owns what across the citizen-developer → platform → release-management boundary. Add 2 deck slides (scope + RACI) → 20 slides. Re-render HTML + PPTX using P1's scripts; commit PPTX; attach to release.

Tasks

  1. Edit PROJECT.md — add a new ## Scope: Nova is Downstream of PDLC subsection under ## Domain Boundaries (after the existing "Interface:" bullet). Content (per REQ-216):
    • State that the PDLC (Product Development Lifecycle — product backlog, code authorship, IDE) is upstream of Nova.
    • State that Nova governs infra + delivery only.
    • State that integration is through the validated contract boundary (the contract is the only ingress; Nova does not penetrate upstream product/SDLC).
    • Promote Core Tenet #2 ("The Delivery Lifecycle is a Sovereign Boundary") + Anti-Goal #1 ("Not an upstream development platform") from buried tenets to this dedicated, unmissable statement.
  2. Edit PROJECT.md — add a new ## RACI Matrix section (after the ## Scope: Nova is Downstream of PDLC subsection, before ## Core Tenets or at the end of the Domain Boundaries cluster). Content (per REQ-215, D-139):
    • Three roles (columns): Citizen Developer, Platform, Release Management (co-owned).
    • Rows = work categories: Functional Requirements, User Acceptance Testing, NFRs, Infrastructure, QA, Production Deploy, Release Attestation.
    • Cells = R/A/C/I per role per category. The assignment per REQ-215:
      • Citizen Developer: Responsible for all Functional Requirements
        • User Acceptance Testing (via their AI coding agent / upstream agentic SDLC / upstream development platform — the source does not matter as all are subject to the same compliance standards).
      • Platform: Responsible for all NFRs + Infrastructure + QA + Production deployments to cloud.
      • Release Management: co-owned — QA + SRE attestations required by the actual release, performed agentically but overseen & triggered by the Citizen Developer.
    • Render as a markdown table.
    • Include the compliance-standard-equivalence note: regardless of the source (AI agent, agentic SDLC, dev platform), the citizen developer's output is subject to the same compliance standards.
  3. Create docs/scope.md — citizen-developer-facing copy of the PDLC-upstream scope statement. Cross-references PROJECT.md §Scope as the source of truth. Plain-language prose (no CIAgent metadata references — REQ-52 precedent).
  4. Create docs/raci.md — citizen-developer-facing copy of the RACI matrix. Renders the same table as PROJECT.md §RACI Matrix. Explains the three roles in plain language. Cross-references PROJECT.md §RACI Matrix as the source of truth. Includes the compliance-standard equivalence note.
  5. Edit docs/presentations/nova-no-humans-platform-marp.md — add 2 new slides after the existing Slide 16 (Recap + Ask), before the appendix slides:
    • Slide 19 — Scope: Downstream of PDLC. States the PDLC is upstream; Nova governs infra + delivery only; integration is through the contract boundary. Benefit callout: "you now know exactly where Nova's boundary is — infrastructure and delivery, not product development."
    • Slide 20 — RACI: Who Owns What. Renders the 3-role × 7-category RACI table. Benefit callout: "you now know who is responsible for what — citizen developer owns FRs + UAT, platform owns NFRs + infra + deploy, release management is co-owned attestation."
    • The 5-act arc (D-130) is preserved — these are append-only context slides, not a new act (per D-134: "no act restructure").
    • Update the Slide 1 — Arc Preview text to reflect the 20-slide count (change "18 slides" / "5-act arc" references if they cite a count; the slide count is now 20 main + appendix). Update the footer Act %{page}/5 — v1.17Act %{page}/5 — v1.18 (the deck now reflects the v1.18 milestone content).
  6. Run scripts/render_deck.sh docs/presentations/nova-no-humans-platform-marp.md — regenerates HTML + PPTX (S&P theme preserved — regression check vs P1).
  7. Commit the updated PROJECT.md, docs/scope.md, docs/raci.md, the updated deck markdown, the regenerated HTML, and the regenerated PPTX binary.
  8. Attach the PPTX to the v1.17.2 Gitea release via scripts/attach_release_asset.py --tag v1.17.2 --file docs/presentations/nova-no-humans-platform.pptx.

Must-haves (verification gate)

  • PROJECT.md has a ## Scope: Nova is Downstream of PDLC section under Domain Boundaries.
  • PROJECT.md has a ## RACI Matrix section with a 3-column (Citizen Developer / Platform / Release Management) × 7-row table.
  • docs/scope.md exists, is citizen-developer-facing (no .ciagent/ references), and cross-references PROJECT.md §Scope.
  • docs/raci.md exists, is citizen-developer-facing, renders the RACI table, and cross-references PROJECT.md §RACI Matrix.
  • The deck has 20 main slides (Slide 19 = Scope, Slide 20 = RACI) + the appendix slides. Slide 1 Arc Preview reflects 20 slides.
  • scripts/render_deck.sh re-renders HTML + PPTX successfully; the S&P theme is preserved (grep #D6002A in the deck markdown still returns ≥4 hits — P1 regression check).
  • docs/presentations/nova-no-humans-platform.pptx is committed (binary) and attached to the v1.17.2 Gitea release.
  • CAP-024 deck structure regression passes (20 slides, x3 arc, per-slide benefits on the 2 new slides).

Ship tag

v1.17.2


Phase P3 — submission-readiness (feat)

  • Wave: 3
  • Requirements covered: REQ-217, REQ-218, REQ-219, REQ-220
  • Persona assignment: data-engineer (schema: schemas/submission-readiness.schema.json
    • the ingestor dispatch wiring co-owned with backend-engineer) + backend-engineer (validator core/submission_readiness.py + CLI mode in contract_ingestor.py + tests/test_submission_readiness.py + reason-code catalog in docs/submission-readiness.md)
  • Description: Define what is "acceptable to start" as a machine- checkable contract — a superset gate above contract.schema.json validity. The schema adds required Nova tags, per-env mandatory metadata (W3.E), declared policy preconditions, the developer/agentic profile (with agentic markers per REQ-22/W3.E), and an appSource pointer. The validator runs as contract_ingestor.py --check-readiness (D-133), returns a structured ReadinessResult with reason codes, and on fail emits a citizen-developer-facing error (not a stack trace).

Tasks

  1. Create schemas/submission-readiness.schema.json (JSON Schema draft 2020-12) — per REQ-217 + RESEARCH §3.3. This is a superset gate ABOVE contract.schema.json, NOT a duplicate (PROJECT.md hard constraint). It references but does not redefine contract fields. Schema fields:
    • contractId: string, non-empty, required (promoted from the Lambda envelope to a contract-level required field).
    • environment: enum ["dev", "qa", "prod", "dr"], required (references contract.schema.json's environment — does not redefine; uses it to select the per-env mandatory set).
    • tags: object, required. Required keys: nova:owner, nova:contract, nova:environment, nova:cost-center (nova:ref optional). References schemas/tagging-standard.json's required_tags shape (D-054).
    • policyPreconditions: object (map of string→boolean/string), required. Declared policy expectations the platform will enforce (e.g. {"public-ingress": false}).
    • profile: enum ["developer", "agentic"], required (REQ-217 / W3.E).
    • appSource: object {repo: string, ref: string}, required (REQ-217 — repo + ref pointer for runtime fetch).
    • Per-env mandatory (W3.E) — conditional allOf / if-then:
      • dev requires stack + environment (base contract fields).
      • qa adds validation.e2eSuite + validation.loadTest.
      • prod adds runbook + dashboard + oncall.
      • dr adds drDrillRef.
    • inputs map: optional everywhere (W3.E).
    • profile: agentic → conditionally requires naturalLanguageIntent (string), confidenceAtSubmission (number 01), agentTrace (object/string) per REQ-22 / W3.E.
    • additionalProperties: false at the top level (the gate is strict — no undocumented fields, per the v1.14 REQ-145 precedent).
    • $id: https://nova.cloudinit.dev/schemas/submission-readiness.schema.json (D-110 brand consistency).
    • $schema: https://json-schema.org/draft/2020-12/schema.
  2. Create core/submission_readiness.py — the validator (REQ-218, D-133). Invoked as contract_ingestor.py --check-readiness. Returns a structured ReadinessResult. Implementation per RESEARCH §3.2 + §3.4:
    • ReadinessResult dataclass/Pydantic model: {passed: bool, checks: list[{name, passed, reason_code}], contract_id: str}.
    • validate_readiness(contract: dict) -> ReadinessResult — the main entry point.
    • Validation order (two-layer gate, RESEARCH §3.2):
      1. Call contract_ingestor._validate_contract_schema(contract) first (the shape gate — reuses the existing function in core/lambda/contract_ingestor.py line 57; if shape fails, return early with a CONTRACT_SHAPE_INVALID reason code).
      2. Validate against schemas/submission-readiness.schema.json via jsonschema (the gate — loads the schema from disk; if jsonschema unavailable, fail loud with SCHEMA_UNAVAILABLE).
      3. Run the readiness checks that produce the citizen-developer-facing reason codes (REQ-218):
        • MISSING_TAGS — the 5 required Nova tags are not all present.
        • ENV_MISSING_MANDATORY:<env>:<field> — the per-env mandatory field is absent (e.g. ENV_MISSING_MANDATORY:qa:validation.e2eSuite).
        • AGENTIC_MISSING_INTENT — profile is agentic but naturalLanguageIntent / confidenceAtSubmission / agentTrace is missing.
        • MISSING_APP_SOURCEappSource is missing or incomplete.
        • POLICY_PRECONDITION_MISSINGpolicyPreconditions is empty or missing.
      4. Return all reason codes at once (not one-at-a-time — C2 Clarity: the citizen developer sees the full scope of fixes needed).
    • On fail → the caller (CLI or Lambda) emits a citizen-developer-facing error (not a stack trace — REQ-218). On pass → proceeds to existing ingestion.
  3. Edit core/lambda/contract_ingestor.py — add the --check-readiness CLI mode (D-133, RESEARCH §3.4 A-7). The ingestor is currently Lambda-only (no __main__ block); P3 adds one:
    • Add if __name__ == "__main__": block at the bottom that parses sys.argv (argparse). Subcommand: --check-readiness <contract-file> (reads a YAML/JSON contract file path; also supports --stdin to read from stdin).
    • The --check-readiness subcommand calls core.submission_readiness.validate_readiness(contract) and prints the ReadinessResult as JSON to stdout.
    • On fail → exit non-zero with the citizen-developer-facing error (the reason codes, not a stack trace). On pass → exit 0 with READY: <contractId>.
    • The Lambda path is NOT changed by this task (the readiness gate is a pre-flight CLI surface; whether the Lambda also gates on readiness is a separate decision — REQ-218 says "On pass → proceeds to existing contract ingestion," which the CLI path satisfies).
    • Co-ownership: backend-engineer owns the dispatch wiring; data-engineer owns the schema it validates against (PERSONAS.md territory-overlap table).
  4. Create docs/submission-readiness.md — citizen-developer-facing doc (REQ-219). Explains what is acceptable to start. Sections:
    • What this checks — the 5 readiness dimensions (tags, per-env mandatory, policy preconditions, profile, appSource).
    • Good example — a complete, passing contract (annotated with which checks it satisfies).
    • Rejected examples — one per reason code (a contract missing tags → MISSING_TAGS; a qa contract missing validation.e2eSuiteENV_MISSING_MANDATORY:qa:validation.e2eSuite; an agentic contract missing intent → AGENTIC_MISSING_INTENT; a contract missing appSourceMISSING_APP_SOURCE; a contract with empty policyPreconditionsPOLICY_PRECONDITION_MISSING).
    • Reason-code catalog — the 5 reason codes with their meaning + how to fix (co-owned: lead-developer writes the narrative, backend-engineer writes the reason-code catalog that mirrors the validator's return codes — PERSONAS.md territory-overlap table).
    • References schemas/submission-readiness.schema.json as the source of truth.
  5. Create tests/test_submission_readiness.py (REQ-220) — covers:
    • Good contract passes (all checks green, ReadinessResult.passed == True).
    • Missing tags fail with MISSING_TAGS.
    • Missing env mandatory fails with ENV_MISSING_MANDATORY:<env>:<field> (test at least qa + prod + dr cases).
    • Agentic profile missing intent fails with AGENTIC_MISSING_INTENT.
    • Missing appSource fails with MISSING_APP_SOURCE.
    • Missing policyPreconditions fails with POLICY_PRECONDITION_MISSING.
    • The CLI mode (contract_ingestor.py --check-readiness) works end-to-end: a good contract file → exit 0 + READY:; a bad contract file → exit non-zero + the reason codes in stdout.
  6. Run the test suitepytest tests/test_submission_readiness.py passes; the existing suite (pytest) still passes (no regressions).

Must-haves (verification gate)

  • schemas/submission-readiness.schema.json exists, is valid JSON Schema draft 2020-12, and python3 -c "import jsonschema; jsonschema.Draft202012Validator.check_schema(json.load(open('schemas/submission-readiness.schema.json')))" succeeds.
  • The schema references contract.schema.json (via $ref or by delegating the shape check to the validator) — it does NOT redefine id/name/environment/infrastructure (superset gate, not duplicate — PROJECT.md hard constraint).
  • core/submission_readiness.py exists, python3 -m py_compile core/submission_readiness.py succeeds, and validate_readiness(good_contract) returns ReadinessResult(passed=True).
  • core/lambda/contract_ingestor.py has a __main__ block; python3 core/lambda/contract_ingestor.py --check-readiness <good-contract.yaml> exits 0; python3 core/lambda/contract_ingestor.py --check-readiness <bad-contract.yaml> exits non-zero with a citizen-developer-facing reason code (not a stack trace).
  • docs/submission-readiness.md exists, has a good example + 5 rejected examples (one per reason code), and references the schema as source of truth.
  • tests/test_submission_readiness.py passes (all 5+ reason-code cases + the CLI end-to-end case).
  • The full test suite passes (pytest — no regressions from the ingestor edit).

Ship tag

v1.17.3


Phase P4 — atelier-skills (docs)

  • Wave: 3 (parallelizable with P3 in a parallelization-enabled run)
  • Requirements covered: REQ-221, REQ-222
  • Persona assignment: lead-developer (9 skill files + docs/skills.md index + PROJECT.md BA.A extension)
  • Description: Create 9 Atelier-derived skill files under skills/ keyed to Atelier domain paths, extending the BA.A 5-skill citizen- developer catalog. Each skill names the Atelier source path, distills the first-principles to the citizen-developer-relevant subset, links to agent-checklist triggers, and maps to the BA.A catalog. Create a docs/skills.md index page. The research (RESEARCH §1.3) confirmed the exact 9-skill list — no adjustment needed.

Tasks

  1. Create skills/ directory with 9 Atelier-derived skill files (REQ-221, D-138). Each file is markdown, structured as:
    • Atelier source path (e.g. domains/security/).
    • P-rules distilled (the citizen-developer-relevant subset — see RESEARCH §1.3 table for the exact P-rules per skill).
    • First-principles distillation (plain language; no Atelier-internal jargon; the citizen-developer-relevant subset, not the full domain).
    • Agent-checklist triggers (links to review/agent-checklist.md sections the citizen developer's AI agent runs before finishing a task).
    • BA.A catalog mapping (which of the 5 BA.A skills this extends: web API, worker, scheduled job, static asset, basic observability bootstrap — per RESEARCH §1.3). The 9 files (per REQ-221 + RESEARCH §1.3):
    • skills/api.md — Atelier domains/api/. P-rules: P1 Contract Fidelity, P2 Clarity, P5 Versioning, P6 Idempotency, P8 Security, P9 Error Transparency. Extends: web API.
    • skills/security.md — Atelier domains/security/. P-rules: P1 Zero Trust, P2 Least Privilege, P4 Input Validation, P6 Crypto Correctness, P8 Fail Securely, P9 Secret Hygiene. Extends: all 5 (cross-cutting).
    • skills/data.md — Atelier domains/data/. P-rules: P1 Truth, P3 Invariants in Schema, P4 Migration Safety, P7 Type Fidelity, P9 Referential Integrity. Extends: web API, worker, scheduled job.
    • skills/testing.md — Atelier domains/testing/. P-rules: P1 Tests as Specification, P3 Determinism, P5 Coverage of Behavior, P9 Edge Case Coverage, P10 No Test Theater. Extends: all 5 (UAT is a citizen- developer RACI responsibility).
    • skills/observability.md — Atelier domains/observability/. P-rules: P1 Structured by Default, P2 Correlation, P6 No Secrets in Obs, P7 Actionable Alerts. Extends: basic observability bootstrap.
    • skills/errors.md — Atelier domains/errors/. P-rules: P1 Errors are Data, P2 Fail Loudly, P3 Fail Specifically, P4 Preserve Context, P5 Recoverable When Possible. Extends: web API, worker, scheduled job.
    • skills/devops.md — Atelier domains/devops/. P-rules: P1 Reproducibility, P4 Rollback First, P5 Progressive Delivery, P6 Config as Code, P8 Security at Every Layer. Extends: scheduled job, worker (deploy/release is co-owned Release Mgmt).
    • skills/infrastructure-as-code.md — Atelier domains/infrastructure-as-code/. P-rules: P1 Declarative Intent, P2 Idempotence, P4 Plan Before Apply, P5 Version Everything, P10 Secrets Never in Code. Extends: static asset (the contract→Terraform path).
    • skills/compliance.md — Atelier domains/compliance/. P-rules: P1 Audit Logs Append-Only, P2 Every Significant Action Logged, P4 Policy is Code, P5 Policy is Evaluated as a Gate, P9 Secrets Redacted in Audit. Extends: all 5 (cross-cutting; Nova's compliance posture).
  2. Create docs/skills.md (REQ-222) — the index page. Sections:
    • Skill catalog — a table listing the 9 skills with their Atelier source path + BA.A catalog mapping.
    • Atelier provenance — explains the skills are derived from coreci/atelier (the first-principles docs-as-code engineering framework — 8 core principles, 19 domains, 190 P-rules); the 9 skills are the citizen-developer-relevant subset of the 13 relevant domains (RESEARCH §1.2 — 6 domains excluded: UI/UX, Kubernetes, GitOps, i18n, Edge, Messaging).
    • How the citizen developer's AI agent consumes them — read the relevant skill before completing a task; run the Atelier review/agent-checklist.md before finishing. The agent-checklist will be exposed as an MCP tool in P5 (atelier.validate_against_principles).
    • The 4 "reference-only" domains (Performance, Documentation, Concurrency, AI/ML) — their principles are cited inside the 9 skills
      • this index but do NOT get their own skill file (RESEARCH §1.2 — a citizen developer's first production-grade service does not need a standalone Concurrency or AI/ML skill).
    • No .ciagent/ references (consumer-facing — REQ-52 precedent).
  3. Edit PROJECT.md — extend the BA.A decision (W3.E resolution table, line ~886) with a reference to the Atelier-derived skill catalog. Add a note that the BA.A 5-skill catalog (web API, worker, scheduled job, static asset, basic observability bootstrap) is extended by the 9 Atelier-derived skills under skills/, indexed at docs/skills.md.

Must-haves (verification gate)

  • skills/ directory exists with exactly 9 markdown files: api.md, security.md, data.md, testing.md, observability.md, errors.md, devops.md, infrastructure-as-code.md, compliance.md.
  • Each skill file names its Atelier source path (e.g. domains/security/), distills ≥4 P-rules, links to agent-checklist triggers, and maps to a BA.A catalog skill.
  • docs/skills.md exists, has a skill-catalog table (9 rows), an Atelier-provenance section, a "how the AI agent consumes them" section, and the 4 reference-only domains note.
  • docs/skills.md has no .ciagent/ references (consumer-facing).
  • PROJECT.md BA.A decision is extended with the Atelier-derived skill catalog reference.
  • The full test suite still passes (pytest — no code changes, docs only, but verify no regressions).

Ship tag

v1.17.4


Phase P5 — atelier-mcp (feat)

  • Wave: 4
  • Requirements covered: REQ-223, REQ-224, REQ-225
  • Persona assignment: backend-engineer (MCP server + plugin-registry + vendored Atelier + tests)
  • Description: Build the Atelier MCP server (mcp/atelier/server.py) with a plugin-registry architecture (D-140): plugins/<name>.py modules each expose register(mcp) -> None and call @mcp.tool() for their tools. The server scans plugins/ and calls register on each. Initial plugins: principles.py (atelier.lookup_principle, atelier.list_domains, atelier.matrix_lookup) and validation.py (atelier.validate_against_principles — agentic validation against the Atelier agent-checklist). Uses the MCP Python SDK v2 (D-137). stdio transport (D-135). Vendor the Atelier snapshot at pinned tag v0.3.6 (D-136) for audit reproducibility.

Tasks

  1. Create mcp/atelier/vendor/ — vendored Atelier snapshot at tag v0.3.6 (REQ-224, D-136, RESEARCH §1.6). The vendored content is a clean copy of the Atelier repo at tag v0.3.6 (the core/, domains/, matrix/, review/ directories — the docs the MCP tools read; examples/ and languages/ are optional but included for completeness). Mechanics per RESEARCH §1.6:
    • Fetch https://git.cloudinit.dev/coreci/atelier/archive/v0.3.6.tar.gz.
    • Extract the doc directories into mcp/atelier/vendor/.
    • Verify the matrix is at the complete state: 19 domains, 190 P-rules (the Coverage Summary in matrix/principles-matrix.md confirms this).
  2. Create mcp/atelier/vendor/VERSION.md — records the pinned tag + provenance (REQ-224, RESEARCH §1.6):
    • Tag: v0.3.6
    • Commit: 66b4767d25
    • Date: 2026-08-05
    • Milestone: "v0.4 Edge + Messaging + Language-Derived Docs"
    • P-rule count: 190
    • Domain count: 19
    • Source URL: https://git.cloudinit.dev/coreci/atelier
  3. Create scripts/update_atelier_vendor.sh (executable, set -euo pipefail) — helper for intentional upgrades (REQ-224). Takes a tag arg, fetches the tarball from https://git.cloudinit.dev/coreci/atelier/archive/<tag>.tar.gz, extracts the doc directories into mcp/atelier/vendor/, and updates VERSION.md. Intentional upgrades only (re-run + re-audit).
  4. Create mcp/atelier/server.py (REQ-223, D-135, D-137, D-140, RESEARCH §2.2) — the MCP server. Implementation per the RESEARCH §2.2 skeleton:
    • from mcp.server import MCPServer (v2 high-level server — NOT FastMCP, which was v1; RESEARCH §2.1 A-2).
    • mcp = MCPServer("atelier") — one arg = server name.
    • Plugin-registry (D-140): scan plugins/, import each module via importlib.import_module(f".plugins.{p.stem}", __package__), call register(mcp) on each. sorted(pathlib.Path(__file__).parent.glob("plugins/*.py")) makes load order deterministic (audit reproducibility — RESEARCH §2.2 notes).
    • @mcp.tool() for the server-level tool atelier_list_domains (or delegate to a plugin — the skeleton shows it inline; the implementation may move it to plugins/principles.py for consistency with the plugin-registry pattern).
    • if __name__ == "__main__": mcp.run() — stdio transport is the default (D-135; RESEARCH §2.1 A-3). HTTP-ready on the same object (future milestone — Out of Scope for v1.18).
  5. Create mcp/atelier/plugins/__init__.py — empty init (makes plugins/ a package).
  6. Create mcp/atelier/plugins/principles.py (REQ-223, RESEARCH §1.5) — the principles plugin. register(mcp: MCPServer) -> None containing @mcp.tool() calls for:
    • atelier_lookup_principle(domain: str, principle_id: str) -> PrincipleLookup — resolves a principle reference to its full text + core derivation + checklist items. Resolution path per RESEARCH §1.5: load vendor/core/first-principles.md (if domain=="core") or vendor/domains/<domain>/first-principles.md, parse the principle section; cross-reference vendor/matrix/principles-matrix.md for the core derivation; cross-reference vendor/review/agent-checklist.md for checklist items; check non-tradeable status in vendor/domains/<domain>/first-principles.md §3. Return the PrincipleLookup Pydantic model (RESEARCH §1.5).
    • atelier_list_domains() -> list[DomainInfo] — returns the 19 domain names + P-rule counts + Nova-relevance flag (the plugin hardcodes the Nova-relevance table from RESEARCH §1.2 so the citizen developer's agent can filter to the 13 relevant / 9 skill-bearing domains).
    • atelier_matrix_lookup(domain: str) -> DomainMatrix — returns the full domain→core mapping for one domain (all 10 P-rules → their core C-rule(s)), used by validate_against_principles to set severity and by conflict resolution when two findings collide.
    • Lazily load + cache the vendored markdown in module-level dicts (C8 Economy — don't re-parse the matrix on every lookup; RESEARCH §2.2 notes).
  7. Create mcp/atelier/plugins/validation.py (REQ-223, RESEARCH §1.4) — the validation plugin. register(mcp: MCPServer) -> None containing:
    • atelier_validate_against_principles(snippet: str, language: str, domains: list[str], run_core: bool = True) -> ValidateResult — agentic validation against the Atelier agent-checklist, beyond Wiz/Checkmarx/Mend. Input/output models per RESEARCH §1.4 (ValidateInput, Violation, ValidateResult Pydantic models). The plugin reads the vendored review/agent-checklist.md (frozen at the pinned tag — RESEARCH §1.4) and maps each checklist line to a predicate function keyed by (language, principle). The validation catches C1 (correctness) + C7 (observability) violations in a known-bad snippet and passes a known-good snippet (REQ-225 test case).
  8. Create mcp/atelier/README.md (REQ-224) — documents the server:
    • How to run (python3 mcp/atelier/server.py — stdio transport; the citizen developer's AI agent spawns the server as a subprocess).
    • Transport: stdio now (D-135); HTTP-ready on the same object (future milestone — Out of Scope).
    • Tool catalog: the 4 tools (atelier.lookup_principle, atelier.list_domains, atelier.matrix_lookup, atelier.validate_against_principles) with their input/output schemas.
    • Plugin-authoring guide: how to add a new plugin (plugins/<name>.py with register(mcp) — D-140; no server.py edits).
    • Vendoring policy: pinned tag v0.3.6 for audit reproducibility (D-136); scripts/update_atelier_vendor.sh for intentional upgrades; live-fetch is NOT implemented (Out of Scope).
  9. Create tests/test_atelier_mcp.py (REQ-225) — covers:
    • Tool registration — all 4 tools discoverable via tools/list (the MCP protocol's tool-discovery call; the test spawns the server in-process or uses the SDK's test harness).
    • atelier.lookup_principle("security", "P4") returns the principle text ("Input Validation") + core C-rule (C1) + checklist items (RESEARCH §1.5 example).
    • atelier.validate_against_principles catches a planted C1 (correctness) + C7 (observability) violation in a known-bad snippet and passes a known-good snippet (REQ-225 explicit case).
    • atelier.matrix_lookup("security") returns the domain→core mapping (all 10 P-rules → their core C-rule(s)).
    • Plugin discovery — the server loads all plugins in plugins/ (the test verifies plugins/principles.py + plugins/validation.py are both loaded; the register function was called on each).
  10. Add the MCP Python SDK v2 dependency to requirements-test.txt (or pyproject.toml test dependencies): mcp>=2.0 (the modelcontextprotocol/python-sdk package; D-137). Pin per the project's dependency convention.
  11. Run the test suitepytest tests/test_atelier_mcp.py passes; the existing suite still passes.

Must-haves (verification gate)

  • mcp/atelier/server.py exists, python3 -m py_compile mcp/atelier/server.py succeeds, and imports from mcp.server import MCPServer (v2 high-level server — NOT FastMCP).
  • mcp/atelier/plugins/principles.py + mcp/atelier/plugins/validation.py exist; each has a register(mcp) function containing @mcp.tool() calls.
  • mcp/atelier/vendor/ exists with core/, domains/, matrix/, review/ directories vendored from Atelier tag v0.3.6.
  • mcp/atelier/vendor/VERSION.md records tag v0.3.6, commit 66b4767d25, 190 P-rules, 19 domains.
  • scripts/update_atelier_vendor.sh exists, is executable, and takes a tag arg.
  • mcp/atelier/README.md documents how to run, transport, tool catalog, plugin-authoring guide, vendoring policy.
  • tests/test_atelier_mcp.py passes: 4 tools discoverable, lookup_principle returns the principle + core rule, validate_against_principles catches C1+C7 violations in a known-bad snippet + passes a known-good snippet, matrix_lookup returns the domain→core mapping, plugin discovery loads all plugins.
  • The full test suite passes (pytest — no regressions from the new dependency).

Ship tag

v1.17.5


Phase P6 — deck-slides-atelier (docs)

  • Wave: 5
  • Requirements covered: REQ-226, REQ-227, REQ-228
  • Persona assignment: lead-developer (3 new deck slides + README update + talking-points sync + HTML/PPTX re-render)
  • Description: Add the 21st deck slide to the unified deck → 21 slides total. P2 added slides 19 (Scope) + 20 (RACI); P6 adds slide 21 (Atelier). Update the Arc Preview slide to reflect 21 slides. Sync the talking-points file for the 3 new slides (Scope, RACI, Atelier). Re-render HTML + PPTX (S&P theme preserved — regression check vs P1). Update the README slide count + deck table.

Tasks

  1. Edit docs/presentations/nova-no-humans-platform-marp.md — add the 21st slide (REQ-226, D-134):
    • Slide 21 — Production-Grade Guidance via Atelier. Content:
      • The 9 Atelier-derived skills (under skills/, indexed at docs/skills.md) extend the BA.A 5-skill catalog.
      • The Atelier MCP server (mcp/atelier/server.py, stdio transport) exposes 4 tools: atelier.lookup_principle, atelier.list_domains, atelier.matrix_lookup, atelier.validate_against_principles.
      • Agentic validation goes beyond deterministic scanners (Wiz/Checkmarx/Mend) by catching correctness/clarity/simplicity/ observability gaps (C1/C2/C3/C7) against the Atelier agent-checklist.
      • Vendored Atelier (pinned tag v0.3.6) for audit reproducibility (D-136) — an agentic validation result is replayable against the exact principles that produced it.
      • Benefit callout: "you now know the citizen developer is not unguided — production-grade engineering principles are machine-checkable, and the validation goes beyond SAST to correctness, clarity, simplicity, and observability."
    • Slides 19 (Scope) + 20 (RACI) were added in P2; P6 confirms they are still present and renumbers if needed so the slide order is Scope → RACI → Atelier (19 → 20 → 21).
    • Update Slide 1 — Arc Preview to reflect 21 slides (change the slide-count reference; the 5-act arc is preserved — D-134: the 3 new slides are append-only context, not a new act).
  2. Edit docs/presentations/nova-no-humans-platform-talking-points.md (REQ-226) — sync the talking points for the 3 new slides (Scope, RACI, Atelier). Each new slide gets a talking-points section with 36 punchy, actionable cues + a key takeaway per slide (per the v1.9.7 talking-points format).
  3. Edit docs/presentations/README.md (REQ-227) — update:
    • The slide count (21 slides + appendix).
    • The deck table (add the 3 new slide titles: "Scope: Downstream of PDLC", "RACI: Who Owns What", "Production-Grade Guidance via Atelier").
  4. Run scripts/render_deck.sh docs/presentations/nova-no-humans-platform-marp.md (REQ-228) — regenerates HTML + PPTX. The S&P theme is preserved (regression check vs P1 — grep #D6002A in the deck markdown still returns ≥4 hits).
  5. Commit the updated deck markdown, talking-points, README, the regenerated HTML, and the regenerated PPTX binary.
  6. Attach the PPTX to the v1.17.6 Gitea release via scripts/attach_release_asset.py --tag v1.17.6 --file docs/presentations/nova-no-humans-platform.pptx.

Must-haves (verification gate)

  • The deck has 21 main slides: Slide 19 = Scope, Slide 20 = RACI, Slide 21 = Atelier (+ appendix slides).
  • Slide 1 Arc Preview reflects 21 slides.
  • Slide 21 (Atelier) mentions the 9 skills, the 4 MCP tools, agentic validation beyond SAST, and the vendored pinned tag v0.3.6.
  • docs/presentations/nova-no-humans-platform-talking-points.md has talking-points sections for all 3 new slides (Scope, RACI, Atelier).
  • docs/presentations/README.md reflects 21 slides + the 3 new titles in the deck table.
  • scripts/render_deck.sh re-renders HTML + PPTX successfully; the S&P theme is preserved (grep #D6002A — P1 regression check).
  • docs/presentations/nova-no-humans-platform.pptx is committed (binary) and attached to the v1.17.6 Gitea release.
  • CAP-024 deck structure regression passes (21 slides, x3 arc, per-slide benefits on all 3 new slides).

Ship tag

v1.17.6


Phase P7 — final-review-ship (final)

  • Wave: 6
  • Requirements covered: all (REQ-214..228) — verification that every requirement is complete; milestone ship.
  • Persona assignment: lead-developer (review coordination + audit + milestone ship) + backend-engineer (regression gate + technical verification) + data-engineer (schema audit)
  • Description: Multi-persona review of all v1.18 phases, audit of the requirement coverage, regression gate run (CAP-023 metrics collector + CAP-024 deck structure + the existing 22 capabilities), and milestone ship: merge to main, tag v1.17.7, delete phase branches.

Tasks

  1. Review — multi-persona review of P1P6. Lead-developer verifies the deck (21 slides, S&P theme, x3 arc, talking-points sync), RACI + scope docs, and skills index. Backend-engineer verifies the MCP server (4 tools, plugin-registry, vendored Atelier), the submission-readiness validator (reason codes, CLI mode), and the render/attach scripts. Data-engineer verifies the submission-readiness schema (superset gate, per-env mandatory, no duplication of contract fields). Findings recorded in .ciagent/REVIEW.md.
  2. Audit — requirement coverage audit. Every REQ-214..228 is checked against the shipped artifacts. The traceability table in REQUIREMENTS.md §v1.18 is updated: all 15 requirements move from pendingcomplete (v1.17.x). Gaps are fixed before ship (no partial shipments).
  3. Regression gatebash scripts/run_regression.sh (D-091) runs all auto-verifiable capabilities. CAP-023 (metrics collector) + CAP-024 (deck structure: 21 slides, x3 present, per-slide benefit present) must pass. The existing 22 capabilities must stay Verified (no regressions from v1.18's schema/code additions).
  4. Milestone ship:
    • Merge the milestone branch milestone/v1.18-citizen-developer-guidance to main.
    • Tag v1.17.7 (the milestone release tag — final patch on the v1.17.x line = the v1.18 milestone release per the tag-line decision).
    • Force-move the floating v1.17 + v1 tags to v1.17.7 (D-057 precedent — consumers on @v1.17 or @v1 receive the update).
    • Create the Gitea release for v1.17.7 with an auto-generated body (the v1.18 milestone summary).
    • Attach the final PPTX to the v1.17.7 release via scripts/attach_release_asset.py.
    • Delete the phase branches (phase/01-sp-theme-restoration through phase/06-deck-slides-atelier) after merge.
  5. Update .ciagent/ metadata — ROADMAP.md §v1.18 marked complete; PROJECT.md §v1.18 objective marked complete with the ship tag; CAPABILITY_INVENTORY.md gains CAP-025 (submission-readiness gate) + CAP-026 (Atelier MCP server) if the regression gate certifies them; REVIEW.md updated with the v1.18 review content.

Must-haves (verification gate)

  • All 15 requirements (REQ-214..228) are complete in the REQUIREMENTS.md §v1.18 traceability table.
  • bash scripts/run_regression.sh passes (all capabilities Verified; CAP-024 deck structure regression passes at 21 slides).
  • The milestone branch is merged to main.
  • Tag v1.17.7 exists; floating tags v1.17 + v1 point at it.
  • The v1.17.7 Gitea release exists with the PPTX attached.
  • Phase branches are deleted.
  • .ciagent/ROADMAP.md §v1.18 marked complete.
  • .ciagent/REVIEW.md updated with v1.18 review content.

Ship tag

v1.17.7 (milestone release)


Plan-Level Risks + Notes

  1. Atelier tag drift (A-1, conf 0.92). The vendored tag is v0.3.6 (fetched 2026-08-05). If a v0.5 milestone lands before P5 ships, the pin is stale — but the VERSION.md + update_atelier_vendor.sh model makes a future upgrade a deliberate, audited action, not silent drift. P5 should re-verify the latest Atelier tag at execution time and document any divergence in VERSION.md.
  2. MCP Python SDK v2 import name (A-2, conf 0.88). The high-level server class is MCPServer (NOT FastMCP, which was v1). If a future SDK patch restores a FastMCP alias, both imports would work, but the v2 canonical name is MCPServer. P5 should verify the import against the installed SDK version at execution time.
  3. mcp.run() stdio entry point (A-3, conf 0.85). The exact run() signature for stdio vs HTTP is not fully spelled out on the SDK landing page. P5 should verify the exact run call from the "Running your server" docs page before finalizing server.py. If stdio requires an explicit transport argument, the fix is a one-line change in server.py (D-135 — the server object is transport-agnostic).
  4. Submission-readiness validator wiring (A-7, conf 0.80). D-133 places the readiness gate as contract_ingestor.py --check-readiness (a CLI pre-flight). REQ-218 says "On pass → proceeds to existing contract ingestion" — this is satisfied by the CLI path (the citizen developer runs --check-readiness before submitting). Whether the Lambda path ALSO gates on readiness (a pre-write gate in _submit_contract) is a P3 implementation decision. The plan defaults to CLI-only (the Lambda path is unchanged) to avoid changing the Lambda's behavior mid-milestone; the Lambda gate can be added in a future milestone if desired.
  5. PPTX binary in git (D-141). Committing the PPTX binary directly (no LFS) is the decision. Decks are small (~15 MiB); git handles binary blobs. Binary diffs are not delta-friendly, but deck changes are infrequent (3 times this milestone). If the repo grows significantly, a future milestone may reconsider LFS — but only if git.cloudinit.dev confirms LFS server-side support.
  6. Wave 3 parallelism (P3‖P4) is theoretical. This run executes sequentially (P3 then P4). The parallelism is noted for future parallelization-enabled runs. The two phases have zero file overlap (P3: schemas/, core/, tests/, docs/submission-readiness.md; P4: skills/, docs/skills.md, PROJECT.md BA.A) so they COULD run concurrently without conflict.
  7. Deck slide numbering. P2 adds slides 19 + 20 (scope + RACI) → 20 slides. P6 adds slide 21 (Atelier) → 21 slides. The Arc Preview slide is updated in both P2 (to 20) and P6 (to 21). The 5-act arc (D-130) is preserved throughout — the new slides are append-only context, not a new act (D-134).
  8. No new frontend (frontend-engineer deactivated). v1.18 has no frontend; decks are markdown (lead-developer territory); the MCP server exposes tools to an AI agent, not a web UI. The frontend-engineer persona stays deactivated (PERSONAS.md v1.18 roster). No reactivation trigger in this milestone.