Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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: 10 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,14 @@ compares leftover pairs can match the pair-row coordinate badge on live
responses; a missing axis stays null and does not invent coordinates from
leftover-map rank, leftover-map distance, leftover-map reconstruction, or
leftover residual. The strip does not gain the leftover-map graphic.
ADR 0368 captions the grouping comparison strip with persisted leftover-map
axis share through leftoverMapCompareAxisShare so a buyer who compares leftover
pairs can read Gabriel inertia of residual SVD axes 1 and 2 for that grouping;
a missing or non-finite share omits that leftover-map comparison axis share
badge and does not invent leftover-map axis share from leftover-map singular
value, leftover pair count, or plotted marker count. Share `0` is shown when
persisted, including rank-0 unused axes. The strip does not gain leftover-map
singular values or the leftover-map graphic.
When `R`, `R̂`, `U`, `x`,
`s`, and `e` are finite, `e + s + x = 1`. When `Y`, `E`, and `R` are
finite, `Y − E = R`. When `R`, `R̂`, and `U` are
Expand Down Expand Up @@ -526,6 +534,8 @@ Grouping comparison leftover-map coordinates (ADR 0302) captions grouping compar
buttons with persisted leftover-map coordinates `ξ` / `ζ`.
Grouping comparison leftover-map coordinates payload (ADR 0303) returns persisted leftover-map
coordinates `ξ` / `ζ` on `GET /api/reports/compare/{period}` leftover pairs.
Grouping comparison leftover-map axis share (ADR 0368) captions the grouping comparison
strip with persisted leftover-map axis share.
Item complete-case coverage
(ADR 0282) captions the leftover-map graphic with how many scored criteria
entered the map. Item complete-case coverage on the pair list (ADR 0285)
Expand Down
7 changes: 5 additions & 2 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,8 @@ ADR 0302 captions grouping comparison leftover-pair buttons with persisted lefto
coordinates `ξ` / `ζ` through formatLeftoverMapCoordinates.
ADR 0303 returns persisted leftover-map coordinates `ξ` / `ζ` on
`GET /api/reports/compare/{period}` leftover pairs.
ADR 0368 captions the grouping comparison strip with persisted leftover-map axis share
through leftoverMapCompareAxisShare.
Click a post marker or a pair button
opens that post. Those ADRs are the normative mathematical, storage, and
display contracts. Leftover-map axis share
Expand Down Expand Up @@ -727,8 +729,9 @@ incomplete item coverage (ADR 0292), leftover-map reconstruction `R̂`
(ADR 0299), leftover expected `E`
(ADR 0300), leftover-map rank
(ADR 0301), leftover-map coordinates `ξ` / `ζ`
(ADR 0302), and leftover-map coordinates on the compare leftover-pair payload
(ADR 0303);
(ADR 0302), leftover-map coordinates on the compare leftover-pair payload
(ADR 0303), and leftover-map axis share on the grouping comparison strip
(ADR 0368);
`POST .../rebuild` scores every grouping kind (post_admin). `make seed`
folds A-100/B-200 Event Lineage fixtures (and the Riverbend calendar
post) that already have constructed IRT cells into the same shared
Expand Down
47 changes: 47 additions & 0 deletions CHANGELOG.d/2.61.0-leftover-map-compare-axis-share.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
## 2.61.0 — Leftover-map axis share on the grouping comparison strip

