unknown, never as a fabricated
zero. A real 0 (contracts exist, nothing was flagged, no spend was recorded against a real
cap) is a different, reportable state from “no source was ever present.” These are BI surfaces
only — nothing here blocks a gate or changes a verdict.
Quality & Risk dials
Computed insrc/observability/dashboard/state/quality-risk.js by computeQualityRisk(run, ...),
and assembled per-focus-run by buildQualityRiskProjection(state, ...). The focus run is the
active run, else the newest run with a pipelineRollup, else the newest run (focusRun).
Aggregated Risk Score (0-100, higher = riskier). Rolled from three real sources, not a bare
count:
- Builder-reported risks, read from either
task.builder.risks(live) or the index-persistedtask.builder_risk.severity_tally(#527) — the same tally, so a run scores identically whether served fully-parsed or from the Hub’s rollup index. Each risk is weighted by severity (RISK_SEVERITY_WEIGHTS:critical: 25, high: 12, medium: 5, low: 2) and discounted to0.25of its weight only when genuinely mitigated (isRiskMitigated— statusmitigated/resolved/closed/fixed, or a non-emptymitigationstring). An accepted risk is explicitly not mitigated — a knowingly-retained residual keeps its full weight. guardrail_triggeredevents (GUARDRAIL_BLOCK_WEIGHT: 15),guardrail_overriddenevents (GUARDRAIL_OVERRIDE_WEIGHT: 8), andtask_blocked_by_validatorevents (VALIDATOR_BLOCK_WEIGHT: 10).
clampScore). The score is null — honest unknown —
only when none of those sources exist at all (riskSignalPresent is false): no builder
contract with risks, no guardrail block, no guardrail override, no validator block. If contracts
exist and genuinely report nothing, the score is a real 0.
Complexity Index (0-100, higher = more complex). Built from structural signal only, never
self-report: files touched across builder tasks (capped at FILES_CAP = 200, worth up to 50 pts),
number of builder tasks (capped at 15, up to 25 pts), and execution_recorded events from the
transient-sandbox execution evidence (capped at 15, up to 25 pts). Same honest-null rule: null
only when there are zero builder tasks, zero files touched, and zero executions.
Both scores map to a labelled band via bandFor — a null score always maps to the literal band
'unknown':
Cost-to-Value (optional) pairs cumulative cost (summed from
pipelineRollup.stages[].cost_usd)
against proof coverage percent (read from the readiness projection or the Evidence Center
summary), yielding cost_per_coverage_point — null whenever coverage is unknown or 0 (a
division the code refuses to fake). Execution posture reports how many recorded executions
were container-verified vs. self-reported-only, alongside PASS/FAIL counts.
Rendering
renderQualityRiskCard in src/observability/dashboard/ui/pages/command-center.js reads
s.overview.qualityRisk (or the top-level s.qualityRisk fallback) and draws each score as an
SVG ring (qrDialHtml) using pathLength="100" so the dash length is the score — a stable
node whose stroke-dasharray attribute is patched by the morph renderer, which is what makes the
value change animate as a draw rather than a re-render. A non-numeric or out-of-range score is
re-guarded client-side (qrNumericScore) even though the projection already clamps 0-100 — belt
and braces against a NaN ever reaching stroke-dasharray. An unknown score draws the empty
track only, never a zero-length arc (a drawn arc implies a measured value, even a zero one).
Chips beneath the dials surface the severity breakdown, mitigated/accepted/guardrail/validator
counts, files touched, builder task count, and execution count — all read straight off the
projection, no re-derivation.
Cost & Budget
Rendered bysrc/observability/dashboard/ui/pages/cost-budget.js into #page-cost-budget. Three
concerns are kept visually separate so a configured cap can never be mistaken for actual
spend:
- Current Enforced Policy (
configuredBudgetPolicyHtml) — the project’s.rstack/budget.jsonas validated, per project in scope.availabilityis one ofconfigured/invalid/inaccessible/ (implicitly) missing; onlyconfiguredrenders the run/day/month caps (configuredCapHtml), and only the run cap is annotated “Enforced by goal loop” — day/month caps are configured policy only, with no observed loop enforcement claimed for them. - Budget Consumption — Loop Cost Brake (
budgetGovernanceHtml) — actual measured spend againstrun.loopBudgetUsd, the exactrun_budget_usdvalue the goal loop’s cost brake reads before every iteration. Runs render only whencap.runBudgetUsd !== null; each row shows percent-of-cap used, headroom, or (ifcap.status === 'exhausted') “cap reached — the loop will not start another iteration.” A distinctenforcement_stalestatus renders “position unavailable” when the loop brake’s own metrics.json is stale or missing relative to the event-derived spend — the UI won’t claim a live position it can’t back. - Cost per Run / Spend by Stage (
costSummaryHtml,costRunRowsHtml,stageCostAcrossRunsHtml) — actual tracked spend, sourced from either persistedmetrics.jsontotals or a recomputation from the event stream, tagged with a provenance pill (moneySourcePill: “persisted metrics” / “recomputed from events” / “no telemetry”). Zero runs in scope, no telemetry recorded, and “runs exist but nothing reports cost yet” are three distinct empty states — none of them render$0.00.
spendPolicyHistoryHtml additionally compares each run’s budget-policy snapshot at start time
against the current .rstack/budget.json, flagging drift (comparison: 'differs') per field.
Run Analytics
Rendered bysrc/observability/dashboard/ui/pages/run-analytics.js into
#page-run-analytics, per selected run (ANALYTICS_RUN_ID):
- KPI row (
analyticsKpisHtml) — duration, tool calls, tasks passed/failed, average quality, cost, and tokens. Cost only renders whensource !== 'none'and eithercost_usd > 0or atokenTotalsobject exists; otherwise it shows—with “no cost telemetry yet” rather than$0.0000. Tokens carry the same provenance pill as Cost & Budget. - Gantt (
ganttHtml, shared with the run drawer inui/lib.js) — one row per task segment with astarted_at, positioned/sized proportionally across the run’s real time span; bar color ispass/fail/runningfrom the segment’s status, and a still-running segment (noended_at) labels its duration “running” instead of computing a fake elapsed time. - Cost & Tokens by Stage (
stageMoneyHtml) — per-stage bars from the persistedmetrics.jsonstageCost/stageTokensmaps; a stage with no cost entry shows “cost n/a” for that bar rather than treating a missing key as zero. - Parallel Benchmark (
benchmarkPanelHtml) — readsartifacts/parallel-benchmark.json(produced byscripts/bench-parallel.mjs) and renders sequential-vs-parallel bars plus an honest mode badge:mode === 'real'draws “measured — real stages” (green), anything else draws “modelled — mock workload” (amber) — a mock measurement is never allowed to look like a live one. A missing artifact, an unparseable one, and one with non-finiteseq_time_ms/par_time_msare three distinct, clearly-labelled failure states. - Stage durations / run trend table (
renderStageBars,renderTrendTable) — average elapsed time per stage across runs, and a sortable per-run history row (duration, tool calls, passed/failed, quality, cost) built froms.trends.
Try it
Open the Business Hub and select a run in Run Analytics to see its Gantt and per-stage spend:events.jsonl and metrics.json change — nothing here requires a page reload.
Every score, band, and dollar figure on these pages is computed server-side from the run’s real
artifacts and events (
state/quality-risk.js, the metrics/rollup readers). If a chart looks
empty, it’s because the underlying signal — a builder contract, a metrics.json write, a
parallel-benchmark.json artifact — hasn’t been produced yet, not because the Hub swallowed an
error.Related
- Business Hub — the full page list and how the Hub launches
- Business Flex profiles — the planned budget envelopes shown alongside actual spend on Cost & Budget
