@validation-os/dashboard 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -295,24 +295,30 @@ interface NeedsHumanCounts {
295
295
  declare function needsHumanCounts(ctx: RegisterContext): NeedsHumanCounts;
296
296
 
297
297
  /**
298
- * The dashboard's client-owned navigation state, across the three workflow
298
+ * The dashboard's client-owned navigation state, across the workflow
299
299
  * altitudes plus the kept register tables (OPS-1298). One `<ValidationOSDashboard/>`
300
300
  * mounts at a single host route and drives everything off the URL hash — there
301
301
  * is no second entry point (OPS-1280).
302
302
  *
303
- * - `next` — the front door ("what's my next move"); the default landing.
304
- * - `pipeline` — the step-back portfolio pipeline.
305
- * - `records` one register's browse table (the manual-override surface,
306
- * kept from the original scheme).
307
- * - `record` — the per-belief drill-in (full record page).
303
+ * - `next` — the front door ("what's my next move"); the default landing.
304
+ * - `pipeline` — the step-back portfolio pipeline.
305
+ * - `stage-grid` the Lens × Stage heatmap (docs/stage-policy.md).
306
+ * - `records` — one register's browse table (the manual-override surface,
307
+ * kept from the original scheme).
308
+ * - `record` — the per-belief drill-in (full record page).
308
309
  */
309
310
  type Route = {
310
311
  name: "next";
311
312
  } | {
312
313
  name: "pipeline";
314
+ } | {
315
+ name: "stage-grid";
313
316
  } | {
314
317
  name: "records";
315
318
  register: Collection;
319
+ lens?: string;
320
+ stage?: string;
321
+ view?: "all";
316
322
  } | {
317
323
  name: "record";
318
324
  id: string;
@@ -1344,6 +1350,9 @@ interface RegisterBrowserProps {
1344
1350
  /** Open a record's canonical full page (story 12). When set, the drawer
1345
1351
  * offers a "Full page" link; reads/edits still happen in the peek drawer. */
1346
1352
  onOpenRecord?: (id: string) => void;
1353
+ /** Pre-filter applied before tab/free-text — Lens × Stage from the grid. */
1354
+ lens?: string;
1355
+ stage?: string;
1347
1356
  }
1348
1357
  /**
1349
1358
  * The browse-create-edit surface for one register. Above the flat table sits the
@@ -1359,7 +1368,7 @@ interface RegisterBrowserProps {
1359
1368
  * gated API (which recomputes derived fields on write). The canonical full record
1360
1369
  * page is reachable via the drawer's "Full page" link when `onOpenRecord` is set.
1361
1370
  */
1362
- declare function RegisterBrowser({ register, basePath, subtitle, onOpenRecord, }: RegisterBrowserProps): react.JSX.Element;
1371
+ declare function RegisterBrowser({ register, basePath, subtitle, onOpenRecord, lens, stage, }: RegisterBrowserProps): react.JSX.Element;
1363
1372
 
1364
1373
  /**
1365
1374
  * The front door — "what's my next move" (design OPS-1295, build OPS-1304): the
@@ -1381,6 +1390,137 @@ interface NextMoveSurfaceProps {
1381
1390
  }
1382
1391
  declare function NextMoveSurface({ basePath, onNavigate }: NextMoveSurfaceProps): react.JSX.Element;
1383
1392
 
1393
+ /**
1394
+ * The Lens × Stage heatmap view-model (docs/stage-policy.md §The dashboard
1395
+ * surface) — pure, no React, no I/O, so the grid's shape and the drill-
1396
+ * through's Risk-ranked list are unit-tested at this seam (like
1397
+ * `pipeline.ts` / `journey.ts` / `next-move.ts`).
1398
+ *
1399
+ * The grid is the **filter**, Risk is the **rank**. Where the pipeline board
1400
+ * reads "where every belief stands" row-by-row, this reads the same beliefs
1401
+ * cross-tabbed by Lens (the actor — who the belief is about) × Stage (the
1402
+ * kind of response — engage / pay / scale / defend). The densest cell per
1403
+ * row is where that part of the business is — no flag, no declaration, the
1404
+ * density tells you. Click a cell → the assumptions in it, ranked by Risk.
1405
+ *
1406
+ * Pure and computed fresh on read (like `pipeline.ts`): it only reads numbers
1407
+ * already kept current (`derived.risk`), so it stays out of the OPS-1251
1408
+ * on-write recompute. The Lens list comes from the caller (the surface
1409
+ * supplies the workspace's configured vocabulary); the Stage list is fixed
1410
+ * (the four discovery stages — see `ontology.yaml §vocabularies.stage`).
1411
+ */
1412
+
1413
+ /** The four discovery stages, in their canonical ordinal order (1→4). The
1414
+ * stored value is the name; the ordinal is for sort/display only. */
1415
+ declare const STAGE_ORDER: readonly ["Discovery", "Validation", "Scale", "Maturity"];
1416
+ type StageValue = (typeof STAGE_ORDER)[number];
1417
+ /** A short, plain-language gloss for each stage — the column header's
1418
+ * subtitle and the cell tooltip. Drawn from docs/stage-policy.md. */
1419
+ declare const STAGE_GLOSS: Record<StageValue, string>;
1420
+ /** One cell of the Lens × Stage grid. */
1421
+ interface StageGridCell {
1422
+ /** The Lens (row) this cell sits under. */
1423
+ lens: string;
1424
+ /** The Stage (column) this cell sits under — one of the four canonical
1425
+ * stages, or the `NO_STAGE` ("—") sentinel for records with no/invalid
1426
+ * Stage (the gate-leakage bucket, only emitted when needed). */
1427
+ stage: StageValue | typeof NO_STAGE;
1428
+ /** How many assumptions hold this Lens × Stage pair. */
1429
+ count: number;
1430
+ /** The assumptions in this cell, ranked by Risk (highest first). Empty
1431
+ * when `count` is 0. The rank is the cell's drill-through order. */
1432
+ assumptions: AnyRecord[];
1433
+ /** Density in [0, 1] — `count / maxCellCount` across the whole grid, for
1434
+ * the heatmap colour scale. 0 for an empty cell. */
1435
+ density: number;
1436
+ }
1437
+ /** The grid view-model — rows per Lens, columns per Stage, cells with counts
1438
+ * and Risk-ranked drill-through lists. */
1439
+ interface StageGridView {
1440
+ /** The Lens values, in first-appearance order (the configured vocabulary
1441
+ * order is the caller's job; the grid keeps the order it sees). Includes
1442
+ * a trailing "—" row for assumptions with no Lens set. */
1443
+ lenses: string[];
1444
+ /** The four stages in their canonical ordinal order. */
1445
+ stages: StageValue[];
1446
+ /** One cell per (lens, stage) pair, in row-major order: lens-first,
1447
+ * stage-within-lens. */
1448
+ cells: StageGridCell[];
1449
+ /** The maximum cell count across the grid — what `density` is normalised
1450
+ * against. 0 when the grid is empty. */
1451
+ maxCellCount: number;
1452
+ /** Total assumptions counted in the grid (every cell's count summed).
1453
+ * Equal to the input length minus any rows with neither Lens nor Stage
1454
+ * set, which fall in the "—" row / "—" cell. */
1455
+ total: number;
1456
+ }
1457
+ declare const NO_LENS = "\u2014";
1458
+ declare const NO_STAGE = "\u2014";
1459
+ /** A stage value from a record, validated against the fixed vocabulary.
1460
+ * Returns null for an empty or unrecognised value — the caller decides
1461
+ * whether to bucket those or drop them. */
1462
+ declare function stageOf(record: AnyRecord): StageValue | null;
1463
+ /** Sort a list of assumptions by Risk, highest first. Stable on tie by id —
1464
+ * matches the pipeline board's "riskiest first" convention. Pure: returns a
1465
+ * new array, leaves the input alone. */
1466
+ declare function rankByRisk(records: AnyRecord[]): AnyRecord[];
1467
+ /**
1468
+ * Build the Lens × Stage grid from the assumption register. Pure — no I/O,
1469
+ * no React. The Lens list is read off the records in first-appearance order
1470
+ * (the configured vocabulary order is the caller's concern; the grid keeps
1471
+ * what it sees, so a workspace with no Commercial-stage-4 bets simply shows
1472
+ * a 0 cell, never a missing row). A record with no Lens set falls into a
1473
+ * trailing "—" row; a record with no Stage set (or an unrecognised Stage)
1474
+ * falls into a trailing "—" column. The "—"/"—" cell holds the records the
1475
+ * gate would have caught — write-time enforcement is the gate's job, this
1476
+ * just surfaces them honestly.
1477
+ *
1478
+ * The "—" row and "—" column are **only emitted when needed** — i.e. when at
1479
+ * least one record has a missing Lens (resp. Stage). A clean register
1480
+ * renders a pure Lens × 4-Stage matrix; a register with gate-leakage gets
1481
+ * the diagnostic row/column added. This keeps the matrix rectangular and
1482
+ * matches the spec ("if a claim doesn't fit any stage, it falls out" — the
1483
+ * "—" column is a diagnostic, not a feature).
1484
+ *
1485
+ * Each cell's `assumptions` list is ranked by Risk (highest first), so the
1486
+ * drill-through reads "the riskiest belief in this cell" first — the grid is
1487
+ * the filter, Risk is the rank. `density` is `count / maxCellCount` across
1488
+ * the whole grid, for the heatmap colour scale; an empty cell reads 0.
1489
+ */
1490
+ declare function buildStageGrid(assumptions: AnyRecord[]): StageGridView;
1491
+ /** The cell at a given (lens, stage) — null if no such cell (e.g. a stage
1492
+ * not in the canonical order). The "—" row / "—" column are addressable
1493
+ * with the `NO_LENS` / `NO_STAGE` sentinels. */
1494
+ declare function cellAt(view: StageGridView, lens: string, stage: StageValue | typeof NO_STAGE): StageGridCell | null;
1495
+
1496
+ /**
1497
+ * The Lens × Stage heatmap surface (docs/stage-policy.md §The dashboard
1498
+ * surface) — the workflow dashboard's portfolio lens, mounted alongside
1499
+ * `NextMoveSurface` and `PipelineSurface`. One row per Lens (the actor — who
1500
+ * the belief is about), one column per Stage (the kind of response — engage
1501
+ * / pay / scale / defend), each cell carrying its assumption count and a
1502
+ * heatmap colour by density. Click a cell → a drill-through drawer with the
1503
+ * assumptions in that cell, ranked by Risk (the grid is the filter, Risk is
1504
+ * the rank).
1505
+ *
1506
+ * No stage-flag selector, no "what stage am I" prompt, no per-stage
1507
+ * confidence model — the grid reads the business state off where the bets
1508
+ * cluster, and lets you drill into any cell ranked by Risk. The densest cell
1509
+ * per row is where that part of the business is; thin/empty cells are gaps
1510
+ * (Consumer × Maturity is honestly 0 — consumers don't drive defense bets).
1511
+ *
1512
+ * Lazy-loads the assumption register and derives everything through the pure
1513
+ * `buildStageGrid` view-model — no number is computed here (spec: explain
1514
+ * from inputs). Clicking a belief in the drill-through routes to that
1515
+ * belief's record page (OPS-1298), the review surface where step-in happens.
1516
+ */
1517
+ interface StageGridSurfaceProps {
1518
+ basePath?: string;
1519
+ /** Navigate across the shell (belief → record). */
1520
+ onNavigate: (route: Route) => void;
1521
+ }
1522
+ declare function StageGridSurface({ basePath, onNavigate }: StageGridSurfaceProps): react.JSX.Element;
1523
+
1384
1524
  interface ScoreImpactFormProps {
1385
1525
  /** The assumption being weighted (its version guards the write). */
1386
1526
  assumption: AnyRecord;
@@ -1803,4 +1943,4 @@ declare const REGISTER_GROUPS: {
1803
1943
  registers: Collection[];
1804
1944
  }[];
1805
1945
 
1806
- export { type BacklinkItem, BeliefJourney, type BeliefJourneyProps, type BeliefVerdict, BeliefVerdicts, CONFLICT_MESSAGE, type CellKind, type ColdStart, type ColumnDef, ConfidenceCell, ConnectClaudeCode, type ConnectClaudeCodeProps, type ConnectCommandInput, type Counts, type CycleReadingView, type CycleView, DEFAULT_TOKEN_ENV, DIRECT_CYCLE_KEY, type DashboardConfig, type DetailRelationItem, type DetailRow, type DetailRowKind, type Draft, EditBeliefForm, type EditBeliefFormProps, EditFields, type ExperimentView, FIRST_RUN_LINE, type FieldEditor, FieldInput, type FieldKind, type FormField, type GlossaryTerm, GlossaryText, type GlossaryTextProps, type GroupBucket, type GroupByAxis, type HumanText, type JourneyColdState, type JourneyEventView, type JourneyView, type LinkArgs, type LinkChoice, type LinkifyNode, type LinkifyOptions, Markdown, type Meter, type MeterKind, type MovePresentation, type NeedsHumanByRegister, type NeedsHumanCounts, type NeighbourChip, type NestedGroup, type NextColdStart, type NextMoveRecords, NextMoveSurface, type NextMoveSurfaceProps, type OtherMover, type Pill, type PipelineColdStart, type PipelineRow, PipelineSurface, type PipelineView, REGISTER_GROUPS, REGISTER_ICON, REGISTER_LABEL, REGISTER_ORDER, REGISTER_SINGULAR, REGISTER_SUBTITLE, RISK_CRIT, RISK_WARN, RecordDrawer, type RecordDrawerProps, RecordForm, type RecordFormProps, RecordPage, type RecordPageModel, type RecordPageProps, type RecordTabId, RegisterBrowser, type RegisterBrowserProps, type RegisterContext, RegisterCounts, type RegisterCountsProps, RegisterTable, type RegisterTableProps, type RelatedSet, RelationEditor, type RelationEditorProps, type RelationPanel, type ResolvedBarLine, type ResolvedRow, type RiskBand, RiskBar, type Route, type SaveResult, type SavedView, type ScoreChip, ScoreImpactForm, type ScoreImpactFormProps, type ShapedRegister, SidebarNav, type SidebarNavProps, type SortSpec, Sparkline, type StageMeterInput, type StageMeterView, StatTile, StatusPill, type StepInForm, type StoryStepIn, SurfacePlaceholder, type SurfacePlaceholderProps, type TabDef, type TermPreview, type Tone, type Understanding, UnderstandingPanel, type UseCountsResult, type UseCreateResult, type UseLinkResult, type UseListResult, type UseNeedsHumanResult, type UseRecordResult, type UseSavedViewsResult, type UseUpdateResult, ValidationOSDashboard, type ValidationOSDashboardProps, type ViewDescriptor, WriteDecisionForm, type WriteDecisionFormProps, backlinkPanels, bodyPreview, buildCycles, buildJourney, buildPatch, buildPipeline, buildRecordPage, buildUnderstanding, cellValue, coldStartFor, columnsFor, composeConnectCommand, confidenceTone, configureRiskBands, defaultTabId, detailRows, dontConfuseWith, draftFrom, editableFields, emptyDraft, eventStepIn, eventTone, filterRecords, formFieldsFor, formatCount, formatRoute, formatSigned, formatValue, groupByAxesFor, groupRecords, hasEdits, headerPills, humanInputFields, interpretSave, journeyColdState, leadingMeters, linkChoicesFrom, linkify, missingRequired, movePresentation, needsHumanCounts, nestReadingsByPlan, ownerNames, parseRoute, primaryLabel, readingAssumptionChips, readingBeliefVerdicts, resolveBarLines, riskBand, riskFraction, riskLevel, scoreChip, shapeRegister, sortRecords, sparklinePath, stageMeters, statusTone, tabsFor, toCreatePayload, toGlossaryTerms, toNextMoveInput, toStageExperimentInput, useCounts, useCreate, useLink, useList, useNeedsHuman, useRecord, useSavedViews, useUpdate, weekOverWeekDelta };
1946
+ export { type BacklinkItem, BeliefJourney, type BeliefJourneyProps, type BeliefVerdict, BeliefVerdicts, CONFLICT_MESSAGE, type CellKind, type ColdStart, type ColumnDef, ConfidenceCell, ConnectClaudeCode, type ConnectClaudeCodeProps, type ConnectCommandInput, type Counts, type CycleReadingView, type CycleView, DEFAULT_TOKEN_ENV, DIRECT_CYCLE_KEY, type DashboardConfig, type DetailRelationItem, type DetailRow, type DetailRowKind, type Draft, EditBeliefForm, type EditBeliefFormProps, EditFields, type ExperimentView, FIRST_RUN_LINE, type FieldEditor, FieldInput, type FieldKind, type FormField, type GlossaryTerm, GlossaryText, type GlossaryTextProps, type GroupBucket, type GroupByAxis, type HumanText, type JourneyColdState, type JourneyEventView, type JourneyView, type LinkArgs, type LinkChoice, type LinkifyNode, type LinkifyOptions, Markdown, type Meter, type MeterKind, type MovePresentation, NO_LENS, NO_STAGE, type NeedsHumanByRegister, type NeedsHumanCounts, type NeighbourChip, type NestedGroup, type NextColdStart, type NextMoveRecords, NextMoveSurface, type NextMoveSurfaceProps, type OtherMover, type Pill, type PipelineColdStart, type PipelineRow, PipelineSurface, type PipelineView, REGISTER_GROUPS, REGISTER_ICON, REGISTER_LABEL, REGISTER_ORDER, REGISTER_SINGULAR, REGISTER_SUBTITLE, RISK_CRIT, RISK_WARN, RecordDrawer, type RecordDrawerProps, RecordForm, type RecordFormProps, RecordPage, type RecordPageModel, type RecordPageProps, type RecordTabId, RegisterBrowser, type RegisterBrowserProps, type RegisterContext, RegisterCounts, type RegisterCountsProps, RegisterTable, type RegisterTableProps, type RelatedSet, RelationEditor, type RelationEditorProps, type RelationPanel, type ResolvedBarLine, type ResolvedRow, type RiskBand, RiskBar, type Route, STAGE_GLOSS, STAGE_ORDER, type SaveResult, type SavedView, type ScoreChip, ScoreImpactForm, type ScoreImpactFormProps, type ShapedRegister, SidebarNav, type SidebarNavProps, type SortSpec, Sparkline, type StageGridCell, StageGridSurface, type StageGridSurfaceProps, type StageGridView, type StageMeterInput, type StageMeterView, type StageValue, StatTile, StatusPill, type StepInForm, type StoryStepIn, SurfacePlaceholder, type SurfacePlaceholderProps, type TabDef, type TermPreview, type Tone, type Understanding, UnderstandingPanel, type UseCountsResult, type UseCreateResult, type UseLinkResult, type UseListResult, type UseNeedsHumanResult, type UseRecordResult, type UseSavedViewsResult, type UseUpdateResult, ValidationOSDashboard, type ValidationOSDashboardProps, type ViewDescriptor, WriteDecisionForm, type WriteDecisionFormProps, backlinkPanels, bodyPreview, buildCycles, buildJourney, buildPatch, buildPipeline, buildRecordPage, buildStageGrid, buildUnderstanding, cellAt, cellValue, coldStartFor, columnsFor, composeConnectCommand, confidenceTone, configureRiskBands, defaultTabId, detailRows, dontConfuseWith, draftFrom, editableFields, emptyDraft, eventStepIn, eventTone, filterRecords, formFieldsFor, formatCount, formatRoute, formatSigned, formatValue, groupByAxesFor, groupRecords, hasEdits, headerPills, humanInputFields, interpretSave, journeyColdState, leadingMeters, linkChoicesFrom, linkify, missingRequired, movePresentation, needsHumanCounts, nestReadingsByPlan, ownerNames, parseRoute, primaryLabel, rankByRisk, readingAssumptionChips, readingBeliefVerdicts, resolveBarLines, riskBand, riskFraction, riskLevel, scoreChip, shapeRegister, sortRecords, sparklinePath, stageMeters, stageOf, statusTone, tabsFor, toCreatePayload, toGlossaryTerms, toNextMoveInput, toStageExperimentInput, useCounts, useCreate, useLink, useList, useNeedsHuman, useRecord, useSavedViews, useUpdate, weekOverWeekDelta };