Skip to content

Phase 7 — Extensibility, reports, docs polish

Status: Planned. See plan.md for the phase overview. Scope: extensibility proof + reports + polish items. Covers #12, #32, #14 Tier 2 subset, #28 Storybook, #F Astro site, gap-14 full engine parity, rolling observability artifacts, #O privacy banner. Predecessor: Phase 6 — Admin + ops + catalog. Successor: none committed; see phase-managed-hosting.md and phase-parking-lot.md for candidates.

Goal

Prove the adapter-by-design commitment (ADR-027) is real: ship the first non-default compute adapter (CLIMADA-in-sidecar) and the first non-CLIMADA ingest adapter (GEM). Deliver the Tier 2 reports subset (save scenario is in Phase 3; add standardized PDF + map snapshot here). Stabilise the redesign with Storybook, split the marketing surface into a dedicated Astro site, land full engine-parity coverage, publish performance / log-sensitivity / engine-cost artifacts, and add the privacy banner.

This is the last phase in the currently committed roadmap. After closing this, the backbone + UI are feature-complete for the researcher + agency personas; anything further is in the parking lot or managed-hosting track.

Entry conditions

  • Phase 6 closed: admin panel + catalog + ingest pipeline live.
  • ADR-027 (adapter-by-design) merged in Phase 3.
  • Scenario model + provenance shipped.
  • UI redesign (ADR-030) stabilised — Storybook can start without rotting.

