Intelligence
Artifacts
Browse the repository, read documents, and manage the governance folders. Source, runtime, and infrastructure are read-only.
Repository
repositories/aaf-holdings/hq01/lib/mission-control/overview.ts
8.0 KB
import { listMissions } from "@/lib/missions/manager";
import { readHistory } from "@/lib/missions/store";
import { listObjectives, missionProgress } from "@/lib/missions/objectives";
import { listWorkOrders } from "@/lib/missions/work-orders";
import { listAssignments } from "@/lib/missions/assignments";
import { listReportsForMission } from "@/lib/missions/reports";
import {
listRisks,
listDependencies,
listKpis,
missionBlockReasons,
} from "@/lib/missions/governance";
import { listAssets } from "@/lib/assets/ledger";
import { listInstances } from "@/lib/workers/instances";
import { getTemplate } from "@/lib/workers/templates";
import { listSessions, getSession } from "@/lib/sessions/manager";
import { loadRegistry } from "@/lib/executives/registry";
import type {
Mission,
MissionStatus,
Report,
} from "@/lib/missions/types";
import type { WorkerInstance } from "@/lib/workers/types";
import type { Asset } from "@/lib/assets/types";
/**
* Mission Control composition (PASS M8). Read-only: it composes the existing
* Mission OS into the headquarters view and never creates or stores new data.
* The mission/assignment pages remain the place where state is reconciled and
* mutated; this view reflects current state and cross-checks session liveness
* so "running" is honest.
*/
const OPEN_STATES: MissionStatus[] = [
"Draft", "Proposed", "Approved", "Planning", "Active", "Blocked", "Review",
];
const NON_TERMINAL = (s: MissionStatus) => s !== "Archived" && s !== "Cancelled";
function durationFrom(start: string | null, end: string | null): string {
if (!start) return "—";
const endMs = end ? Date.parse(end) : Date.now();
const secs = Math.max(0, Math.round((endMs - Date.parse(start)) / 1000));
return secs >= 60 ? `${Math.floor(secs / 60)}m ${secs % 60}s` : `${secs}s`;
}
export interface PortfolioRow {
mission: Mission;
progress: { completed: number; total: number; percentage: number };
workerCount: number;
openRisks: number;
blockReasons: number;
recentActivity: string | null;
}
export interface WorkerRow {
instance: WorkerInstance;
templateName: string;
missionTitle: string;
runtime: string;
reportStatus: string;
}
export interface ExecRow {
id: string;
displayName: string;
office: string;
status: string;
missionCount: number;
workerCount: number;
lastReport: string | null;
lastActivity: string | null;
}
export interface MissionControl {
header: { activeSessions: number; runningWorkers: number; openMissions: number };
portfolio: PortfolioRow[];
execution: { running: WorkerRow[]; recentCompleted: WorkerRow[]; failed: WorkerRow[] };
attention: {
blockedMissions: Mission[];
criticalRisks: { missionId: string; title: string }[];
activeBlockingDeps: { missionId: string; detail: string }[];
offTrackKpis: { missionId: string; name: string }[];
reviewRequired: Mission[];
};
executives: ExecRow[];
recentReports: Report[];
recentAssets: Asset[];
health: {
byState: Record<string, number>;
objectivesCompletePct: number;
openWorkOrders: number;
assignments: number;
workerInstances: number;
};
}
export function getMissionControl(): MissionControl {
const missions = listMissions();
const missionById = new Map(missions.map((m) => [m.id, m]));
const allInstances = listInstances();
const allAssets = listAssets();
// A worker is genuinely running only if its session is still alive.
const sessionAlive = new Map<string, boolean>();
const aliveOf = (sid: string | null): boolean => {
if (!sid) return false;
if (!sessionAlive.has(sid)) {
const s = getSession(sid);
sessionAlive.set(sid, s?.status === "running" || s?.status === "starting");
}
return sessionAlive.get(sid)!;
};
const workerRow = (i: WorkerInstance): WorkerRow => ({
instance: i,
templateName: getTemplate(i.template_id)?.name ?? i.template_id,
missionTitle: missionById.get(i.mission_id)?.title ?? i.mission_id,
runtime: durationFrom(i.started_at, i.completed_at),
reportStatus: i.report_id ? `report ${i.report_id.replace("REPORT-", "R-")}` : i.status,
});
const running = allInstances.filter((i) => i.status === "Running" && aliveOf(i.session_id));
const recentCompleted = allInstances
.filter((i) => i.status === "Terminated" || i.status === "Completed")
.slice(0, 8);
const failed = allInstances.filter((i) => i.status === "Failed").slice(0, 8);
// Aggregate reports + governance across missions.
const allReports: Report[] = [];
const criticalRisks: { missionId: string; title: string }[] = [];
const activeBlockingDeps: { missionId: string; detail: string }[] = [];
const offTrackKpis: { missionId: string; name: string }[] = [];
let openWorkOrders = 0;
let assignmentCount = 0;
let objCompleted = 0;
let objTotal = 0;
const portfolio: PortfolioRow[] = missions.map((m) => {
const progress = missionProgress(m.id);
objCompleted += progress.completed;
objTotal += progress.total;
const wos = listWorkOrders(m.id);
openWorkOrders += wos.filter(
(w) => !["Completed", "Cancelled", "Archived"].includes(w.status),
).length;
assignmentCount += listAssignments(m.id).length;
for (const r of listReportsForMission(m.id)) allReports.push(r);
const risks = listRisks(m.id);
const openRisks = risks.filter(
(r) => !["Resolved", "Closed", "Accepted"].includes(r.status),
).length;
for (const r of risks) {
if (r.severity === "Critical" && !["Resolved", "Closed", "Accepted"].includes(r.status))
criticalRisks.push({ missionId: m.id, title: r.title });
}
for (const d of listDependencies(m.id)) {
if (d.blocking && d.status === "Active")
activeBlockingDeps.push({ missionId: m.id, detail: `${d.type}: ${d.depends_on}` });
}
for (const k of listKpis(m.id)) {
if (k.status === "Off Track") offTrackKpis.push({ missionId: m.id, name: k.name });
}
const hist = readHistory(m.id).sort((a, b) => b.at.localeCompare(a.at));
const recentActivity = hist[0]
? `${hist[0].type.replace(/_/g, " ")} · ${new Date(hist[0].at).toLocaleString()}`
: null;
return {
mission: m,
progress,
workerCount: running.filter((i) => i.mission_id === m.id).length,
openRisks,
blockReasons: missionBlockReasons(m.id).length,
recentActivity,
};
});
allReports.sort((a, b) => b.created_at.localeCompare(a.created_at));
// Executives.
const executives: ExecRow[] = loadRegistry().map((e) => {
const execReports = allReports.filter((r) => r.executive === e.id);
return {
id: e.id,
displayName: e.displayName,
office: e.office,
status: e.status,
missionCount: missions.filter((m) => m.executive_owner === e.id && NON_TERMINAL(m.status)).length,
workerCount: running.filter((i) => i.executive === e.id).length,
lastReport: execReports[0]?.report_id ?? null,
lastActivity: execReports[0]?.created_at ?? null,
};
});
const byState: Record<string, number> = {};
for (const m of missions) byState[m.status] = (byState[m.status] ?? 0) + 1;
return {
header: {
activeSessions: listSessions().filter(
(s) => s.status === "running" || s.status === "starting",
).length,
runningWorkers: running.length,
openMissions: missions.filter((m) => OPEN_STATES.includes(m.status)).length,
},
portfolio,
execution: {
running: running.map(workerRow),
recentCompleted: recentCompleted.map(workerRow),
failed: failed.map(workerRow),
},
attention: {
blockedMissions: missions.filter((m) => m.status === "Blocked"),
criticalRisks,
activeBlockingDeps,
offTrackKpis,
reviewRequired: missions.filter((m) => m.status === "Review"),
},
executives,
recentReports: allReports.slice(0, 8),
recentAssets: allAssets.slice(0, 8),
health: {
byState,
objectivesCompletePct: objTotal === 0 ? 0 : Math.round((objCompleted / objTotal) * 100),
openWorkOrders,
assignments: assignmentCount,
workerInstances: allInstances.length,
},
};
}
root · /srv/aaf