import type { OrgRole, RuntimeFrontierSummary, RuntimeSeatInfo, RuntimeTeamInfo, RuntimeWorkItemInfo, RuntimePolicy } from '../types/visual' interface DelegationStrategyPanelProps { roles: OrgRole[] runtimeTeams: RuntimeTeamInfo[] runtimeSeats: RuntimeSeatInfo[] workItems: RuntimeWorkItemInfo[] frontier: RuntimeFrontierSummary companyProfile: string runtimePolicy?: RuntimePolicy finalDeciderRoleId?: string | null topLevelRoleIds?: string[] readOnly?: boolean onUpdateOrgStrategy?: (data: { final_decider_role_id?: string | null }) => void onUpdateRuntimePolicy?: (policy: Record) => void } function adaptiveForWorkItem(item: RuntimeWorkItemInfo): Record | undefined { if (item.adaptive && typeof item.adaptive === 'object') return item.adaptive const metadata = item.metadata if (metadata && typeof metadata === 'object' && metadata.adaptive && typeof metadata.adaptive === 'object') { return metadata.adaptive as Record } return undefined } function missingSignalsForWorkItem(item: RuntimeWorkItemInfo): string[] { const adaptive = adaptiveForWorkItem(item) const signals = Array.isArray(adaptive?.signals) ? adaptive.signals : [] return signals .filter(signal => signal && typeof signal === 'object') .filter(signal => Boolean((signal as Record).required ?? true) && !Boolean((signal as Record).satisfied)) .map(signal => String((signal as Record).name ?? '').trim()) .filter(Boolean) } function gateOwnerForWorkItem(item: RuntimeWorkItemInfo): string { const adaptive = adaptiveForWorkItem(item) const stageProfile = adaptive?.work_item_profile if (stageProfile && typeof stageProfile === 'object') { return String((stageProfile as Record).gate_owner_role_id ?? '').trim() } return '' } function adaptiveConfidenceLabel(item: RuntimeWorkItemInfo): string { const adaptive = adaptiveForWorkItem(item) const confidence = typeof adaptive?.confidence === 'number' ? adaptive.confidence : undefined return typeof confidence === 'number' ? `${Math.round(confidence * 100)}%` : '' } export function DelegationStrategyPanel({ roles, runtimeTeams, runtimeSeats, workItems, frontier, companyProfile, runtimePolicy, finalDeciderRoleId, topLevelRoleIds, readOnly = false, onUpdateOrgStrategy, onUpdateRuntimePolicy, }: DelegationStrategyPanelProps) { const topLevel = roles.filter(r => (topLevelRoleIds ?? []).includes(r.role_id)) const selectedFinalDecider = finalDeciderRoleId || (topLevel.length === 1 ? topLevel[0]?.role_id : '') const hasSelectionError = topLevel.length > 1 && !selectedFinalDecider const roleNameMap = new Map(roles.map(r => [r.role_id, r.name])) return (

Actor Runtime

{companyProfile}
Runtime wakeups, delegation, approvals, and recovery are seat-scoped.
{hasSelectionError && (
Multiple top-level roles exist. Select one final decider before company execution can start.
)}
{(runtimeTeams.length || runtimeSeats.length || workItems.length) ? (
{frontier.status || 'running'} {frontier.run_id ? ` (${frontier.run_id.slice(0, 8)})` : ''}
{frontier.running_count ?? 0} running, {frontier.ready_count ?? 0} ready, {frontier.blocked_count ?? 0} blocked, {frontier.waiting_count ?? 0} waiting
{runtimeTeams.length}
{runtimeSeats.length}
{workItems.length}
{workItems.length > 0 && (
{workItems.slice(0, 6).map(item => { const adaptive = adaptiveForWorkItem(item) const normalizedState = typeof adaptive?.normalized_state === 'string' ? adaptive.normalized_state : '' const blockedReason = typeof adaptive?.blocked_reason === 'string' ? adaptive.blocked_reason : (item.blocked_reason ?? '') const gateOwner = gateOwnerForWorkItem(item) const missingSignals = missingSignalsForWorkItem(item) const confidence = adaptiveConfidenceLabel(item) const summary = [ blockedReason ? `waiting ${blockedReason}` : '', gateOwner ? `gate ${roleNameMap.get(gateOwner) ?? gateOwner}` : '', missingSignals.length ? `signals ${missingSignals.join(', ')}` : '', confidence ? `confidence ${confidence}` : '', normalizedState === 'invalidated' ? 'invalidated' : '', ].filter(Boolean) return (
{roleNameMap.get(item.role_id) ?? item.role_id}: {item.title} [{item.phase}] {item.kanban_column && ( · {item.kanban_column} )} {item.batch_id && batch:{item.batch_id}} {normalizedState && normalizedState !== item.phase && ( state:{normalizedState} )}
{summary.length > 0 && (
{summary.join(' • ')}
)}
) })}
)}
) : null}
) }