- Caption leftover-map axis share on the grouping comparison strip through
leftoverMapCompareAxisShare and return persisted leftover_map_axes on
`GET /api/reports/compare/{period}` (ADR 0368). After `make seed`, closest
and farthest leftover pairs sit above the member list with the Gabriel
biplot of already-named coordinates, leftover-map axis share when finite,
axis ticks that match `ξ (x, y) ζ (x, y)` on the pair row, pair segments
that match `d` on the pair row, pair segments that match `R̂` on the pair
row, pair segments that match `R̂²/R²` on the pair row, pair segments that
match `U²/R²` on the pair row, pair segments that match `2R̂U/R²` on the
pair row, pair segments that match `U` on the pair row, pair segments that
match `R` on the pair row, pair segments that match `Y` on the pair row,
pair segments that match `E` on the pair row, pair segments that match
leftover-map rank on the pair row, a plot caption that matches leftover-map
complete-case coverage above the pair list, a plot caption that matches
leftover-map item complete-case coverage, a plot caption that matches
leftover-map incomplete post coverage, a plot caption that matches
leftover-map incomplete item coverage, a pair-list note that matches
leftover-map post complete-case coverage, a pair-list note that matches
leftover-map item complete-case coverage, a pair-list note that matches
leftover-map incomplete post coverage, a pair-list note that matches
leftover-map incomplete item coverage, a grouping comparison note that
matches leftover-map post complete-case coverage, a grouping comparison
note that matches leftover-map item complete-case coverage, a grouping
comparison note that matches leftover-map incomplete post coverage, a
grouping comparison note that matches leftover-map incomplete item
coverage, grouping comparison leftover-pair buttons that match leftover-map
reconstruction `R̂`, leftover-map explained leftover share `e`, leftover-map
unexplained leftover share `s`, leftover-map cross share `x`, leftover-map
unexplained leftover `U`, leftover residual `R`, leftover observed `Y`,
leftover expected `E`, leftover-map rank, leftover-map coordinates `ξ` / `ζ`
on the pair row, a live compare payload that carries those persisted leftover-map
coordinates, and a grouping comparison leftover-map axis share badge that
matches leftover-axis report badges from the live compare leftover_map_axes
payload; click a post marker or a pair button opens that post. A missing or
non-finite share omits that leftover-map comparison axis share badge.
Share `0` is shown when that persisted share is a finite number, including
rank-0 unused axes. A finite negative share is shown; do not clamp to
nonnegative. Do not invent leftover-map axis share from leftover-map
singular value, leftover pair count, plotted marker count, leftover-map
distance, leftover-map rank, leftover-map post coverage, leftover-map item
coverage, leftover-map incomplete post coverage, leftover-map incomplete
item coverage, leftover-map reconstruction, leftover-map unexplained leftover,
leftover-map coordinates, or the count of unused axes. The strip does not
gain leftover-map singular values or the leftover-map graphic. Never invent
a leftover score. Never invent a theta. No new columns.
58 changes: 58 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,64 @@ All notable changes to this project are documented here. Format follows

### Added

