Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
8fa6042
feat(reports): leftover-map axis share on leftover-axis ticks indepen…
seonghobae Aug 31, 2026
d19f1fd
fix(reports): drop trailing blank line in leftover-map comparison lef…
seonghobae Aug 31, 2026
ee9c72d
test(red): reconstruct report axis tick-share contract
seonghobae Sep 11, 2026
7cf0b01
chore(stack): converge #875 onto repaired #874 head
seonghobae Sep 12, 2026
ffc998c
chore(stack): converge #875 onto repaired #874
seonghobae Sep 12, 2026
c227823
chore(stack): converge #875 onto repaired ancestry
seonghobae Sep 13, 2026
3ed98da
chore(stack): converge #875 onto repaired #874
seonghobae Sep 15, 2026
b220dcb
chore(stack): converge #875 onto repaired #874
seonghobae Sep 15, 2026
9303d67
merge: converge v2.91.0 onto current v2.90.0 parent
seonghobae Sep 15, 2026
73665d0
merge: converge v2.91.0 onto repaired v2.90.0 parent
seonghobae Sep 15, 2026
4e90d97
chore(stack): converge #875 onto repaired #874
seonghobae Sep 15, 2026
758da1e
chore(stack): converge #875 onto repaired #874
seonghobae Sep 15, 2026
ef6b542
merge(reports): converge report-axis missingness repair into axis sha…
seonghobae Sep 15, 2026
f56c9cf
merge(reports): converge #875 onto #874 RED contract head
seonghobae Sep 15, 2026
05ca9a1
chore(stack): converge current #874 into #875
seonghobae Sep 15, 2026
8bfc951
chore(stack): converge #875 on current #874
seonghobae Sep 15, 2026
2286cfb
chore(stack): converge semantic RED harness onto #875
seonghobae Sep 16, 2026
18448d3
chore(stack): converge #874 product repair into #875
seonghobae Sep 16, 2026
2e90523
chore(stack): converge #875 on repaired tick foundation
seonghobae Sep 16, 2026
fb4cc93
chore(stack): converge #875 on repaired comparison tick foundation
seonghobae Sep 16, 2026
e705eed
chore(stack): converge #875 on repaired comparison-strip tick foundation
seonghobae Sep 16, 2026
e38b07e
chore(stack): converge #875 on repaired report-axis tick foundation
seonghobae Sep 16, 2026
29255a8
chore(stack): converge #875 on repaired comparison tick share foundation
seonghobae Sep 16, 2026
b6c2ca2
chore(stack): adopt repaired tick-share parent source
seonghobae Sep 16, 2026
b771f63
fix(reports): compose report axis tick share independently
seonghobae Sep 16, 2026
c3528b7
chore(stack): converge #875 on repaired comparison-strip share founda…
seonghobae Sep 16, 2026
582491e
chore(stack): converge #875 on repaired #874 contracts
seonghobae Sep 16, 2026
1ac7ddd
Merge parent #874 convergence into #875
seonghobae Sep 17, 2026
70faa16
merge: converge buyer-visible tick evidence into report-axis share lane
seonghobae Sep 18, 2026
a20fbb2
test(reports): execute leftover-axis tick evidence states
seonghobae Sep 19, 2026
fa46703
test(reports): align tick share contract with formatter boundary
seonghobae Sep 19, 2026
d1f96f9
test(reports): align tick singular contract with formatter boundary
seonghobae Sep 19, 2026
1a15a5b
chore(stack): converge v2.84 comparison tick contract repair
seonghobae Sep 19, 2026
937415e
merge: converge #875 on report contract repairs
seonghobae Sep 19, 2026
b7e948a
chore(stack): converge #875 onto #874 owner stack
seonghobae Sep 20, 2026
66eab13
chore(reports): converge #875 onto repaired #874 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
28 changes: 24 additions & 4 deletions frontend/src/leftoverMapAxisBadge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ export const LEFTOVER_MAP_AXIS_BADGE_SINGULAR_ONLY = "leftover axis {axis} σ {v
export const LEFTOVER_MAP_AXIS_TICK_SINGULAR =
"leftover axis {axis} tick {value} σ {singular}";

export const LEFTOVER_MAP_AXIS_TICK_SHARE =
"leftover axis {axis} tick {value} {share}%";

export const LEFTOVER_MAP_AXIS_TICK_SINGULAR_SHARE =
"leftover axis {axis} tick {value} σ {singular} {share}%";

export type LeftoverMapAxisBadge = {
template: string;
values: Record<string, string | number>;
Expand Down Expand Up @@ -74,18 +80,32 @@ export function leftoverMapAxisBadge(
};
}

/** Project finite persisted σ onto one report-axis tick without inventing share evidence. */
/** Compose persisted report-axis tick σ/share without deriving either field. */
export function leftoverMapAxisTickBadge(
axisIndex: number,
tickLabel: string,
leftoverSingular: number | null | undefined,
leftoverShare?: LeftoverMapAxis["leftover_share"] | null,
): LeftoverMapAxisBadge | 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_AXIS_TICK_SHARE,
values: { axis: axisIndex, value: tickLabel, share: share as string },
};
}
if (share === null) {
return {
template: LEFTOVER_MAP_AXIS_TICK_SINGULAR,
values: { axis: axisIndex, value: tickLabel, singular },
};
}
return {
template: LEFTOVER_MAP_AXIS_TICK_SINGULAR,
values: { axis: axisIndex, value: tickLabel, singular },
template: LEFTOVER_MAP_AXIS_TICK_SINGULAR_SHARE,
values: { axis: axisIndex, value: tickLabel, singular, share },
};
}
31 changes: 31 additions & 0 deletions frontend/src/leftoverMapAxisTickBadge.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { describe, expect, it } from "vitest";
import {
LEFTOVER_MAP_AXIS_TICK_SHARE,
LEFTOVER_MAP_AXIS_TICK_SINGULAR,
LEFTOVER_MAP_AXIS_TICK_SINGULAR_SHARE,
leftoverMapAxisTickBadge,
} from "./leftoverMapAxisBadge";

