Changelog
2026-04-22 — In-console docs surface + Examples Service docs sync
Moves the UI Console and Examples Service docs out of the marketing website and into the Console app itself at /docs. Operators now read the docs next to the product.
New
/docs— single-page landing with hand-authored themed SVG diagrams (architecture, scenario-pack pipeline, run flow) plus a doc index./docs/ui-console/[slug]— renders this repo'sdocs/*.mdviareact-markdown+remark-gfm. Mermaid code fences render as diagrams via a lazy-loaded client component that re-renders on theme change./docs/examples-service/[slug]— renders markdown fromdocs-content/examples-service/, which is synced from the upstream repo.- Sidebar gains a Docs entry (BookOpen icon, immediately after Dashboard).
- New sync workflow
.github/workflows/sync-examples-docs.yml+scripts/sync-examples-docs.sh. Listens forrepository_dispatch: docs-updatedfrom the examples-service repo (plus a 6-hour fallback schedule), copies the docs, and opens an auto-PR. lib/docs/loader.ts— small server-side helper (title / first-paragraph extraction).components/docs/markdown-renderer.tsxwith link rewriting (relative.md→/docs/<collection>/<slug>, cross-repo paths → GitHub URLs), styled code / tables / blockquotes, andgithub-sluggerheading anchors.
Removed
.github/workflows/notify-website.yml— the console is the docs host now, not a source for the website. Website-side cleanup (removingapp/console/+app/examples-service/+ their sync blocks) lands in a separate website commit.
Dependencies
- Added
react-markdown,remark-gfm,mermaid,github-slugger.
Operator note
The examples-service repo's notify-website.yml is retargeted at ui-console in a sibling commit. Once that ships, a push to examples-service main automatically opens a sync PR here. Merging the PR redeploys the Console with fresh Examples Service docs.
2026-04-22 — Docs refresh: cross-repo references, reduced duplication
Backend docs (examples-service, control-plane, runtime, python-sdk, typescript-sdk) were all refreshed upstream. The UI console docs are realigned to reference those sources rather than mirror their endpoint tables. No UI code changes.
backend-repo-notes.mdrewritten as a pointer index. Per-service endpoint inventories removed; each service now links to its canonical upstream doc plus a short note on the UI-facing role.api-integration.mdtrimmed: endpoint schemas now point tocontrol-plane/docs/API.mdandexamples-service/docs/api-reference.md; the UI-specific pieces (proxy, normalizers, SSE hook, demo mode, launch sequences) remain documented inline.architecture.mdgained an Upstream services section linking to each repo's architecture doc (CP, ES, runtime, SDKs). Client line counts resynced.README.mdgained an Upstream repositories table and updated doc index.- All occurrences of "Example Service" normalized to the upstream spelling Examples Service.
2026-04-22 — Observer-only CP alignment, session-interaction rework, Playwright removal
Consolidates a run of UI ↔ backend integration changes (5adcc20, 1045a59, 65433b6, fdbe99f, 6cd9da6, 4965a63, 6da8a76).
Control Plane contract alignment
- Aligned the client with the observer-only Control Plane authority model: agent-originated traffic (messages, signals, context updates) now flows through the runtime SDKs. CP endpoints
POST /runs/:id/messages,POST /runs/:id/signal, andPOST /runs/:id/contextreturn410 Gone.POST /runs/:id/cancelproxies to the initiator agent's cancel callback (or callsCancelSessiondirectly when policy-delegated). POST /runsis the only run-creation path and accepts a whitelisted-safe compiledRunDescriptoronly — CP rejects any body containingkickoff[],participants[].role,commitments[],policyHints, orinitiatorParticipantId. The UI continues to compile via Examples Service, which is already whitelisted-safe.POST /runs/:id/clonerejects non-emptycontextoverrides.CreateRunResponsenow surfacessessionIdalongsiderunId(equal under observer-only; reserved for future auto-discovery).- Extended
RunStateProjectionwith thellmprojection:{ calls[], totals: { callCount, promptTokens, completionTokens, totalTokens, estimatedCostUsd } }pluscontextIdandextensionKeyson therunblock.NodeInspectorsurfaces the LLM tab from this data.
Runtime policy registry integration (RFC-MACP-0012 pass-through)
- New client functions:
listRuntimePolicies,getRuntimePolicy,registerRuntimePolicy,unregisterRuntimePolicyagainst CP/runtime/policies{?mode}and/runtime/policies/:policyId. - Surface:
/policies(registry browser) and/modes(mode-scoped policy list). PolicyBadgeandPolicyPaneltones updated to reflect the revised governance rules and commitment-evaluation contract.- Mock dataset gains
MOCK_RUNTIME_POLICIESto keep demo mode exercisable.
Session interaction simplification
- Removed UI-side message/signal/context POST forms that targeted the now-410 CP endpoints. The runs workbench is now a read-only consumer of CP state, canonical events, and artifacts; agents drive envelopes via
macp-sdk-python/macp-sdk-typescript. - Artifact creation (
POST /runs/:id/artifacts) and projection rebuild (POST /runs/:id/projection/rebuild) remain CP-local and are kept.
Dashboard chart series
- CP now emits a single
decisionOutcomeseries (positive/negative encoded as +1/-1 per bucket) instead of the earlier splitdecisionOutcomePositive/decisionOutcomeNegativearrays. Client and mock data updated; any callers relying on the split fields were removed.
Response normalization cleanup
normalizeRun()no longer synthesizesarchivedAtfrom tags — CP exposes the column directly; the client passes it through unchanged.normalizeEvent()promoted out of the SSE hook and applied uniformly ingetRunEventsandlistEventsso every CP event consumer gets the nestedsource/subjectshape.listEventsgained a session-cachedeventsEndpointMissingflag — when CP returns404for/events, the fallback per-run fan-out is used for the rest of the browser session without re-probing.
Test infrastructure
- Playwright removed (
4965a63) — the visual-regression and E2E spec suites are retired. All golden-PNG baselines deleted. The Vitest + React Testing Library suite remains canonical. - Integration tests under
test/integration/tightened for the observer-only contracts and the new 410 responses (6da8a76).
UI regression fixes
- Color palette and chart/config warning cleanup that regressed during the CP rewrite work (
fdbe99f). - Lint-only fixes across
decision-panel,policy-panel, andrun-workbench(6cd9da6,ddd8a26). ExecutionGraphregained the four extra auto-layout passes lost in the CP rewrite (part of6da8a76).
Docs
api-integration.md,backend-repo-notes.md, andarchitecture.mdregenerated against the currentlib/api/client.ts. Runtime policy endpoints,/admin/circuit-breaker/history,/readyz,/runs/:id/replay/state?seq=,/runs/batch/export, and the Jaeger proxy route are now documented.README.mdroute map includes/modesand/policies; added thenpm run local:{up,down,status}Docker full-stack section.
2026-04-14 (continued) — Phase F + Phase D remainder
Second push on 2026-04-14: completes Phase F (filters + observability) and the
remaining Phase D items (D3 Prometheus parser, D4 tree waterfall, D5 /traces
filters). All items below ship against the backend substantially-complete
plan; no console / lint warnings; npm run build clean.
Added
API client extensions
listEvents(demoMode, query)(lib/api/client.ts) — wrapper around BE §4.1 cross-run/eventsendpoint. Query shape:{ runId, scenarioRef, type, afterTs, beforeTs, afterSeq, limit }. Returns{ data, total, nextCursor }. Demo mode fans out acrossMOCK_RUN_EVENTSwith the same filters so/logsis exercisable without a backend.getRunEventsacceptsRunEventsQuery— new fieldsafterTs,beforeTs,type(csv) map to BE §4.2. Legacy(runId, demoMode, limit, afterSeq)call signature preserved for back-compat.getDashboardOverview(demoMode, query)— accepts{ window, scenarioRef, environment, from, to }per BE §5.1. Forwards as query params; demo mode filtersMOCK_RUNSclient-side so KPIs respond to the pickers.- Chart series extended:
charts.throughput,queueDepth,latencyP50/P95/P99,cost,successRate,decisionOutcomePositive,decisionOutcomeNegative,perScenario— matches BE §5.2 output. getCircuitBreakerHistory(demoMode, window?)— BE §5.3 endpoint. ReturnsCircuitBreakerHistoryEntry[]({ state, enteredAt, reason? }).computeDashboardKpis(runs?)accepts an optional filtered run list so demo mode can respond to scenario/environment filters.
Pure helpers
lib/utils/prometheus.ts—parsePrometheusText()with full support for counters, gauges, histograms (grouped under base name via_bucket/_sum/_countsuffixes), summaries, and escaped quotes in labels.metricSummaryValue()returns the one-value-per-row summary (sum of labeled counters,_countfor histograms).histogramQuantile(metric, p)interpolates percentiles fromlebuckets — same algorithm as Grafana'shistogram_quantile. 13 unit tests.lib/utils/traces.ts—buildSpanTree()builds depth-annotated tree fromspan.references[CHILD_OF], sorts siblings bystartTime, treats orphans as additional roots, and counts descendants.findCriticalPath()post-order DP finds the longest root-to-leaf chain by cumulative duration. 7 unit tests.
New components
PrometheusMetricsTable(components/observability/prometheus-metrics-table.tsx) — sortable, filterable table over parsed exposition. Type chips (counter/gauge/histogram/summary), name/help search, click-row →EventDetailDialogwith per-series breakdown. 4 integration tests.CircuitBreakerTimeline(components/observability/circuit-breaker-timeline.tsx) — horizontal proportional-width state timeline + current-state badge + per-transition table. Freezesnowat mount for render-purity. 3 tests.
Page rewrites
-
/logs(PR-F1) — rewritten against the cross-run/eventsendpoint:- Shared
<RunSelectorFilters>(scenario + runId + time window) - Event type filter with
EVENT_TYPE_GROUPSincl. newLLMgroup - Cursor-based "Load more" pagination (cursors kept as an append-only
useStatearray; each new cursor concatenates a dedup'd page) - Client-side free-text search over the current page
summarizeEvent()one-line summary in the Payload columnEventDetailDialogopens on row click with full payload + Run / Trace / Event id meta rows- URL state for every filter → shareable links (runId / scenario / window / type)
- Empty states + proper loading/error panels
- Shared
-
/traces(PR-D4 + PR-D5) — tree-indented span waterfall:- Calls
buildSpanTree()+findCriticalPath() - Per-row depth indentation with
└connector - Critical path segments tinted accent-blue; non-critical use accent-2; errors tinted red
- Click-a-span →
EventDetailDialogwith Span ID / Trace ID / Start / Status meta - Shared
<RunSelectorFilters>(scenario + status + runId) replaces the single-select dropdown; URL deep-linkable - Graceful fallback to flat render when
references[]is missing (runtime-side fix still pending — BE §10)
- Calls
-
/observability(PR-F3 / PR-F4 / PR-F5 / PR-F6 / PR-D3):- Shared
<RunSelectorFilters>(scenario + environment + time window) - New chart grid for BE §5.2 series (throughput / queue depth / latency percentiles / cost over time) — each renders only when data is present
- Three new KPI cards for p50 / p95 / p99 latency computed client-side from the Prometheus histogram (PR-F6)
CircuitBreakerTimelinecard (BE §5.3)- Raw
<pre>dump replaced withPrometheusMetricsTable(raw link preserved as "Open raw exposition ↗")
- Shared
-
Signal Rail (
components/runs/signal-rail.tsx) — "Open in full view ↗" link to/logs?runId=...&type=signal.emitted(PR-B3, the last remaining surface).
Changed
- Many pages now wrap their content in
<Suspense>boundaries to satisfy Next.js 16useSearchParamsrequirements. RunWorkbenchpassesrunIdintoSignalRail(for the deep-link) andLiveEventFeed.
Tests
- New unit tests:
prometheus.test.ts(13),traces.test.ts(7),prometheus-metrics-table.test.tsx(4),circuit-breaker-timeline.test.tsx(3). - Full suite now at 371 unit tests passing (up from 344), across 30 test files.
- 36 visual baselines regenerated and passing deterministically.
npm run buildsucceeds — all pages render without runtime errors.
Notes
- Spurious
posttooluse-validatehook recommendations suggesting Vercel Workflow migration were ignored —lib/api/client.tsis a browser-side fetch wrapper, not a serverless handler.
2026-04-14 — Phase A–E implementation against the enriched backend projection
This release consumes the substantially-complete backend plan (see
plans/backend-changes-plan.md status table as of 2026-04-14): state
projection completeness, decision/policy enrichment, canonical event
contracts, cross-run query endpoints, observability enrichment, and the
re-scoped llm.call.completed event are all live on the Control Plane.
Added
Shared primitives
<Tooltip>(components/ui/tooltip.tsx) — CSS-positioned, keyboard-focusable hint primitive. Used by policy panel commitment ids and ready for further adoption.<EventDetailDialog>(components/ui/event-detail-dialog.tsx) — shared native-<dialog>modal for click-through event / span / metric details. Consumed by LiveEventFeed; ready for/tracesspan details and/observabilitymetric details.<RunSelectorFilters>(components/runs/run-selector-filters.tsx) — shared filter bar (scenario / runId / status / environment / time-window). Prop-driven rendering so each consumer shows only the controls it needs. Q24 decision: build once, use three times.<EmptyState>(components/ui/empty-state.tsx) — standardized icon + title + description + action.<KpiCard>(components/ui/kpi-card.tsx) — Syne-displayed KPI tile with optional colored top-stripe accent.<Panel>(components/ui/panel.tsx) — replaces ad-hocCard + CardHeader + section-actionscomposition.<Breadcrumbs>(components/layout/breadcrumbs.tsx) — derives a navigation trail from the current route, truncating UUID-like segments.
summarizeEvent() helper (lib/utils/events.ts)
Pure, type-aware helper that produces a one-line semantic summary for a CanonicalEvent. Covers the high-volume types (run., signal., proposal., decision., policy., message., tool.*, llm.call.completed) with a generic fallback for everything else. Unit-tested with 11 assertions.
LLM interaction visibility (finding #12)
- New
LlmCallCompletedDatatype mirrors the CP-synthesized event payload. NodeInspectorgains a conditional "LLM (N)" tab that listsllm.call.completedevents for the selected participant — each row shows model, token counts, latency, and expandable prompt + response. HonorsredactedPromptwhen theRedactionServiceapplied.- Mock data includes
llm.call.completedevents for the completed fraud run so demo mode exercises the tab.
Enriched projection consumption (BE-3 / BE-5 / BE-6 / BE-7 / BE-8 / BE-9)
DecisionProjection.currenttype extended withproposals[],resolvedAt,resolvedBy,prompt.outcomePositivewidened toboolean | nullper BE-3.PolicyProjectiontype extended withexpectedCommitments[],voteTally[],quorumStatus.- Decision panel (
components/runs/decision-panel.tsx) rewritten to render the action header with action→tone mapping (approve/step_up/decline → success/warning/danger, neutral fallback), bulleted reasons, contributors table (fromproposals[]), resolvedBy/at sub-line with deep-link to originating event seq, and the scenariopromptlabeled distinctly from reasons. Outcome badge branches onrun.statusfirst, thenoutcomePositive: boolean | null. Removes the literal'mode'/'unknown'badges (finding #6a). - Policy panel (
components/runs/policy-panel.tsx) rewritten to show expected commitments with Tooltip-on-hover revealing title + description + required roles, inline tally (allow/deny/quorum), per-commitment evaluation decisions, andquorumStatusbadge. Falls back to the legacycommitmentEvaluations[]table when new fields aren't yet populated. Policy version badge links to/policies/[policyVersion]. - Run overview card (
components/runs/run-overview-card.tsx) — Q1/Q2/Q3 KPI unification. Events + Messages counters now source from the SSE projection during live statuses and from the metrics aggregate once terminal. Tokens/Cost removed from the top strip (moved to the observability summary card).
Event feed redesign (PR-B1)
LiveEventFeed rewritten:
- Drops the truncated
JSON.stringify()snippet per row. - Each row: type badge + seq + semantic summary (
summarizeEvent) + meta line (timestamp, source). - Whole row is a button — click opens
<EventDetailDialog>with the full payload, copy-JSON action, and metadata rows (subject, source, trace id, event id). - Size selector chips (100 / 500, default 100 per Q13).
- Type filter chips auto-populated from observed event types.
- "Open in full view ↗" link to
/logs?runId=....
Changed
RunWorkbenchnow passesstate+events+runIdintoRunOverviewCard,DecisionPanel, andLiveEventFeedto support the new projection-consuming behaviour.ExecutionGraphoutcomePositivehandling widened to acceptboolean | null | undefinedfrom the enriched decision projection;nullmaps to undefined accent.policy-panel.tsxremoves thepolicyHints.type !== 'none'gate — full rules now render whenever a descriptor is reachable.
Tests
- New unit tests:
events.test.ts(11 cases),run-selector-filters.test.tsx(5),event-detail-dialog.test.tsx(3),tooltip.test.tsx(6),empty-state.test.tsx(3),panel.test.tsx(2),kpi-card.test.tsx(4). - New integration-style tests:
decision-panel.test.tsx(9 cases covering outcome branching, prompt/reasons/contributors),policy-panel.test.tsx(5 cases covering enriched + legacy fallback paths). - Full suite: 344 unit tests passing (up from 311), 36 visual baselines passing deterministically.
Policy governance and RFC-MACP-0012 alignment
Added
Policy hints throughout the UI
- New
PolicyHintstype with governance fields: type, threshold, vetoEnabled, vetoRoles, vetoThreshold, minimumConfidence, designatedRoles PolicyProjectionandCommitmentEvaluationtypes for runtime policy resolutionPolicyBadgecomponent displays policy type with color coding (none/majority/supermajority/unanimous)PolicyPanelcomponent shows policy version, resolution status, and commitment evaluation table- Scenario catalog cards now show policy type badge
- Scenario detail page shows full policy governance section (thresholds, veto config, designated roles)
- Launch form displays policy version and description when template is selected
- Run workbench shows PolicyPanel with commitment evaluations when policy data is available
Token and cost tracking
MetricsSummarynow includespromptTokens,completionTokens,totalTokens,estimatedCostUsd- Run workbench observability summary shows token count and estimated cost when available
Mock data updates
- Fraud scenario templates expanded to include
majority-vetoandunanimousvariants - All mock scenarios enriched with
policyVersionandpolicyHints - Mock run state projections include
policysection with commitment evaluations - Mock metrics include token usage and cost
- Policy canonical events (
policy.resolved,policy.commitment.evaluated) added to mock events
Changed
API client
normalizeRun()simplified:archivedAtnow passed through directly from CP instead of synthesized from tagslistRuns()always sendslimitandoffsetdefaults (required by CP validation)
Deep analysis fixes: gaps, stubs, bugs, and test coverage
Critical bug fixes
- Delete run redirect:
deleteMutationin RunWorkbench now redirects to/runsafter successful deletion instead of leaving user on an error page - Form reset after send: SendMessageForm and SendSignalForm in SessionInteractionPanel now reset fields on successful mutation
Type safety and error handling
- 14 API functions now have explicit return type annotations with shared interfaces (
MutationAck,BatchOperationResult,RebuildProjectionResult,CircuitBreakerResult,RunExampleResult,CreateArtifactResult,AgentMetricsEntry) defined inlib/types.ts ApiErrorclass added tolib/api/fetcher.ts— preserves HTTP status, service, and path for error discriminationgetAgentProfile()now only returnsundefinedfor 404; re-throws other errorsgetDashboardOverview()returnsdegraded: trueflag when overview endpoint fails; logs warninggetAgentMetrics()logs warning on failure instead of silently returning[]normalizeRun()validates required fields (id,status,runtimeKind) before processing
Agent metrics improvements
averageLatencyMsis now optional — displays "N/A" instead of misleading "0ms" when unavailablemessagesfield from CP response is now mapped through toAgentMetricsEntry- Demo mode returns representative mock metrics instead of empty array
Pagination and configuration
getRunEvents()accepts optionallimitparameter (default 500)getAuditLogs()accepts optionallimitandoffsetparametersintegrations.tsthrows in production if base URLs are not configured; warns on empty auth tokens- Preset IDs now use
crypto.randomUUID()instead ofDate.now()
UI and component improvements
- Mutation error messages now include backend error details
- ExecutionGraph uses data-driven auto-layout by node kind instead of hardcoded positions
formatDateTime()andformatChartLabel()accept optionaltimeZoneparameter- Tabs component:
defaultTabprop deprecated in favor ofdefaultValue - Removed unused imports (
Plus,createArtifact,updateRunContext) from RunWorkbench
Documentation
- Added 10 missing API endpoints to
docs/api-integration.md: session interaction, batch operations, context updates, artifact creation, projection rebuild, run deletion
Test coverage
- 47 new unit tests (226 total): real-mode API client tests, SSE hook tests, agent metrics tests
- 6 new integration tests (85 total): error scenarios for getRun/cancelRun/sendRunMessage (500/422), dashboard degradation, empty results
- New test files:
lib/api/client.real-mode.test.ts,lib/hooks/use-live-run.test.ts
Agent metrics normalization and dynamic environment filter
Fixed
Agent metrics field mapping
getAgentMetrics()now normalizes CP response:participantIdmapped toagentRef,averageLatencyMspassed through when available (optional)- Previously the agent catalog page silently failed to enrich profiles because the CP returns
participantIdwhile the UI looked up byagentRef - Updated integration test fixtures to match actual CP response shape (
participantId,messagesfields)
Dynamic environment filter
- Runs page environment dropdown now dynamically populated from actual run metadata
- Removed hardcoded
local-dev | stage | prodoptions that didn't match real environments - Supports any environment value including
development(the default set by Example Service)
Control plane full integration
Changed
Chart timestamp handling
LineChartCardandBarChartCardnow useformatChartLabel()to auto-detect ISO timestamp labels and format them as short date strings (e.g. "Apr 1, 3 PM")- added
formatChartLabelutility inlib/utils/format.ts
Token and cost KPIs from control plane
getDashboardOverview()now extractstotalTokensandtotalCostUsdfrom CP KPIs when available, instead of hardcoded zeros
Server-side run filtering
- runs page now passes
status,environment, andsearchparams toGET /runsfor server-side filtering - client-side filtering retained as fallback in demo mode
Agent metrics enrichment
- added
getAgentMetrics()API function callingGET /dashboard/agents/metricson the control plane - agents page fetches real per-agent metrics (runs, signals, latency, confidence) and merges into profiles
Clone with overrides
cloneRun()now accepts optional{ tags, context }overrides parameter- added clone UI form in run workbench with tag and context JSON inputs
Batch export
- added
batchExportRuns()API function callingPOST /runs/batch/export - added "Export" button to batch toolbar in runs table
Webhook delivery stats
WebhookSubscriptiontype now includes optionaldeliveryStatswithtotal,succeeded,failed,lastDeliveredAt- settings page displays delivery counts and last delivery timestamp per webhook
Testing
- added unit tests for
formatChartLabel,getAgentMetrics,cloneRunwith overrides,batchExportRuns - added integration tests for batch export, clone with overrides, server-side filters, agent metrics
- updated dashboard integration tests: token/cost KPI extraction from CP, fallback to zero when omitted
- updated backend-response fixtures:
dashboardOverviewincludes token/cost KPIs, addedagentMetrics()andbatchExportResponse()fixtures
Real-mode integration fixes
Changed
Response normalization layer
- added
normalizeRun()helper inlib/api/client.tsthat maps Control Plane response shapes to UI types listRuns()now unwraps the paginated{ data, total }response from the Control PlanegetRun()now normalizes the raw response throughnormalizeRun()- flat
sourceKind/sourceReffields are mapped to nestedsource: { kind, ref }on all run records archivedAtis synthesized fromtags.includes('archived')as a bridge until the Control Plane adds a dedicated column
Validate, cancel, and archive response mapping
validateRun()now maps the Control Plane's{ valid, errors, warnings, runtime }response to a typedValidateRunResponsewithokfieldcancelRun()now extracts{ ok, runId, status }from the full run record returned by the Control PlanearchiveRun()now extracts{ ok, runId, archived }from the full run record returned by the Control Plane
Agent profiles via Example Service
getAgentProfiles()now calls Example ServiceGET /agentsdirectly instead of computing profiles client-side via N+1 cascading calls to packs/scenarios/launch-schemasgetAgentProfile()now calls Example ServiceGET /agents/:agentRefdirectly with fallback toundefined
Dashboard overview with Control Plane aggregation
getDashboardOverview()now fetches from Control PlaneGET /dashboard/overviewfor KPIs and chart data- falls back gracefully to client-side computation if the endpoint is unavailable
- Control Plane chart data (
{ labels, data }arrays) is converted to UIChartPoint[]format
Types
- added
ValidateRunResponseinterface tolib/types.ts
Initial MACP UI Console delivery
Added
Project foundation
- created a new Next.js App Router project scaffold
- added TypeScript, Tailwind-free custom CSS shell, React Query, Zustand, React Flow, and Recharts integration points
- added route-handler proxy for Example Service and Control Plane
Layout and navigation
- app shell with sidebar navigation
- sticky topbar with demo-mode and theme toggles
- command palette with route shortcuts
Scenario surfaces
- scenario catalog page
- scenario detail page with version/template switching
- launch schema and defaults inspection
Run launch flow
- new-run page with pack/scenario/template selection
- schema-driven input editor
- raw JSON editor
- compile launch flow against Example Service
- validate execution request against Control Plane
- submit run flow
- optional Example Service one-shot bootstrap flow
Live and historical run analysis
- live-runs page
- shared run workbench for live and historical views
- execution graph built with React Flow
- node inspector with overview, payloads, signals, logs, traces, and metrics tabs
- live event rail
- signal rail
- final decision panel
- observability summary panel
- artifacts and messages panel
- replay descriptor request panel
History and comparison
- run history page with filtering
- run comparison page
Agent and observability surfaces
- agent catalog and detail pages
- logs explorer
- traces explorer
- observability dashboard
- settings page with webhook and audit surfaces
Demo mode
- rich mock data for packs, scenarios, runs, states, metrics, traces, and audit/webhooks
- simulated live run streaming frames
Integration alignment
The UI was aligned to the uploaded repositories by using their exposed contracts and endpoints:
- Example Service for scenario/launch compilation
- Control Plane for run lifecycle, state, streaming, metrics, traces, audit, and webhooks
- runtime metadata as surfaced by Control Plane runtime endpoints
Intentionally not changed
- no modifications were made to the uploaded backend repositories
- no assumptions were added that require backend code changes to render the demo mode