# Dashboard

<!-- BEGIN GENERATED: guide-map -->
## Guide map

Read only the section needed for the next decision. Line ranges are exact
for this generated runtime target.

| Section | What it covers | Lines |
| --- | --- | --- |
| [Purpose](#purpose) | Scope, ownership, and the central operating question. | 27-38 |
| [Use This When](#use-this-when) | Tasks and conditions that belong in this guide. | 39-50 |
| [Do Not Use This For](#do-not-use-this-for) | Boundaries and the correct routes for excluded work. | 51-66 |
| [Mental Model](#mental-model) | Concepts and state boundaries needed for correct operation. | 67-83 |
| [Preflight](#preflight) | State, authority, inputs, and readiness to verify before execution. | 84-98 |
| [Risk And Side Effects](#risk-and-side-effects) | Effects, approvals, cost, privacy, and retry boundaries. | 99-107 |
| [Embedding Untrusted Strings In HTML](#embedding-untrusted-strings-in-html) | The SDK already handles this for you when you go through `vf.viz.spreadsheet(...)` and `vf.viz.pipeline_visualizer(...)`: row contents, step notes, view labe... | 108-119 |
| [Canonical Operating Pattern](#canonical-operating-pattern) | The normal end-to-end execution sequence. | 120-130 |
| [Core SDK Surfaces](#core-sdk-surfaces) | Exact source-backed callable contracts owned by this guide. | 131-139 |
| [Data Contracts](#data-contracts) | Required identities, fields, evidence, handles, and durable shapes. | 140-151 |
| [Examples](#examples) | Representative usage patterns and code. | 152-196 |
| [Verification](#verification) | Evidence required before reporting success. | 197-206 |
| [Troubleshooting](#troubleshooting) | Failure diagnosis and corrective routes. | 207-216 |
| [Related References](#related-references) | Adjacent boundaries and when to cross them. | 217-227 |
<!-- END GENERATED: guide-map -->

## Purpose

Use `vf.viz.*` for first-class standalone HTML visualization: a self-contained
spreadsheet over already-produced rows, or a simple pipeline overview that
links to step HTML files in a Play/script folder.

This guide is intentionally narrower than `workflow_reports.md`. Dashboard
helpers write standalone `.html` files for fast audit, initialization, and
debugging. They do not produce the editable Svelte Play app, sidecars, static
`dist/` bundle, or workspace `/plays` Play UI output produced by
`vf.reports.*`.

## Use This When

- You already have rows in Python, JSON, CSV, or a script pipeline
  and need a quick inspectable HTML spreadsheet.
- A Play folder uses `visualization/step_*.html`, `pipeline.html`, or
  `dashboard.html` for fast row or step inspection.
- You need a standalone audit artifact with sortable columns, search, filters,
  saved views, pagination, and row detail without running the Play report
  renderer.
- You need a pipeline overview that links to existing per-step HTML files for
  debugging a pipeline or initialized Play scaffold.

## Do Not Use This For

- Generated Workflow Play final outputs, report sidecars, Play UI bundles, or
  `/plays` snapshots. Use `workflow_reports.md`.
- Workflow run status, event history, output manifests, or local operations
  status dashboards. Use `workflow_operations.md` and
  `vf.workflows.status_report(...)`.
- Same-machine job-progress dashboards or `vf.log.*` JSONL telemetry.
  Use `logging.md`.
- Provider work, audience discovery, CRM fetches, enrichment, qualification,
  sequence staging, publish, send, or billing/domain actions.
- Large production datasets where inline `ROWS` would make the HTML slow to
  load. Use artifacts/report sidecars or a paged frontend/grid path instead.
- Final GTM Play report design. Start with `workflow_composition.md` and
  `workflow_reports.md`; use this file for standalone visualization.

## Mental Model

`vf.viz.*` is standalone HTML glue. It is useful when the output should be a single
file an agent can open or hand-edit during debugging. It is not an SDK runtime,
not a data source, not a report builder, and not an activation surface.

Comparison with `workflow_reports.md`:

| Dimension | `dashboard.md` / `vf.viz.*` | `workflow_reports.md` / `vf.reports.*` |
| --- | --- | --- |
| Primary use | Standalone audit HTML, initialized Play spreadsheet views, and pipeline views. | Final business-facing Workflow Play report UI. |
| Output | One standalone `.html` file per spreadsheet/pipeline. | Editable Vite/Svelte Play app plus sidecars and optional static `dist/`. |
| Data contract | Inline `ROWS` JavaScript array and hand-editable constants. | `rows.json`, `rows.csv`, `summary.json`, `manifest.json`, `play_spec.json`. |
| UI model | Generic table, saved filters, optional hand-written map/cluster extension. | Typed views: tables, cards, maps, graphs, charts, timelines, evidence galleries, row drawers. |
| Publish/sync path | None by itself. | Static bundle can be included in `vf.workflows.sync(...)` / daemon auto-sync. |
| Best for | Inspecting rows or step outputs quickly. | Productionizing a Workflow Play output. |

## Preflight

1. Confirm rows already exist. Do not use dashboard helpers to fetch or enrich
   data.
2. Decide whether this is a quick standalone audit view or a final Play output. If
   final, stop and use `workflow_reports.md`.
3. Choose an intentional output path. Python `vf.viz.spreadsheet(...)` writes
   exactly to that path; CLI `verbiflow viz create ...` has separate
   non-overwrite behavior unless `--force` is passed.
4. Keep row payloads small enough for inline HTML. If the row count is large or
   rows contain huge blobs, hide bulky keys with `ignore_keys` or use report
   sidecars instead.
5. If adding saved views, remember each `where` value is literal JavaScript
   predicate source, not a Python lambda.

## Risk And Side Effects

| Operation | Risk | Rule |
| --- | --- | --- |
| `vf.viz.spreadsheet(...)` | local file write | Writes a standalone HTML file at the requested path. Inspect row count and output path. |
| `vf.viz.pipeline_visualizer(...)` | local file write | Writes an overview HTML that links to local step files. It does not inspect workflow SQLite state. |
| Hand-editing generated HTML regions | local file edit | Fine for ad hoc views; do not treat edits as source of truth for Workflow Play reports. |
| Provider, CRM, enrichment, sequence, publish, send, billing | out of scope | Use the owning reference and typed SDK call. |

## Embedding Untrusted Strings In HTML

The SDK already handles this for you when you go through `vf.viz.spreadsheet(...)` and `vf.viz.pipeline_visualizer(...)`: row contents, step notes, view labels, and column labels are JSON-encoded with `vf.viz.safe_inline_data(...)`, which unicode-escapes `<`, `>`, `&`, U+2028, and U+2029 before they land inside the page's inline `<script>` block.

If you ever hand-roll your own HTML template that interpolates JSON data into a `<script>` tag, use `safe_inline_data` — not bare `json.dumps`. Background:

- `json.dumps` only escapes `"` and `\` (JSON spec). It leaves `<`, `>`, `&` raw.
- A scraped row containing a substring like `<!-- ... <script ... </script>` will flip the HTML5 tokenizer into script-data-double-escaped state mid-`<script>`, silently swallow the rest of the page, and render as a blank screen.
- The browser console error is "Unexpected token '<'" with no hint that the HTML tokenizer (not the JS engine) ate the page. The debugging session that finds this without the helper takes hours.

Rule: **never `json.dumps(...)` directly into a `<script>` body. Always go through `safe_inline_data` (or use `<script type="application/json">` + `JSON.parse(document.getElementById('data').textContent)`).**

## Canonical Operating Pattern

1. Load or construct the rows.
2. Print row count, key fields, and a small sample.
3. Call `vf.viz.spreadsheet(...)` for a one-off spreadsheet view, or
   `vf.viz.pipeline_visualizer(...)` for a pipeline overview.
4. Preserve the returned `Path`.
5. Open the file locally for inspection.
6. If the view becomes a production Play output, migrate it to
   `vf.reports.*` instead of extending the ad hoc HTML further.

## Core SDK Surfaces

<!-- BEGIN GENERATED: core-sdk-surfaces -->
| Function | Use When | Inputs | Output And Handles To Preserve | Side Effect | Source |
| --- | --- | --- | --- | --- | --- |
| `vf.viz.pipeline_visualizer` | Use when a local play or script pipeline needs an HTML overview linking to `visualization/step_*.html` files and an optional `dashboard.html`. | <strong>Required</strong>: `output_path` (str \| Path; required): Absolute or relative `.html` output path for the local pipeline overview.<br><strong>Optional</strong>: `play_dir` (str \| Path \| None; optional; default `None`): Optional play folder to scan for `visualization/step_*.html` and `dashboard.html` links.; `steps` (Sequence[Mapping[str, Any]] \| None; optional; default `None`): Optional explicit step metadata with number, name, script, html, status, counts, timestamp, and note.; `subtitle` (str \| None; optional; default `None`): Optional secondary label displayed under the title.; `title` (str; optional; default `'Pipeline'`): Page title for the generated pipeline overview. | `Path` to the generated pipeline overview HTML. Preserve it with the per-step HTML paths it links to.<br><strong>Common next calls</strong>: `vf.viz.spreadsheet` | local_file_write | installed SDK: `verbiflow/viz.py:196-338` |
| `vf.viz.spreadsheet` | Use for a one-off self-contained HTML spreadsheet over already-produced local rows when the user needs a quick audit view without the Workflow Play report pipeline. | <strong>Required</strong>: `output_path` (str \| Path; required): Absolute or relative `.html` output path for the self-contained spreadsheet view.<br><strong>Optional</strong>: `column_labels` (Mapping[str, str] \| None; optional; default `None`): Optional mapping from row key to displayed column header.; `ignore_keys` (Sequence[str]; optional): Row keys to hide from table columns while keeping the values available in row detail.; `page_size` (int; optional; default `200`): Initial rows per page. Set to 0 to disable pagination.; `pipeline_link` (str \| None; optional; default `None`): Optional relative link to a pipeline overview HTML file; pass None to hide it.; `rows` (Sequence[Mapping[str, Any]] \| None; optional; default `None`): Optional list of row dictionaries to embed inline as `ROWS`; omit for an empty editable starter file.; `subtitle` (str \| None; optional; default `None`): Optional secondary label displayed below the title.; `title` (str; optional; default `'Spreadsheet'`): Page title and topbar label for the generated spreadsheet HTML.; `views` (Sequence[Mapping[str, Any]] \| None; optional; default `None`): Optional saved filter definitions; `where` values are literal JavaScript predicate source strings. | `Path` to the generated self-contained spreadsheet HTML. Preserve it as a local audit artifact, not a Workflow Play report bundle.<br><strong>Common next calls</strong>: `vf.viz.pipeline_visualizer` | local_file_write | installed SDK: `verbiflow/viz.py:68-193` |
<!-- END GENERATED: core-sdk-surfaces -->

## Data Contracts

| Contract | Meaning |
| --- | --- |
| `output_path` | Local HTML file path. Python writes this exact path; CLI non-overwrite suffixing is handled by the CLI wrapper, not `vf.viz.spreadsheet(...)`. |
| `ROWS` | Inline JavaScript array of row objects inside the generated spreadsheet. Columns are inferred from the union of keys. |
| `IGNORE_KEYS` | Keys hidden from table columns while remaining available in row detail. Use this for raw HTML, embeddings, internal ids, and bulky fields. |
| `COLUMN_LABELS` | Optional display labels by row key. This should not rename source data. |
| `VIEWS` | Saved sidebar filters with literal JavaScript `where: r => ...` predicates. |
| `EXTRA_VIEWS` | Optional hand-written map/cluster/custom view hooks inside the generated HTML. Keep this to one focused secondary view. |
| `steps` | Pipeline overview metadata: number, name, script, html, status, counts, timestamp, and note. |

## Examples

### One-Off Spreadsheet

```python
import verbiflow as vf

rows = [
    {"company": "Acme", "domain": "acme.com", "score": 87, "status": "review"},
]

path = vf.viz.spreadsheet(
    "/absolute/path/visualization/companies.html",
    rows=rows,
    title="Company audit",
    subtitle="1 candidate",
    ignore_keys=("raw_payload",),
    column_labels={"score": "Fit Score"},
    views=[
        {
            "id": "review",
            "label": "Needs review",
            "color": "#f97316",
            "where": "r => r.status === 'review'",
        },
    ],
    page_size=200,
    pipeline_link=None,
)
print(path)
```

### Pipeline Overview

```python
import verbiflow as vf

path = vf.viz.pipeline_visualizer(
    "/absolute/path/pipeline.html",
    play_dir="/absolute/path/local-play",
    title="Play pipeline",
)
print(path)
```

## Verification

- The output path exists and is the path you intended to write.
- The file opens without blank rows or browser console errors.
- Important columns are visible and bulky/raw columns are hidden with
  `ignore_keys`.
- Saved views filter correctly; remember `where` is JavaScript source.
- The output is not described as a Workflow Play report or synced `/plays`
  output unless it has been migrated through `workflow_reports.md`.

## Troubleshooting

| Symptom | Likely Cause | Fix |
| --- | --- | --- |
| Generated file overwrote a local edit | Python API writes the exact requested path | Choose a new path before calling `vf.viz.spreadsheet(...)`, or use the CLI wrapper when suffixing behavior is desired. |
| Saved view fails | `where` was written like Python instead of JavaScript | Use literal JS predicate source such as `"r => r.score >= 80"`. |
| HTML loads slowly | Too many rows or large inline values | Reduce rows, hide bulky keys, or use `workflow_reports.md` sidecars instead. |
| User expects `/plays` output | Dashboard helper only wrote standalone HTML | Build a proper report with `vf.reports.*`, then sync through `workflow_schedules.md`. |
| Pipeline overview has no steps | No explicit `steps` and no `visualization/step_*.html` files under `play_dir` | Pass explicit step metadata or generate per-step spreadsheet files first. |

## Related References

| If you are doing this | Read next |
| --- | --- |
| Building final Workflow Play UI/report output | `workflow_reports.md` |
| Operating or reporting from a generated workflow root | `workflow_operations.md` |
| Syncing a generated Play | `workflow_schedules.md` |
| Designing repeatable Play outputs | `workflow_composition.md` |
| Preparing rows before visualization | `row_operations.md` |
| Inspecting artifact rows before visualization | `artifacts_jobs.md` |
| Quality-checking displayed rows and counts | `testing.md` |
