Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/dashboard/components/RunDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ export default function RunDetail({
const reviewReport = reportsState.find((r) => r.name === "review_report.json")?.data;
const taskResult = reportsState.find((r) => r.name === "task_result.json")?.data;
const workReport = reportsState.find((r) => r.name === "work_report.json")?.data;
const completionGovernanceReport = toObject(
reportsState.find((r) => r.name === "completion_governance_report.json")?.data
);
const evidenceReport = reportsState.find((r) => r.name === "evidence_report.json")?.data;
const incidentPack = reportsState.find((r) => r.name === "incident_pack.json")?.data;
const proofPack = reportsState.find((r) => r.name === "proof_pack.json")?.data;
Expand Down Expand Up @@ -532,6 +535,7 @@ export default function RunDetail({
pendingApprovals={pendingApprovals}
evidenceHashes={evidenceHashes}
manifestArtifacts={manifestArtifacts}
completionGovernanceReport={completionGovernanceReport}
planningContracts={planningContracts}
planningContractsError={planningContractsError}
unblockTasks={unblockTasks}
Expand Down
127 changes: 100 additions & 27 deletions apps/dashboard/components/run-detail/RunDetailStatusContractCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type RunDetailStatusContractCardProps = {
pendingApprovals: EventRecord[];
evidenceHashes: Record<string, unknown>;
manifestArtifacts: unknown[];
completionGovernanceReport: Record<string, unknown>;
planningContracts: Array<Record<string, unknown>>;
planningContractsError: string;
unblockTasks: Array<Record<string, unknown>>;
Expand Down Expand Up @@ -68,6 +69,7 @@ export default function RunDetailStatusContractCard({
pendingApprovals,
evidenceHashes,
manifestArtifacts,
completionGovernanceReport,
planningContracts,
planningContractsError,
unblockTasks,
Expand All @@ -77,6 +79,7 @@ export default function RunDetailStatusContractCard({
failedTerminalActionFeedback,
}: RunDetailStatusContractCardProps) {
const bindingReadModelCopy = getUiCopy(DEFAULT_UI_LOCALE).desktop.runDetail.bindingReadModel;
const completionGovernanceCopy = getUiCopy(DEFAULT_UI_LOCALE).desktop.runDetail.completionGovernance;
const terminal = terminalStatus.toUpperCase();
const isTerminal = terminal === "FAILED" || terminal === "ERROR" || terminal === "SUCCESS" || terminal === "DONE" || terminal === "REJECTED";
const isFailedTerminal = terminal === "FAILED" || terminal === "ERROR" || terminal === "REJECTED";
Expand Down Expand Up @@ -129,6 +132,27 @@ export default function RunDetailStatusContractCard({
),
);
const roleBindingReadModel = run.role_binding_read_model;
const runtimeCompletionGovernance = toObject(completionGovernanceReport);
const hasRuntimeCompletionGovernance = Object.keys(runtimeCompletionGovernance).length > 0;
const runtimeDodChecker = toObject(runtimeCompletionGovernance.dod_checker);
const runtimeReplyAuditor = toObject(runtimeCompletionGovernance.reply_auditor);
const runtimeContinuationDecision = toObject(runtimeCompletionGovernance.continuation_decision);
const runtimeContextPack = toObject(runtimeCompletionGovernance.context_pack);
const runtimeHarnessRequest = toObject(runtimeCompletionGovernance.harness_request);
const runtimeDodRequiredChecks = Array.from(
new Set(
toArray(runtimeDodChecker.required_checks as unknown[] | null | undefined)
.map((value) => toDisplayText(value))
.filter((value) => value !== "-"),
),
);
const runtimeDodUnmetChecks = Array.from(
new Set(
toArray(runtimeDodChecker.unmet_checks as unknown[] | null | undefined)
.map((value) => toDisplayText(value))
.filter((value) => value !== "-"),
),
);
const unblockTaskOwners = Array.from(
new Set(unblockTasks.map((task) => toDisplayText(task.owner)).filter((value) => value !== "-")),
);
Expand Down Expand Up @@ -281,36 +305,85 @@ export default function RunDetailStatusContractCard({
</div>
</div>
) : null}
{planningContracts.length > 0 || planningContractsError || unblockTasks.length > 0 || unblockTasksError ? (
{hasRuntimeCompletionGovernance || planningContracts.length > 0 || planningContractsError || unblockTasks.length > 0 || unblockTasksError ? (
<div className="run-detail-section" data-testid="run-completion-governance-summary">
<div className="mono run-detail-section-label">Completion governance</div>
<div className="mono">Worker prompt contracts: {planningContracts.length}</div>
{unblockTasks.length > 0 ? <div className="mono">Unblock tasks: {unblockTasks.length}</div> : null}
{continuationOnIncomplete.length > 0 ? (
<div className="mono">On incomplete: {continuationOnIncomplete.join(" / ")}</div>
) : null}
{continuationOnBlocked.length > 0 ? (
<div className="mono">On blocked: {continuationOnBlocked.join(" / ")}</div>
) : null}
{doneChecks.length > 0 ? (
<div className="mono">DoD checks: {doneChecks.join(" / ")}</div>
) : null}
{unblockTaskOwners.length > 0 ? (
<div className="mono">Unblock owner: {unblockTaskOwners.join(" / ")}</div>
) : null}
{unblockTaskModes.length > 0 ? (
<div className="mono">Unblock mode: {unblockTaskModes.join(" / ")}</div>
<div className="mono run-detail-section-label">{completionGovernanceCopy.title}</div>
{hasRuntimeCompletionGovernance ? (
<div data-testid="run-completion-governance-report">
<div className="mono run-detail-section-label">{completionGovernanceCopy.runtimeTitle}</div>
<div className="mono">{completionGovernanceCopy.overallVerdict}: {toDisplayText(runtimeCompletionGovernance.overall_verdict)}</div>
<div className="mono">{completionGovernanceCopy.reportAuthority}: {toDisplayText(runtimeCompletionGovernance.authority)}</div>
<div className="mono">{completionGovernanceCopy.reportSource}: {toDisplayText(runtimeCompletionGovernance.source)}</div>
<div className="mono">{completionGovernanceCopy.reportExecutionAuthority}: {toDisplayText(runtimeCompletionGovernance.execution_authority)}</div>
<div className="mono">{completionGovernanceCopy.dodChecker}: {toDisplayText(runtimeDodChecker.status)}</div>
{toDisplayText(runtimeDodChecker.summary) !== "-" ? (
<div className="mono">{completionGovernanceCopy.dodSummary}: {toDisplayText(runtimeDodChecker.summary)}</div>
) : null}
{runtimeDodRequiredChecks.length > 0 ? (
<div className="mono">{completionGovernanceCopy.dodRequiredChecks}: {runtimeDodRequiredChecks.join(" / ")}</div>
) : null}
{runtimeDodUnmetChecks.length > 0 ? (
<div className="mono">{completionGovernanceCopy.dodUnmetChecks}: {runtimeDodUnmetChecks.join(" / ")}</div>
) : null}
<div className="mono">{completionGovernanceCopy.replyAuditor}: {toDisplayText(runtimeReplyAuditor.status)}</div>
{toDisplayText(runtimeReplyAuditor.summary) !== "-" ? (
<div className="mono">{completionGovernanceCopy.replySummary}: {toDisplayText(runtimeReplyAuditor.summary)}</div>
) : null}
<div className="mono">{completionGovernanceCopy.continuationDecision}: {toDisplayText(runtimeContinuationDecision.selected_action)}</div>
{toDisplayText(runtimeContinuationDecision.summary) !== "-" ? (
<div className="mono">{completionGovernanceCopy.continuationSummary}: {toDisplayText(runtimeContinuationDecision.summary)}</div>
) : null}
{toDisplayText(runtimeContinuationDecision.action_source) !== "-" ? (
<div className="mono">{completionGovernanceCopy.actionSource}: {toDisplayText(runtimeContinuationDecision.action_source)}</div>
) : null}
{toDisplayText(runtimeContinuationDecision.unblock_task_id) !== "-" ? (
<div className="mono">{completionGovernanceCopy.selectedUnblockTask}: {toDisplayText(runtimeContinuationDecision.unblock_task_id)}</div>
) : null}
<div className="mono">{completionGovernanceCopy.contextPack}: {toDisplayText(runtimeContextPack.status)}</div>
{toDisplayText(runtimeContextPack.summary) !== "-" ? (
<div className="mono">{completionGovernanceCopy.contextPackSummary}: {toDisplayText(runtimeContextPack.summary)}</div>
) : null}
<div className="mono">{completionGovernanceCopy.harnessRequest}: {toDisplayText(runtimeHarnessRequest.status)}</div>
{toDisplayText(runtimeHarnessRequest.summary) !== "-" ? (
<div className="mono">{completionGovernanceCopy.harnessRequestSummary}: {toDisplayText(runtimeHarnessRequest.summary)}</div>
) : null}
<div className="mono muted">{completionGovernanceCopy.runtimeNote}</div>
</div>
) : null}
{unblockTaskTriggers.length > 0 ? (
<div className="mono">Unblock trigger: {unblockTaskTriggers.join(" / ")}</div>
{planningContracts.length > 0 || planningContractsError || unblockTasks.length > 0 || unblockTasksError ? (
<>
{hasRuntimeCompletionGovernance ? (
<div className="mono run-detail-section-label">{completionGovernanceCopy.planningFallbackTitle}</div>
) : null}
<div className="mono">{completionGovernanceCopy.workerPromptContracts}: {planningContracts.length}</div>
{unblockTasks.length > 0 ? (
<div className="mono">{completionGovernanceCopy.unblockTasks}: {unblockTasks.length}</div>
) : null}
{continuationOnIncomplete.length > 0 ? (
<div className="mono">{completionGovernanceCopy.onIncomplete}: {continuationOnIncomplete.join(" / ")}</div>
) : null}
{continuationOnBlocked.length > 0 ? (
<div className="mono">{completionGovernanceCopy.onBlocked}: {continuationOnBlocked.join(" / ")}</div>
) : null}
{doneChecks.length > 0 ? (
<div className="mono">{completionGovernanceCopy.doneChecks}: {doneChecks.join(" / ")}</div>
) : null}
{unblockTaskOwners.length > 0 ? (
<div className="mono">{completionGovernanceCopy.unblockOwner}: {unblockTaskOwners.join(" / ")}</div>
) : null}
{unblockTaskModes.length > 0 ? (
<div className="mono">{completionGovernanceCopy.unblockMode}: {unblockTaskModes.join(" / ")}</div>
) : null}
{unblockTaskTriggers.length > 0 ? (
<div className="mono">{completionGovernanceCopy.unblockTrigger}: {unblockTaskTriggers.join(" / ")}</div>
) : null}
{planningContractsError || unblockTasksError ? (
<div className="mono muted">{planningContractsError || unblockTasksError}</div>
) : (
<div className="mono muted">{completionGovernanceCopy.advisoryNote}</div>
)}
</>
) : null}
{planningContractsError || unblockTasksError ? (
<div className="mono muted">{planningContractsError || unblockTasksError}</div>
) : (
<div className="mono muted">
Derived from persisted worker prompt contracts and unblock tasks. These summaries stay advisory; task_contract still owns execution authority.
</div>
)}
</div>
) : null}
<div className="mono">Manifest artifacts:</div>
Expand Down
98 changes: 98 additions & 0 deletions apps/dashboard/tests/rundetail_core.suite.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,104 @@ describe("RunDetail core flows", () => {
).toBeInTheDocument();
});

it("prefers runtime completion governance report when one is present", async () => {
const run = {
run_id: "run_runtime_governance",
task_id: "task_runtime_governance",
status: "SUCCESS",
allowed_paths: ["README.md"],
contract: { task_id: "task_runtime_governance" },
manifest: {
artifacts: [
{ name: "planning_worker_prompt_contracts", path: "artifacts/planning_worker_prompt_contracts.json" },
{ name: "planning_unblock_tasks", path: "artifacts/planning_unblock_tasks.json" },
],
},
};
const reports = [
{
name: "completion_governance_report.json",
data: {
authority: "runtime-evaluated-read-back",
source: "reports/completion_governance_report.json",
execution_authority: "task_contract",
overall_verdict: "continue_required",
dod_checker: {
status: "failed",
summary: "Missing test_report before completion.",
required_checks: ["repo_hygiene", "test_report"],
unmet_checks: ["test_report"],
},
reply_auditor: {
status: "needs_followup",
summary: "Reply stopped before verification evidence landed.",
},
continuation_decision: {
selected_action: "reply_auditor_reprompt_and_continue_same_session",
summary: "Continue in the same session after the auditor reprompt.",
action_source: "reply_auditor",
unblock_task_id: "unblock-runtime-1",
},
context_pack: {
status: "not_requested",
summary: "Fallback context pack stayed idle.",
},
harness_request: {
status: "not_requested",
summary: "Harness escalation was not required.",
},
},
},
];
const fetchMock = mockFetchFactory({
events: [],
reports,
availableRuns: [],
planningContracts: [
{
prompt_contract_id: "worker-1",
done_definition: { acceptance_checks: ["repo_hygiene", "test_report"] },
continuation_policy: {
on_incomplete: "reply_auditor_reprompt_and_continue_same_session",
on_blocked: "spawn_independent_temporary_unblock_task",
},
},
],
planningUnblockTasks: [
{
unblock_task_id: "unblock-runtime-1",
owner: "L0",
mode: "independent_temporary_task",
trigger: "spawn_independent_temporary_unblock_task",
},
],
});
// @ts-expect-error test override
global.fetch = fetchMock;

render(<RunDetail run={run as any} events={[]} diff="" reports={reports as any} />);
await act(async () => {
await flushPromises();
});

await waitFor(() => {
expect(screen.getByText("Runtime evaluator verdict")).toBeInTheDocument();
});
expect(screen.getByText("Overall verdict: continue_required")).toBeInTheDocument();
expect(screen.getByText("DoD checker: failed")).toBeInTheDocument();
expect(screen.getByText("Reply auditor: needs_followup")).toBeInTheDocument();
expect(screen.getByText("Continuation decision: reply_auditor_reprompt_and_continue_same_session")).toBeInTheDocument();
expect(screen.getByText("Context Pack: not_requested")).toBeInTheDocument();
expect(screen.getByText("Harness Request: not_requested")).toBeInTheDocument();
expect(
screen.getByText(
"Runtime-evaluated read-back: this report reflects the live completion evaluator. task_contract still owns execution authority; this report does not replace the contract.",
),
).toBeInTheDocument();
expect(screen.getByText("Planning advisory fallback")).toBeInTheDocument();
expect(screen.getByText("Worker prompt contracts: 1")).toBeInTheDocument();
});

it("uses SSE transport and consumes stream events", async () => {
const run = {
run_id: "run_sse",
Expand Down
Loading
Loading