Skip to content

Tier 1 static-surface verdict

Module 13 treats Tier 1 as the durable, authored, static layer over the analytical contract from ADR-0006. The Tier 1 candidate is not the place for open-ended BI editing or natural-language exploration. It is the place where an analyst writes down the reference argument, binds it to DuckDB-backed data, and ships a static artefact that can live beside the docs site and be reviewed in git. The head-to-head prototype compared the incumbent Evidence dashboards with two sibling challengers, Observable Framework and Quarto, using the same three reference views: the Pareto view, the constraint-history view, and the per-publisher metric breakdown.

Verdict: Observable Framework is the Tier 1 winner.

The short version is that Observable gives the tutorial the best static data app shape without leaving the local-first constraint. Evidence loses because it is excellent for SQL-led dashboards but too narrow once the lesson needs richer layout and client-side state. Quarto loses because it is the clearest narrative reporting tool, but the dashboard interaction has to be assembled by hand once the page moves past prose and figures. The losing prototypes remain runnable in the repo: Evidence stays in tutorial/analyst-dashboards/, Quarto stays in tutorial/analytical-surfaces/tier-1/quarto/, and neither is deleted by this verdict.

Evidence has the friendliest first five minutes for a SQL-fluent analyst. A page is markdown, a fenced SQL block becomes a named result set, and the chart components read like dashboard vocabulary. That is why it was a good incumbent: the syntax makes the analytical contract feel deployed without asking the author to build an application. The cost appears when the page wants to become more than a sequence of Evidence components. The authoring surface is shaped around Evidence’s component model, so custom layout and data transformation move from “write the argument” to “work around the dashboard grammar.”

Observable feels more like a small static application. The source page is still markdown, but the live cells are JavaScript and the charting layer is just code. That is a higher bar than Evidence for someone who only wants SQL and a bar chart. It is also the reason Observable wins this tier. The tutorial’s Tier 1 surface needs to carry a product-like reference experience: controls, small-multiple layout, tables, notes, and exception handling on the same page. Observable lets those pieces share one data object and one reactive runtime without turning the output into a server application.

Quarto has the best prose posture. It is the easiest tool for a long-form analyst note where code supports a written argument and the generated page should feel like a report. That matters for this tutorial because the surfaces are lessons, not only charts. The weakness is the same as the strength: once the comparison asks for browser-side filtering, compact cards, or a repeated view over eight metrics, Quarto pushes the author toward custom JavaScript anyway. At that point the Quarto document is hosting a small app rather than being the natural app surface.

All three candidates can stay local-first. Evidence already builds into the Cloudflare Pages artefact at /dashboard/, so it has the strongest deployed precedent. It reads the DuckDB warehouse through the existing source setup and fits the “static dashboard beside docs” shape from ADR-0021. The downside is that the existing Evidence project is a separate dashboard product with its own conventions. Productionising the whole Tier 1 module there would preserve today’s route, but it would keep the tutorial tied to Evidence’s page model.

Observable’s build pipeline is explicit: ask the storage module for the read-only analytical snapshot, generate the reference-view JSON, then let Observable Framework build static files. That extra data-loader step is a good trade for this repo because it makes the boundary honest. DuckDB remains the analytical contract; the static site gets a checked build process and a serialised data artefact at build time. The page can then use browser-side controls without a live database. That is the right Tier 1 contract: static output, deterministic build, local source data.

Quarto’s pipeline is also understandable, but it adds a toolchain dependency outside the Node workspace. The quarto render command is normal for analysts, and the pre-render hook can regenerate the same JSON as Observable. For this repo, though, the production path wants one docs-oriented static app pipeline more than it wants a general publishing system. Quarto is a credible report generator, but it is less natural as the canonical dashboard-like surface that will replace or re-home the incumbent Evidence pages.

Evidence’s chart components are useful because they are constrained. A SQL query can become a scatter plot, table, or bar chart without much ceremony. That keeps an analyst out of frontend code and makes a page reviewable by reading markdown and SQL. The constraint becomes visible in the Tier 1 prototype’s “17th column” question: when a real metric breakdown gains another metric, another publisher attribute, or another policy annotation, the author needs more control over grouping, filtering, labels, and explanatory layout.

