Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
923bcfe
feat(reports): leftover-map axis share on leftover-map graphic leftov…
seonghobae Aug 31, 2026
804ade0
test(red): reconstruct report graphic tick-share contract
seonghobae Sep 11, 2026
be6a8df
chore(stack): converge #873 onto repaired #872 head
seonghobae Sep 12, 2026
58c5fa6
chore(stack): converge #873 onto repaired #872
seonghobae Sep 12, 2026
b25b387
chore(stack): converge #873 onto repaired ancestry
seonghobae Sep 13, 2026
ad0e97d
chore(stack): converge #873 onto repaired #872
seonghobae Sep 15, 2026
11dcddf
chore(stack): converge #873 onto repaired #872
seonghobae Sep 15, 2026
5579a4d
merge: converge v2.89.0 onto current v2.88.0 parent
seonghobae Sep 15, 2026
7cae368
merge: converge v2.89.0 onto repaired v2.88.0 parent
seonghobae Sep 15, 2026
bc03c62
chore(stack): converge #873 onto repaired #872
seonghobae Sep 15, 2026
c8a5063
chore(stack): converge #873 onto repaired #872
seonghobae Sep 15, 2026
c80e4e6
merge(reports): converge report-axis missingness repair into report s…
seonghobae Sep 15, 2026
9f17e6a
merge(reports): converge #873 onto #872 RED contract head
seonghobae Sep 15, 2026
59fa096
chore(stack): converge current #872 into #873
seonghobae Sep 15, 2026
41a755c
chore(stack): converge #873 on current #872
seonghobae Sep 15, 2026
6da64e7
chore(stack): converge semantic RED harness onto #873
seonghobae Sep 16, 2026
36ed750
chore(stack): converge #872 product repair into #873
seonghobae Sep 16, 2026
ba16a8d
chore(stack): converge #873 on repaired tick foundation
seonghobae Sep 16, 2026
4cc0296
chore(stack): converge #873 on repaired comparison tick foundation
seonghobae Sep 16, 2026
e3defd1
chore(stack): converge #873 on repaired comparison-strip tick foundation
seonghobae Sep 16, 2026
ea01e6c
chore(stack): converge #873 on repaired report-axis tick foundation
seonghobae Sep 16, 2026
d03f913
chore(stack): converge #873 on repaired comparison tick share foundation
seonghobae Sep 16, 2026
0528241
fix(reports): compose report graphic tick share independently
seonghobae Sep 16, 2026
a27c248
test(reports): align singular/share contracts with independent evidence
seonghobae Sep 16, 2026
262700d
test(reports): cover independent tick sigma/share states
seonghobae Sep 17, 2026
e840ca2
merge: converge buyer-visible tick evidence into report share lane
seonghobae Sep 18, 2026
80438dc
chore(stack): converge v2.84 comparison tick contract repair
seonghobae Sep 19, 2026
aefa45a
merge: converge #873 on report contract repairs
seonghobae Sep 19, 2026
a62807d
chore(stack): converge #873 onto #872 owner stack
seonghobae Sep 20, 2026
050477c
test(report): preserve #861 exact App acceptance RED through #873
seonghobae Sep 20, 2026
4949dd5
chore(reports): converge #873 onto repaired #872 ancestry
seonghobae Sep 20, 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
10 changes: 3 additions & 7 deletions frontend/src/components/LeftoverMapPlot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -364,18 +364,14 @@ export function LeftoverMapPlot({
</text>
{layout.ticks.map((tick) => {
const singular = leftoverSingularForAxis(leftoverMapAxes, tick.axis);
const share = leftoverShareForAxis(leftoverMapAxes, tick.axis);
const reportTickBadge =
variant === "report"
? leftoverMapPlotTickAxisBadge(tick.axis, tick.label, singular)
? leftoverMapPlotTickAxisBadge(tick.axis, tick.label, singular, share)
: null;
const comparisonTickBadge =
variant === "comparison"
? leftoverMapComparePlotTickAxisBadge(
tick.axis,
tick.label,
singular,
leftoverShareForAxis(leftoverMapAxes, tick.axis),
)
? leftoverMapComparePlotTickAxisBadge(tick.axis, tick.label, singular, share)
: null;
const tickAriaLabel =
variant === "comparison"
Expand Down
75 changes: 75 additions & 0 deletions frontend/src/leftoverMapPlotAxisSingular.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { describe, expect, it } from "vitest";
import {
leftoverMapCompareAxisTickBadge,
leftoverMapComparePlotTickAxisBadge,
leftoverMapPlotTickAxisBadge,
LEFTOVER_MAP_COMPARE_AXIS_TICK_SINGULAR,
LEFTOVER_MAP_COMPARE_PLOT_TICK_SHARE,
LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR,
LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR_SHARE,
LEFTOVER_MAP_PLOT_TICK_SHARE,
LEFTOVER_MAP_PLOT_TICK_SINGULAR,
LEFTOVER_MAP_PLOT_TICK_SINGULAR_SHARE,
} from "./leftoverMapPlotAxisSingular";

describe("leftoverMapPlotTickAxisBadge", () => {
it("keeps report-graphic tick singular and share evidence independent", () => {
expect(leftoverMapPlotTickAxisBadge(1, "-1.0", null, null)).toBeNull();
expect(leftoverMapPlotTickAxisBadge(1, "-1.0", 1.24, null)).toEqual({
template: LEFTOVER_MAP_PLOT_TICK_SINGULAR,
values: { axis: 1, value: "-1.0", singular: "1.24" },
});
expect(leftoverMapPlotTickAxisBadge(2, "0.5", null, 0.18)).toEqual({
template: LEFTOVER_MAP_PLOT_TICK_SHARE,
values: { axis: 2, value: "0.5", share: "18" },
});
expect(leftoverMapPlotTickAxisBadge(2, "0.5", 0, 0.18)).toEqual({
template: LEFTOVER_MAP_PLOT_TICK_SINGULAR_SHARE,
values: { axis: 2, value: "0.5", singular: "0.00", share: "18" },
});
});

it("fails closed for invalid persisted tick evidence without fabricating the other field", () => {
expect(
leftoverMapPlotTickAxisBadge(1, "0", Number.NaN, Number.POSITIVE_INFINITY),
).toBeNull();
expect(leftoverMapPlotTickAxisBadge(1, "0", -0.01, 0.42)).toEqual({
template: LEFTOVER_MAP_PLOT_TICK_SHARE,
values: { axis: 1, value: "0", share: "42" },
});
});
});

describe("leftoverMapComparePlotTickAxisBadge", () => {
it("keeps comparison-graphic tick singular and share evidence independent", () => {
expect(leftoverMapComparePlotTickAxisBadge(1, "-1.0", null, null)).toBeNull();
expect(leftoverMapComparePlotTickAxisBadge(1, "-1.0", 1.24, null)).toEqual({
template: LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR,
values: { axis: 1, value: "-1.0", singular: "1.24" },
});
expect(leftoverMapComparePlotTickAxisBadge(2, "0.5", null, 0.18)).toEqual({
template: LEFTOVER_MAP_COMPARE_PLOT_TICK_SHARE,
values: { axis: 2, value: "0.5", share: "18" },
});
expect(leftoverMapComparePlotTickAxisBadge(2, "0.5", 0, 0.18)).toEqual({
template: LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR_SHARE,
values: { axis: 2, value: "0.5", singular: "0.00", share: "18" },
});
});
});

describe("leftoverMapCompareAxisTickBadge", () => {
it("projects only finite persisted singular evidence onto comparison-strip ticks", () => {
expect(leftoverMapCompareAxisTickBadge(1, "0", 1.24)).toEqual({
template: LEFTOVER_MAP_COMPARE_AXIS_TICK_SINGULAR,
values: { axis: 1, value: "0", singular: "1.24" },
});
expect(leftoverMapCompareAxisTickBadge(2, "1", 0)).toEqual({
template: LEFTOVER_MAP_COMPARE_AXIS_TICK_SINGULAR,
values: { axis: 2, value: "1", singular: "0.00" },
});
expect(leftoverMapCompareAxisTickBadge(1, "0", null)).toBeNull();
expect(leftoverMapCompareAxisTickBadge(1, "0", Number.NaN)).toBeNull();
expect(leftoverMapCompareAxisTickBadge(1, "0", -0.01)).toBeNull();
});
});
28 changes: 24 additions & 4 deletions frontend/src/leftoverMapPlotAxisSingular.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ export const LEFTOVER_MAP_COMPARE_AXIS_SHARE =
export const LEFTOVER_MAP_PLOT_TICK_SINGULAR =
"leftover-map axis {axis} tick {value} σ {singular}";

export const LEFTOVER_MAP_PLOT_TICK_SHARE =
"leftover-map axis {axis} tick {value} {share}%";

export const LEFTOVER_MAP_PLOT_TICK_SINGULAR_SHARE =
"leftover-map axis {axis} tick {value} σ {singular} {share}%";

export const LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR =
"leftover map comparison graphic leftover-map axis {axis} tick {value} σ {singular}";

Expand Down Expand Up @@ -147,19 +153,33 @@ export function leftoverMapCompareAxisBadge(
};
}

/** Project finite persisted σ onto one report-graphic tick without inventing share evidence. */
/** Compose persisted report-graphic tick σ/share without deriving either field. */
export function leftoverMapPlotTickAxisBadge(
axisIndex: number,
tickLabel: string,
leftoverSingular: number | null | undefined,
leftoverShare?: LeftoverMapAxis["leftover_share"] | null,
): LeftoverMapCompareAxisBadge | null {
const singular = formatLeftoverMapPlotAxisSingular(leftoverSingular);
if (singular === null) {
const share = formatLeftoverMapPlotAxisShare(leftoverShare);
if (singular === null && share === null) {
return null;
}
if (singular === null) {
return {
template: LEFTOVER_MAP_PLOT_TICK_SHARE,
values: { axis: axisIndex, value: tickLabel, share: share as string },
};
}
if (share === null) {
return {
template: LEFTOVER_MAP_PLOT_TICK_SINGULAR,
values: { axis: axisIndex, value: tickLabel, singular },
};
}
return {
template: LEFTOVER_MAP_PLOT_TICK_SINGULAR,
values: { axis: axisIndex, value: tickLabel, singular },
template: LEFTOVER_MAP_PLOT_TICK_SINGULAR_SHARE,
values: { axis: axisIndex, value: tickLabel, singular, share },
};
}

Expand Down
25 changes: 17 additions & 8 deletions tests/test_grouping_comparison_graphic_tick_singular_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,29 @@ def test_comparison_graphic_tick_keeps_persisted_singular_value_without_share()


def test_comparison_graphic_consumes_tick_singular_projection() -> None:
"""The buyer-visible comparison graphic must consume its persisted-σ tick projection."""
"""The buyer-visible comparison graphic consumes independently persisted σ/share."""
source = PLOT_COMPONENT_SOURCE.read_text(encoding="utf-8")

assert "leftoverMapComparePlotTickAxisBadge" in source
assert "leftoverSingularForAxis(leftoverMapAxes, tick.axis)" in source
assert "leftoverShareForAxis(leftoverMapAxes, tick.axis)" in source
assert "tf(comparisonTickBadge.template, comparisonTickBadge.values)" in source


def test_comparison_graphic_tick_does_not_infer_sigma_or_share() -> None:
"""Invalid σ falls back to the comparison tick and tick captions never synthesize share."""
"""Comparison ticks compose independently persisted σ/share without deriving either."""
assert SINGULAR_SOURCE.exists(), "singular-value axis helper is missing"
source = SINGULAR_SOURCE.read_text(encoding="utf-8")

assert "formatLeftoverMapPlotAxisSingular" in source
assert "Number.isFinite" in source
assert "Math.sqrt" not in source
tail = source.split("leftoverMapComparePlotTickAxisBadge", 1)[-1][:1600]
assert "leftover_share" not in tail
helper = source.split("export function leftoverMapComparePlotTickAxisBadge", 1)[-1].split(
"export function leftoverMapCompareAxisTickBadge", 1
)[0]

assert "formatLeftoverMapPlotAxisSingular" in helper
assert "formatLeftoverMapPlotAxisShare" in helper
assert "leftoverSingular" in helper
assert "leftoverShare" in helper
assert "LEFTOVER_MAP_COMPARE_PLOT_TICK_SHARE" in helper
assert "LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR_SHARE" in helper
assert "Math.sqrt" not in helper
assert "Math.max" not in helper
assert "Math.min" not in helper
16 changes: 12 additions & 4 deletions tests/test_leftover_axis_report_singular_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,24 @@


def test_report_axis_badge_keeps_singular_value_and_share_semantically_distinct() -> None:
"""Report badges must expose persisted σ without borrowing comparison-graphic copy."""
"""Report badges compose persisted σ/share independently without comparison copy."""
assert BADGE_SOURCE.exists(), "report-axis singular-value badge helper is missing"
badge_source = BADGE_SOURCE.read_text(encoding="utf-8")

assert 'LEFTOVER_MAP_AXIS_BADGE_SHARE = "leftover axis {axis}{share}"' in badge_source
assert 'LEFTOVER_MAP_AXIS_BADGE_SINGULAR = "leftover axis {axis} σ {value}{share}"' in badge_source
assert 'LEFTOVER_MAP_AXIS_BADGE_SINGULAR_ONLY = "leftover axis {axis} σ {value}"' in badge_source
assert (
'LEFTOVER_MAP_AXIS_BADGE_SINGULAR = "leftover axis {axis} σ {value}{share}"'
in badge_source
)
assert (
'LEFTOVER_MAP_AXIS_BADGE_SINGULAR_ONLY = "leftover axis {axis} σ {value}"'
in badge_source
)
assert "leftoverMapAxisBadgeShare" in badge_source
assert "formatLeftoverMapPlotAxisShare" in badge_source
assert 'return share === null ? "" : ` ${share}%`;' in badge_source
assert "leftoverSingularForAxis" in badge_source
assert "formatLeftoverMapPlotAxisSingular" in badge_source
assert "formatLeftoverMapPlotAxisShare" in badge_source
assert "leftover map comparison graphic" not in badge_source


Expand Down
12 changes: 10 additions & 2 deletions tests/test_leftover_map_report_graphic_axis_singular_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,16 @@ def test_report_graphic_axis_has_distinct_singular_and_singular_share_copy() ->
source = SINGULAR_SOURCE.read_text(encoding="utf-8")
plot_source = PLOT_SOURCE.read_text(encoding="utf-8")

assert '"leftover-map axis {axis} σ {value}"' in source
assert '"leftover-map axis {axis} σ {value} ({share}%)"' in source
assert (
'export const LEFTOVER_MAP_PLOT_AXIS_SINGULAR =\n'
' "leftover-map axis {axis} σ {value}";'
in source
)
assert (
'export const LEFTOVER_MAP_PLOT_AXIS_SINGULAR_SHARE =\n'
' "leftover-map axis {axis} σ {value} ({share}%)";'
in source
)
assert "LEFTOVER_MAP_PLOT_AXIS_SINGULAR" in plot_source
assert "LEFTOVER_MAP_PLOT_AXIS_SINGULAR_SHARE" in plot_source

Expand Down
29 changes: 29 additions & 0 deletions tests/test_leftover_map_report_graphic_tick_share_contract.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""Executable contract for report-graphic tick axis-share captions."""

from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]
SINGULAR_SOURCE = ROOT / "frontend" / "src" / "leftoverMapPlotAxisSingular.ts"


def test_report_graphic_tick_keeps_axis_share_independent_of_singular() -> None:
"""A report-graphic tick may name persisted share when singular evidence is absent."""
assert SINGULAR_SOURCE.exists(), "report graphic axis projection helper is missing"
source = SINGULAR_SOURCE.read_text(encoding="utf-8")

assert "leftoverMapPlotTickAxisBadge" in source
assert "leftover-map axis {axis} tick {value} {share}%" in source
assert "leftover-map axis {axis} tick {value} σ {singular} {share}%" in source


def test_report_graphic_tick_never_infers_share_from_singular() -> None:
"""Share-only, singular-only, combined, and empty states remain persisted-data decisions."""
assert SINGULAR_SOURCE.exists(), "report graphic axis projection helper is missing"
source = SINGULAR_SOURCE.read_text(encoding="utf-8")

assert "Number.isFinite" in source
assert "leftover_share" in source
assert "formatLeftoverMapPlotAxisSingular" in source
assert "Math.sqrt" not in source
assert "Math.max" not in source
23 changes: 16 additions & 7 deletions tests/test_leftover_map_report_tick_singular_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,29 @@ def test_report_graphic_tick_keeps_persisted_singular_value_without_share() -> N


def test_report_graphic_consumes_tick_singular_projection() -> None:
"""The buyer-visible report graphic must consume the persisted-σ tick projection."""
"""The buyer-visible report graphic consumes independently persisted σ/share."""
source = PLOT_COMPONENT_SOURCE.read_text(encoding="utf-8")

assert "leftoverMapPlotTickAxisBadge" in source
assert "leftoverSingularForAxis(leftoverMapAxes, tick.axis)" in source
assert "leftoverShareForAxis(leftoverMapAxes, tick.axis)" in source
assert "tf(reportTickBadge.template, reportTickBadge.values)" in source


def test_report_graphic_tick_does_not_infer_sigma_or_share() -> None:
"""Invalid σ falls back to the ordinary tick and ticks never synthesize share."""
"""Report ticks compose independently persisted σ/share without deriving either."""
assert SINGULAR_SOURCE.exists(), "singular-value axis helper is missing"
source = SINGULAR_SOURCE.read_text(encoding="utf-8")

assert "formatLeftoverMapPlotAxisSingular" in source
assert "Number.isFinite" in source
assert "Math.sqrt" not in source
assert "leftover_share" not in source.split("leftoverMapPlotTickAxisBadge", 1)[-1][:1400]
helper = source.split("export function leftoverMapPlotTickAxisBadge", 1)[-1].split(
"export function leftoverMapComparePlotTickAxisBadge", 1
)[0]

assert "formatLeftoverMapPlotAxisSingular" in helper
assert "formatLeftoverMapPlotAxisShare" in helper
assert "leftoverSingular" in helper
assert "leftoverShare" in helper
assert "LEFTOVER_MAP_PLOT_TICK_SHARE" in helper
assert "LEFTOVER_MAP_PLOT_TICK_SINGULAR_SHARE" in helper
assert "Math.sqrt" not in helper
assert "Math.max" not in helper
assert "Math.min" not in helper
Loading