feat(work-items): surface product governance matrix
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m37s
CD Pipeline / build-and-deploy (push) Successful in 5m21s
CD Pipeline / post-deploy-checks (push) Has been cancelled

This commit is contained in:
ogt
2026-07-10 10:42:38 +08:00
parent 8b575cc81f
commit 99f427a3cf
6 changed files with 815 additions and 3 deletions

View File

@@ -1469,6 +1469,61 @@ type SecurityCockpitRegistryReadback = {
} | null;
};
type ProductGovernanceMatrixProduct = {
product_id?: string | null;
status?: string | null;
canonical_repo?: string | null;
prod_branch?: string | null;
prod_sha_short?: string | null;
dev_branch?: string | null;
dev_sha_short?: string | null;
ssh_refs_readable?: boolean | null;
environment_split_ready?: boolean | null;
owner_readiness_row_present?: boolean | null;
visibility_readback?: string | null;
public_ui_visible?: boolean | null;
private_or_auth_only?: boolean | null;
tokenless_http_status?: number | null;
tokenless_404_is_visibility_auth?: boolean | null;
backup_evidence_ref?: string | null;
backup_evidence_state?: string | null;
source_control_ready?: boolean | null;
blockers?: string[] | null;
next_gate?: string | null;
};
type ProductGovernanceMatrixResponse = {
schema_version?: string | null;
status?: string | null;
source_control_authority?: string | null;
source_refs?: Record<string, string | null | undefined> | null;
summary?: {
product_count?: number | null;
ready_product_count?: number | null;
blocked_product_count?: number | null;
canonical_repo_count?: number | null;
ssh_verified_product_repo_count?: number | null;
main_branch_present_product_repo_count?: number | null;
dev_branch_present_product_repo_count?: number | null;
dev_prod_environment_split_ready_count?: number | null;
public_visible_product_repo_count?: number | null;
private_or_auth_only_product_repo_count?: number | null;
tokenless_http_404_private_or_auth_product_repo_count?: number | null;
owner_readiness_row_present_count?: number | null;
all_products_have_source_control_ready?: boolean | null;
all_active_product_repos_have_owner_readiness_row?: boolean | null;
all_expected_product_repos_have_dev_and_main?: boolean | null;
backup_bundle_ready?: boolean | null;
backup_bundle_expected_repo_count?: number | null;
backup_evidence_linked_product_count?: number | null;
backup_bundle_verified_product_count?: number | null;
active_blocker_count?: number | null;
} | null;
products?: ProductGovernanceMatrixProduct[] | null;
active_blockers?: string[] | null;
next_action?: string | null;
};
const COMMANDER_INSERTED_REQUIREMENT_FALLBACK: PriorityWorkOrderResponse = {
summary: {
active_p0_state: "blocked_reboot_auto_recovery_slo_not_ready",
@@ -1824,6 +1879,7 @@ type Telemetry = {
aiRouteStatus: AiRouteStatusResponse | null;
reportSourceHealth: ReportSourceHealthResponse | null;
priorityWorkOrder: PriorityWorkOrderResponse | null;
productGovernanceMatrix: ProductGovernanceMatrixResponse | null;
};
type AutomationAssetLedgerKey = "km" | "playbook" | "script" | "schedule" | "verifier";
@@ -11276,6 +11332,181 @@ function MainlineWorkProgressStrip({
);
}
function ProductGovernanceMatrixPanel({
matrix,
loading,
}: {
matrix: ProductGovernanceMatrixResponse | null;
loading: boolean;
}) {
const t = useTranslations("awooop.workItems.productGovernance");
const summary = matrix?.summary;
const products = (matrix?.products ?? []).slice(0, 6);
const total = toCount(summary?.product_count ?? products.length);
const ready = toCount(summary?.ready_product_count);
const sshVerified = toCount(summary?.ssh_verified_product_repo_count);
const devMainReady = toCount(summary?.dev_prod_environment_split_ready_count);
const privateRepos = toCount(summary?.private_or_auth_only_product_repo_count);
const backupLinked = toCount(summary?.backup_evidence_linked_product_count);
const activeBlockers = toCount(summary?.active_blocker_count);
const sourceReady =
summary?.all_products_have_source_control_ready === true ||
(total > 0 && ready === total && activeBlockers === 0);
const metricCards = [
{
key: "products",
label: t("metrics.products"),
value: loading ? "--" : `${ready}/${total}`,
icon: Database,
tone: sourceReady ? "border-[#bfdcc4] bg-[#f2fbf3]" : "border-[#ead5bd] bg-[#fff8ef]",
},
{
key: "ssh",
label: t("metrics.ssh"),
value: loading ? "--" : sshVerified,
icon: GitBranch,
tone: "border-[#c9d8ea] bg-[#eef5ff]",
},
{
key: "devmain",
label: t("metrics.devMain"),
value: loading ? "--" : devMainReady,
icon: GitPullRequest,
tone: "border-[#d8d3c7] bg-white",
},
{
key: "private",
label: t("metrics.private"),
value: loading ? "--" : privateRepos,
icon: Lock,
tone: "border-[#e6d0d0] bg-[#fff6f6]",
},
{
key: "backup",
label: t("metrics.backup"),
value: loading ? "--" : backupLinked,
icon: Archive,
tone: "border-[#d5d6ea] bg-[#f6f6ff]",
},
];
return (
<section
className="border border-[#e0ddd4] bg-white"
data-testid="product-governance-matrix-panel"
>
<div className="grid gap-px bg-[#e0ddd4] xl:grid-cols-[minmax(260px,0.42fr)_minmax(0,1fr)]">
<div className="bg-[#101411] p-4 text-white">
<div className="inline-flex items-center gap-2 border border-[#315a39] bg-[#17241a] px-2 py-0.5 text-xs font-semibold text-[#b8e2bf]">
<ShieldCheck className="h-3.5 w-3.5" aria-hidden="true" />
{t("eyebrow")}
</div>
<h3 className="mt-3 text-base font-semibold tracking-normal">
{t("title")}
</h3>
<div className="mt-4 grid grid-cols-2 gap-2">
<div className="border border-[#314034] bg-[#151b17] p-3">
<div className="text-[11px] font-semibold text-[#9fa8a1]">
{t("status")}
</div>
<div className="mt-1 text-sm font-semibold text-[#d8f5dc]">
{loading ? "--" : sourceReady ? t("ready") : t("actionRequired")}
</div>
</div>
<div className="border border-[#314034] bg-[#151b17] p-3">
<div className="text-[11px] font-semibold text-[#9fa8a1]">
{t("authority")}
</div>
<div className="mt-1 font-mono text-sm font-semibold text-white">
{matrix?.source_control_authority ?? "gitea"}
</div>
</div>
</div>
<p className="mt-3 text-xs leading-5 text-[#b8c0b9]">
{t("subtitle")}
</p>
</div>
<div className="bg-white p-4">
<div className="grid gap-2 md:grid-cols-5">
{metricCards.map((metric) => {
const Icon = metric.icon;
return (
<div key={metric.key} className={cn("border p-3", metric.tone)}>
<div className="flex items-center justify-between gap-2 text-[11px] font-semibold text-[#5f5b52]">
<span>{metric.label}</span>
<Icon className="h-3.5 w-3.5" aria-hidden="true" />
</div>
<div className="mt-1 font-mono text-lg font-semibold text-[#141413]">
{metric.value}
</div>
</div>
);
})}
</div>
<div className="mt-3 grid gap-2 xl:grid-cols-3">
{products.map((product) => {
const rowReady = product.source_control_ready === true;
return (
<div
key={product.product_id ?? product.canonical_repo}
className={cn(
"min-w-0 border p-3",
rowReady
? "border-[#bfdcc4] bg-[#f7fcf7]"
: "border-[#ead5bd] bg-[#fff8ef]"
)}
>
<div className="flex items-center justify-between gap-2">
<div className="min-w-0 truncate font-mono text-xs font-semibold text-[#141413]">
{product.product_id}
</div>
<span
className={cn(
"border px-2 py-0.5 text-[11px] font-semibold",
rowReady
? "border-[#bfdcc4] bg-[#eef9f0] text-[#17602a]"
: "border-[#ead5bd] bg-[#fff3e0] text-[#7a3d00]"
)}
>
{rowReady ? t("ready") : t("actionRequired")}
</span>
</div>
<div className="mt-2 truncate font-mono text-xs text-[#5f5b52]">
{product.canonical_repo}
</div>
<div className="mt-2 grid grid-cols-2 gap-2 text-[11px] text-[#5f5b52]">
<span className="truncate">
{t("prod")} {product.prod_branch}:{product.prod_sha_short}
</span>
<span className="truncate">
{t("dev")} {product.dev_branch}:{product.dev_sha_short}
</span>
<span className="truncate">
{product.private_or_auth_only ? t("privateAuth") : t("publicVisible")}
</span>
<span className="truncate">
{product.backup_evidence_state === "bundle_backup_verified"
? t("backupVerified")
: t("backupLinked")}
</span>
</div>
</div>
);
})}
</div>
<div className="mt-3 border border-[#c9d8ea] bg-[#eef5ff] p-3 text-xs leading-5 text-[#1f5b9b]">
<span className="font-semibold">{t("nextAction")}</span>{" "}
{loading ? "--" : matrix?.next_action ?? "--"}
</div>
</div>
</div>
</section>
);
}
function CommanderInsertedRequirementsPanel({
priority,
loading,
@@ -11706,6 +11937,7 @@ export default function AwoooPWorkItemsPage() {
aiRouteStatus: null,
reportSourceHealth: null,
priorityWorkOrder: null,
productGovernanceMatrix: null,
});
const [loading, setLoading] = useState(true);
const [priorityWorkOrderReadback, setPriorityWorkOrderReadback] =
@@ -11786,6 +12018,8 @@ export default function AwoooPWorkItemsPage() {
projectId
);
const reportSourceHealthUrl = `${API_BASE}/api/v1/agents/agent-report-source-health`;
const productGovernanceMatrixUrl =
`${API_BASE}/api/v1/agents/product-governance-matrix-readback`;
const priorityWorkOrderUrl = `${API_BASE}/api/v1/agents/awoooi-priority-work-order-readback`;
const priorityWorkOrderPromise =
fetchJson<PriorityWorkOrderResponse>(priorityWorkOrderUrl, 12000);
@@ -11819,6 +12053,7 @@ export default function AwoooPWorkItemsPage() {
callbackReplies,
aiRouteStatus,
reportSourceHealth,
productGovernanceMatrix,
priorityWorkOrder,
] = await Promise.all([
fetchJson<AutomationQualitySummary>(qualityUrl, 15000),
@@ -11839,6 +12074,7 @@ export default function AwoooPWorkItemsPage() {
fetchJson<CallbackRepliesWorkItemResponse>(callbackRepliesUrl, 12000),
fetchJson<AiRouteStatusResponse>(aiRouteStatusUrl, 12000),
fetchJson<ReportSourceHealthResponse>(reportSourceHealthUrl, 12000),
fetchJson<ProductGovernanceMatrixResponse>(productGovernanceMatrixUrl, 12000),
priorityWorkOrderPromise,
]);
@@ -11888,6 +12124,7 @@ export default function AwoooPWorkItemsPage() {
incidentTimeline,
aiRouteStatus,
reportSourceHealth,
productGovernanceMatrix,
priorityWorkOrder,
});
setLastUpdated(new Date());
@@ -11991,6 +12228,11 @@ export default function AwoooPWorkItemsPage() {
loading={priorityWorkOrderLoading && !priorityWorkOrder}
/>
<ProductGovernanceMatrixPanel
matrix={telemetry.productGovernanceMatrix}
loading={loading && !telemetry.productGovernanceMatrix}
/>
<SecurityMainlineCockpit
priority={commanderInsertedRequirementWorkOrder}
locale={locale}