Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
b9b413a
Generated with Hive: Surface concept fix details, sibling diffs, and …
tomsmith8 Aug 25, 2026
6f6448c
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 25, 2026
8b1f3c8
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 25, 2026
80336bf
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 25, 2026
b0ffb4a
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 25, 2026
e4ebdc6
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 25, 2026
cf6f26a
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 25, 2026
dac9203
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 25, 2026
0646019
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 25, 2026
a1dabee
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 25, 2026
a269b8f
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 25, 2026
3691c01
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 25, 2026
eb761a6
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 25, 2026
288e381
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 26, 2026
62e9d02
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 26, 2026
8183ac2
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 26, 2026
df46e52
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 26, 2026
12d063c
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 26, 2026
3a90630
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 26, 2026
83b8a78
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 27, 2026
f6a2bb1
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 27, 2026
7fc4da5
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 27, 2026
f48e53c
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 27, 2026
633e143
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 27, 2026
05a36b0
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 27, 2026
319e8ed
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 27, 2026
8d33409
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 27, 2026
292f03e
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 27, 2026
37bd1ef
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 27, 2026
527e3cf
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 27, 2026
961428c
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 27, 2026
aa2d77a
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 27, 2026
74bfc78
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 28, 2026
6d6a7bc
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 28, 2026
f3d1e82
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 28, 2026
839b875
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 30, 2026
5890edb
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 30, 2026
a4da089
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 31, 2026
a8e1985
Merge branch 'master' into feature/cmt74230k-surface-concept-fixes-si…
tomsmith8 Aug 31, 2026
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
34 changes: 17 additions & 17 deletions src/__tests__/unit/components/EvalRunsBox.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -762,56 +762,56 @@ describe("EvalRunsBox — isSuperAdmin / StakworkRunLink", () => {
);
});

