fix(rectification): wire unique-minute confirmation to VedAstro and sealed holdout

Keep confirmation fail-closed until the public AA set is ready, and rewrite Technique Audit from the attached VedAstro status instead of a hardcoded blocked row.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-08-20 10:05:35 +08:00
parent a93a3cc1a9
commit 55d3119c68
34 changed files with 1220 additions and 59 deletions
@@ -31,7 +31,7 @@ import {
} from "./chat-message-actions";
import { ModelSelector } from "./model-selector";
import { RectificationHouseTableView } from "./rectification-house-table";
import { TechniqueAuditDisclosure } from "./technique-audit-disclosure";
import { TechniqueAuditDisclosure, ConfirmationGateDisclosure } from "./technique-audit-disclosure";
import { Button } from "./ui/button";
import { Textarea } from "./ui/textarea";
@@ -752,6 +752,7 @@ export function RectificationAgenticChat(props: RectificationAgenticChatProps) {
<p className="rectification-refinement__stage">{candidateResult.natalRecast.user_meaning}</p>
)}
<RectificationHouseTableView table={candidateResult.houseTable} />
<ConfirmationGateDisclosure gate={candidateResult.confirmationGate} />
{savedStatus === "accepted" && candidateResult.techniqueAudit.length > 0 && (
<TechniqueAuditDisclosure rows={candidateResult.techniqueAudit} />
)}
@@ -6,6 +6,7 @@ import {
techniqueAuditStatusLabel,
} from "@/lib/consultation-technique-audit";
import type { TechniqueAuditRow } from "@/lib/consultation-agent-events";
import type { ConfirmationGate } from "@/lib/rectification-agentic/v9/confirmation-gate";
export function TechniqueAuditDisclosure({
rows,
@@ -43,3 +44,57 @@ export function TechniqueAuditDisclosure({
</details>
);
}
const GATE_LABELS: Readonly<Record<ConfirmationGate["blockers"][number]["id"], string>> = {
vedastro_minute_sensitive: "官方分钟层",
adjacent_minutes_indistinguishable: "相邻分钟",
public_aa_holdout: "公开密封集",
};
function gateStatusLabel(status: string): string {
if (status === "passed") return "已通过";
if (status === "not_evaluated") return "尚未跑通";
if (status === "not_ready") return "未达标";
if (status === "failed") return "未通过";
return "未通过";
}
function gateStatusToken(status: string): "executed" | "blocked" {
return status === "passed" ? "executed" : "blocked";
}
export function ConfirmationGateDisclosure({
gate,
}: {
readonly gate: ConfirmationGate;
}) {
return (
<details className="technique-audit">
<summary>
<small>{gate.confirmation_allowed ? "已允许" : "未允许"}</small>
</summary>
<div className="technique-audit-panel">
<table>
<caption className="sr-only"></caption>
<thead>
<tr>
<th scope="col"></th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
{gate.blockers.map((blocker) => (
<tr key={blocker.id}>
<th scope="row">{GATE_LABELS[blocker.id]}</th>
<td data-status={gateStatusToken(blocker.status)}>{gateStatusLabel(blocker.status)}</td>
<td>{blocker.user_meaning}</td>
</tr>
))}
</tbody>
</table>
</div>
</details>
);
}