describe("leftoverMapAxisTickBadge", () => {
it("keeps persisted singular and share evidence independently observable", () => {
expect(leftoverMapAxisTickBadge(1, "0.25", 0.5, 0.4)).toEqual({
template: LEFTOVER_MAP_AXIS_TICK_SINGULAR_SHARE,
values: { axis: 1, value: "0.25", singular: "0.50", share: "40" },
});
expect(leftoverMapAxisTickBadge(1, "0.00", 0, null)).toEqual({
template: LEFTOVER_MAP_AXIS_TICK_SINGULAR,
values: { axis: 1, value: "0.00", singular: "0.00" },
});
expect(leftoverMapAxisTickBadge(2, "−0.25", null, 0.4)).toEqual({
template: LEFTOVER_MAP_AXIS_TICK_SHARE,
values: { axis: 2, value: "−0.25", share: "40" },
});
});

it("fails closed when neither persisted evidence value is usable", () => {
expect(
leftoverMapAxisTickBadge(1, "0.25", Number.NaN, Number.POSITIVE_INFINITY),
).toBeNull();
expect(leftoverMapAxisTickBadge(1, "0.25", null, undefined)).toBeNull();
});
});
40 changes: 40 additions & 0 deletions tests/test_leftover_axis_tick_share_contract.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""Executable contract for report leftover-axis tick share captions."""

from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]
BADGE_SOURCE = ROOT / "frontend" / "src" / "leftoverMapAxisBadge.ts"
BADGE_TEST_SOURCE = ROOT / "frontend" / "src" / "leftoverMapAxisTickBadge.test.ts"


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

assert "leftoverMapAxisTickBadge" in source
assert "leftover axis {axis} tick {value} {share}%" in source
assert "leftover axis {axis} tick {value} σ {singular} {share}%" in source


def test_report_axis_tick_never_infers_share_from_singular() -> None:
"""Share is formatted from its persisted field rather than inferred from σ."""
assert BADGE_SOURCE.exists(), "report-axis badge helper is missing"
source = BADGE_SOURCE.read_text(encoding="utf-8")
tick_badge = source.split("export function leftoverMapAxisTickBadge", 1)[1]

assert "formatLeftoverMapPlotAxisShare(leftoverShare)" in tick_badge
assert "formatLeftoverMapPlotAxisSingular(leftoverSingular)" in tick_badge
assert "Math.sqrt(" not in tick_badge
assert "Math.max(" not in tick_badge


def test_report_axis_tick_share_states_are_executable() -> None:
"""Frontend tests execute combined, share-only, and invalid persisted-share states."""
assert BADGE_TEST_SOURCE.exists(), "report-axis tick badge behavior test is missing"
test_source = BADGE_TEST_SOURCE.read_text(encoding="utf-8")

assert 'leftoverMapAxisTickBadge(1, "0.25", 0.5, 0.4)' in test_source
assert 'leftoverMapAxisTickBadge(2, "−0.25", null, 0.4)' in test_source
assert "Number.POSITIVE_INFINITY" in test_source
22 changes: 17 additions & 5 deletions tests/test_leftover_axis_tick_singular_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

ROOT = Path(__file__).resolve().parents[1]
BADGE_SOURCE = ROOT / "frontend" / "src" / "leftoverMapAxisBadge.ts"
BADGE_TEST_SOURCE = ROOT / "frontend" / "src" / "leftoverMapAxisTickBadge.test.ts"


def test_report_leftover_axis_tick_keeps_persisted_singular_without_share() -> None:
Expand All @@ -17,11 +18,22 @@ def test_report_leftover_axis_tick_keeps_persisted_singular_without_share() -> N


def test_report_leftover_axis_tick_never_infers_sigma_or_share() -> None:
"""Invalid σ falls back to an ordinary leftover-axis tick; share is never synthesized."""
"""Tick σ/share are delegated to their persisted-value formatters without derivation."""
assert BADGE_SOURCE.exists(), "report-axis badge helper is missing"
source = BADGE_SOURCE.read_text(encoding="utf-8")
tick_badge = source.split("export function leftoverMapAxisTickBadge", 1)[1]

assert "formatLeftoverMapPlotAxisSingular" in source
assert "Math.sqrt" not in source
tail = source.split("leftoverMapAxisTickBadge", 1)[-1][:1600]
assert "leftover_share" not in tail
assert "formatLeftoverMapPlotAxisSingular(leftoverSingular)" in tick_badge
assert "formatLeftoverMapPlotAxisShare(leftoverShare)" in tick_badge
assert "Math.sqrt(" not in tick_badge
assert "Math.max(" not in tick_badge


def test_report_leftover_axis_tick_singular_states_are_executable() -> None:
"""Frontend tests execute singular-only zero and fail-closed invalid evidence states."""
assert BADGE_TEST_SOURCE.exists(), "report-axis tick badge behavior test is missing"
test_source = BADGE_TEST_SOURCE.read_text(encoding="utf-8")

assert 'leftoverMapAxisTickBadge(1, "0.00", 0, null)' in test_source
assert 'singular: "0.00"' in test_source
assert "Number.NaN" in test_source
Loading