Observable has the deepest answer here. Observable Plot covers the reference chart shapes cleanly, and Observable Inputs give the static page a real browser interaction layer. The constraint-history view can filter by actor and date range after the build. The per-publisher metrics can be rendered as repeated small multiples without asking the author to predeclare every tile in a dashboard grammar. The output is still static HTML and JavaScript; the interactivity does not imply a BI server.

Quarto can produce charts in several ways, and that breadth is attractive for analysts who already live in Python, R, or notebook-style publishing. In this prototype, however, the useful browser interaction came from custom JavaScript included inside the Quarto page. That works, but it weakens Quarto’s case as the Tier 1 winner. If the canonical production surface needs custom JavaScript for the parts that make it feel like a dashboard, the tool whose native unit is reactive JavaScript should be the default.

The per-publisher view is the strongest test of the comparison because the source datasets do not line up perfectly. EB-NeRD, Adressa, and MIND share the unified impression contract, but they do not carry identical upstream meaning. Adressa lacks sentiment signal in the same shape as the other sources. MIND has a different category taxonomy. The Tier 1 surface must make those differences visible without turning every chart into a footnote.

Evidence can show the unified metrics and add prose around the missing pieces. That is good enough for stable dashboards where the question is known and the reader accepts a little explanation around the chart. It is less good when the page needs to reshape the display around missingness: show a callout, suppress a misleading mark, keep the metric grid balanced, and still let the reader compare publishers.

Observable handles that pattern most cleanly because missingness can stay in the same data flow as rendering. The page can map each publisher-metric pair, decide whether the value is measured, not applicable, or absent, and render the right mark or note without splitting the lesson into special-case sections. That matters for the tutorial’s domain language. Graceful degradation should be shown as an analytical-contract behaviour, not hidden as a dashboard footnote.

Quarto is clear when the degradation needs narrative treatment. It is easy to write “Adressa lacks sentiment” and “MIND uses a different taxonomy” beside a figure. It is less ergonomic when the page should carry that distinction across a grid of many metric cards. The author can solve it with embedded scripts, but again the solution lives outside Quarto’s strongest authoring mode.

The “17th column” question asks what happens when the tidy prototype becomes real work. Three publishers and eight metrics are manageable in any of the tools. Seventeen columns, more policy annotations, new constraint versions, and a few null-heavy publisher fields are where the surface starts to reveal its true shape.

Evidence would probably remain the fastest path to a respectable dashboard. That is a real strength, especially for operational pages that are mostly SQL tables and standard charts. But the 17th column makes layout a product question: which fields collapse, which become tooltips, which become filters, and which are hidden until the reader asks for detail? Evidence can answer some of that, but the author spends more time negotiating with the framework.

Quarto would remain the best way to write the explanatory memo that accompanies the table. If the 17th column is mostly something to describe, Quarto is comfortable. If it is something the reader needs to filter, pivot, compare, and inspect at volume, Quarto drifts toward a custom web page.

Observable is the best fit once volume changes the design. The same page can load the build-time data, compute derived groups, expose a few controls, and render a compact view that does not pretend every column deserves the same visual weight. That flexibility is what Tier 1 needs before Tier 2 begins. Tier 2 will handle server-side BI exploration. Tier 1 still needs enough client-side structure to make the published reference page hold up under real analyst volume.

ADR-0025 captures the decision: Observable Framework becomes the Tier 1 production candidate. M13-S4 reproduces the current Evidence pages in Observable’s project shape while keeping the deployed /dashboard/ route stable. Evidence and Quarto remain in the repo as comparison artefacts. They are part of the lesson record, not failed branches to clean up.

The important boundary is that Observable wins Tier 1, not the whole analytical-surface module. Metabase and Rill still own the Tier 2 comparison for self-hostable BI. Nao still owns the Tier 3 conversational walkthrough. Observable wins the static reference layer because it gives the tutorial the best combination of authored prose, deterministic static output, layout flexibility, and browser-side interaction over the local DuckDB analytical contract.