feat(web): show IwoooS owner response gate in approvals
This commit is contained in:
@@ -3764,6 +3764,46 @@
|
||||
"item4": "Open the AwoooP work map"
|
||||
}
|
||||
},
|
||||
"approvals": {
|
||||
"securityOwnerResponseGate": {
|
||||
"title": "IwoooS Owner Response Read-only Review Focus",
|
||||
"subtitle": "The AwoooP approval queue only shows the next human intake focus for S4.9-S4.12 owner response. This is not an approval record and does not open a runtime gate.",
|
||||
"badge": "Read-only focus",
|
||||
"ownerChecksTitle": "Owner response intake order",
|
||||
"boundaryLabel": "Approval Boundary",
|
||||
"boundaryTitle": "There is still nothing to approve here",
|
||||
"boundaryDetail": "This panel does not send requests, mark received / accepted, create approval records, call GitHub / Gitea / Kali, or add approve, execute, deploy, primary switch, or refs actions.",
|
||||
"openIwooos": "Open IwoooS",
|
||||
"metrics": {
|
||||
"received": "Received",
|
||||
"receivedDetail": "S4.9-S4.12 owner response received remains 0.",
|
||||
"accepted": "Accepted",
|
||||
"acceptedDetail": "No acceptable redacted owner evidence has been received.",
|
||||
"activeRuntimeGates": "Active runtime gates",
|
||||
"activeRuntimeGatesDetail": "Any runtime gate still needs separate approval plus rollback and post-check evidence.",
|
||||
"headline": "Overall Security Mesh",
|
||||
"headlineDetail": "58% is only reviewed when owner response, runtime gate, GitHub primary, or production landing evidence changes."
|
||||
},
|
||||
"checks": {
|
||||
"s49OwnerAttestation": {
|
||||
"title": "S4.9 Gitea owner attestation",
|
||||
"detail": "Recommended first intake; needs public-only / local gap, org / user endpoint, 110 adjacent source, canonical owner, and legacy disposition answers."
|
||||
},
|
||||
"s410GithubTarget": {
|
||||
"title": "S4.10 GitHub target owner",
|
||||
"detail": "After S4.9, collect owner / visibility / canonical decisions for the seven GitHub targets."
|
||||
},
|
||||
"s411RefsTruth": {
|
||||
"title": "S4.11 refs truth owner response",
|
||||
"detail": "Wait for redacted owner decisions on main / dev truth, deprecated drift, release tags, and GitHub-only refs."
|
||||
},
|
||||
"s412WorkflowSecret": {
|
||||
"title": "S4.12 workflow / secret names",
|
||||
"detail": "Wait for redacted owner decisions on webhooks, runners, deploy keys, branch protection / CODEOWNERS, and secret name parity."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"workItems": {
|
||||
"title": "Work Chain",
|
||||
"subtitle": "{count} control points synced from production truth-chain and governance data",
|
||||
|
||||
@@ -3765,6 +3765,46 @@
|
||||
"item4": "查看 AwoooP 工作鏈路地圖"
|
||||
}
|
||||
},
|
||||
"approvals": {
|
||||
"securityOwnerResponseGate": {
|
||||
"title": "IwoooS Owner Response 只讀審查焦點",
|
||||
"subtitle": "AwoooP 審批佇列只顯示 S4.9-S4.12 owner response 的下一個人工收件焦點;這不是 approval record,也不會開 runtime gate。",
|
||||
"badge": "只讀焦點",
|
||||
"ownerChecksTitle": "Owner response 收件順序",
|
||||
"boundaryLabel": "審批邊界",
|
||||
"boundaryTitle": "目前仍沒有可核准項目",
|
||||
"boundaryDetail": "這個面板不送出 request、不標記 received / accepted、不建立 approval record、不呼叫 GitHub / Gitea / Kali,也不新增 approve、execute、deploy、primary switch 或 refs action。",
|
||||
"openIwooos": "開啟 IwoooS",
|
||||
"metrics": {
|
||||
"received": "Received",
|
||||
"receivedDetail": "S4.9-S4.12 owner response received 仍為 0。",
|
||||
"accepted": "Accepted",
|
||||
"acceptedDetail": "尚未有可接受的脫敏 owner evidence。",
|
||||
"activeRuntimeGates": "Active runtime gates",
|
||||
"activeRuntimeGatesDetail": "任何 runtime gate 仍需獨立批准與 rollback / post-check evidence。",
|
||||
"headline": "整體資安網",
|
||||
"headlineDetail": "58% 只在 owner response、runtime gate、GitHub primary 或 production landing 有 evidence 時重估。"
|
||||
},
|
||||
"checks": {
|
||||
"s49OwnerAttestation": {
|
||||
"title": "S4.9 Gitea owner attestation",
|
||||
"detail": "下一個建議先收;需要回覆 public-only / local gap、org / user endpoint、110 adjacent source、canonical owner 與 legacy disposition。"
|
||||
},
|
||||
"s410GithubTarget": {
|
||||
"title": "S4.10 GitHub target owner",
|
||||
"detail": "等待 S4.9 之後收斂 7 個 GitHub target 的 owner / visibility / canonical decision。"
|
||||
},
|
||||
"s411RefsTruth": {
|
||||
"title": "S4.11 refs truth owner response",
|
||||
"detail": "等待 owner 對 main / dev truth、deprecated drift、release tags 與 GitHub-only refs 做脫敏判定。"
|
||||
},
|
||||
"s412WorkflowSecret": {
|
||||
"title": "S4.12 workflow / secret 名稱",
|
||||
"detail": "等待 owner 對 webhook、runner、deploy key、branch protection / CODEOWNERS、secret name parity 做脫敏判定。"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"workItems": {
|
||||
"title": "工作鏈路",
|
||||
"subtitle": "{count} 個控制點,依 production truth-chain 與治理資料同步狀態",
|
||||
|
||||
@@ -287,6 +287,104 @@ function ApprovalRow({ approval }: { approval: Approval }) {
|
||||
);
|
||||
}
|
||||
|
||||
function SecurityOwnerResponseGatePanel() {
|
||||
const t = useTranslations("awooop.approvals.securityOwnerResponseGate");
|
||||
const metrics = [
|
||||
{
|
||||
label: t("metrics.received"),
|
||||
value: "0",
|
||||
detail: t("metrics.receivedDetail"),
|
||||
},
|
||||
{
|
||||
label: t("metrics.accepted"),
|
||||
value: "0",
|
||||
detail: t("metrics.acceptedDetail"),
|
||||
},
|
||||
{
|
||||
label: t("metrics.activeRuntimeGates"),
|
||||
value: "0",
|
||||
detail: t("metrics.activeRuntimeGatesDetail"),
|
||||
},
|
||||
{
|
||||
label: t("metrics.headline"),
|
||||
value: "58%",
|
||||
detail: t("metrics.headlineDetail"),
|
||||
},
|
||||
];
|
||||
const checks = [
|
||||
{ phase: "S4.9", key: "s49OwnerAttestation" },
|
||||
{ phase: "S4.10", key: "s410GithubTarget" },
|
||||
{ phase: "S4.11", key: "s411RefsTruth" },
|
||||
{ phase: "S4.12", key: "s412WorkflowSecret" },
|
||||
];
|
||||
|
||||
return (
|
||||
<section className="border border-[#e0ddd4] bg-white">
|
||||
<div className="flex flex-wrap items-start justify-between gap-3 border-b border-[#e0ddd4] bg-[#faf9f3] px-4 py-3">
|
||||
<div className="flex items-start gap-2">
|
||||
<ShieldCheck className="mt-0.5 h-4 w-4 text-[#d97757]" aria-hidden="true" />
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold text-[#141413]">{t("title")}</h3>
|
||||
<p className="mt-1 max-w-3xl text-xs leading-5 text-[#77736a]">{t("subtitle")}</p>
|
||||
</div>
|
||||
</div>
|
||||
<span className="inline-flex border border-[#9bb6d9] bg-[#eef5ff] px-2 py-0.5 text-xs font-semibold text-[#1f5b9b]">
|
||||
{t("badge")}
|
||||
</span>
|
||||
</div>
|
||||
<div className="grid gap-px bg-[#e0ddd4] md:grid-cols-2 xl:grid-cols-4">
|
||||
{metrics.map((item) => (
|
||||
<div key={item.label} className="bg-white px-4 py-3">
|
||||
<p className="text-xs font-semibold text-[#77736a]">{item.label}</p>
|
||||
<p className="mt-2 font-mono text-2xl font-semibold text-[#141413]">{item.value}</p>
|
||||
<p className="mt-2 text-xs leading-5 text-[#5f5b52]">{item.detail}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="grid gap-4 p-4 xl:grid-cols-[1.1fr_0.9fr]">
|
||||
<div className="border border-[#e0ddd4] bg-white">
|
||||
<div className="border-b border-[#e0ddd4] bg-[#faf9f3] px-4 py-3 text-xs font-semibold text-[#141413]">
|
||||
{t("ownerChecksTitle")}
|
||||
</div>
|
||||
<div className="divide-y divide-[#eee9dd]">
|
||||
{checks.map((item) => (
|
||||
<div key={item.key} className="grid gap-3 px-4 py-3 md:grid-cols-[72px_1fr]">
|
||||
<span className="font-mono text-xs font-semibold text-[#141413]">{item.phase}</span>
|
||||
<div>
|
||||
<p className="text-sm font-semibold text-[#141413]">
|
||||
{t(`checks.${item.key}.title`)}
|
||||
</p>
|
||||
<p className="mt-1 text-xs leading-5 text-[#5f5b52]">
|
||||
{t(`checks.${item.key}.detail`)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="border border-[#e0ddd4] bg-[#faf9f3] px-4 py-3">
|
||||
<p className="text-xs font-semibold text-[#77736a]">{t("boundaryLabel")}</p>
|
||||
<p className="mt-2 text-sm font-semibold text-[#141413]">{t("boundaryTitle")}</p>
|
||||
<p className="mt-2 text-xs leading-5 text-[#5f5b52]">{t("boundaryDetail")}</p>
|
||||
<div className="mt-4 grid gap-2 font-mono text-xs text-[#141413]">
|
||||
<span>approval_record_created=false</span>
|
||||
<span>owner_response_accepted_count=0</span>
|
||||
<span>runtime_execution_authorized=false</span>
|
||||
<span>action_buttons_allowed=false</span>
|
||||
</div>
|
||||
<Link
|
||||
href="/iwooos"
|
||||
className="mt-4 inline-flex items-center gap-2 border border-[#d8d3c7] bg-white px-3 py-1.5 text-xs font-semibold text-[#141413] hover:border-[#d97757]"
|
||||
>
|
||||
{t("openIwooos")}
|
||||
<ArrowRight className="h-3.5 w-3.5 text-[#77736a]" aria-hidden="true" />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Main Component
|
||||
// =============================================================================
|
||||
@@ -454,6 +552,8 @@ export default function ApprovalsPage() {
|
||||
})}
|
||||
</section>
|
||||
|
||||
<SecurityOwnerResponseGatePanel />
|
||||
|
||||
<div className="flex flex-wrap items-center gap-3 border border-[#e0ddd4] bg-white p-4">
|
||||
<Filter className="w-4 h-4 text-muted-foreground flex-shrink-0" aria-hidden="true" />
|
||||
<span className="text-sm text-muted-foreground">{tEvidence("filters.label")}</span>
|
||||
|
||||
Reference in New Issue
Block a user