- Period leftover pairs now return persisted leftover-map axis share on
`GET /api/reports/compare/{period}` grouping rows and caption the grouping
comparison strip through leftoverMapCompareAxisShare (ADR 0368 / v2.61.0).
After `make seed`, closest and farthest leftover pairs sit above the member
list with the Gabriel biplot of already-named coordinates, leftover-map axis
share when finite, axis ticks that match `ξ (x, y) ζ (x, y)` on the pair
row, pair segments that match `d` on the pair row, pair segments that match
`R̂` on the pair row, pair segments that match `R̂²/R²` on the pair row, pair
segments that match `U²/R²` on the pair row, pair segments that match
`2R̂U/R²` on the pair row, pair segments that match `U` on the pair row, pair
segments that match `R` on the pair row, pair segments that match `Y` on the
pair row, pair segments that match `E` on the pair row, pair segments that
match leftover-map rank on the pair row, a plot caption that matches leftover-map
complete-case coverage above the pair list, a plot caption that matches
leftover-map item complete-case coverage, a plot caption that matches
leftover-map incomplete post coverage, a plot caption that matches leftover-map
incomplete item coverage, a pair-list note that matches leftover-map post
complete-case coverage, a pair-list note that matches leftover-map item
complete-case coverage, a pair-list note that matches leftover-map incomplete
post coverage, a pair-list note that matches leftover-map incomplete item
coverage, a grouping comparison note that matches leftover-map post
complete-case coverage, a grouping comparison note that matches leftover-map
item complete-case coverage, a grouping comparison note that matches leftover-map
incomplete post coverage, a grouping comparison note that matches leftover-map
incomplete item coverage, grouping comparison leftover-pair buttons that match
leftover-map reconstruction `R̂` on the pair row, grouping comparison leftover-pair
buttons that match leftover-map explained leftover share `e` on the pair row,
grouping comparison leftover-pair buttons that match leftover-map unexplained
leftover share `s` on the pair row, grouping comparison leftover-pair buttons
that match leftover-map cross share `x` on the pair row, grouping comparison
leftover-pair buttons that match leftover-map unexplained leftover `U` on the
pair row, grouping comparison leftover-pair buttons that match leftover residual
`R` on the pair row, grouping comparison leftover-pair buttons that match leftover
observed `Y` on the pair row, grouping comparison leftover-pair buttons that match
leftover expected `E` on the pair row, grouping comparison leftover-pair buttons
that match leftover-map rank on the pair row, grouping comparison leftover-pair
buttons that match leftover-map coordinates `ξ` / `ζ` on the pair row, a live
compare payload that carries those persisted leftover-map coordinates, and a
grouping comparison leftover-map axis share badge that matches leftover-axis
report badges from the live compare leftover_map_axes payload; click a post
marker or a pair button opens that post. A missing or non-finite share omits
that leftover-map comparison axis share badge and keeps leftover-map coordinates
when those axes are finite, leftover-map rank when that rank is a non-negative
integer, leftover expected `E` when finite, leftover observed `Y` when finite,
leftover residual `R` when finite, leftover-map unexplained leftover `U` when
finite, leftover-map cross share `x` when finite, leftover-map unexplained leftover
share `s` when finite, leftover-map explained leftover share `e` when finite,
leftover-map reconstruction `R̂` when finite, leftover-map distance `d`, plus the
strip coverage notes. Share `0` is shown when that persisted share is a finite
number, including rank-0 unused axes. Do not invent leftover-map axis share from
leftover-map singular value, leftover pair count, plotted marker count, leftover-map
distance, leftover-map rank, leftover-map post coverage, leftover-map item coverage,
leftover-map incomplete post coverage, leftover-map incomplete item coverage,
leftover-map reconstruction, leftover-map unexplained leftover, leftover-map
coordinates, or the count of unused axes. A finite negative leftover is shown,
never clamped. The strip does not gain leftover-map singular values or the
leftover-map graphic. Never invent a leftover score or a theta. No new columns.

- Period leftover pairs now return persisted leftover-map coordinates
`ξ` / `ζ` on `GET /api/reports/compare/{period}` leftover pairs
(ADR 0303 / v2.60.0). After `make seed`, closest and farthest leftover
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ cutoff. Global Ask optional `knowledge_cutoff` uses the same cover

