Financial artifacts
Two things distinguish a financial artifact from a generic dashboard: the numbers must be
provable, and the as-of must be explicit. Everything below follows from those.
For general visual craft, use Chartroom's concrete artifact-architecture, visual-hierarchy,
chart-selection, and artifact-testing skills when that companion pack is installed. If it is
not installed, follow the conventions and degraded mode below; this skill remains self-contained.
Tier 1 — the as-of snapshot (default)
Build this unless liveness is explicitly required. Data pulled at build time, baked into a
self-contained page, stamped with the as-of.
Why this is the default rather than a fallback:
- A board number that silently changes is a defect. If the deck said $4.82M on Tuesday and reads
$4.79M on Thursday because a late invoice posted, you have created a credibility problem, not a
freshness feature.
- It is reproducible. Six months later the page still shows what was reported, which is the
whole basis of an audit trail.
- It needs no runtime capability, so it works on the most restricted seat.
- It can be shared, which a connector-backed page cannot (see below).
Every snapshot artifact carries a provenance footer. Not optional:
As-of 2026-08-19 14:20 ET | Period Jul 2026 (closed)
Source bq://finance.gl_summary snapshot 2026-08-05T09:00Z | Run 2026-07-close
Tie-out PASS - subscription revenue agrees to GL 4100 within $0.00
Tier 2 — live connector mode (conditional)
A published artifact can call the viewer's claude.ai connectors via the mcp runtime capability.
Two hard constraints follow, and both are commonly discovered too late:
- The source must be a claude.ai connector on the organization's account. A BigQuery or Sheets
MCP server configured locally on your laptop is not reachable from a published page. If your
org has not exposed BigQuery as a connector, live mode is unavailable regardless of your local
setup.
- A page declaring connector access cannot be shared publicly. It is a viewer-consented grant,
so each viewer authenticates as themselves. For financial data that is the correct security
posture — and it is also a distribution constraint. A board pack that only opens for people with
warehouse credentials is not a board pack.
Before writing a connector call, load the host's artifact-capabilities skill when available
and read its type definitions. If that platform skill is unavailable, do not guess a connector
shape: ship the Tier 1 snapshot and state that live mode was unavailable. Then:
- Observe one real request/response pair per tool before publishing. Never guess argument names
or result encoding. If you cannot safely observe one, say so at publish time rather than shipping a
guessed shape.
- Learn the shape, discard the values. Real figures never become placeholder content in the page.
- Handle
null from claude.use("mcp") — that is the unavailable case, and the page must degrade to
its snapshot rather than render empty.
- Drive freshness UI from the result's cache timestamp, and show it. A live page that cannot say
how stale it is, is worse than a snapshot that can.
When live mode is right: an operational monitor someone watches during the day — cash position,
collections, pipeline, daily bookings. When it is wrong: anything reported, sent, or presented.
Chart conventions for financial data
Bridges / waterfalls — the highest-value financial chart
Use for any movement between two states: ARR, revenue, EBITDA, cash, headcount.
- Anchor bars (opening, closing) sit on the baseline; movement bars float
- Connector lines between bars — without them the eye cannot follow the cumulative
- Consistent sign colour: increases one hue, decreases another, anchors neutral. Never red/green
alone — pair with position and label so it survives colourblindness and greyscale printing
- Label every bar with its value. A bridge the reader must estimate from axis position has
failed at its one job
- The bars must sum exactly to the endpoint. If they do not, the decomposition is wrong — fix the
analysis, never plug the chart
- "Other" stays below the investigation floor or gets broken out
Cohort heatmaps
- Rows = cohort (acquisition month), columns = periods since acquisition
- Show cohort size beside each row. 120% retention on 4 customers is one upsell
- Suppress cells under 5 entities — noise, and per
finance-guardrails Rail 5 potentially
identifying
- Mark immature periods explicitly rather than truncating them; silently dropping the incomplete tail
biases the curve upward
- Sequential colour scale, not diverging — unless you are showing variance against a target, which
is a different chart
Actual vs budget / forecast
- Plot the variance, not two lines the reader has to subtract mentally
- Band the acceptable range so "on track" is visible without arithmetic
- State the comparison basis in the title: "vs Plan (Board approved 2026-01)" — plan versions
multiply, and an unlabelled "plan" is unreconcilable later
Benchmark bands (SaaS metrics)
- Draw the stage-appropriate range as a band, plot your value against it
- Label the stage in the chart. A mid-market band on a seed-stage company is misleading even
when the numbers are right (see
saas-metrics)
- Cite the benchmark source and vintage in a caption
Time series
- Zero baseline for anything additive (revenue, cash, headcount). Truncating the axis to dramatize a
trend is the most common chart lie in finance
- Truncation is acceptable for rates and ratios, where zero is not meaningful — say so in the axis
label
- Mark period boundaries and any definition change with an annotation. A metric that changed
definition mid-series needs a visible break, not a smooth line
Never
Dual axes (they encode an arbitrary relationship as a visual correlation), pie charts for anything
with more than three slices or any time dimension, 3D effects, and any chart whose caption restates
its title instead of stating the takeaway.
Sign conventions
Pick one, state it in the page, never mix within a view:
| Convention |
Reads well for |
| Expenses positive, subtracted in the roll-up |
P&L tables that mirror the statements |
| Expenses negative, added in the roll-up |
Bridges and waterfalls, where direction is the point |
For cash flows, outflows negative, always — a cash chart with positive outflows will be misread
by someone, and that someone will be in a board meeting.
Wrap negatives in parentheses in tables (accounting convention), use a minus sign in charts (reads
correctly at small sizes and in labels).
Numbers in the page
- Right-align all numerics. Tabular figures (
font-variant-numeric: tabular-nums) so digits
align across rows
- Thousands separators always; consistent decimal places within a column
- State units once in the header (
$K, $M, %), not on every cell
- Do not show more precision than the number has. An ARR figure derived from a rounded extract
displayed to the cent is a false precision claim
- Percentages: state whether a change is percentage points or percent. "NRR fell 4%" and "NRR fell 4
points" are different claims and the difference matters
Suppression and disclosure
Before publishing, per finance-guardrails Rail 5:
Build checklist
Degraded mode
No artifact publishing: produce a self-contained local HTML file with identical content. Every
convention above applies to a local file exactly as it does to a published page.
No connector access: Tier 1, which is the default anyway. State in the footer that the page is a
snapshot, so nobody assumes it refreshes.
No warehouse access at build time: build the page against a CSV extract someone provides, and
carry the extract's own as-of rather than the build time. Those are different timestamps and
conflating them misstates the data's age.
Going deeper
This skill is the finance-facing summary. The full craft — hand-built SVG charting under a strict
CSP, bridge/cohort/variance/uncertainty/flow chart design, financial table layout, theming,
accessibility, interaction patterns, and a tested dependency-free chart kit — lives in the companion
pack:
chartroom — 27 skills plus chartkit.js
/plugin marketplace add Lukehle/chartroom
Reach for it when you are actually building the page rather than deciding what belongs on it. Of
particular use here: bridge-charts (the ARR and cash bridges this skill calls for, with a footing
check in code), financial-tables, chart-annotation, and artifact-testing.
Related skills
- Chartroom
artifact-architecture, visual-hierarchy, chart-selection, and
artifact-testing — optional companion craft; use the snapshot fallback when absent
- Host
artifact-capabilities — conditional connector reference; never required for Tier 1
tie-out — the proof behind every figure on the page
saas-metrics — definitions and benchmark bands
flux-analysis — the bridges this skill renders
startup-board-pack — what goes on which slide
warehouse-sql / sheets-bridge — where the data comes from
1---2name: fin-artifact3description: Build financial dashboards and reporting artifacts backed by BigQuery, Google Sheets, or a warehouse extract - in two tiers, an as-of snapshot by default and a live connector mode when the organization exposes one. Carries the finance visualization conventions - ARR and cash bridges, cohort heatmaps, actual-vs-budget variance bands, sign conventions, benchmark bands, suppression rules. Use when building any chart, dashboard, board visual, or data-backed page for financial data. Trigger on "dashboard", "build a chart", "visualize", "live board pack", "board visual", "EBITDA waterfall", "bridge chart", "cohort chart", "financial dashboard", "wire it to the warehouse".4---56# Financial artifacts78Two things distinguish a financial artifact from a generic dashboard: **the numbers must be9provable**, and **the as-of must be explicit**. Everything below follows from those.1011For general visual craft, use Chartroom's concrete `artifact-architecture`, `visual-hierarchy`,12`chart-selection`, and `artifact-testing` skills when that companion pack is installed. If it is13not installed, follow the conventions and degraded mode below; this skill remains self-contained.1415---1617## Tier 1 — the as-of snapshot (default)1819**Build this unless liveness is explicitly required.** Data pulled at build time, baked into a20self-contained page, stamped with the as-of.2122Why this is the default rather than a fallback:2324- **A board number that silently changes is a defect.** If the deck said $4.82M on Tuesday and reads25 $4.79M on Thursday because a late invoice posted, you have created a credibility problem, not a26 freshness feature.27- **It is reproducible.** Six months later the page still shows what was reported, which is the28 whole basis of an audit trail.29- **It needs no runtime capability**, so it works on the most restricted seat.30- **It can be shared**, which a connector-backed page cannot (see below).3132Every snapshot artifact carries a provenance footer. Not optional:3334```35As-of 2026-08-19 14:20 ET | Period Jul 2026 (closed)36Source bq://finance.gl_summary snapshot 2026-08-05T09:00Z | Run 2026-07-close37Tie-out PASS - subscription revenue agrees to GL 4100 within $0.0038```3940---4142## Tier 2 — live connector mode (conditional)4344A published artifact can call **the viewer's claude.ai connectors** via the `mcp` runtime capability.45Two hard constraints follow, and both are commonly discovered too late:46471. **The source must be a claude.ai connector on the organization's account.** A BigQuery or Sheets48 MCP server configured locally on your laptop is *not* reachable from a published page. If your49 org has not exposed BigQuery as a connector, live mode is unavailable regardless of your local50 setup.512. **A page declaring connector access cannot be shared publicly.** It is a viewer-consented grant,52 so each viewer authenticates as themselves. For financial data that is the correct security53 posture — and it is also a distribution constraint. A board pack that only opens for people with54 warehouse credentials is not a board pack.5556Before writing a connector call, load the host's `artifact-capabilities` skill **when available**57and read its type definitions. If that platform skill is unavailable, do not guess a connector58shape: ship the Tier 1 snapshot and state that live mode was unavailable. Then:5960- **Observe one real request/response pair per tool before publishing.** Never guess argument names61 or result encoding. If you cannot safely observe one, say so at publish time rather than shipping a62 guessed shape.63- **Learn the shape, discard the values.** Real figures never become placeholder content in the page.64- Handle `null` from `claude.use("mcp")` — that is the unavailable case, and the page must degrade to65 its snapshot rather than render empty.66- Drive freshness UI from the result's cache timestamp, and **show it**. A live page that cannot say67 how stale it is, is worse than a snapshot that can.6869**When live mode is right:** an operational monitor someone watches during the day — cash position,70collections, pipeline, daily bookings. **When it is wrong:** anything reported, sent, or presented.7172---7374## Chart conventions for financial data7576### Bridges / waterfalls — the highest-value financial chart7778Use for any movement between two states: ARR, revenue, EBITDA, cash, headcount.7980- Anchor bars (opening, closing) sit on the baseline; movement bars float81- Connector lines between bars — without them the eye cannot follow the cumulative82- Consistent sign colour: increases one hue, decreases another, anchors neutral. Never red/green83 alone — pair with position and label so it survives colourblindness and greyscale printing84- **Label every bar with its value.** A bridge the reader must estimate from axis position has85 failed at its one job86- The bars must sum exactly to the endpoint. If they do not, the decomposition is wrong — fix the87 analysis, never plug the chart88- "Other" stays below the investigation floor or gets broken out8990### Cohort heatmaps9192- Rows = cohort (acquisition month), columns = periods since acquisition93- **Show cohort size** beside each row. 120% retention on 4 customers is one upsell94- **Suppress cells under 5 entities** — noise, and per `finance-guardrails` Rail 5 potentially95 identifying96- Mark immature periods explicitly rather than truncating them; silently dropping the incomplete tail97 biases the curve upward98- Sequential colour scale, not diverging — unless you are showing variance against a target, which99 is a different chart100101### Actual vs budget / forecast102103- **Plot the variance, not two lines the reader has to subtract mentally**104- Band the acceptable range so "on track" is visible without arithmetic105- State the comparison basis in the title: "vs Plan (Board approved 2026-01)" — plan versions106 multiply, and an unlabelled "plan" is unreconcilable later107108### Benchmark bands (SaaS metrics)109110- Draw the stage-appropriate range as a band, plot your value against it111- **Label the stage in the chart.** A mid-market band on a seed-stage company is misleading even112 when the numbers are right (see `saas-metrics`)113- Cite the benchmark source and vintage in a caption114115### Time series116117- Zero baseline for anything additive (revenue, cash, headcount). Truncating the axis to dramatize a118 trend is the most common chart lie in finance119- Truncation is acceptable for rates and ratios, where zero is not meaningful — say so in the axis120 label121- Mark period boundaries and any definition change with an annotation. A metric that changed122 definition mid-series needs a visible break, not a smooth line123124### Never125126Dual axes (they encode an arbitrary relationship as a visual correlation), pie charts for anything127with more than three slices or any time dimension, 3D effects, and any chart whose caption restates128its title instead of stating the takeaway.129130---131132## Sign conventions133134Pick one, state it in the page, never mix within a view:135136| Convention | Reads well for |137|---|---|138| Expenses **positive**, subtracted in the roll-up | P&L tables that mirror the statements |139| Expenses **negative**, added in the roll-up | Bridges and waterfalls, where direction is the point |140141For cash flows, **outflows negative, always** — a cash chart with positive outflows will be misread142by someone, and that someone will be in a board meeting.143144Wrap negatives in parentheses in tables (accounting convention), use a minus sign in charts (reads145correctly at small sizes and in labels).146147---148149## Numbers in the page150151- **Right-align all numerics.** Tabular figures (`font-variant-numeric: tabular-nums`) so digits152 align across rows153- Thousands separators always; consistent decimal places within a column154- State units once in the header (`$K`, `$M`, `%`), not on every cell155- **Do not show more precision than the number has.** An ARR figure derived from a rounded extract156 displayed to the cent is a false precision claim157- Percentages: state whether a change is percentage points or percent. "NRR fell 4%" and "NRR fell 4158 points" are different claims and the difference matters159160---161162## Suppression and disclosure163164Before publishing, per `finance-guardrails` Rail 5:165166- [ ] No customer-identifying detail below the aggregation threshold (5+ entities, none over 50%)167- [ ] No employee compensation detail, no individually-identifying pay figures168- [ ] No account numbers, tax IDs, or credentials anywhere in the page or its source169- [ ] Suppressed cells are **marked as suppressed**, not silently blank — a blank reads as zero170- [ ] Publishing is a deliberate step. Artifacts start private; sharing is the user's decision, and171 distributing financial data is exactly the kind of action that gets confirmed first172173---174175## Build checklist176177- [ ] Every figure has a `tie-out` block behind it, and the page says PASS178- [ ] As-of, period, and period status (open/closed) are visible on the page179- [ ] Source and snapshot identifier in the footer180- [ ] Tier stated — snapshot or live; if live, the freshness indicator works and the null path181 degrades to snapshot182- [ ] Metric definitions available in the page (a definitions panel, or a link)183- [ ] Charts obey the conventions above; bridges foot exactly184- [ ] Suppression checklist clean185- [ ] Renders in both light and dark, and prints legibly in greyscale — board packs get printed186- [ ] Self-contained: no external CDN, font, or script requests187188---189190## Degraded mode191192**No artifact publishing:** produce a self-contained local HTML file with identical content. Every193convention above applies to a local file exactly as it does to a published page.194195**No connector access:** Tier 1, which is the default anyway. State in the footer that the page is a196snapshot, so nobody assumes it refreshes.197198**No warehouse access at build time:** build the page against a CSV extract someone provides, and199carry the extract's own as-of rather than the build time. Those are different timestamps and200conflating them misstates the data's age.201202---203204## Going deeper205206This skill is the finance-facing summary. The full craft — hand-built SVG charting under a strict207CSP, bridge/cohort/variance/uncertainty/flow chart design, financial table layout, theming,208accessibility, interaction patterns, and a tested dependency-free chart kit — lives in the companion209pack:210211> **[chartroom](https://github.com/Lukehle/chartroom)** — 27 skills plus `chartkit.js`212> `/plugin marketplace add Lukehle/chartroom`213214Reach for it when you are actually building the page rather than deciding what belongs on it. Of215particular use here: `bridge-charts` (the ARR and cash bridges this skill calls for, with a footing216check in code), `financial-tables`, `chart-annotation`, and `artifact-testing`.217218---219220## Related skills221222- Chartroom `artifact-architecture`, `visual-hierarchy`, `chart-selection`, and223 `artifact-testing` — optional companion craft; use the snapshot fallback when absent224- Host `artifact-capabilities` — conditional connector reference; never required for Tier 1225- `tie-out` — the proof behind every figure on the page226- `saas-metrics` — definitions and benchmark bands227- `flux-analysis` — the bridges this skill renders228- `startup-board-pack` — what goes on which slide229- `warehouse-sql` / `sheets-bridge` — where the data comes from