it("colSpan is 6 for skeleton rows when isSuperAdmin=false", () => {
it("colSpan is 7 for skeleton rows when isSuperAdmin=false", () => {
renderBox({ isLoading: true, fixes: [], isSuperAdmin: false });
const skeletonCell = document.querySelector("td[colspan]");
expect(skeletonCell?.getAttribute("colspan")).toBe("6");
expect(skeletonCell?.getAttribute("colspan")).toBe("7");
});

it("colSpan is 7 for skeleton rows when isSuperAdmin=true", () => {
it("colSpan is 8 for skeleton rows when isSuperAdmin=true", () => {
renderBox({ isLoading: true, fixes: [], isSuperAdmin: true });
const skeletonCells = document.querySelectorAll("td[colspan]");
expect(skeletonCells[0]?.getAttribute("colspan")).toBe("7");
expect(skeletonCells[0]?.getAttribute("colspan")).toBe("8");
});

it("colSpan is 6 for empty-state row when isSuperAdmin=false", () => {
it("colSpan is 7 for empty-state row when isSuperAdmin=false", () => {
renderBox({ fixes: [], isLoading: false, isSuperAdmin: false });
const emptyCell = document.querySelector("td[colspan]");
expect(emptyCell?.getAttribute("colspan")).toBe("6");
expect(emptyCell?.getAttribute("colspan")).toBe("7");
});

it("colSpan is 7 for empty-state row when isSuperAdmin=true", () => {
it("colSpan is 8 for empty-state row when isSuperAdmin=true", () => {
renderBox({ fixes: [], isLoading: false, isSuperAdmin: true });
const emptyCell = document.querySelector("td[colspan]");
expect(emptyCell?.getAttribute("colspan")).toBe("7");
expect(emptyCell?.getAttribute("colspan")).toBe("8");
});

it("colSpan is 7 for expanded-detail row when isSuperAdmin=true", async () => {
it("colSpan is 8 for expanded-detail row when isSuperAdmin=true", async () => {
renderBox({ fixes: [makeFix()], isSuperAdmin: true });

const chevron = screen.getByRole("button", { name: "Expand" });
await act(async () => { fireEvent.click(chevron); });

// Expanded row detail td should have colSpan=7
// Expanded row detail td should have colSpan=8
const expandedCells = document.querySelectorAll("td[colspan]");
const expandedCell = Array.from(expandedCells).find(
(el) => el.getAttribute("colspan") === "7",
(el) => el.getAttribute("colspan") === "8",
);
expect(expandedCell).toBeTruthy();
});

it("colSpan is 6 for expanded-detail row when isSuperAdmin=false", async () => {
it("colSpan is 7 for expanded-detail row when isSuperAdmin=false", async () => {
renderBox({ fixes: [makeFix()], isSuperAdmin: false });

const chevron = screen.getByRole("button", { name: "Expand" });
await act(async () => { fireEvent.click(chevron); });

const expandedCells = document.querySelectorAll("td[colspan]");
// All colspan values should be 6 (no 7 present)
const hasSevenColspan = Array.from(expandedCells).some(
(el) => el.getAttribute("colspan") === "7",
// All colspan values should be 7 (no 8 present)
const hasEightColspan = Array.from(expandedCells).some(
(el) => el.getAttribute("colspan") === "8",
);
expect(hasSevenColspan).toBe(false);
expect(expandedCells[0]?.getAttribute("colspan")).toBe("6");
expect(hasEightColspan).toBe(false);
expect(expandedCells[0]?.getAttribute("colspan")).toBe("7");
});
});
20 changes: 12 additions & 8 deletions src/__tests__/unit/components/RecursionActivityRail.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ function makeRow(overrides: Partial<AttemptRailRow> = {}): AttemptRailRow {
graphReportRef: null,
reportPending: false,
inFlight: false,
fixSnapshot: null,
fixSnapshots: [],
siblingCount: 0,
...overrides,
};
}
Expand Down Expand Up @@ -232,13 +233,16 @@ describe("RecursionActivityRail — fix snapshot diff control", () => {
const rows = [
makeRow({
key: "with-snapshot",
fixSnapshot: {
ref_id: "fix-1",
target_type: "concept",
target_name: "Limitation of Liability",
old_value: '{"docs": "before"}',
new_value: '{"docs": "after"}',
},
fixSnapshots: [
{
ref_id: "fix-1",
target_type: "concept",
target_name: "Limitation of Liability",
old_value: '{"docs": "before"}',
new_value: '{"docs": "after"}',
},
],
siblingCount: 1,
}),
makeRow({ key: "without-snapshot" }),
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,8 @@ function makeAttemptRow(overrides: {
graphReportRef: null,
reportPending: false,
inFlight: false,
fixSnapshot: null,
fixSnapshots: [],
siblingCount: 0,
};
}

Expand Down
2 changes: 2 additions & 0 deletions src/__tests__/unit/components/RecursionBox.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,8 @@ describe("RecursionCard — activity rail", () => {
graphReportRef: null,
reportPending: false,
inFlight: false,
fixSnapshots: [],
siblingCount: 0,
},
];

Expand Down
59 changes: 59 additions & 0 deletions src/__tests__/unit/lib/harvey-lab/fix-sort.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { describe, it, expect } from "vitest";
import { compareFixRows } from "@/lib/harvey-lab/fix-sort";

describe("compareFixRows", () => {
it("orders by target_name ascending, nulls last", () => {
const a = { target_name: "Alpha", criterion_id: null, ref_id: "1" };
const b = { target_name: "Beta", criterion_id: null, ref_id: "2" };
expect(compareFixRows(a, b)).toBeLessThan(0);
expect(compareFixRows(b, a)).toBeGreaterThan(0);
});

it("falls through to criterion_id when target_name is equal (or null)", () => {
const a = { target_name: null, criterion_id: "AAA", ref_id: "1" };
const b = { target_name: null, criterion_id: "BBB", ref_id: "2" };
expect(compareFixRows(a, b)).toBeLessThan(0);
});

it("falls through to ref_id when target_name and criterion_id are both null", () => {
const a = { target_name: null, criterion_id: null, ref_id: "aaa" };
const b = { target_name: null, criterion_id: null, ref_id: "bbb" };
expect(compareFixRows(a, b)).toBeLessThan(0);
});

it("puts nulls last at every tier", () => {
type Row = { target_name: string | null; criterion_id: string | null; ref_id: string };
const withName: Row = { target_name: "Alpha", criterion_id: null, ref_id: "1" };
const noName: Row = { target_name: null, criterion_id: "ZZZ", ref_id: "2" };
expect(compareFixRows(withName, noName)).toBeLessThan(0); // Alpha before null
expect(compareFixRows(noName, withName)).toBeGreaterThan(0);
});

it("handles prompt fixes (no target_name) ordering by criterion_id", () => {
const a = { target_name: null, criterion_id: "crit-001", ref_id: "1" };
const b = { target_name: null, criterion_id: "crit-002", ref_id: "2" };
expect(compareFixRows(a, b)).toBeLessThan(0);
});

it("produces identical ordering for an all-criterion_id-null concept group", () => {
const fixes = [
{ target_name: "Limitation", criterion_id: null, ref_id: "z3" },
{ target_name: "Arbitration", criterion_id: null, ref_id: "z1" },
{ target_name: "Indemnification", criterion_id: null, ref_id: "z2" },
];
const sorted = [...fixes].sort(compareFixRows);
expect(sorted.map(f => f.target_name)).toEqual(["Arbitration", "Indemnification", "Limitation"]);
});

it("is stable on equal inputs", () => {
const a = { target_name: "Same", criterion_id: "same", ref_id: "same" };
const b = { target_name: "Same", criterion_id: "same", ref_id: "same" };
expect(compareFixRows(a, b)).toBe(0);
});

it("trims whitespace before comparing", () => {
const a = { target_name: " Alpha ", criterion_id: null, ref_id: "same" };
const b = { target_name: "Alpha", criterion_id: null, ref_id: "same" };
expect(compareFixRows(a, b)).toBe(0);
});
});
Loading
Loading