Out of scope (deferred)

  • Managed hosting, K8s implementation — parked.
  • Stripe billing, custom report templates (#14e), bulk scenario submission, webhooks, map drawing tools, building-level / 3D, GPU engine — parking lot.
  • Scenario versioning (#P), data versioning (gap-8), frequency-curve uncertainty bands (#L) — parking lot / gated on engine work.
  • User-provided engines Level 3b — parking lot, security-sensitive.

Scope

7.1 — IngestAdapter ABC + registry (#12 architecture)

Context. Vision #12 Tier 3 architecture. Defines the IngestAdapter interface and a registry pattern so subsequent adapters (GEM, Hazus, OASIS LMF) plug in without backbone changes.

Acceptance criteria. - [ ] src/climate_lama/ingest/adapters/base.py defines the ABC: supports(mime_type, manifest), validate(path, manifest), ingest(path, manifest, dataset_id). - [ ] Registry mechanism via Python entry points (under climate_lama.ingest_adapters). Backbone discovers third-party adapters from installed packages. - [ ] Refactor existing CSV + XLSX upload paths (Phase 6) to sit behind the ABC as the two first-party adapters. - [ ] Unit tests: registry discovery, adapter selection per mime_type/manifest. - [ ] ADR-033 "IngestAdapter ABC + registry" in DECISIONS.md with **Phase**: 7 header — the sub-ADR under the ADR-027 parent.

Cross-stack: backbone. Linked ADR: authors ADR-033; sub-ADR of ADR-027. Suggested /analyze tier: 4 (Opus · high) — architectural refactor touching existing upload paths.


7.2 — First non-CLIMADA ingest adapter: GEM

Context. Vision #12 Tier 3 first alternative format. GEM exposure CSV is open, global building-stock standard — the lowest-friction non- CLIMADA format to prove the pattern.

Acceptance criteria. - [ ] New repo / package climate-lama-adapter-gem per ADR-027 packaging rule; publishes to PyPI. - [ ] Implements IngestAdapter ABC (7.1): ingests GEM exposure CSV; emits our exposure data model. - [ ] Backbone declares optional extra: pip install climate-lama[gem] pulls it. - [ ] Integration test: a real GEM sample CSV ingests successfully and appears in the catalog. - [ ] Docs-site page adapters/gem.md.

Cross-stack: new repo + backbone packaging metadata + docs. Linked ADR: references ADR-027, ADR-033. Suggested /analyze tier: 4 (Opus · high) — new repo + publish pipeline + schema mapping.


7.3 — CLIMADA compute engine adapter (#32, #24 Level 2)

Context. Vision #32 + #24 Level 2 reference implementation. A subprocess-based adapter invoking CLIMADA in a sidecar container, honouring ADR-024 (backbone never imports CLIMADA). Proves pluggable engines work end-to-end; acts as a compat bridge for CLIMADA users.

Acceptance criteria. - [ ] New repo climate-lama-adapter-climada with ClimadaEngineAdapter implementing ModelInterface from worker/models/base.py. - [ ] Adapter communicates with a CLIMADA sidecar container over a subprocess / IPC boundary — no import climada in the backbone or engine; the sidecar is the only process with CLIMADA installed. - [ ] Engine selection via X-Engine: climate_lama (default) or X-Engine: climada header on POST /v1/compute/impact. Request routing lives in worker/models/registry.py. - [ ] Input/output contracts match the existing ModelInterface; adapter translates to/from CLIMADA types. - [ ] Integration test: same inputs through both engines, impact matrices within 1% (ties to 7.7 parity harness). - [ ] Docs-site page engines/climada-adapter.md explaining when to use it (compat bridge, validation) and when not (default path stays climate-lama-engine). - [ ] ADR-034 "Engine registry + request-time dispatch" as the sub-ADR under ADR-027 / #N; **Phase**: 7 header.

Cross-stack: new repo + backbone (registry + dispatch) + worker (adapter loading). Linked ADR: authors ADR-034. Suggested /analyze tier: 5 (Opus · extra high) — CLIMADA-isolation- adjacent (rubric bump), cross-process IPC, load-bearing.


7.4 — Standardized PDF report (#14a+d+b Tier 2 subset)

Context. Vision #14 Tier 2 subset: save scenario already shipped in Phase 3; this delivers the standardized PDF report via Quarto + the light map-snapshot via canvas export.

Acceptance criteria. - [ ] Celery task render_report(scenario_id, template="standard") invokes Quarto with a .qmd template + scenario data, writes the PDF to reports/{org_id}/{report_id}.pdf per ADR-029. - [ ] Standard template: cover, summary metrics, map, frequency curve, cost-benefit, methodology, sources (attribution), reproducibility stamp (Phase 3 #3.8). - [ ] POST /v1/scenarios/{id}/reports triggers render; GET /v1/scenarios/{id}/reports/{report_id} returns the PDF. - [ ] Quarto container added to the stack; CI smoke test renders one sample report. - [ ] UI: "Export report" button on scenario view; progress indicator; download when done. - [ ] Map snapshot light: leaflet-image equivalent for MapLibre (native map.getCanvas().toDataURL()) — saves current view as PNG embedded in the report. - [ ] Custom templates (#14e) remain out of scope (Tier 4).

Cross-stack: backbone + worker + UI + infra (Quarto container). Linked ADR: short ADR "Quarto as report generator" optional — author if the /build agent hits non-obvious trade-offs. Suggested /analyze tier: 5 (Opus · extra high) — multi-component (worker + template + UI + infra), new dep with real ops implications, failure modes numerous.


7.5 — Storybook (#28 Tier 3)

Context. Vision #28 Tier 3 Storybook. Introduced now that redesign (ADR-030) has stabilised — stories won't rot on day one. Scope: shared components only; not every page.

Acceptance criteria. - [ ] Storybook project at climate-lama-ui/.storybook/ with Vite integration. - [ ] Stories for shared components: buttons, panels, chart wrappers, layer toggle, InfoIcon, ErrorDisplay, ImpactFunctionChart, brand-aware theme preview. - [ ] CI job builds Storybook on PR; static bundle deployed alongside the docs site (or Netlify preview — decide during /build). - [ ] Visual-regression tooling (Chromatic / Percy) deferred — note in docs why. - [ ] Docs-site page contributing/storybook.md for contributor onboarding.

Cross-stack: UI + CI + docs. Linked ADR: none. Suggested /analyze tier: 3 (Sonnet · high).


7.6 — Astro marketing site (#F)

Context. Landing site placement resolution: start with MkDocs Material's landing page (Phase 3 #3.6); now split to a dedicated Astro site in climate-lama-site repo. Mobile-shareable demo URL is the argument; docs and marketing diverge enough that keeping them fused hurts both.

Acceptance criteria. - [ ] New repo climate-lama-site with Astro scaffold. - [ ] Pages: landing (hero + features + CTA to docs/quickstart + CTA to GitHub), a "why Climate-Lama" narrative, pricing placeholder (empty until managed hosting goes live), contact. - [ ] Mobile-first responsive; Lighthouse score ≥90 on mobile. - [ ] Deploy pipeline: Cloudflare Pages or Netlify, auto-deploy on push to main, preview URLs on PR. - [ ] Content migrated: the MkDocs landing page in Phase 3 reverts to a neutral docs home; the marketing copy moves to Astro. - [ ] Docs site links to the marketing site from its header; marketing site links to docs from every page. - [ ] **Phase**: 7 noted in the repo README.

Cross-stack: new repo + docs updates. Linked ADR: none. Suggested /analyze tier: 4 (Opus · high) — new repo, design copy, deploy pipeline.


7.7 — Full engine parity coverage (gap-14)

Context. Phase 3 #3.12 shipped the parity harness scaffold + one working comparison. This item expands coverage to all four hazards (RF, TC, WF, WS) and a matrix of scenarios + exposures, publishes a parity report, and commits to a tolerance policy.

Acceptance criteria. - [ ] Parity tests cover: RF × Greek buildings, TC × global coastal exposure, WF × Mediterranean, WS × Western Europe — each at present + 2050 RCP4.5 + 2050 RCP8.5. - [ ] Per-metric tolerances documented in tests/parity/tolerances.yaml: EAD within 1%, AAI within 1%, frequency-curve points within 2% at each return period. - [ ] Parity report generated as part of the CI workflow (still gated by workflow_dispatch — long-running); published to docs site under architecture/engine-parity-report.md. - [ ] Known discrepancies (if any) documented with root-cause analysis; decide whether to align the engine, accept the deviation (with rationale), or file an engine issue.

Cross-stack: tests + docs. Linked ADR: none; extends #3.12 scaffold. Suggested /analyze tier: 5 (Opus · extra high) — research-flavored ambiguity, numerical correctness, CLIMADA-adjacent.


7.8 — Rolling observability artifacts (gap-10/11/12)

Context. Vision gaps 10 (performance budgets), 11 (cost of engine calls), 12 (log-sensitivity classification) — all Tier 3 "publish as we go." This item batches them into a single rolling publication.

Acceptance criteria. - [ ] docs/architecture/performance-budgets.md published with benchmarks: "100k points: <1s; 1M points: ~10s; 10M points: plan ahead." Ties to Phase 4 #4.11 Playwright perf tests. - [ ] docs/architecture/engine-call-cost.md: CPU-seconds + memory envelope per hazard × dataset-size combination, read from the usage_events table (Phase 6 #6.11). - [ ] docs/architecture/log-sensitivity.md: classifies each structlog field as PII / tenant-metadata / operational / debug. Introduces a per-deployment filter config that can redact PII fields at the structlog processor level. - [ ] Log sensitivity filter config documented with a worked example for a regulated self-hoster. - [ ] CI job regenerates the performance budget doc on every Playwright perf run so it stays fresh.

Cross-stack: docs + small backbone change (structlog filter config). Linked ADR: none. Suggested /analyze tier: 3 (Sonnet · high).


7.9 — Privacy / data residency banner (#O)

Context. Vision #O Tier 3. "No external calls, no telemetry, your data stays here" surfaced in marketing + UI footer. Already true per plan.md; just needs to be a marketed feature.

Acceptance criteria. - [ ] UI footer component: "Self-hosted • No external calls • Your data stays here" with link to concepts/privacy.md. - [ ] Astro marketing site (7.6) has a "Privacy & data residency" section on landing + a dedicated /privacy page. - [ ] Docs-site page concepts/privacy.md enumerates the guarantees: no egress, no telemetry, self-host-only compute, attribution of third-party data sources (which may have their own terms). - [ ] Verify: a backbone instance run without any external network access (Docker network with internal: true) starts + serves + completes one compute job. CI job captures the verification.

Cross-stack: UI + marketing site + docs + CI. Linked ADR: none. Suggested /analyze tier: 3 (Sonnet · high).


ADRs authored in this phase

ID Title Owner work item
ADR-033 (approx.) IngestAdapter ABC + registry 7.1
ADR-034 (approx.) Engine registry + request-time dispatch 7.3

Numbers assigned at merge time; may shift.

Exit criteria

  • All 9 work items closed.
  • pip install climate-lama[climada] pulls the CLIMADA adapter and the X-Engine: climada header routes compute to it.
  • pip install climate-lama[gem] pulls the GEM ingest adapter and a GEM CSV ingests successfully.
  • Standardized PDF report renders end-to-end and is downloadable from the UI.
  • Engine parity report published; known discrepancies documented.
  • Astro marketing site live at the project's public URL.
  • Storybook bundle deployed alongside docs.
  • Privacy guarantee verified by CI (instance boots + computes with no network egress).

Risks

  • 7.3 CLIMADA adapter is the single most complex item in the phase. Subprocess IPC, CLIMADA install in a sidecar, input/output translation all have sharp edges. Budget the highest /analyze tier; /build --review mandatory.
  • 7.4 report rendering via Quarto adds a container + a heavy dep; if the ops overhead turns out to be painful, descope to WeasyPrint as a fallback path documented in the report ADR.
  • 7.7 parity coverage can discover real engine bugs. Treat engine bugs as Phase 1/engine-repo issues, not blockers on this phase — the parity work's deliverable is the report, not the fixes.
  • 7.6 Astro site — ongoing content maintenance. Keep the scope tight: landing + 3-4 static pages. Growing it is a future phase.