Skip to content

Commit afd3bdb

Browse files
committed
fix(showcase): require emitted data above achievedDepth for isRegression
A cell is a regression only when the next rung above achievedDepth has emitted data (exists && status !== null). Drops the no-data-D5 false positive (mapped but unemitted D5) while keeping red-below-ceiling and D3-red regressions.
1 parent 8c61713 commit afd3bdb

3 files changed

Lines changed: 73 additions & 10 deletions

File tree

showcase/shell-dashboard/src/components/__tests__/cell-matrix.test.tsx

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -292,13 +292,15 @@ describe("CellMatrix", () => {
292292
it("filters to rows with regressions when filter=regressions", () => {
293293
// Uses buildCellModel D3/D4/D5 depth model (not the old D0-D6 ladder).
294294
//
295-
// lgp/agentic-chat: e2e row GREEN (D3 passes), chat row GREEN (D4 passes),
296-
// but "agentic-chat" has a CATALOG_TO_D5_KEY mapping so ceiling=5.
297-
// No D5 PB rows → D5 status=null → achieved=4 < ceiling=5 → REGRESSION.
295+
// lgp/agentic-chat: e2e GREEN (D3), chat GREEN (D4), and an EMITTED RED
296+
// D5 row. "agentic-chat" maps to a CATALOG_TO_D5_KEY so ceiling=5;
297+
// achieved=4 < ceiling=5 AND the next rung (D5) has emitted data
298+
// (status='red') → genuine REGRESSION (unification C requires emitted
299+
// data above achievedDepth, so a no-data D5 would NOT count).
298300
//
299-
// lgp/no-d5-feature: e2e row GREEN (D3 passes), chat row GREEN (D4 passes),
300-
// "no-d5-feature" has NO CATALOG_TO_D5_KEY mapping → ceiling=4.
301-
// achieved=4 === ceiling=4 → NOT a regression.
301+
// lgp/no-d5-feature: e2e GREEN (D3), chat GREEN (D4), "no-d5-feature" has
302+
// NO CATALOG_TO_D5_KEY mapping → ceiling=4. achieved=4 === ceiling=4 →
303+
// NOT a regression.
302304
const regressFeatures = [
303305
{ id: "agentic-chat", name: "Agentic Chat", category: "chat-ui" },
304306
{ id: "no-d5-feature", name: "No D5 Feature", category: "platform" },
@@ -331,6 +333,9 @@ describe("CellMatrix", () => {
331333
row("e2e:lgp/agentic-chat", "e2e", "green"),
332334
row("e2e:lgp/no-d5-feature", "e2e", "green"),
333335
row("chat:lgp", "chat", "green"),
336+
// Emitted RED D5 keeps agentic-chat a genuine regression under the
337+
// refined (unification C) rule — a missing D5 row would be no-data.
338+
row("d5:lgp/agentic-chat", "d5", "red"),
334339
]);
335340
const oneIntegration = [
336341
{ slug: "lgp", name: "LangGraph Python", tier: "reference" as const },
@@ -347,7 +352,7 @@ describe("CellMatrix", () => {
347352
referenceSlug="lgp"
348353
/>,
349354
);
350-
// agentic-chat: achieved=4 < ceiling=5 → regression → visible
355+
// agentic-chat: achieved=4 < ceiling=5, D5 emitted red → regression → visible
351356
expect(queryByText("Agentic Chat")).not.toBeNull();
352357
// no-d5-feature: achieved=4 === ceiling=4 → at ceiling → hidden
353358
expect(queryByText("No D5 Feature")).toBeNull();

showcase/shell-dashboard/src/lib/__tests__/cell-model.test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,41 @@ describe("buildCellModel", () => {
718718
});
719719
expect(notWired.isRegression).toBe(false);
720720
});
721+
722+
// ── refinement (unification C): the next rung above achievedDepth must
723+
// have EMITTED data (exists && status !== null) for a cell to count
724+
// as a regression. A mapped-but-unemitted D5 (status === null) is
725+
// no-data, not a slide-back. ──
726+
it("is FALSE when the next rung (D5) is mapped but has no emitted data", () => {
727+
// D3 green + D4 green, D5 mapped but NO d5 rows emitted →
728+
// achieved=4, ceiling=5, d5.exists=true but d5.status===null.
729+
// No data above achieved → NOT a regression.
730+
const live = mapOf([
731+
row(keyFor("e2e", "agno", "agentic-chat"), "e2e", "green"),
732+
row(keyFor("chat", "agno"), "chat", "green"),
733+
]);
734+
const model = buildCellModel(live, wiredInput("agno", "agentic-chat"));
735+
expect(model.achievedDepth).toBe(4);
736+
expect(model.ceilingDepth).toBe(5);
737+
expect(model.d5?.exists).toBe(true);
738+
expect(model.d5?.status).toBeNull();
739+
expect(model.isRegression).toBe(false);
740+
});
741+
742+
it("is TRUE when the next rung (D5) is below ceiling AND emitted red data", () => {
743+
// D3 green + D4 green + D5 red → achieved=4, ceiling=5, and d5 has
744+
// emitted (status==='red'). A real slide-back → regression.
745+
const live = mapOf([
746+
row(keyFor("e2e", "agno", "agentic-chat"), "e2e", "green"),
747+
row(keyFor("chat", "agno"), "chat", "green"),
748+
row(keyFor("d5", "agno", "agentic-chat"), "d5", "red"),
749+
]);
750+
const model = buildCellModel(live, wiredInput("agno", "agentic-chat"));
751+
expect(model.achievedDepth).toBe(4);
752+
expect(model.ceilingDepth).toBe(5);
753+
expect(model.d5?.status).toBe("red");
754+
expect(model.isRegression).toBe(true);
755+
});
721756
});
722757

723758
// ── e2e staleness downgrade (false-green D3 bug) ────────────────────

showcase/shell-dashboard/src/lib/cell-model.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -405,9 +405,32 @@ export function buildCellModel(
405405
chipColor = "red";
406406
}
407407

408-
// isRegression: a cell has slid below its own ceiling — tests exist
409-
// (ceilingDepth > 0) but the contiguous passing depth is short of them.
410-
const isRegression = ceilingDepth > 0 && achievedDepth < ceilingDepth;
408+
// isRegression: a cell has slid below its own ceiling. Beyond
409+
// `achievedDepth < ceilingDepth`, the NEXT rung above `achievedDepth` must
410+
// have EMITTED data — `exists && status !== null` — for the slide-back to
411+
// be real. A mapped-but-unemitted D5 (e.g. achieved=4, ceiling=5, but
412+
// `d5.status === null` because no d5 rows have ticked) is no-data, not a
413+
// regression: flagging it would paint every D5-mapped cell amber the moment
414+
// its D5 driver hasn't run yet. A present RED/AMBER next rung (status !==
415+
// null) still counts — that is a genuine failure below the ceiling.
416+
//
417+
// Next-rung map by achievedDepth: 0→d3, 3→d4, 4→d5, 5→d6.
418+
const nextRung: TestLevel | null =
419+
achievedDepth === 0
420+
? d3
421+
: achievedDepth === 3
422+
? d4
423+
: achievedDepth === 4
424+
? d5
425+
: achievedDepth === 5
426+
? d6
427+
: null;
428+
const isRegression =
429+
ceilingDepth > 0 &&
430+
achievedDepth < ceilingDepth &&
431+
nextRung !== null &&
432+
nextRung.exists &&
433+
nextRung.status !== null;
411434

412435
return {
413436
supported: true,

0 commit comments

Comments
 (0)