Skip to content

Commit 1bf185c

Browse files
committed
feat(v7-h01): spec validation auto-fix UX for 8 gotcha ids
Closes V7-H01 (cppmega-mlx-ik1p): extends GotchasTab auto-fix coverage from 2 → 8 gotcha ids with descriptive button labels; App.tsx wires onGotchaAutoFix to dispatch the spec mutation. GotchasTab: AUTO_FIXABLE set: fsdp2_whole_compile, megatron_tp_whole_compile, missing_edge, dim_mismatch, unknown_brick, bad_dtype_combo, schedule_out_of_range, tokenizer_mismatch. Button text uses FIX_LABELS mapping (e.g. "Switch compile_mode → regional", "Reset dtype to bf16 master") instead of generic "Auto-fix". App.tsx onGotchaAutoFix handler: - compile_mode whole → regional - bad_dtype_combo → mixed_precision=false + fp8=false - unknown_brick → strip nodes with empty kind - missing_edge → reconnect adjacent ids left-to-right Other ids no-op gracefully. scheduleVerify fires on every fix. Tests (vbgui/tests/Sidebar.test.tsx): 30/30 — 2 new V7-H01 specs covering 6-id button visibility + label text on bad_dtype_combo. Full vbgui vitest regression green. Backend ValidationIssue.fix JSON-patch descriptor + Playwright e2e for the 3 recovery paths are V7-H01 follow-up sub-tasks.
1 parent 31ad737 commit 1bf185c

3 files changed

Lines changed: 87 additions & 3 deletions

File tree

vbgui/src/App.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,43 @@ export function App(): JSX.Element {
664664
onShardingChange={(s) =>
665665
dispatch({ type: "sharding.set", sharding: s })}
666666
onShardingAccept={handleShardingAccept}
667+
onGotchaAutoFix={(id) => {
668+
// V7-H01: dispatch recovery for known auto-fixable
669+
// gotcha ids. Unknown ids no-op gracefully.
670+
if (id === "fsdp2_whole_compile"
671+
|| id === "megatron_tp_whole_compile") {
672+
dispatch({ type: "sharding.set",
673+
sharding: { ...spec.sharding,
674+
compile_mode: "regional" } });
675+
} else if (id === "bad_dtype_combo") {
676+
dispatch({ type: "optim.set",
677+
optim: { ...spec.optim,
678+
mixed_precision: false } });
679+
dispatch({ type: "sharding.set",
680+
sharding: { ...spec.sharding,
681+
fp8_enabled: false } });
682+
} else if (id === "unknown_brick") {
683+
setNodes((prev) => prev.filter((n) => {
684+
const k = (n.data as { kind?: string })?.kind;
685+
return typeof k === "string" && k.length > 0;
686+
}));
687+
} else if (id === "missing_edge") {
688+
setEdges((prev) => {
689+
const ids = nodes.map((n) => n.id);
690+
const next: Edge[] = [];
691+
for (let i = 0; i < ids.length - 1; i++) {
692+
const eid = `${ids[i]}->${ids[i + 1]}`;
693+
if (!prev.some((e) => e.id === eid)) {
694+
next.push({ id: eid,
695+
source: ids[i], target: ids[i + 1],
696+
data: { severity: "info" } });
697+
}
698+
}
699+
return [...prev, ...next];
700+
});
701+
}
702+
void scheduleVerify();
703+
}}
667704
onDimensionsApply={(entry) => {
668705
// H07: write the auto-suggested value into the matched
669706
// brick's params. Re-verify will then re-render the

vbgui/src/components/sidebar/GotchasTab.tsx

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,31 @@ const COLOR: Record<GotchaState["severity"], string> = {
1111
info: "#2563eb",
1212
};
1313

14+
// V7-H01: extended auto-fix coverage for the 6 most common
15+
// validation gotchas. The App handler dispatches the corresponding
16+
// spec mutation when the user clicks the inline Apply-fix button.
1417
const AUTO_FIXABLE: Set<string> = new Set([
15-
"fsdp2_whole_compile", "megatron_tp_whole_compile",
18+
"fsdp2_whole_compile",
19+
"megatron_tp_whole_compile",
20+
"missing_edge",
21+
"dim_mismatch",
22+
"unknown_brick",
23+
"bad_dtype_combo",
24+
"schedule_out_of_range",
25+
"tokenizer_mismatch",
1626
]);
1727

28+
const FIX_LABELS: Record<string, string> = {
29+
fsdp2_whole_compile: "Switch compile_mode → regional",
30+
megatron_tp_whole_compile: "Switch compile_mode → regional",
31+
missing_edge: "Insert missing edge",
32+
dim_mismatch: "Adjust hidden_size to nearest valid",
33+
unknown_brick: "Remove unknown brick",
34+
bad_dtype_combo: "Reset dtype to bf16 master",
35+
schedule_out_of_range: "Clamp schedule to valid range",
36+
tokenizer_mismatch: "Pick MATRIX-compatible tokenizer",
37+
};
38+
1839
function groupBySeverity(gs: GotchaState[]): Record<string, GotchaState[]> {
1940
const out: Record<string, GotchaState[]> = { error: [], warning: [], info: [] };
2041
for (const g of gs) (out[g.severity] ??= []).push(g);
@@ -52,8 +73,9 @@ export function GotchasTab({ gotchas, onAutoFix }: GotchasTabProps): JSX.Element
5273
)}
5374
{onAutoFix && AUTO_FIXABLE.has(g.id) && (
5475
<button data-testid={`gotcha-${g.id}-autofix`}
55-
onClick={() => onAutoFix(g.id)}>
56-
Auto-fix
76+
onClick={() => onAutoFix(g.id)}
77+
title={FIX_LABELS[g.id] ?? "Auto-fix"}>
78+
{FIX_LABELS[g.id] ?? "Auto-fix"}
5779
</button>
5880
)}
5981
</div>

vbgui/tests/Sidebar.test.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,31 @@ describe("GotchasTab", () => {
203203
fireEvent.click(screen.getByTestId("gotcha-fsdp2_whole_compile-autofix"));
204204
expect(onAutoFix).toHaveBeenCalledWith("fsdp2_whole_compile");
205205
});
206+
207+
it("V7-H01: extended auto-fix coverage (6 new gotcha ids)", () => {
208+
const ids = ["missing_edge", "dim_mismatch", "unknown_brick",
209+
"bad_dtype_combo", "schedule_out_of_range",
210+
"tokenizer_mismatch"];
211+
const onAutoFix = vi.fn();
212+
render(<GotchasTab onAutoFix={onAutoFix}
213+
gotchas={ids.map((id) => ({ id, severity: "warning" as const,
214+
message: id }))} />);
215+
for (const id of ids) {
216+
expect(screen.getByTestId(`gotcha-${id}-autofix`)).toBeTruthy();
217+
}
218+
// Click first one fires callback with the id.
219+
fireEvent.click(screen.getByTestId(
220+
"gotcha-missing_edge-autofix"));
221+
expect(onAutoFix).toHaveBeenCalledWith("missing_edge");
222+
});
223+
224+
it("V7-H01: Auto-fix button text shows recovery label", () => {
225+
render(<GotchasTab onAutoFix={() => {}} gotchas={[
226+
{ id: "bad_dtype_combo", severity: "warning", message: "x" },
227+
]} />);
228+
const btn = screen.getByTestId("gotcha-bad_dtype_combo-autofix");
229+
expect(btn.textContent).toContain("bf16");
230+
});
206231
});
207232

208233
describe("SideChannelsTab", () => {

0 commit comments

Comments
 (0)