Create/start endpoint rules (ADR 0017 / 0021), tie-vs-miss similarity
(ADR 0026), R&R catalog ids (ADR 0019 / 0027), leftover pairs
(ADR 0048–0164 / 0182 / 0185 / 0201 / 0233 / 0266 / 0267 / 0268 / 0269 / 0270 / 0271 / 0272 / 0273 / 0274 / 0275 / 0276 / 0277 / 0278 / 0279 / 0280 / 0281 / 0282 / 0283 / 0284 / 0285 / 0286 / 0287 / 0288 / 0289 / 0290 / 0291 / 0292 / 0293 / 0294 / 0295 / 0296 / 0297 / 0298 / 0299 / 0300 / 0301 / 0302 / 0303), occupational construct catalog search
(ADR 0048–0164 / 0182 / 0185 / 0201 / 0233 / 0266 / 0267 / 0268 / 0269 / 0270 / 0271 / 0272 / 0273 / 0274 / 0275 / 0276 / 0277 / 0278 / 0279 / 0280 / 0281 / 0282 / 0283 / 0284 / 0285 / 0286 / 0287 / 0288 / 0289 / 0290 / 0291 / 0292 / 0293 / 0294 / 0295 / 0296 / 0297 / 0298 / 0299 / 0300 / 0301 / 0302 / 0303 / 0368), occupational construct catalog search
(ADR 0257), the text-channel embedding swap and cosine
clamp (ADR 0190), per-edge channel-score persistence (ADR 0195),
token-backed status notices (ADR 0220),
Expand Down
5 changes: 5 additions & 0 deletions backend/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3052,6 +3052,11 @@ async def compare_period_groupings(
**row,
"members": [],
"leftover_pairs": leftover_pairs,
"leftover_map_axes": (
row.get("leftover_map_axes", [])
if len(members) == len(row["members"])
else []
),
"post_count": len(members),
}
)
Expand Down
25 changes: 25 additions & 0 deletions backend/app/report_ingestion.py
Original file line number Diff line number Diff line change
Expand Up @@ -1088,6 +1088,21 @@ async def fetch_period_comparison(
leftover_coverage_by_key = {
(row["grouping_kind"], row["grouping_key"]): row for row in leftover_coverage
}
leftover_axes = await conn.fetch(
"""
select grouping_kind, grouping_key, axis_index, leftover_singular_value, leftover_share
from report_leftover_map_axis
where period_code = $1 and rubric_version = $2
and grouping_kind = any($3::text[])
order by grouping_kind, grouping_key, axis_index
""",
period_code,
RUBRIC_VERSION,
list(GROUPING_KINDS),
)
leftover_axes_by_key: dict[tuple[str, str], list[asyncpg.Record]] = defaultdict(list)
for row in leftover_axes:
leftover_axes_by_key[(row["grouping_kind"], row["grouping_key"])].append(row)
payload: list[dict[str, Any]] = []
for row in rows:
label = await resolve_grouping_label(conn, row["grouping_kind"], row["grouping_key"])
Expand Down Expand Up @@ -1151,6 +1166,16 @@ async def fetch_period_comparison(
}
for pair in leftover_by_key.get((row["grouping_kind"], row["grouping_key"]), [])
],
"leftover_map_axes": [
{
"axis_index": int(axis["axis_index"]),
"leftover_singular_value": float(axis["leftover_singular_value"]),
"leftover_share": float(axis["leftover_share"]),
}
for axis in leftover_axes_by_key.get(
(row["grouping_kind"], row["grouping_key"]), []
)
],
"leftover_map_coverage": _leftover_map_coverage_payload(
leftover_coverage_by_key.get((row["grouping_kind"], row["grouping_key"]))
),
Expand Down
9 changes: 9 additions & 0 deletions backend/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5836,6 +5836,15 @@ def test_seed_period_report_surfaces_on_get_reports(client, demo_analyst_token,
assert leftover_compare_coverage["incomplete_post_count"] == (
leftover_compare_coverage["scored_post_count"] - leftover_compare_coverage["map_post_count"]
)
leftover_compare_axes = leftover_thread.get("leftover_map_axes", [])
assert [axis["axis_index"] for axis in leftover_compare_axes] == [1, 2]
assert all(isinstance(axis["leftover_share"], (int, float)) for axis in leftover_compare_axes)
assert all(
axis["leftover_share"] == axis["leftover_share"] for axis in leftover_compare_axes
)
assert leftover_compare_axes[0]["leftover_share"] != leftover_compare_axes[0][
"leftover_singular_value"
] or leftover_compare_axes[0]["leftover_share"] in {0, 1}
assert leftover_compare_coverage["map_item_count"] <= leftover_compare_coverage["scored_item_count"]
assert leftover_compare_coverage["map_post_count"] != len(
leftover_thread.get("leftover_pairs", [])
Expand Down
4 changes: 3 additions & 1 deletion docs/adr/0148-leftover-map-axis-share.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
**Decision status:** Accepted
**Date:** 2026-08-24
**Amended by:** [ADR 0269](0269-leftover-map-axis-share-plot.md)
(leftover-map axis share on the graphic display)
(leftover-map axis share on the graphic display),
[ADR 0368](0368-leftover-map-compare-axis-share.md)
(leftover-map axis share on the grouping comparison strip)

## Context

Expand Down
Loading
Loading