Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ try {
if (await navigation.isVisible()) await navigation.click();
await page.locator(".personal-goal-link").first().click();
await page.getByRole("button", { name: locale === "en" ? "Overview" : "概览", exact: true }).click();
const section = page.locator(".delivery-acceptance-contract");
const openInspection = async () => {
const inspection = section.locator(".delivery-check-inspection");
if (await inspection.isVisible() && await inspection.getAttribute("open") === null) {
await inspection.locator(":scope > summary").focus();
await page.keyboard.press("Enter");
}
};
// Both current read owners must describe the same fixture. An empty native
// response correctly supersedes retained status, so it cannot test stale work.
// The owner can invalidate work without changing the contract revision.
const imageDir = resolve(root, "output/playwright/acceptance-currentness");
await mkdir(imageDir, {recursive: true});
Expand All @@ -72,25 +82,26 @@ try {
value.verification.contract_revision = value.revision;
value.verification.contract_digest = value.digest;
}
response = {...snapshot, acceptance: {...acceptance, goal_acceptance_contract: value}};
payload.run_history.goals[0].acceptance_observation = {...acceptance, goal_acceptance_contract: value};
await page.reload({waitUntil: "networkidle"});
const direction = page.locator(".goal-overview-direction");
await direction.waitFor();
const toggle = direction.locator(".goal-direction-toggle");
if (await toggle.isVisible() && await toggle.getAttribute("aria-expanded") === "false") await toggle.click();
await openInspection();
await direction.getByText(contract.criteria[0].description, {exact: true}).waitFor();
await page.screenshot({path: resolve(imageDir, `${locale}-${status}.png`), animations: "disabled"});
const passing = direction.locator(".goal-overview-criteria .is-verified, .goal-overview-criteria .is-accepted");
assert.equal(await passing.count(), status === "accepted" ? 1 : 0, `${status}: retained checks are not current whole-scope success`);
assert.equal(await direction.locator(".goal-overview-criteria li").count(), value.criteria.length);
}
response = structuredClone(snapshot);
payload.run_history.goals[0].acceptance_observation = acceptance;
await page.reload({waitUntil: "networkidle"});
const review = page.locator(".delivery-review");
const section = review.locator(".delivery-acceptance-contract");
const refresh = review.getByRole("button", { name: locale === "en" ? "Refresh snapshot" : "刷新快照", exact: true });
const exportButton = review.getByRole("button", { name: locale === "en" ? "Export delivery snapshot" : "导出交付快照", exact: true });
const openAdvanced = async () => {
await openInspection();
const advanced = section.locator(".delivery-check-advanced");
if (await advanced.isVisible() && await advanced.getAttribute("open") === null) {
await advanced.locator(":scope > summary").focus();
Expand Down Expand Up @@ -138,9 +149,9 @@ try {
await section.getByText(next.digest, { exact: true }).waitFor();
assert.equal(await section.getByText(contract.digest, { exact: true }).count(), 0);
assert.match(await section.locator(".delivery-check-advanced dl").innerText(), /8/);
await section.locator("details > summary").first().click();
await section.getByText(locale === "en" ? "Check record and versions" : "检查记录与版本", {exact: true}).click();
await section.getByText("c".repeat(64), { exact: true }).waitFor();
assert.match(await section.locator(".delivery-check-result dl").innerText(), /6/);
assert.match(await section.getByText(locale === "en" ? "Check record and versions" : "检查记录与版本", {exact: true}).locator("..").locator("dl").innerText(), /6/);
assert.equal(await section.evaluate(element => element.scrollWidth > element.clientWidth + 2), false, "Long digests must wrap at narrow widths");
const downloadPromise = page.waitForEvent("download");
await exportButton.click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,19 @@ export function verifiedContract(status) {
},
};
}
export function oracleContract(state = "current") {
const value = structuredClone(verifiedContract("accepted"));
value.criteria[0].oracle = {
kind: "owner_pinned_oracle", source_id: "recovery-checker", source_digest: "d".repeat(64),
input_refs: ["expected.txt"], output_refs: ["recovery.txt"], state,
};
value.verification.results[0].oracle_evidence = {
source_id: "recovery-checker", source_digest: "d".repeat(64), checked_at: "2026-09-01T01:02:03Z",
input_versions: [{ref: "expected.txt", sha256: "e".repeat(64)}],
output_versions: [{ref: "recovery.txt", sha256: "f".repeat(64)}],
};
return value;
}
export const snapshot = {
ok: true, goal_id: "release-demo", observed_at: "2026-09-01T00:00:00Z", acceptance,
graph: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import assert from "node:assert/strict";
import { deliveryReviewMarkdown, parseDeliveryReview } from "../node_modules/.cache/delivery-review/data/delivery-review.js";
import { deliveryReviewCopy } from "../node_modules/.cache/delivery-review/features/personal-workspace/delivery-review-copy.js";
import { acceptance, contract, snapshot, verifiedContract } from "./goal-acceptance-contract-fixture.mjs";
import { acceptance, contract, oracleContract, snapshot, verifiedContract } from "./goal-acceptance-contract-fixture.mjs";

const withContract = value => ({ ...snapshot, acceptance: { ...acceptance, goal_acceptance_contract: value } });
const before = structuredClone(contract);
Expand All @@ -16,6 +16,7 @@ for (const copy of Object.values(deliveryReviewCopy)) {
const parsed = parseDeliveryReview(source, snapshot.goal_id);
assert.deepEqual(parsed.acceptance.goal_acceptance_contract, source.acceptance.goal_acceptance_contract);
const markdown = deliveryReviewMarkdown(parsed, copy);
assert.ok(markdown.includes(`- recovery: ${contract.criteria[0].description}\n`), "Ordinary criterion export retains its existing shape");
for (const text of [copy.contract.boundary, contract.objective, contract.digest, `${copy.contract.revision}: 7`,
`${copy.contract.source}: release-demo`, copy.contract.taskState.ready, copy.contract.taskState.stale,
copy.contract.notApplicable, copy.contract.verificationState[status]]) {
Expand All @@ -33,6 +34,28 @@ for (const copy of Object.values(deliveryReviewCopy)) {
const empty = parseDeliveryReview(withContract({ ...contract, criteria: [], tasks: [] }), snapshot.goal_id);
assert.ok(deliveryReviewMarkdown(empty, copy).includes(copy.contract.noTasks));
assert.ok(deliveryReviewMarkdown(empty, copy).includes(copy.contract.noCriteria));
for (const [state, expected] of Object.entries({current: "accepted", stale: "stale", failed: "failed", recorded: "unverified", unavailable: "unverified", unverified: "unverified"})) {
const value = oracleContract(state), original = structuredClone(value);
const markdown = deliveryReviewMarkdown(parseDeliveryReview(withContract(value), snapshot.goal_id), copy);
for (const evidence of ["recovery-checker", "d".repeat(64), "2026-09-01T01:02:03Z", "expected.txt", "e".repeat(64), "recovery.txt", "f".repeat(64)]) {
assert.ok(markdown.includes(evidence), `Downloaded checks must preserve their actual source and tested versions: ${evidence}`);
}
assert.ok(markdown.includes(copy.contract.verificationState[expected]));
if (expected !== "accepted") assert.ok(!markdown.includes(copy.contract.verificationState.accepted), "A retained pass is not a current pass");
assert.deepEqual(value, original, "Export cannot update current authority or historical receipts");
}
const missing = oracleContract("unavailable");
delete missing.verification.results[0].oracle_evidence;
const markdown = deliveryReviewMarkdown(parseDeliveryReview(withContract(missing), snapshot.goal_id), copy);
assert.ok(!markdown.includes("2026-09-01T01:02:03Z") && !markdown.includes("f".repeat(64)), "Missing execution evidence cannot acquire invented time or versions");
assert.ok(!markdown.includes(copy.contract.verificationState.accepted));
const replaced = oracleContract("stale");
replaced.criteria[0].oracle.source_id = "replacement-checker";
replaced.criteria[0].oracle.source_digest = "1".repeat(64);
const changed = deliveryReviewMarkdown(parseDeliveryReview(withContract(replaced), snapshot.goal_id), copy);
const [currentBasis, retainedWitness] = changed.split(`### ${copy.contract.receipt}`);
assert.ok(currentBasis.includes("replacement-checker") && currentBasis.includes("1".repeat(64)));
assert.ok(retainedWitness.includes("recovery-checker") && retainedWitness.includes("d".repeat(64)), "A new checker cannot rewrite the saved witness's source");
}
for (const mutation of [
{ ...contract, enabled: "true" }, { ...contract, revision: "7" }, { ...contract, revision: 1.5 },
Expand Down
27 changes: 23 additions & 4 deletions apps/presentation/dashboard/src/data/delivery-review.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { z } from "zod";
import { goalAcceptanceDisplayStatus, goalAcceptanceObservationSchema, type GoalAcceptanceContract } from "./goal-acceptance-observation.js";
import { goalAcceptanceDisplayStatus, goalAcceptanceObservationSchema, projectGoalAcceptanceCriteria, type GoalAcceptanceContract } from "./goal-acceptance-observation.js";

// Consumer validation only; freshness and coverage remain kernel decisions.
const projectionEnvelopeSchema = z.object({
Expand Down Expand Up @@ -140,9 +140,11 @@ export function reviewNodeColumn(node: ReviewNode) {
type EnabledContract = Extract<GoalAcceptanceContract, { enabled: true }>;
type ContractExportLabels = Record<"title" | "boundary" | "scope" | "selectedWork" | "allWork" | "source" | "revision" | "digest" | "objective" | "criteria"
| "nonGoals" | "tasks" | "verification" | "unknown" | "noTasks" | "noCriteria" | "notApplicable"
| "heldTasks" | "receipt" | "receiptNote" | "operation" | "verificationScope" | "allCriteria" | "passed" | "failed" | "exitCode", string> & {
| "heldTasks" | "receipt" | "receiptNote" | "operation" | "verificationScope" | "allCriteria" | "passed" | "failed" | "exitCode"
| "oracleChecker" | "oracleSourceDigest" | "oracleCheckedAt" | "oracleInputVersions" | "oracleOutputVersions", string> & {
taskState: Record<EnabledContract["tasks"][number]["state"], string>;
verificationState: Record<EnabledContract["status"], string>;
oracleState: Record<NonNullable<EnabledContract["criteria"][number]["oracle"]>["state"], string>;
};
export type ReviewExportLabels = {
contract: ContractExportLabels;
Expand Down Expand Up @@ -229,7 +231,11 @@ export function deliveryReviewMarkdown(snapshot: DeliveryReviewSnapshot, labels:
"", `### ${copy.objective}`, line(contract.objective || copy.unknown), "", `### ${copy.criteria}`);
if (contract.non_goals.length) rows.push(`${copy.nonGoals}: ${line(contract.non_goals.join("; "))}`);
if (!contract.criteria.length) rows.push(copy.noCriteria);
for (const criterion of contract.criteria) rows.push(`- ${line(criterion.id)}: ${line(criterion.description)}`);
for (const criterion of projectGoalAcceptanceCriteria(contract)) {
rows.push(`- ${line(criterion.id)}: ${line(criterion.description)}${criterion.oracle ? ` · ${copy.verificationState[criterion.state]}` : ""}`);
if (criterion.oracle) rows.push(` ${copy.oracleChecker}: ${line(criterion.oracle.source_id)} · ${copy.oracleState[criterion.oracle.state]}`,
` ${copy.oracleSourceDigest}: ${line(criterion.oracle.source_digest)}`);
}
rows.push("", `### ${copy.tasks}`);
if (!contract.tasks.length) rows.push(copy.noTasks);
for (const task of contract.tasks) {
Expand All @@ -247,7 +253,20 @@ export function deliveryReviewMarkdown(snapshot: DeliveryReviewSnapshot, labels:
rows.push(copy.receiptNote, `${copy.operation}: ${line(receipt.operation_id)}`,
`${copy.revision}: ${receipt.contract_revision}`, `${copy.digest}: ${line(receipt.contract_digest)}`,
`${copy.verificationScope}: ${line(receipt.todo_id ?? copy.allCriteria)}`);
for (const result of receipt.results) rows.push(`- ${line(result.criterion_id)}: ${result.passed ? copy.passed : copy.failed}; ${copy.exitCode}: ${result.exit_code ?? copy.unknown}`);
for (const result of receipt.results) {
rows.push(`- ${line(result.criterion_id)}: ${result.passed ? copy.passed : copy.failed}; ${copy.exitCode}: ${result.exit_code ?? copy.unknown}`);
// The saved witness belongs to this historical result. Its hashes and
// timestamp never upgrade the current criterion observation above.
const evidence = result.oracle_evidence;
if (!evidence) continue;
rows.push(` ${copy.oracleChecker}: ${line(evidence.source_id)}`,
` ${copy.oracleSourceDigest}: ${line(evidence.source_digest)}`,
` ${copy.oracleCheckedAt}: ${line(evidence.checked_at)}`);
for (const [label, versions] of [[copy.oracleInputVersions, evidence.input_versions], [copy.oracleOutputVersions, evidence.output_versions]] as const) {
rows.push(` ${label}:`);
for (const version of versions) rows.push(` - ${line(version.ref)}: ${line(version.sha256)}`);
}
}
}
}
return rows.join("\n") + "\n";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export const goalAcceptanceContractCopy = {
verificationState: { unverified: "Artifact checks not verified", accepted: "Artifact checks passed", failed: "Artifact checks failed", stale: "Artifact checks stale", partial: "Task checks passed; Goal-wide verification unknown", held: "Task associations require confirmation" },
notApplicable: "Outside the current task gate", heldTasks: "Tasks held", receipt: "Recorded artifact checks", receiptNote: "Recorded results use the revision below. The current contract status above accounts for stale checks and task holds.",
operation: "Verification reference", verificationScope: "Verification scope", allCriteria: "All contract criteria", passed: "Passed", failed: "Failed", exitCode: "Exit code",
oracleChecker: "Owner-pinned checker", oracleSourceDigest: "Source digest", oracleCheckedAt: "Checked at", oracleInputVersions: "Input versions", oracleOutputVersions: "Output versions",
oracleState: {current: "Current versions checked", recorded: "Recorded; current versions not checked", stale: "Source or versions changed; check again", failed: "Checks failed; repair the delivery before checking again", unverified: "Not checked", unavailable: "Evidence unavailable"},
help: "Setup and readback", guide: "Check setup guide (v0)", guidance: "The Agent can prepare a plan for review without running it. Existing technical contracts can also be imported here or managed through CLI configure/verify/disable. Saving does not run commands. Disabling retains historical evidence.",
},
"zh-CN": {
Expand All @@ -23,6 +25,8 @@ export const goalAcceptanceContractCopy = {
verificationState: { unverified: "产物检查未验证", accepted: "产物检查通过", failed: "产物检查失败", stale: "产物检查已过期", partial: "任务检查通过;Goal 整体验证未知", held: "任务关联需要确认" },
notApplicable: "不属于当前任务门禁范围", heldTasks: "受阻任务", receipt: "已记录的产物检查", receiptNote: "记录对应下方版本。上方当前合同状态已考虑检查过期和任务阻塞。",
operation: "验证引用", verificationScope: "验证范围", allCriteria: "全部合同条件", passed: "通过", failed: "失败", exitCode: "退出码",
oracleChecker: "负责人指定的版本固定检查器", oracleSourceDigest: "来源摘要", oracleCheckedAt: "检查时间", oracleInputVersions: "输入版本", oracleOutputVersions: "输出版本",
oracleState: {current: "当前版本已核对", recorded: "历史结果,当前版本未核对", stale: "来源或版本已变化,请重新检查", failed: "检查失败;修复交付物后可再次检查", unverified: "尚未检查", unavailable: "证据不可用"},
help: "配置与读回", guide: "检查配置指南(v0)", guidance: "Agent 可先准备方案供你核对,准备不会运行检查。已有技术合同也可在这里导入,或通过 CLI configure/verify/disable 管理。保存不执行命令,停用保留历史依据。",
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export function GoalAcceptanceContractSection({goalId, contract: retained, copy,
{notice ? <p role="status">{notice}</p> : null}</>;
const readOnly = !canManage;
const criterionText = (item: typeof criteria[number]) => item.oracle
? ({current: zh ? "当前版本已核对" : "Current versions checked", recorded: zh ? "历史结果,当前版本未核对" : "Recorded; current versions not checked", stale: zh ? "来源或版本已变化,请重新检查" : "Source or versions changed; check again", failed: zh ? "检查失败;修复交付物后可再次检查" : "Checks failed; repair the delivery before checking again", unverified: zh ? "尚未检查" : "Not checked", unavailable: zh ? "证据不可用" : "Evidence unavailable"})[fresh ? item.oracle.state : "recorded"]
? copy.oracleState[fresh ? item.oracle.state : "recorded"]
: fresh ? copy.verificationState[item.state] : copy.retained;
const advancedConfiguration = management || enabled ? <details className="delivery-check-advanced"><summary>{zh ? "高级配置与诊断" : "Advanced configuration and diagnostics"}</summary>
<p>{copy.guidance}</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import type {OracleEvidence} from "../../data/goal-acceptance-observation";
import {goalAcceptanceContractCopy} from "./delivery-review-copy";
export function GoalOracleEvidence({evidence, zh}: {evidence: OracleEvidence; zh: boolean}) {
const copy = goalAcceptanceContractCopy[zh ? "zh-CN" : "en"];
return <div className="delivery-oracle-evidence">
<p><strong>{zh ? "负责人指定的版本固定检查器" : "Owner-pinned checker"}</strong> · {evidence.source_id}</p>
<p><strong>{copy.oracleChecker}</strong> · {evidence.source_id}</p>
<p><time dateTime={evidence.checked_at}>{evidence.checked_at}</time></p>
<p>{zh ? "检查在声明文件的隔离副本上执行;不代表远程复核者身份或异议已解决。" : "Checks ran on copies of the declared files. This does not authenticate a remote reviewer or resolve an objection."}</p>
<details><summary>{zh ? "查看来源与实际检查版本" : "Source and tested versions"}</summary>
<p>{zh ? "来源摘要" : "Source digest"} · <code>{evidence.source_digest}</code></p>
<p>{copy.oracleSourceDigest} · <code>{evidence.source_digest}</code></p>
{(["input", "output"] as const).map(role => <div key={role}>
<h4>{role === "input" ? (zh ? "输入版本" : "Input versions") : (zh ? "输出版本" : "Output versions")}</h4>
<h4>{role === "input" ? copy.oracleInputVersions : copy.oracleOutputVersions}</h4>
<ul>{evidence[`${role}_versions`].map(row => <li key={row.ref}>{row.ref} · <code>{row.sha256}</code></li>)}</ul>
</div>)}
</details>
Expand Down
Loading
Loading