mirror of
https://github.com/block/buzz.git
synced 2026-10-30 05:51:46 +00:00
Refine prototype review check tracks
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
This commit is contained in:
@@ -8,24 +8,47 @@ export const PROJECT_REVIEW_CHECK_RESULT_MARKER = "BUZZ_CHECK_RESULT_V1";
|
||||
export const DEFAULT_PROJECT_REVIEW_CHECKS = [
|
||||
{
|
||||
id: "interface",
|
||||
name: "Interface & design system",
|
||||
name: "Interface & frontend",
|
||||
description:
|
||||
"Reviews user-facing changes against the design system and their backend contracts.",
|
||||
"Reviews the user-facing experience and frontend implementation as one surface.",
|
||||
instructions: [
|
||||
"Inspect user-facing changes and the backend behavior that supplies them.",
|
||||
"Check design-system component usage, interaction states, accessibility, and visual consistency.",
|
||||
"Inspect the user-facing behavior and frontend implementation changed by this review.",
|
||||
"Check design-system usage, interaction states, accessibility, loading and error states, performance, and visual consistency.",
|
||||
"Flag hand-rolled UI where the project design system already provides the intended primitive.",
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "frontend",
|
||||
name: "Frontend quality",
|
||||
id: "code-correctness",
|
||||
name: "Code correctness",
|
||||
description:
|
||||
"Reviews frontend correctness, state boundaries, accessibility, and maintainability.",
|
||||
"Checks whether the changed code behaves correctly in normal, edge, and failure paths.",
|
||||
instructions: [
|
||||
"Inspect the frontend implementation changed by this review.",
|
||||
"Check data flow, loading and error states, accessibility, performance, and maintainability.",
|
||||
"Only report issues introduced by or made materially worse by this review.",
|
||||
"Trace the changed behavior through its callers, data flow, and external contracts.",
|
||||
"Look for logic errors, invalid state transitions, missed edge cases, unsafe error handling, races, and resource-lifecycle defects.",
|
||||
"Report behavior-level defects introduced by or made materially worse by this review; leave codebase conventions to their own check.",
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "codebase-patterns",
|
||||
name: "Codebase patterns",
|
||||
description:
|
||||
"Checks whether the implementation follows the architecture and established patterns of this codebase.",
|
||||
instructions: [
|
||||
"Compare the change with contributor guidance and analogous code already in the repository.",
|
||||
"Check architectural boundaries, shared abstractions, naming, error handling, and framework idioms for consistency with established patterns.",
|
||||
"Report departures that create meaningful maintenance or integration risk; leave functional defects to the code correctness check.",
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "historical-intent",
|
||||
name: "Historical intent",
|
||||
description:
|
||||
"Explores the history of the changed area to identify intentional or accidental shifts in project philosophy.",
|
||||
instructions: [
|
||||
"Inspect relevant line and path history with git blame and git log, then follow related commits into pull requests or review discussion when available.",
|
||||
"Look for prior design rationale, analogous changes, reversions, and decisions from maintainers or frequent contributors to this area.",
|
||||
"Evaluate whether this review continues, deliberately revises, or accidentally contradicts the philosophy behind the existing implementation; clearly distinguish historical evidence from inference.",
|
||||
"Do not reject a change merely because it differs from precedent. Recommend a fix only when an unexplained philosophical shift creates material product, architecture, or maintenance risk.",
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -12,13 +12,31 @@ import {
|
||||
writeProjectReviewCheckRuns,
|
||||
} from "./projectReviewChecks.mjs";
|
||||
|
||||
test("starter checks cover interface, frontend, and test quality", () => {
|
||||
test("starter checks keep experience, correctness, patterns, history, and tests independent", () => {
|
||||
assert.deepEqual(
|
||||
DEFAULT_PROJECT_REVIEW_CHECKS.map((check) => check.id),
|
||||
["interface", "frontend", "test-quality"],
|
||||
[
|
||||
"interface",
|
||||
"code-correctness",
|
||||
"codebase-patterns",
|
||||
"historical-intent",
|
||||
"test-quality",
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
test("historical intent check investigates precedent without treating it as a veto", () => {
|
||||
const check = DEFAULT_PROJECT_REVIEW_CHECKS.find(
|
||||
(candidate) => candidate.id === "historical-intent",
|
||||
);
|
||||
assert.ok(check);
|
||||
const instructions = check.instructions.join("\n");
|
||||
assert.match(instructions, /git blame and git log/);
|
||||
assert.match(instructions, /pull requests or review discussion/);
|
||||
assert.match(instructions, /historical evidence from inference/);
|
||||
assert.match(instructions, /Do not reject a change merely because/);
|
||||
});
|
||||
|
||||
test("parses an approved structured agent result", () => {
|
||||
const result = parseProjectReviewCheckResult(`Analysis first.
|
||||
|
||||
@@ -220,7 +238,7 @@ test("builds a review-only prompt pinned to the exact commit", () => {
|
||||
|
||||
assert.match(prompt, /Review only; do not modify code/);
|
||||
assert.match(prompt, /Commit under review: abc123/);
|
||||
assert.match(prompt, /Frontend quality/);
|
||||
assert.match(prompt, /Code correctness/);
|
||||
assert.match(prompt, /"request_id":"request-123"/);
|
||||
assert.match(prompt, /Echo request_id exactly/);
|
||||
assert.match(prompt, /process every event independently/);
|
||||
@@ -256,7 +274,9 @@ test("local check state is isolated by relay, signer, repo, and review", () => {
|
||||
getItem: (key) => entries.get(key) ?? null,
|
||||
setItem: (key, value) => entries.set(key, value),
|
||||
};
|
||||
const runs = { frontend: { agentPubkey: "agent", status: "idle" } };
|
||||
const runs = {
|
||||
"code-correctness": { agentPubkey: "agent", status: "idle" },
|
||||
};
|
||||
writeProjectReviewCheckRuns(storage, first, runs);
|
||||
assert.deepEqual(readProjectReviewCheckRuns(storage, first), runs);
|
||||
assert.deepEqual(readProjectReviewCheckRuns(storage, second), {});
|
||||
|
||||
@@ -167,7 +167,7 @@ test("review checks dispatch to an agent authorized for the relay identity", asy
|
||||
|
||||
const checks = page.getByTestId("project-review-checks");
|
||||
await expect(checks).toBeVisible();
|
||||
await expect(checks.getByTestId("project-review-check")).toHaveCount(3);
|
||||
await expect(checks.getByTestId("project-review-check")).toHaveCount(5);
|
||||
const interfaceCheck = checks.getByTestId("project-review-check").first();
|
||||
await page.getByTestId("project-review-debug-harness-trigger").click();
|
||||
await page
|
||||
@@ -201,7 +201,7 @@ test("review checks dispatch to an agent authorized for the relay identity", asy
|
||||
| { content?: string; mentionPubkeys?: string[] }
|
||||
| undefined;
|
||||
});
|
||||
expect(sentCheck?.content).toContain("Interface & design system");
|
||||
expect(sentCheck?.content).toContain("Interface & frontend");
|
||||
expect(sentCheck?.content).toContain("Commit under review:");
|
||||
expect(sentCheck?.content).toContain("buzz messages send-diff");
|
||||
expect(sentCheck?.mentionPubkeys).toContain(RELAY_REVIEW_AGENT_PUBKEY);
|
||||
@@ -449,11 +449,11 @@ test("concurrent review checks only accept their correlated result", async ({
|
||||
await page.getByRole("button", { name: "Checks", exact: true }).click();
|
||||
|
||||
const checks = page.getByTestId("project-review-check");
|
||||
await expect(checks).toHaveCount(3);
|
||||
await expect(checks).toHaveCount(5);
|
||||
for (const check of await checks.all()) {
|
||||
await check.getByRole("button", { name: "Run", exact: true }).click();
|
||||
}
|
||||
await expect(checks.filter({ hasText: "Running" })).toHaveCount(3);
|
||||
await expect(checks.filter({ hasText: "Running" })).toHaveCount(5);
|
||||
|
||||
await expect
|
||||
.poll(() =>
|
||||
@@ -470,7 +470,7 @@ test("concurrent review checks only accept their correlated result", async ({
|
||||
).length ?? 0,
|
||||
),
|
||||
)
|
||||
.toBe(3);
|
||||
.toBe(5);
|
||||
|
||||
const prompts = await page.evaluate(
|
||||
() =>
|
||||
@@ -490,12 +490,20 @@ test("concurrent review checks only accept their correlated result", async ({
|
||||
requestIdFromCheckPrompt(
|
||||
prompts.find((prompt) => prompt.includes(`"${checkName}"`)),
|
||||
);
|
||||
const interfaceRequestId = requestIdFor("Interface & design system");
|
||||
const frontendRequestId = requestIdFor("Frontend quality");
|
||||
const interfaceRequestId = requestIdFor("Interface & frontend");
|
||||
const correctnessRequestId = requestIdFor("Code correctness");
|
||||
const patternsRequestId = requestIdFor("Codebase patterns");
|
||||
const historicalIntentRequestId = requestIdFor("Historical intent");
|
||||
const testRequestId = requestIdFor("Test quality");
|
||||
const openerByRequestId = new Map(
|
||||
await Promise.all(
|
||||
[interfaceRequestId, frontendRequestId, testRequestId].map(
|
||||
[
|
||||
interfaceRequestId,
|
||||
correctnessRequestId,
|
||||
patternsRequestId,
|
||||
historicalIntentRequestId,
|
||||
testRequestId,
|
||||
].map(
|
||||
async (requestId) =>
|
||||
[requestId, await checkOpenerEventId(page, requestId)] as const,
|
||||
),
|
||||
@@ -503,14 +511,14 @@ test("concurrent review checks only accept their correlated result", async ({
|
||||
);
|
||||
const responses = [
|
||||
{
|
||||
request_id: frontendRequestId,
|
||||
request_id: patternsRequestId,
|
||||
conclusion: "fix-recommended",
|
||||
summary: "Frontend-specific result.",
|
||||
summary: "Pattern-specific result.",
|
||||
findings: [
|
||||
{
|
||||
title: "Frontend-only finding",
|
||||
detail: "This must stay on the frontend check.",
|
||||
file: "desktop/src/frontend.tsx",
|
||||
title: "Pattern-only finding",
|
||||
detail: "This must stay on the codebase patterns check.",
|
||||
file: "desktop/src/pattern.ts",
|
||||
line: 12,
|
||||
},
|
||||
],
|
||||
@@ -527,6 +535,18 @@ test("concurrent review checks only accept their correlated result", async ({
|
||||
summary: "Interface-specific result.",
|
||||
findings: [],
|
||||
},
|
||||
{
|
||||
request_id: correctnessRequestId,
|
||||
conclusion: "approved",
|
||||
summary: "Correctness-specific result.",
|
||||
findings: [],
|
||||
},
|
||||
{
|
||||
request_id: historicalIntentRequestId,
|
||||
conclusion: "approved",
|
||||
summary: "Historical-intent-specific result.",
|
||||
findings: [],
|
||||
},
|
||||
];
|
||||
|
||||
await waitForMockLiveSubscription(page, "DM");
|
||||
@@ -547,9 +567,9 @@ test("concurrent review checks only accept their correlated result", async ({
|
||||
response: responses[0],
|
||||
},
|
||||
);
|
||||
await expect(checks.nth(1)).toContainText("Running");
|
||||
await expect(checks.nth(2)).toContainText("Running");
|
||||
|
||||
const targetIndexes = [1, 2, 0];
|
||||
const targetIndexes = [2, 4, 0, 1, 3];
|
||||
for (const [index, response] of responses.entries()) {
|
||||
await page.evaluate(
|
||||
({ agentPubkey, createdAt, openerEventId, response }) => {
|
||||
@@ -574,16 +594,24 @@ test("concurrent review checks only accept their correlated result", async ({
|
||||
);
|
||||
if (index === 0) {
|
||||
await expect(checks.nth(0)).toContainText("Running");
|
||||
await expect(checks.nth(2)).toContainText("Running");
|
||||
await expect(checks.nth(1)).toContainText("Running");
|
||||
await expect(checks.nth(3)).toContainText("Running");
|
||||
await expect(checks.nth(4)).toContainText("Running");
|
||||
}
|
||||
}
|
||||
|
||||
await expect(checks.nth(0)).toContainText("Interface-specific result.");
|
||||
await expect(checks.nth(1)).toContainText("Frontend-specific result.");
|
||||
await expect(checks.nth(1)).toContainText("Frontend-only finding");
|
||||
await expect(checks.nth(2)).toContainText("Test-specific result.");
|
||||
await expect(checks.nth(0)).not.toContainText("Frontend-specific result.");
|
||||
await expect(checks.nth(2)).not.toContainText("Frontend-specific result.");
|
||||
await expect(checks.nth(1)).toContainText("Correctness-specific result.");
|
||||
await expect(checks.nth(2)).toContainText("Pattern-specific result.");
|
||||
await expect(checks.nth(2)).toContainText("Pattern-only finding");
|
||||
await expect(checks.nth(3)).toContainText(
|
||||
"Historical-intent-specific result.",
|
||||
);
|
||||
await expect(checks.nth(4)).toContainText("Test-specific result.");
|
||||
await expect(checks.nth(0)).not.toContainText("Pattern-specific result.");
|
||||
await expect(checks.nth(1)).not.toContainText("Pattern-specific result.");
|
||||
await expect(checks.nth(3)).not.toContainText("Pattern-specific result.");
|
||||
await expect(checks.nth(4)).not.toContainText("Pattern-specific result.");
|
||||
});
|
||||
|
||||
test("same-second request changes supersedes approval", async ({ page }) => {
|
||||
|
||||
Reference in New Issue
Block a user