Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions apps/dashboard/smoke/frontstage-route-smoke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@ includes(frontstageSource, "resolveFrontstageOpsStatusUrl", "ops status URL reso
includes(frontstageSource, "statusContractFreshnessIssue", "schema freshness gate");
includes(frontstageSource, "localDashboardApiCapabilities", "local capability projection");
includes(frontstageSource, "Ops statusUrl accepts only relative or loopback sources.", "ops source guard helper copy");
includes(frontstageSource, 'data-testid="frontstage-management-surface-mock"', "management surface mock");
includes(frontstageSource, 'data-testid={`frontstage-management-${card.id}`}', "management surface card ids");
includes(frontstageSource, "Mission Bar", "management surface mission bar");
includes(frontstageSource, "Team Roster", "management surface team roster");
includes(frontstageSource, "Ticket Board", "management surface ticket board");
includes(frontstageSource, "Gate Inbox", "management surface gate inbox");
includes(frontstageSource, "Cadence / Budget", "management surface cadence budget");
includes(frontstageSource, "Evidence Timeline", "management surface evidence timeline");
includes(frontstageSource, "goal_id + next_action", "management surface mission source");
includes(frontstageSource, "user_todos + agent_todos", "management surface ticket source");
includes(frontstageSource, "quota + scheduler hints", "management surface budget source");
includes(frontstageSource, "recent_events + artifacts", "management surface evidence source");
includes(frontstageSource, 'data-testid="frontstage-user-todos"', "user todo lane");
includes(frontstageSource, 'data-testid="frontstage-agent-todos"', "agent todo lane");
includes(frontstageSource, 'data-testid="frontstage-todo-discovery"', "todo discovery controls");
Expand Down
123 changes: 122 additions & 1 deletion apps/dashboard/src/views/frontstage-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ function uniqueClaimOwners(projection: GoalChannelProjection) {
[
...projection.agent_todos.map((todo) => todo.claimed_by),
...projection.active_leases.map((lease) => lease.owner_agent),
].filter(Boolean),
].filter((value): value is string => Boolean(value)),
),
);
}
Expand Down Expand Up @@ -477,6 +477,116 @@ function Panel({
);
}

type ManagementSurfaceCard = {
body: string;
icon: React.ComponentType<{ className?: string }>;
id: string;
label: string;
source: string;
value: string;
};

function FrontstageManagementSurfaceMock({
claimOwners,
claimedAgentTodos,
openAgentTodos,
openUserTodos,
projection,
quotaUsed,
}: {
claimOwners: string[];
claimedAgentTodos: number;
openAgentTodos: number;
openUserTodos: number;
projection: GoalChannelProjection;
quotaUsed: string;
}) {
const firstGate = projection.open_gates[0];
const latestEvent = projection.recent_events[0];
const cards: ManagementSurfaceCard[] = [
{
body: projection.next_action,
icon: LayoutDashboard,
id: "mission",
label: "Mission Bar",
source: "goal_id + next_action",
value: projection.display_name,
},
{
body: claimOwners.length ? claimOwners.slice(0, 3).join(", ") : "No claimed owner projected.",
icon: Users,
id: "team",
label: "Team Roster",
source: "active_leases + claimed_by",
value: `${claimOwners.length} visible agents`,
},
{
body: `${openUserTodos} user todo, ${openAgentTodos} agent todo; ${claimedAgentTodos} claimed.`,
icon: ListChecks,
id: "tickets",
label: "Ticket Board",
source: "user_todos + agent_todos",
value: `${openUserTodos + openAgentTodos} open tickets`,
},
{
body: firstGate ? `${firstGate.kind} blocks ${(firstGate.blocks ?? []).join(", ") || "delivery"}.` : "No open gate in this projection.",
icon: CircleAlert,
id: "gates",
label: "Gate Inbox",
source: "decision_frame + open_gates",
value: projection.decision_frame.user_action_required ? "decision visible" : "clear",
},
{
body: `${artifactDisplayValue(projection.quota.spend_policy)}; state=${stringifyScalar(projection.quota.state)}.`,
icon: Clock3,
id: "cadence",
label: "Cadence / Budget",
source: "quota + scheduler hints",
value: quotaUsed,
},
{
body: latestEvent ? `${latestEvent.classification ?? "event"}: ${latestEvent.summary ?? latestEvent.generated_at ?? "recorded"}` : "No compact event projected.",
icon: ShieldCheck,
id: "evidence",
label: "Evidence Timeline",
source: "recent_events + artifacts",
value: `${projection.recent_events.length} events`,
},
];

return (
<Panel icon={LayoutDashboard} title="Management Surface Mock">
<div className="grid gap-3 p-4 sm:grid-cols-2 xl:grid-cols-3" data-testid="frontstage-management-surface-mock">
{cards.map((card) => {
const Icon = card.icon;
return (
<section
className="min-w-0 rounded-md border border-slate-200 bg-slate-50 px-3 py-3"
data-testid={`frontstage-management-${card.id}`}
key={card.id}
>
<div className="flex items-center justify-between gap-3">
<div className="flex min-w-0 items-center gap-2">
<span className="flex h-8 w-8 shrink-0 items-center justify-center rounded-md border border-slate-200 bg-white text-slate-600">
<Icon className="h-4 w-4" />
</span>
<div className="min-w-0">
<div className="truncate text-sm font-semibold text-slate-950">{card.label}</div>
<div className="truncate text-[11px] font-medium text-slate-500">{card.source}</div>
</div>
</div>
<Badge variant="neutral">kernel</Badge>
</div>
<div className="mt-3 break-words text-lg font-semibold leading-7 text-slate-950">{card.value}</div>
<p className="mt-1 line-clamp-3 break-words text-xs font-medium leading-5 text-slate-600">{card.body}</p>
</section>
);
})}
</div>
</Panel>
);
}

function EfficiencyEvidencePanel() {
const workload = selfIterationShowcase?.workload_signal;
const model = workload?.efficiency_model;
Expand Down Expand Up @@ -1833,6 +1943,17 @@ function FrontstageRoute({
</div>
</div>

{isOpsMode ? (
<FrontstageManagementSurfaceMock
claimOwners={claimOwners}
claimedAgentTodos={claimedAgentTodos}
openAgentTodos={openAgentTodos}
openUserTodos={openUserTodos}
projection={projection}
quotaUsed={quotaUsed}
/>
) : null}

{!isDeveloperMode ? <EfficiencyEvidencePanel /> : null}

{isShowcaseMode ? <TrajectoryAnalysisPanel /> : null}
Expand Down
4 changes: 4 additions & 0 deletions docs/product/frontstage-dashboard-interaction-baseline.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ The route currently exposes these durable anchors:
- `frontstage-ops-command-strip` for search/filter/result-count controls.
- `frontstage-todo-search`, `frontstage-todo-lane-filter`, and
`frontstage-todo-result-count` for reviewable todo projection slices.
- `frontstage-management-surface-mock` for the low-fidelity ops projection
that maps kernel state into mission, team roster, ticket board, gate inbox,
cadence/budget, and evidence timeline without introducing a parallel state
model.
- `frontstage-role-map`, `frontstage-active-claims`, `frontstage-open-gates`,
`frontstage-artifacts`, and `frontstage-timeline` for the operator workspace.
- `frontstage-showcase-motion-beam` and `frontstage-state-flow-beam` for
Expand Down
Loading