diff --git a/AGENTS.md b/AGENTS.md
index 64d26c5df..4868ff49b 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -708,6 +708,16 @@ axis share. Rank-0 unused axes still name leftover-axis tick
`σ 0.00`. Do not invent leftover-map singular values from leftover-map axis share. Do not invent leftover-map
axis share from leftover-map singular values. This increment does not change leftover-map comparison leftover-axis
ticks.
+ADR 0331 captions leftover-map comparison graphic leftover-map axis ticks with persisted leftover-map
+axis share when leftoverMapComparePlotTickAxisBadge returns a usable leftover-map axis tick leftover-map
+axis share caption. Distinct accessible names
+`leftover map comparison graphic leftover-map axis {axis} tick {value} {share}%` and
+`leftover map comparison graphic leftover-map axis {axis} tick {value} σ {singular} {share}%`.
+Share and singular value omit independently. Rank-0 unused axes still name leftover-map
+comparison graphic leftover-map axis tick leftover-map axis share `0%`. Do not invent leftover-map
+axis share from leftover-map singular values. Do not invent leftover-map singular values from leftover-map
+axis share. Leftover-map graphic leftover-map axis ticks, leftover-map comparison leftover-axis ticks,
+and leftover-axis ticks never name leftover-map axis share this increment.
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
@@ -827,6 +837,16 @@ singular values `σ_k` when leftoverMapPlotTickAxisBadge returns a usable leftov
Leftover-map comparison graphic leftover-map axis tick leftover-map singular values independently of leftover-map axis share
(ADR 0328) captions leftover-map comparison graphic leftover-map axis ticks with persisted leftover-map
singular values `σ_k` when leftoverMapComparePlotTickAxisBadge returns a usable leftover-map axis tick caption.
+Leftover-map comparison leftover-axis tick leftover-map singular values independently of leftover-map axis share
+(ADR 0329) captions leftover-map comparison leftover-axis ticks with persisted leftover-map
+singular values `σ_k` when leftoverMapCompareAxisTickBadge returns a usable leftover-axis tick caption.
+Leftover-axis tick leftover-map singular values independently of leftover-map axis share
+(ADR 0330) captions leftover-axis ticks with persisted leftover-map
+singular values `σ_k` when leftoverMapAxisTickBadge returns a usable leftover-axis tick caption.
+Leftover-map comparison graphic leftover-map axis tick leftover-map axis share independently of leftover-map singular values
+(ADR 0331) captions leftover-map comparison graphic leftover-map axis ticks with persisted leftover-map
+axis share when leftoverMapComparePlotTickAxisBadge returns a usable leftover-map axis tick leftover-map
+axis share caption.
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)
diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md
index 2d798c8f2..dd2457d15 100644
--- a/ARCHITECTURE.md
+++ b/ARCHITECTURE.md
@@ -773,6 +773,9 @@ tick caption independently of leftover-map axis share.
ADR 0330 captions leftover-axis ticks with persisted leftover-map
singular values `σ_k` when leftoverMapAxisTickBadge returns a usable leftover-axis
tick caption independently of leftover-map axis share.
+ADR 0331 captions leftover-map comparison graphic leftover-map axis ticks with persisted leftover-map
+axis share when leftoverMapComparePlotTickAxisBadge returns a usable leftover-map axis tick leftover-map
+axis share caption independently of leftover-map singular values.
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
@@ -833,7 +836,8 @@ comparison graphic leftover-map axis leftover-map singular values as leftoverMap
(ADR 0327), leftover-map comparison graphic leftover-map axis tick leftover-map singular values independently of leftover-map axis share
(ADR 0328), leftover-map comparison leftover-axis tick leftover-map singular values independently of leftover-map axis share
(ADR 0329), leftover-axis tick leftover-map singular values independently of leftover-map axis share
-(ADR 0330);
+(ADR 0330), leftover-map comparison graphic leftover-map axis tick leftover-map axis share independently of leftover-map singular values
+(ADR 0331);
`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
diff --git a/CHANGELOG.d/2.88.0-leftover-map-compare-plot-tick-share-badge.md b/CHANGELOG.d/2.88.0-leftover-map-compare-plot-tick-share-badge.md
new file mode 100644
index 000000000..6a3e922d5
--- /dev/null
+++ b/CHANGELOG.d/2.88.0-leftover-map-compare-plot-tick-share-badge.md
@@ -0,0 +1,30 @@
+## 2.88.0 — Leftover-map axis share on leftover-map comparison graphic leftover-map axis ticks independently of leftover-map singular values
+
+- Caption leftover-map comparison graphic leftover-map axis ticks with persisted leftover-map
+ axis share through leftoverMapComparePlotTickAxisBadge independently of leftover-map
+ singular values (ADR 0331). After `make seed`, leftover-map comparison graphic leftover-map axis
+ ticks name persisted leftover-map axis share when leftoverMapComparePlotTickAxisBadge
+ returns a usable leftover-map axis tick leftover-map axis share caption even when leftover-map
+ singular values are omitted; click a leftover pair opens that post. A missing or
+ non-finite leftover-map axis share omits that leftover-map axis share tick caption and keeps
+ `leftover map comparison graphic leftover-map axis {k} tick {value}` or
+ `leftover map comparison graphic leftover-map axis {k} tick {value} σ {singular}`. Rank-0 unused
+ axes still name leftover-map axis share `0%`. Leftover-map comparison graphic leftover-map axis ticks stay
+ `leftover map comparison graphic leftover-map axis {k} tick {value} {share}%` when leftover-map
+ axis share is finite and `σ_k` omits, and
+ `leftover map comparison graphic leftover-map axis {k} tick {value} σ {singular} {share}%`
+ when both are finite so they stay distinct from leftover-map graphic leftover-map axis ticks
+ `leftover-map axis {k} tick {value} σ {singular}`, from leftover-map graphic leftover-map
+ axis `leftover-map axis {k} σ {value} ({share}%)`, from leftover-axis
+ `leftover axis {k} {share}%`, from comparison leftover-axis
+ `leftover map comparison leftover axis {k} {share}%`, from comparison graphic leftover-map
+ axis `leftover map comparison graphic leftover-map axis {k} σ {value} ({share}%)`, from comparison
+ leftover-axis ticks `leftover map comparison leftover axis {k} tick {value} σ {singular}`,
+ from leftover-axis ticks `leftover axis {k} tick {value} σ {singular}`, and from comparison
+ graphic leftover-map axis ticks
+ `leftover map comparison graphic leftover-map axis {k} tick {value} σ {singular}`. Do not invent
+ leftover-map axis share from `σ_k`. Do not invent `σ_k` from leftover-map axis
+ share. This increment does not change leftover-map graphic leftover-map axis ticks,
+ leftover-map comparison leftover-axis ticks, or leftover-axis ticks.
+ A finite negative leftover is shown, never clamped. Never invent a leftover score.
+ Never invent a theta. No new columns.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d9aa3a434..82bc23928 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,36 @@ All notable changes to this project are documented here. Format follows
### Added
+- Period leftover pairs now caption leftover-map comparison graphic leftover-map
+ axis ticks with persisted leftover-map axis share through leftoverMapComparePlotTickAxisBadge
+ independently of leftover-map singular values (ADR 0331 / v2.88.0). After `make seed`,
+ leftover-map comparison graphic leftover-map axis ticks name persisted leftover-map
+ axis share when leftoverMapComparePlotTickAxisBadge returns a usable leftover-map
+ axis tick leftover-map axis share caption even when leftover-map singular values are
+ omitted; click a leftover pair opens that post. A missing or non-finite leftover-map
+ axis share omits that leftover-map axis share tick caption and keeps
+ `leftover map comparison graphic leftover-map axis {k} tick {value}` or
+ `leftover map comparison graphic leftover-map axis {k} tick {value} σ {singular}`.
+ Rank-0 unused axes still name leftover-map axis share `0%`. Leftover-map comparison
+ graphic leftover-map axis ticks stay
+ `leftover map comparison graphic leftover-map axis {k} tick {value} {share}%` when leftover-map
+ axis share is finite and `σ_k` omits, and
+ `leftover map comparison graphic leftover-map axis {k} tick {value} σ {singular} {share}%`
+ when both are finite so they stay distinct from leftover-map graphic leftover-map axis ticks
+ `leftover-map axis {k} tick {value} σ {singular}`, from leftover-map graphic leftover-map
+ axis `leftover-map axis {k} σ {value} ({share}%)`, from leftover-axis
+ `leftover axis {k} {share}%`, from comparison leftover-axis
+ `leftover map comparison leftover axis {k} {share}%`, from comparison graphic leftover-map
+ axis `leftover map comparison graphic leftover-map axis {k} σ {value} ({share}%)`, from comparison
+ leftover-axis ticks `leftover map comparison leftover axis {k} tick {value} σ {singular}`,
+ from leftover-axis ticks `leftover axis {k} tick {value} σ {singular}`, and from comparison
+ graphic leftover-map axis ticks
+ `leftover map comparison graphic leftover-map axis {k} tick {value} σ {singular}`. Do not invent
+ leftover-map axis share from `σ_k`. Do not invent `σ_k` from leftover-map axis
+ share. This increment does not change leftover-map graphic leftover-map axis ticks,
+ leftover-map comparison leftover-axis ticks, or leftover-axis ticks. A finite negative leftover
+ is shown, never clamped. Never invent a leftover score or a theta. No new columns.
+
- Period leftover pairs now caption leftover-axis ticks with persisted leftover-map
singular values `σ_k` through leftoverMapAxisTickBadge independently of leftover-map
axis share (ADR 0330 / v2.87.0). After `make seed`, leftover-axis ticks name
diff --git a/CLAUDE.md b/CLAUDE.md
index e9bf54c9b..8cef4b47f 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -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 / 0304 / 0305 / 0306 / 0307 / 0308 / 0309 / 0310 / 0311 / 0312 / 0313 / 0314 / 0315 / 0316 / 0317 / 0318 / 0319 / 0320 / 0321 / 0322 / 0323 / 0324 / 0325 / 0326 / 0327 / 0328 / 0329 / 0330), 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 / 0304 / 0305 / 0306 / 0307 / 0308 / 0309 / 0310 / 0311 / 0312 / 0313 / 0314 / 0315 / 0316 / 0317 / 0318 / 0319 / 0320 / 0321 / 0322 / 0323 / 0324 / 0325 / 0326 / 0327 / 0328 / 0329 / 0330 / 0331), 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),
diff --git a/docs/adr/0148-leftover-map-axis-share.md b/docs/adr/0148-leftover-map-axis-share.md
index 0ee0869db..c1ecf1ff0 100644
--- a/docs/adr/0148-leftover-map-axis-share.md
+++ b/docs/adr/0148-leftover-map-axis-share.md
@@ -21,7 +21,9 @@
[ADR 0329](0329-leftover-map-compare-axis-tick-badge.md)
(leftover-map comparison leftover-axis tick leftover-map singular values independently of leftover-map axis share);
[ADR 0330](0330-leftover-map-axis-tick-badge.md)
-(leftover-axis tick leftover-map singular values independently of leftover-map axis share)
+(leftover-axis tick leftover-map singular values independently of leftover-map axis share);
+[ADR 0331](0331-leftover-map-compare-plot-tick-share-badge.md)
+(leftover-map comparison graphic leftover-map axis tick leftover-map axis share independently of leftover-map singular values)
## Context
diff --git a/docs/adr/0320-leftover-map-compare-plot-ticks.md b/docs/adr/0320-leftover-map-compare-plot-ticks.md
index 4742ecf1c..2b89e4f6f 100644
--- a/docs/adr/0320-leftover-map-compare-plot-ticks.md
+++ b/docs/adr/0320-leftover-map-compare-plot-ticks.md
@@ -101,7 +101,9 @@ and distance are finite, `R̂ = ξ · ζ` and `d = ‖ξ − ζ‖`.
Independent of leftover-map singular values on leftover-axis report badges.
Independent of leftover-map comparison graphic leftover-map axis tick leftover-map
singular values independently of leftover-map axis share
-([ADR 0328](0328-leftover-map-compare-plot-tick-axis-badge.md)).
+([ADR 0328](0328-leftover-map-compare-plot-tick-axis-badge.md)). Independent of leftover-map
+comparison graphic leftover-map axis tick leftover-map axis share independently of leftover-map
+singular values ([ADR 0331](0331-leftover-map-compare-plot-tick-share-badge.md)).
## References
diff --git a/docs/adr/0326-leftover-map-compare-plot-axis-badge.md b/docs/adr/0326-leftover-map-compare-plot-axis-badge.md
index d6f601a24..2ee4f8f48 100644
--- a/docs/adr/0326-leftover-map-compare-plot-axis-badge.md
+++ b/docs/adr/0326-leftover-map-compare-plot-axis-badge.md
@@ -121,7 +121,9 @@ Independent of leftover-map graphic leftover-map axis tick leftover-map singular
values independently of leftover-map axis share
([ADR 0327](0327-leftover-map-plot-tick-axis-badge.md)). Independent of leftover-map
comparison graphic leftover-map axis tick leftover-map singular values independently of leftover-map axis share
-([ADR 0328](0328-leftover-map-compare-plot-tick-axis-badge.md)).
+([ADR 0328](0328-leftover-map-compare-plot-tick-axis-badge.md)). Independent of leftover-map
+comparison graphic leftover-map axis tick leftover-map axis share independently of leftover-map
+singular values ([ADR 0331](0331-leftover-map-compare-plot-tick-share-badge.md)).
## References
diff --git a/docs/adr/0327-leftover-map-plot-tick-axis-badge.md b/docs/adr/0327-leftover-map-plot-tick-axis-badge.md
index f0bd6c0a5..8e8f279b2 100644
--- a/docs/adr/0327-leftover-map-plot-tick-axis-badge.md
+++ b/docs/adr/0327-leftover-map-plot-tick-axis-badge.md
@@ -110,7 +110,9 @@ share ([ADR 0325](0325-leftover-map-axis-singular-only.md)). Independent of left
coordinate ticks on the grouping comparison leftover-map graphic
([ADR 0320](0320-leftover-map-compare-plot-ticks.md)). Independent of leftover-map
comparison graphic leftover-map axis tick leftover-map singular values independently of leftover-map axis share
-([ADR 0328](0328-leftover-map-compare-plot-tick-axis-badge.md)).
+([ADR 0328](0328-leftover-map-compare-plot-tick-axis-badge.md)). Independent of leftover-map
+comparison graphic leftover-map axis tick leftover-map axis share independently of leftover-map
+singular values ([ADR 0331](0331-leftover-map-compare-plot-tick-share-badge.md)).
## References
diff --git a/docs/adr/0328-leftover-map-compare-plot-tick-axis-badge.md b/docs/adr/0328-leftover-map-compare-plot-tick-axis-badge.md
index f39915f14..ceba164af 100644
--- a/docs/adr/0328-leftover-map-compare-plot-tick-axis-badge.md
+++ b/docs/adr/0328-leftover-map-compare-plot-tick-axis-badge.md
@@ -112,7 +112,9 @@ share ([ADR 0325](0325-leftover-map-axis-singular-only.md)). Independent of left
coordinate ticks on the grouping comparison leftover-map graphic
([ADR 0320](0320-leftover-map-compare-plot-ticks.md)). Independent of leftover-map
comparison leftover-axis tick leftover-map singular values independently of leftover-map axis share
-([ADR 0329](0329-leftover-map-compare-axis-tick-badge.md)).
+([ADR 0329](0329-leftover-map-compare-axis-tick-badge.md)). Independent of leftover-map
+comparison graphic leftover-map axis tick leftover-map axis share independently of leftover-map
+singular values ([ADR 0331](0331-leftover-map-compare-plot-tick-share-badge.md)).
## References
diff --git a/docs/adr/0329-leftover-map-compare-axis-tick-badge.md b/docs/adr/0329-leftover-map-compare-axis-tick-badge.md
index bd849cf59..faea0787b 100644
--- a/docs/adr/0329-leftover-map-compare-axis-tick-badge.md
+++ b/docs/adr/0329-leftover-map-compare-axis-tick-badge.md
@@ -118,7 +118,9 @@ report badges on the grouping comparison strip
comparison leftover-map graphic
([ADR 0320](0320-leftover-map-compare-plot-ticks.md)). Independent of leftover-axis
tick leftover-map singular values independently of leftover-map axis share
-([ADR 0330](0330-leftover-map-axis-tick-badge.md)).
+([ADR 0330](0330-leftover-map-axis-tick-badge.md)). Independent of leftover-map
+comparison graphic leftover-map axis tick leftover-map axis share independently of leftover-map
+singular values ([ADR 0331](0331-leftover-map-compare-plot-tick-share-badge.md)).
## References
diff --git a/docs/adr/0330-leftover-map-axis-tick-badge.md b/docs/adr/0330-leftover-map-axis-tick-badge.md
index ee425ea24..a8189c827 100644
--- a/docs/adr/0330-leftover-map-axis-tick-badge.md
+++ b/docs/adr/0330-leftover-map-axis-tick-badge.md
@@ -98,7 +98,9 @@ axis tick leftover-map singular values independently of leftover-map axis share
singular values independently of leftover-map axis share
([ADR 0327](0327-leftover-map-plot-tick-axis-badge.md)). Independent of leftover-map singular values on leftover-axis report badges
independently of leftover-map axis share ([ADR 0325](0325-leftover-map-axis-singular-only.md)). Independent of leftover-map
-coordinate ticks on the leftover-map graphic ([ADR 0270](0270-leftover-map-coordinate-ticks.md)).
+coordinate ticks on the leftover-map graphic ([ADR 0270](0270-leftover-map-coordinate-ticks.md)). Independent of leftover-map
+comparison graphic leftover-map axis tick leftover-map axis share independently of leftover-map
+singular values ([ADR 0331](0331-leftover-map-compare-plot-tick-share-badge.md)).
## References
diff --git a/docs/adr/0331-leftover-map-compare-plot-tick-share-badge.md b/docs/adr/0331-leftover-map-compare-plot-tick-share-badge.md
new file mode 100644
index 000000000..1d014dbe0
--- /dev/null
+++ b/docs/adr/0331-leftover-map-compare-plot-tick-share-badge.md
@@ -0,0 +1,154 @@
+# ADR 0331 — Name leftover-map axis share on leftover-map comparison graphic leftover-map axis ticks independently of leftover-map singular values
+
+**Decision status:** Accepted
+**Date:** 2026-08-31
+
+Amends leftover-map comparison graphic leftover-map axis tick leftover-map singular
+values independently of leftover-map axis share
+([ADR 0328](0328-leftover-map-compare-plot-tick-axis-badge.md)), leftover-map
+coordinate ticks on the grouping comparison leftover-map graphic
+([ADR 0320](0320-leftover-map-compare-plot-ticks.md)), leftover-map comparison
+graphic leftover-map axis leftover-map singular values as leftoverMapComparePlotAxisBadge
+([ADR 0326](0326-leftover-map-compare-plot-axis-badge.md)), leftover-map axis share
+persistence ([ADR 0148](0148-leftover-map-axis-share.md)). Independent of leftover-map
+graphic leftover-map axis tick leftover-map singular values independently of leftover-map
+axis share ([ADR 0327](0327-leftover-map-plot-tick-axis-badge.md)). Independent of leftover-map
+comparison leftover-axis tick leftover-map singular values independently of leftover-map
+axis share ([ADR 0329](0329-leftover-map-compare-axis-tick-badge.md)). Independent of leftover-axis
+tick leftover-map singular values independently of leftover-map axis share
+([ADR 0330](0330-leftover-map-axis-tick-badge.md)).
+
+## Context
+
+ADR 0148 already persists leftover-map singular values `σ_k` and leftover-map
+axis share `σ_k² / Σ_j σ_j²`. ADR 0320 already ticks leftover-map comparison
+graphic leftover-map axes at persisted `ξ` / `ζ` projections as
+`leftover map comparison graphic leftover-map axis {k} tick {value}`. ADR 0326
+already captions leftover-map comparison graphic-display leftover-map axes with
+`σ_k` and leftover-map axis share through leftoverMapComparePlotAxisBadge, omitting
+each independently. ADR 0328 already captions leftover-map comparison graphic
+leftover-map axis ticks with `σ_k` through leftoverMapComparePlotTickAxisBadge
+independently of leftover-map axis share. Those leftover-map comparison graphic
+leftover-map axis ticks still omit leftover-map axis share, so a buyer who reads
+leftover-map comparison graphic leftover-map axis ticks can treat leftover-map
+coordinate ticks or leftover-map singular values as leftover-map structure without
+a next action. A missing or non-finite leftover-map axis share is not a leftover
+score and must omit independently of leftover-map singular values. Rank-0 unused
+axes still persist leftover-map axis share `0`. A finite negative leftover is
+shown, never clamped. Do not invent leftover-map axis share from `σ_k`. Do not
+invent `σ_k` from leftover-map axis share. Leftover-map graphic leftover-map axis
+ticks never name leftover-map axis share. Leftover-map comparison leftover-axis
+ticks (ADR 0329) and leftover-axis ticks (ADR 0330) never name leftover-map axis
+share this increment.
+
+This increment names leftover-map comparison graphic leftover-map axis ticks leftover-map
+axis share as leftoverMapComparePlotTickAxisBadge, matching leftoverMapComparePlotAxisBadge,
+leftoverMapCompareAxisBadge, leftoverMapPlotAxisBadge, leftoverMapAxisBadge, leftoverMapPlotTickAxisBadge,
+and leftoverMapComparePlotTickAxisBadge leftover-map singular values. Leftover-map
+comparison graphic leftover-map axis ticks stay
+`leftover map comparison graphic leftover-map axis {k} tick {value} {share}%` when leftover-map
+axis share is finite and `σ_k` omits, and
+`leftover map comparison graphic leftover-map axis {k} tick {value} σ {singular} {share}%`
+when both are finite, so they stay distinct from leftover-map graphic leftover-map axis ticks
+`leftover-map axis {k} tick {value} σ {singular}` (ADR 0327), from leftover-map graphic leftover-map axis
+`leftover-map axis {k} σ {value} ({share}%)` (ADR 0324), from leftover-axis
+`leftover axis {k} {share}%` (ADR 0325), from comparison leftover-axis
+`leftover map comparison leftover axis {k} {share}%` (ADR 0323), from comparison graphic leftover-map
+axis `leftover map comparison graphic leftover-map axis {k} σ {value} ({share}%)` (ADR 0326),
+from comparison leftover-axis ticks
+`leftover map comparison leftover axis {k} tick {value} σ {singular}` (ADR 0329),
+from leftover-axis ticks `leftover axis {k} tick {value} σ {singular}` (ADR 0330),
+and from comparison graphic leftover-map axis ticks
+`leftover map comparison graphic leftover-map axis {k} tick {value} σ {singular}` (ADR 0328).
+It does not add columns. Do not invent a leftover score. Do not invent a theta.
+
+This protected increment uses **0331** so it does not collide with leftover-axis
+tick leftover-map singular values independently of leftover-map axis share
+(0330), leftover-map comparison leftover-axis tick leftover-map singular values independently of leftover-map axis share
+(0329), leftover-map comparison graphic leftover-map axis tick leftover-map singular values independently of leftover-map axis share
+(0328), leftover-map graphic leftover-map axis tick leftover-map singular values independently of leftover-map axis share
+(0327), leftover-map comparison graphic leftover-map axis leftover-map singular values as leftoverMapComparePlotAxisBadge
+(0326), leftover-map coordinate ticks on the grouping comparison leftover-map graphic
+(0320), leftover-map axis share persistence (0148), or the dashboard stacks.
+
+## Decision
+
+On leftover-map comparison graphic leftover-map axis ticks, caption leftover-map axis `k`
+with persisted leftover-map axis share when leftoverMapComparePlotTickAxisBadge
+returns a usable leftover-map axis tick caption that includes that share.
+Share and singular value omit independently through that helper: no `σ_k` and no
+share keeps `leftover map comparison graphic leftover-map axis {k} tick {value}`;
+`σ_k` only is `leftover map comparison graphic leftover-map axis {k} tick {value} σ {singular}`;
+share only is `leftover map comparison graphic leftover-map axis {k} tick {value} {share}%`;
+both are `leftover map comparison graphic leftover-map axis {k} tick {value} σ {singular} {share}%`.
+A missing or non-finite leftover-map axis share omits that share tick caption and
+keeps a usable leftover-map comparison graphic leftover-map axis tick coordinate caption,
+including any leftover-map singular value. Rank-0 unused axes still name leftover-map
+axis share `0%`. Click a post marker to open that post. Criterion markers are not post
+buttons.
+
+Leftover-map comparison graphic leftover-map axis tick leftover-map axis share omits
+independently of leftover-map graphic leftover-map axis tick leftover-map singular values,
+leftover-map comparison leftover-axis tick leftover-map singular values, leftover-axis
+tick leftover-map singular values, leftover-map comparison graphic leftover-map axis leftover-map axis share, leftover-map graphic-display leftover-map axis
+leftover-map axis share, leftover-axis report badge leftover-map axis share, and leftover-map comparison leftover-axis
+leftover-map axis share. A missing leftover-map singular value omits leftover-map singular
+values and keeps a usable leftover-map comparison graphic leftover-map axis tick leftover-map
+axis share caption.
+
+This increment does not change leftover-map graphic leftover-map axis ticks. Those leftover-map
+graphic leftover-map axis ticks stay `leftover-map axis {axis} tick {value} σ {singular}`
+(ADR 0327) and never name leftover-map axis share. This increment does not change leftover-map
+comparison leftover-axis ticks or leftover-axis ticks. This increment does not persist leftover-map inner product, cosine, or length.
+
+Do not add SQL. Do not edit shipped migrations. Do not invent a leftover
+score. Do not invent a theta.
+
+## Consequences
+
+After `make seed`, leftover-map comparison graphic leftover-map axis ticks name persisted
+leftover-map axis share when leftoverMapComparePlotTickAxisBadge returns a usable
+leftover-map axis tick leftover-map axis share caption even when leftover-map singular
+values are omitted; click a leftover pair opens that post. Hidden posts stay hidden. Rank-0 unused
+axes still name leftover-map comparison graphic leftover-map axis tick leftover-map axis share `0%`. Leftover-map
+comparison graphic leftover-map axis tick leftover-map singular values independently of leftover-map axis share
+(ADR 0328), leftover-map graphic leftover-map axis tick leftover-map singular values independently of leftover-map axis share
+(ADR 0327), leftover-map comparison leftover-axis tick leftover-map singular values independently of leftover-map axis share
+(ADR 0329), leftover-axis tick leftover-map singular values independently of leftover-map axis share
+(ADR 0330), leftover-map comparison graphic leftover-map axis leftover-map singular values (ADR 0326), leftover-map
+graphic-display leftover-map singular values (ADR 0324), leftover-axis report badge
+leftover-map singular values independently of leftover-map axis share (ADR 0325),
+and grouping comparison leftover-map graphic leftover-map axis ticks (ADR 0320)
+remain.
+
+## Related
+
+Independent of leftover-map comparison graphic leftover-map axis tick leftover-map singular values
+independently of leftover-map axis share
+([ADR 0328](0328-leftover-map-compare-plot-tick-axis-badge.md)). Independent of leftover-map
+graphic leftover-map axis tick leftover-map singular values independently of leftover-map axis share
+([ADR 0327](0327-leftover-map-plot-tick-axis-badge.md)). Independent of leftover-map
+comparison leftover-axis tick leftover-map singular values independently of leftover-map axis share
+([ADR 0329](0329-leftover-map-compare-axis-tick-badge.md)). Independent of leftover-axis
+tick leftover-map singular values independently of leftover-map axis share
+([ADR 0330](0330-leftover-map-axis-tick-badge.md)). Independent of leftover-map
+comparison graphic leftover-map axis leftover-map singular values as leftoverMapComparePlotAxisBadge
+([ADR 0326](0326-leftover-map-compare-plot-axis-badge.md)). Independent of leftover-map
+singular values on leftover-map graphic-display axes
+([ADR 0324](0324-leftover-map-plot-axis-singular.md)). Independent of leftover-map
+coordinate ticks on the grouping comparison leftover-map graphic
+([ADR 0320](0320-leftover-map-compare-plot-ticks.md)). Independent of leftover-map
+axis share persistence ([ADR 0148](0148-leftover-map-axis-share.md)).
+
+## References
+
+Gabriel, K. R. (1971). The biplot graphic display of matrices with
+application to principal component analysis. *Biometrika, 58*(3),
+453–467. https://doi.org/10.1093/biomet/58.3.453
+
+Jeon, M., Jin, I. H., Schweinberger, M., & Baugh, S. (2021). Mapping
+unobserved item–respondent interactions: A latent space item response
+model with interaction map. *Psychometrika, 86*(2), 378–403.
+https://doi.org/10.1007/s11336-021-09762-5
+(LSIRM interaction `−γ‖ξ_j − ζ_i‖` after main effects
+`α_j − β_i`; typically `p = 2` for the interaction map.)
diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md
index be94f06bf..737eac3c3 100644
--- a/docs/product-technical-gap-baseline.md
+++ b/docs/product-technical-gap-baseline.md
@@ -1,5 +1,27 @@
# Product & Technical Gap Baseline
+> Exact-head loop overlay: 2026-08-31 13:56 KST. Protected `main` is
+> `cb187cadee5fb6c46d8a944815ccc154a1e028d1`. Writes work. Do not
+> self-approve. #871 leftover-map singular values on leftover-axis ticks
+> independently of leftover-map axis share (v2.87.0 / ADR 0330) is
+> `e9e4c2a`, stacked on #870 @ `b086d97`. Independent APPROVE is missing. Next
+> buyer increment on this cycle: leftover-map comparison graphic leftover-map axis
+> ticks naming persisted leftover-map axis share independently of leftover-map
+> singular values (ADR 0331 / v2.88.0) delivered locally on
+> `feat/leftover-map-compare-plot-tick-share-badge-v2880`. Caption persisted leftover-map
+> axis share on leftover-map comparison graphic leftover-map axis ticks when leftoverMapComparePlotTickAxisBadge
+> returns a usable leftover-map axis tick leftover-map axis share caption even when leftover-map
+> singular values omit. Distinct accessible names
+> `leftover map comparison graphic leftover-map axis {axis} tick {value} {share}%` and
+> `leftover map comparison graphic leftover-map axis {axis} tick {value} σ {singular} {share}%`.
+> Rank-0 unused axes still name leftover-map axis share `0%`. Share omits independently of
+> leftover-map singular values. Leftover-map graphic leftover-map axis ticks, leftover-map
+> comparison leftover-axis ticks, and leftover-axis ticks never name leftover-map axis share.
+> Do not invent leftover-map axis share from `σ_k`. Do not invent `σ_k` from leftover-map
+> axis share. Do not persist leftover-map inner product, cosine, or length. Stack onto #871.
+> Leave open for independent review. Do not squash-merge. Do not self-approve. Issues #79
+> and #87 stay open. Do not merge #808 without independent APPROVE. Never self-approve.
+
> Exact-head loop overlay: 2026-08-31 13:28 KST. Protected `main` is
> `cb187cadee5fb6c46d8a944815ccc154a1e028d1`. Writes work. Do not
> self-approve. #870 leftover-map singular values on leftover-map comparison leftover-axis
diff --git a/frontend/package.json b/frontend/package.json
index 712ee4a66..92d3e5edf 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -1,7 +1,7 @@
{
"name": "frontend",
"private": true,
- "version": "2.87.0",
+ "version": "2.88.0",
"type": "module",
"scripts": {
"dev": "vite",
diff --git a/frontend/src/App.test.tsx b/frontend/src/App.test.tsx
index 25999ef95..61eeed3c9 100644
--- a/frontend/src/App.test.tsx
+++ b/frontend/src/App.test.tsx
@@ -4738,7 +4738,7 @@ describe("App, authenticated", () => {
).not.toBeInTheDocument();
expect(
within(screen.getByLabelText("Grouping comparison")).getByLabelText(
- "leftover map comparison graphic leftover-map axis 1 tick +0.50 σ 1.84",
+ "leftover map comparison graphic leftover-map axis 1 tick +0.50 σ 1.84 82%",
),
).toBeInTheDocument();
expect(
diff --git a/frontend/src/components/LeftoverMapPlot.test.tsx b/frontend/src/components/LeftoverMapPlot.test.tsx
index 65d3a5e5e..be6c6f7e4 100644
--- a/frontend/src/components/LeftoverMapPlot.test.tsx
+++ b/frontend/src/components/LeftoverMapPlot.test.tsx
@@ -2695,17 +2695,20 @@ describe("LeftoverMapPlot", () => {
/>,
);
expect(
- screen.getByLabelText("leftover map comparison graphic leftover-map axis 1 tick +0.50 σ 1.84"),
+ screen.getByLabelText("leftover map comparison graphic leftover-map axis 1 tick +0.50 σ 1.84 82%"),
).toBeInTheDocument();
expect(
- screen.getByLabelText("leftover map comparison graphic leftover-map axis 2 tick −0.02 σ 0.86"),
+ screen.getByLabelText("leftover map comparison graphic leftover-map axis 2 tick −0.02 σ 0.86 18%"),
).toBeInTheDocument();
expect(
- screen.getByLabelText("leftover map comparison graphic leftover-map axis 1 tick 0.00 σ 1.84"),
+ screen.getByLabelText("leftover map comparison graphic leftover-map axis 1 tick 0.00 σ 1.84 82%"),
).toBeInTheDocument();
expect(
screen.queryByLabelText("leftover map comparison graphic leftover-map axis 1 tick +0.50"),
).not.toBeInTheDocument();
+ expect(
+ screen.queryByLabelText("leftover map comparison graphic leftover-map axis 1 tick +0.50 σ 1.84"),
+ ).not.toBeInTheDocument();
expect(screen.queryByLabelText("leftover-map axis 1 tick +0.50")).not.toBeInTheDocument();
expect(screen.queryByLabelText("leftover-map axis 1 tick +0.50 σ 1.84")).not.toBeInTheDocument();
expect(screen.queryByLabelText("leftover-map axis 2 tick −0.02")).not.toBeInTheDocument();
@@ -2766,7 +2769,7 @@ describe("LeftoverMapPlot", () => {
/>,
);
expect(
- screen.getAllByLabelText("leftover map comparison graphic leftover-map axis 1 tick 0.00 σ 0.00").length,
+ screen.getAllByLabelText("leftover map comparison graphic leftover-map axis 1 tick 0.00 σ 0.00 0%").length,
).toBeGreaterThan(0);
expect(
screen.queryByLabelText("leftover map comparison graphic leftover-map axis 1 tick +1.00"),
@@ -2822,10 +2825,10 @@ describe("LeftoverMapPlot", () => {
/>,
);
expect(
- screen.getByLabelText("leftover map comparison graphic leftover-map axis 1 tick 0.00 σ 0.00"),
+ screen.getByLabelText("leftover map comparison graphic leftover-map axis 1 tick 0.00 σ 0.00 0%"),
).toBeInTheDocument();
expect(
- screen.getByLabelText("leftover map comparison graphic leftover-map axis 2 tick 0.00 σ 0.00"),
+ screen.getByLabelText("leftover map comparison graphic leftover-map axis 2 tick 0.00 σ 0.00 0%"),
).toBeInTheDocument();
expect(screen.queryByLabelText("leftover-map axis 1 tick 0.00")).not.toBeInTheDocument();
expect(screen.queryByLabelText("leftover-map axis 2 tick 0.00")).not.toBeInTheDocument();
@@ -2884,10 +2887,10 @@ describe("LeftoverMapPlot", () => {
/>,
);
expect(
- screen.getByLabelText("leftover map comparison graphic leftover-map axis 1 tick +0.50"),
+ screen.getByLabelText("leftover map comparison graphic leftover-map axis 1 tick +0.50 82%"),
).toBeInTheDocument();
expect(
- screen.getByLabelText("leftover map comparison graphic leftover-map axis 2 tick −0.02"),
+ screen.getByLabelText("leftover map comparison graphic leftover-map axis 2 tick −0.02 18%"),
).toBeInTheDocument();
expect(
screen.queryByLabelText("leftover map comparison graphic leftover-map axis 1 tick +0.50 σ 1.84"),
@@ -2895,4 +2898,33 @@ describe("LeftoverMapPlot", () => {
expect(screen.getByText("leftover map comparison axis 1 (82%)")).toBeInTheDocument();
expect(screen.getByText("leftover map comparison axis 2 (18%)")).toBeInTheDocument();
});
+
+ it("captions leftover-map comparison graphic leftover-map axis ticks with leftover-map axis share independently of leftover-map singular values", () => {
+ render(
+ ,
+ );
+ expect(
+ screen.getByLabelText("leftover map comparison graphic leftover-map axis 1 tick +0.50 σ 1.84 82%"),
+ ).toBeInTheDocument();
+ expect(
+ screen.getByLabelText("leftover map comparison graphic leftover-map axis 2 tick −0.02 18%"),
+ ).toBeInTheDocument();
+ expect(
+ screen.queryByLabelText("leftover map comparison graphic leftover-map axis 1 tick +0.50 σ 1.84"),
+ ).not.toBeInTheDocument();
+ expect(
+ screen.queryByLabelText("leftover map comparison graphic leftover-map axis 2 tick −0.02 σ 0.86"),
+ ).not.toBeInTheDocument();
+ expect(screen.queryByLabelText("leftover-map axis 1 tick +0.50 σ 1.84")).not.toBeInTheDocument();
+ expect(screen.queryByText("leftover axis 1 tick +0.50 82%")).not.toBeInTheDocument();
+ });
});
diff --git a/frontend/src/components/LeftoverMapPlot.tsx b/frontend/src/components/LeftoverMapPlot.tsx
index 9e862e0cc..b592416b6 100644
--- a/frontend/src/components/LeftoverMapPlot.tsx
+++ b/frontend/src/components/LeftoverMapPlot.tsx
@@ -106,7 +106,13 @@ function leftoverMapPlotTickText(
): string {
const leftoverSingular = leftoverSingularForAxis(leftoverMapAxes, axisIndex);
if (variant === "comparison") {
- const badge = leftoverMapComparePlotTickAxisBadge(axisIndex, tickLabel, leftoverSingular);
+ const leftoverShare = leftoverShareForAxis(leftoverMapAxes, axisIndex);
+ const badge = leftoverMapComparePlotTickAxisBadge(
+ axisIndex,
+ tickLabel,
+ leftoverSingular,
+ leftoverShare,
+ );
return tf(badge.key, badge.values);
}
const badge = leftoverMapPlotTickAxisBadge(axisIndex, tickLabel, leftoverSingular);
@@ -218,6 +224,9 @@ function leftoverMapPlotTickText(
* ADR 0328 fail-closes leftover-map comparison graphic leftover-map axis ticks leftover-map
* singular values through leftoverMapComparePlotTickAxisBadge independently of leftover-map
* axis share.
+ * ADR 0331 fail-closes leftover-map comparison graphic leftover-map axis ticks leftover-map
+ * axis share through leftoverMapComparePlotTickAxisBadge independently of leftover-map
+ * singular values.
* Never invent a leftover score.
*/
export function LeftoverMapPlot({
diff --git a/frontend/src/i18n.test.ts b/frontend/src/i18n.test.ts
index 00f665876..324616623 100644
--- a/frontend/src/i18n.test.ts
+++ b/frontend/src/i18n.test.ts
@@ -113,6 +113,8 @@ describe("i18n", () => {
"leftover map comparison graphic leftover-map distance {label}",
"leftover map comparison graphic leftover-map axis {axis} tick {value}",
"leftover map comparison graphic leftover-map axis {axis} tick {value} σ {singular}",
+ "leftover map comparison graphic leftover-map axis {axis} tick {value} {share}%",
+ "leftover map comparison graphic leftover-map axis {axis} tick {value} σ {singular} {share}%",
"leftover map comparison graphic leftover-map axis {axis} σ {value}",
"leftover map comparison graphic leftover-map axis {axis} σ {value} ({share}%)",
"leftover map comparison leftover axis {axis} σ {value}",
@@ -724,6 +726,48 @@ describe("i18n", () => {
},
);
+ it.each([
+ ["ko", "잔여 지도 비교 그림 축 1 눈금 +0.50 82%"],
+ ["zh", "残差地图比较图形轴 1 刻度 +0.50 82%"],
+ ["ja", "残差マップの比較図軸 1 目盛 +0.50 82%"],
+ ["vi", "vạch trục đồ họa so sánh bản đồ phần dư 1 +0.50 82%"],
+ ] as const)(
+ "formats leftover map comparison graphic leftover-map axis tick leftover-map axis share in %s",
+ (locale, expected) => {
+ setLocale(locale);
+ expect(
+ tf("leftover map comparison graphic leftover-map axis {axis} tick {value} {share}%", {
+ axis: 1,
+ value: "+0.50",
+ share: "82",
+ }),
+ ).toBe(expected);
+ },
+ );
+
+ it.each([
+ ["ko", "잔여 지도 비교 그림 축 1 눈금 +0.50 σ 1.84 82%"],
+ ["zh", "残差地图比较图形轴 1 刻度 +0.50 σ 1.84 82%"],
+ ["ja", "残差マップの比較図軸 1 目盛 +0.50 σ 1.84 82%"],
+ ["vi", "vạch trục đồ họa so sánh bản đồ phần dư 1 +0.50 σ 1.84 82%"],
+ ] as const)(
+ "formats leftover map comparison graphic leftover-map axis tick leftover-map singular values and leftover-map axis share in %s",
+ (locale, expected) => {
+ setLocale(locale);
+ expect(
+ tf(
+ "leftover map comparison graphic leftover-map axis {axis} tick {value} σ {singular} {share}%",
+ {
+ axis: 1,
+ value: "+0.50",
+ singular: "1.84",
+ share: "82",
+ },
+ ),
+ ).toBe(expected);
+ },
+ );
+
it.each([
["ko", "잔여 지도 비교 그림 축 1 σ 1.84"],
["zh", "残差地图比较图形轴 1 σ 1.84"],
diff --git a/frontend/src/i18n.ts b/frontend/src/i18n.ts
index 745722b7f..ff8b1abbb 100644
--- a/frontend/src/i18n.ts
+++ b/frontend/src/i18n.ts
@@ -299,6 +299,10 @@ const TRANSLATIONS: Partial>> = {
"leftover map comparison graphic leftover-map axis {axis} tick {value}": "잔여 지도 비교 그림 축 {axis} 눈금 {value}",
"leftover map comparison graphic leftover-map axis {axis} tick {value} σ {singular}":
"잔여 지도 비교 그림 축 {axis} 눈금 {value} σ {singular}",
+ "leftover map comparison graphic leftover-map axis {axis} tick {value} {share}%":
+ "잔여 지도 비교 그림 축 {axis} 눈금 {value} {share}%",
+ "leftover map comparison graphic leftover-map axis {axis} tick {value} σ {singular} {share}%":
+ "잔여 지도 비교 그림 축 {axis} 눈금 {value} σ {singular} {share}%",
"leftover map comparison graphic leftover-map axis {axis} σ {value}": "잔여 지도 비교 그림 축 {axis} σ {value}",
"leftover map comparison graphic leftover-map axis {axis} σ {value} ({share}%)":
"잔여 지도 비교 그림 축 {axis} σ {value} ({share}%)",
@@ -964,6 +968,10 @@ const TRANSLATIONS: Partial>> = {
"leftover map comparison graphic leftover-map axis {axis} tick {value}": "残差地图比较图形轴 {axis} 刻度 {value}",
"leftover map comparison graphic leftover-map axis {axis} tick {value} σ {singular}":
"残差地图比较图形轴 {axis} 刻度 {value} σ {singular}",
+ "leftover map comparison graphic leftover-map axis {axis} tick {value} {share}%":
+ "残差地图比较图形轴 {axis} 刻度 {value} {share}%",
+ "leftover map comparison graphic leftover-map axis {axis} tick {value} σ {singular} {share}%":
+ "残差地图比较图形轴 {axis} 刻度 {value} σ {singular} {share}%",
"leftover map comparison graphic leftover-map axis {axis} σ {value}": "残差地图比较图形轴 {axis} σ {value}",
"leftover map comparison graphic leftover-map axis {axis} σ {value} ({share}%)":
"残差地图比较图形轴 {axis} σ {value} ({share}%)",
@@ -1650,6 +1658,10 @@ const TRANSLATIONS: Partial>> = {
"leftover map comparison graphic leftover-map axis {axis} tick {value}": "残差マップの比較図軸 {axis} 目盛 {value}",
"leftover map comparison graphic leftover-map axis {axis} tick {value} σ {singular}":
"残差マップの比較図軸 {axis} 目盛 {value} σ {singular}",
+ "leftover map comparison graphic leftover-map axis {axis} tick {value} {share}%":
+ "残差マップの比較図軸 {axis} 目盛 {value} {share}%",
+ "leftover map comparison graphic leftover-map axis {axis} tick {value} σ {singular} {share}%":
+ "残差マップの比較図軸 {axis} 目盛 {value} σ {singular} {share}%",
"leftover map comparison graphic leftover-map axis {axis} σ {value}": "残差マップの比較図軸 {axis} σ {value}",
"leftover map comparison graphic leftover-map axis {axis} σ {value} ({share}%)":
"残差マップの比較図軸 {axis} σ {value} ({share}%)",
@@ -2315,6 +2327,10 @@ const TRANSLATIONS: Partial>> = {
"leftover map comparison graphic leftover-map axis {axis} tick {value}": "vạch trục đồ họa so sánh bản đồ phần dư {axis} {value}",
"leftover map comparison graphic leftover-map axis {axis} tick {value} σ {singular}":
"vạch trục đồ họa so sánh bản đồ phần dư {axis} {value} σ {singular}",
+ "leftover map comparison graphic leftover-map axis {axis} tick {value} {share}%":
+ "vạch trục đồ họa so sánh bản đồ phần dư {axis} {value} {share}%",
+ "leftover map comparison graphic leftover-map axis {axis} tick {value} σ {singular} {share}%":
+ "vạch trục đồ họa so sánh bản đồ phần dư {axis} {value} σ {singular} {share}%",
"leftover map comparison graphic leftover-map axis {axis} σ {value}":
"trục đồ họa so sánh bản đồ phần dư {axis} σ {value}",
"leftover map comparison graphic leftover-map axis {axis} σ {value} ({share}%)":
diff --git a/frontend/src/leftoverMapAxisBadge.test.ts b/frontend/src/leftoverMapAxisBadge.test.ts
index 5f3469b10..3d4bf13f5 100644
--- a/frontend/src/leftoverMapAxisBadge.test.ts
+++ b/frontend/src/leftoverMapAxisBadge.test.ts
@@ -201,6 +201,9 @@ describe("leftover-axis leftover-axis tick leftover-map singular values", () =>
expect(leftoverMapAxisTickBadge(1, "+0.50", 1.84).key).not.toBe(
leftoverMapComparePlotTickAxisBadge(1, "+0.50", 1.84).key,
);
+ expect(leftoverMapAxisTickBadge(1, "+0.50", 1.84).key).not.toBe(
+ leftoverMapComparePlotTickAxisBadge(1, "+0.50", 1.84, 0.82).key,
+ );
expect(leftoverMapAxisTickBadge(1, "+0.50", 1.84).key).not.toBe(
leftoverMapAxisBadge(1, 1.84, null)?.key,
);
diff --git a/frontend/src/leftoverMapAxisBadge.ts b/frontend/src/leftoverMapAxisBadge.ts
index 498f68d9d..9aefed2dd 100644
--- a/frontend/src/leftoverMapAxisBadge.ts
+++ b/frontend/src/leftoverMapAxisBadge.ts
@@ -14,6 +14,8 @@
* leftoverMapCompareAxisTickBadge, not this helper.
* ADR 0330 names leftover-map leftover-axis ticks leftover-map singular
* values as leftoverMapAxisTickBadge independently of leftover-map axis share.
+ * ADR 0331 captions leftover-map comparison graphic leftover-map axis ticks leftover-map
+ * axis share as leftoverMapComparePlotTickAxisBadge, not this helper.
*/
import type { LeftoverMapAxis } from "./api";
diff --git a/frontend/src/leftoverMapPlotAxisSingular.test.ts b/frontend/src/leftoverMapPlotAxisSingular.test.ts
index 520fb2677..5b22701b1 100644
--- a/frontend/src/leftoverMapPlotAxisSingular.test.ts
+++ b/frontend/src/leftoverMapPlotAxisSingular.test.ts
@@ -17,7 +17,9 @@ import {
LEFTOVER_MAP_COMPARE_AXIS_TICK_SINGULAR,
LEFTOVER_MAP_COMPARE_PLOT_AXIS_SINGULAR,
LEFTOVER_MAP_COMPARE_PLOT_AXIS_SINGULAR_SHARE,
+ LEFTOVER_MAP_COMPARE_PLOT_TICK_SHARE,
LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR,
+ LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR_SHARE,
LEFTOVER_MAP_PLOT_AXIS_SINGULAR,
LEFTOVER_MAP_PLOT_AXIS_SINGULAR_SHARE,
LEFTOVER_MAP_PLOT_TICK_SINGULAR,
@@ -540,3 +542,113 @@ describe("leftover-map comparison leftover-axis tick leftover-map singular value
);
});
});
+
+describe("leftover-map comparison graphic leftover-map axis tick leftover-map axis share", () => {
+ it("names persisted leftover-map axis share on leftover-map comparison graphic leftover-map axis ticks independently of leftover-map singular values", () => {
+ expect(leftoverMapComparePlotTickAxisBadge(1, "+0.50", 1.84, 0.82)).toEqual({
+ key: LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR_SHARE,
+ values: { axis: 1, value: "+0.50", singular: "1.84", share: "82" },
+ });
+ expect(leftoverMapComparePlotTickAxisBadge(2, "−0.02", 0.86, 0.18)).toEqual({
+ key: LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR_SHARE,
+ values: { axis: 2, value: "−0.02", singular: "0.86", share: "18" },
+ });
+ });
+
+ it("names leftover-map axis share on leftover-map comparison graphic leftover-map axis ticks when leftover-map singular values omit", () => {
+ expect(leftoverMapComparePlotTickAxisBadge(1, "+0.50", Number.NaN, 0.82)).toEqual({
+ key: LEFTOVER_MAP_COMPARE_PLOT_TICK_SHARE,
+ values: { axis: 1, value: "+0.50", share: "82" },
+ });
+ expect(leftoverMapComparePlotTickAxisBadge(2, "−0.02", -0.01, 0.18)).toEqual({
+ key: LEFTOVER_MAP_COMPARE_PLOT_TICK_SHARE,
+ values: { axis: 2, value: "−0.02", share: "18" },
+ });
+ expect(leftoverMapComparePlotTickAxisBadge(1, "+0.50", null, 0.82).values.singular).toBeUndefined();
+ });
+
+ it("names rank-0 zero leftover-map axis share on leftover-map comparison graphic leftover-map axis ticks", () => {
+ expect(leftoverMapComparePlotTickAxisBadge(1, "0.00", 0, 0)).toEqual({
+ key: LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR_SHARE,
+ values: { axis: 1, value: "0.00", singular: "0.00", share: "0" },
+ });
+ expect(leftoverMapComparePlotTickAxisBadge(1, "0.00", null, 0)).toEqual({
+ key: LEFTOVER_MAP_COMPARE_PLOT_TICK_SHARE,
+ values: { axis: 1, value: "0.00", share: "0" },
+ });
+ });
+
+ it("omits leftover-map axis share independently of leftover-map singular values", () => {
+ expect(leftoverMapComparePlotTickAxisBadge(1, "+0.50", 1.84, Number.NaN)).toEqual({
+ key: LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR,
+ values: { axis: 1, value: "+0.50", singular: "1.84" },
+ });
+ expect(leftoverMapComparePlotTickAxisBadge(1, "+0.50", 1.84, null)).toEqual({
+ key: LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR,
+ values: { axis: 1, value: "+0.50", singular: "1.84" },
+ });
+ expect(leftoverMapComparePlotTickAxisBadge(1, "+0.50", Number.NaN, Number.NaN)).toEqual({
+ key: LEFTOVER_MAP_COMPARE_PLOT_TICK,
+ values: { axis: 1, value: "+0.50" },
+ });
+ });
+
+ it("does not invent leftover-map axis share from leftover-map singular values", () => {
+ expect(leftoverMapComparePlotTickAxisBadge(1, "+0.50", 1.84, undefined).key).toBe(
+ LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR,
+ );
+ expect(leftoverMapComparePlotTickAxisBadge(1, "+0.50", 1.84, undefined).values.share).toBeUndefined();
+ });
+
+ it("does not invent leftover-map singular values from leftover-map axis share", () => {
+ expect(leftoverMapComparePlotTickAxisBadge(1, "+0.50", undefined, 0.82).key).toBe(
+ LEFTOVER_MAP_COMPARE_PLOT_TICK_SHARE,
+ );
+ expect(leftoverMapComparePlotTickAxisBadge(1, "+0.50", undefined, 0.82).values.singular).toBeUndefined();
+ });
+
+ it("does not name leftover-map axis share on leftover-map graphic leftover-map axis ticks", () => {
+ expect(leftoverMapPlotTickAxisBadge(1, "+0.50", 1.84).values.share).toBeUndefined();
+ expect(leftoverMapPlotTickAxisBadge(1, "+0.50", 1.84).key).toBe(LEFTOVER_MAP_PLOT_TICK_SINGULAR);
+ expect(leftoverMapPlotTickAxisBadge(1, "+0.50", 1.84).key).not.toBe(
+ leftoverMapComparePlotTickAxisBadge(1, "+0.50", 1.84, 0.82).key,
+ );
+ });
+
+ it("stays distinct from leftover-axis, leftover-map graphic axis, leftover-map graphic tick, comparison leftover-axis, and comparison graphic copy", () => {
+ expect(LEFTOVER_MAP_COMPARE_PLOT_TICK_SHARE).toBe(
+ "leftover map comparison graphic leftover-map axis {axis} tick {value} {share}%",
+ );
+ expect(LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR_SHARE).toBe(
+ "leftover map comparison graphic leftover-map axis {axis} tick {value} σ {singular} {share}%",
+ );
+ expect(LEFTOVER_MAP_COMPARE_PLOT_TICK_SHARE).not.toBe(LEFTOVER_MAP_COMPARE_PLOT_TICK);
+ expect(LEFTOVER_MAP_COMPARE_PLOT_TICK_SHARE).not.toBe(LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR);
+ expect(LEFTOVER_MAP_COMPARE_PLOT_TICK_SHARE).not.toBe(LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR_SHARE);
+ expect(LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR_SHARE).not.toBe(LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR);
+ expect(LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR_SHARE).not.toBe(LEFTOVER_MAP_PLOT_TICK_SINGULAR);
+ expect(LEFTOVER_MAP_COMPARE_PLOT_TICK_SHARE).not.toBe(LEFTOVER_MAP_COMPARE_PLOT_AXIS_SHARE);
+ expect(LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR_SHARE).not.toBe(
+ LEFTOVER_MAP_COMPARE_PLOT_AXIS_SINGULAR_SHARE,
+ );
+ expect(LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR_SHARE).not.toBe(
+ LEFTOVER_MAP_COMPARE_AXIS_SINGULAR_SHARE,
+ );
+ expect(LEFTOVER_MAP_COMPARE_PLOT_TICK_SHARE).not.toBe(LEFTOVER_MAP_COMPARE_AXIS_TICK);
+ expect(LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR_SHARE).not.toBe(
+ LEFTOVER_MAP_COMPARE_AXIS_TICK_SINGULAR,
+ );
+ expect(leftoverMapComparePlotTickAxisBadge(1, "+0.50", 1.84, 0.82).key).not.toBe(
+ leftoverMapComparePlotAxisBadge(1, 1.84, 0.82)?.key,
+ );
+ expect(leftoverMapComparePlotTickAxisBadge(1, "+0.50", null, 0.82).key).not.toBe(
+ leftoverMapComparePlotAxisBadge(1, null, 0.82)?.key,
+ );
+ expect(leftoverMapComparePlotTickAxisBadge(1, "+0.50", 1.84, 0.82).key).not.toBe(
+ leftoverMapPlotTickAxisBadge(1, "+0.50", 1.84).key,
+ );
+ expect(leftoverMapComparePlotTickAxisBadge(1, "+0.50", 1.84, 0.82).key).not.toBe(
+ leftoverMapCompareAxisTickBadge(1, "+0.50", 1.84).key,
+ );
+ });
+});
diff --git a/frontend/src/leftoverMapPlotAxisSingular.ts b/frontend/src/leftoverMapPlotAxisSingular.ts
index ab64a2f55..380ecf2a5 100644
--- a/frontend/src/leftoverMapPlotAxisSingular.ts
+++ b/frontend/src/leftoverMapPlotAxisSingular.ts
@@ -17,6 +17,9 @@
* ADR 0330 names leftover-map leftover-axis ticks leftover-map singular
* values as leftoverMapAxisTickBadge independently of leftover-map axis share,
* not leftoverMapCompareAxisTickBadge.
+ * ADR 0331 names leftover-map comparison graphic leftover-map axis ticks leftover-map
+ * axis share as leftoverMapComparePlotTickAxisBadge independently of leftover-map
+ * singular values.
*/
import type { LeftoverMapAxis } from "./api";
@@ -47,6 +50,12 @@ export const LEFTOVER_MAP_PLOT_TICK_SINGULAR =
export const LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR =
"leftover map comparison graphic leftover-map axis {axis} tick {value} σ {singular}";
+export const LEFTOVER_MAP_COMPARE_PLOT_TICK_SHARE =
+ "leftover map comparison graphic leftover-map axis {axis} tick {value} {share}%";
+
+export const LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR_SHARE =
+ "leftover map comparison graphic leftover-map axis {axis} tick {value} σ {singular} {share}%";
+
export const LEFTOVER_MAP_COMPARE_AXIS_SINGULAR =
"leftover map comparison leftover axis {axis} σ {value}";
@@ -190,14 +199,28 @@ export function leftoverMapComparePlotTickAxisBadge(
axisIndex: number,
tickLabel: string,
leftoverSingular: number | null | undefined,
+ leftoverShare?: number | null,
): LeftoverMapCompareAxisBadge {
const singular = formatLeftoverMapPlotAxisSingular(leftoverSingular);
- if (singular === null) {
+ const percent = formatLeftoverMapPlotAxisShare(leftoverShare);
+ if (singular === null && percent === null) {
return { key: LEFTOVER_MAP_COMPARE_PLOT_TICK, values: { axis: axisIndex, value: tickLabel } };
}
+ if (singular === null && percent !== null) {
+ return {
+ key: LEFTOVER_MAP_COMPARE_PLOT_TICK_SHARE,
+ values: { axis: axisIndex, value: tickLabel, share: percent },
+ };
+ }
+ if (singular !== null && percent === null) {
+ return {
+ key: LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR,
+ values: { axis: axisIndex, value: tickLabel, singular },
+ };
+ }
return {
- key: LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR,
- values: { axis: axisIndex, value: tickLabel, singular },
+ key: LEFTOVER_MAP_COMPARE_PLOT_TICK_SINGULAR_SHARE,
+ values: { axis: axisIndex, value: tickLabel, singular: singular as string, share: percent as string },
};
}
diff --git a/frontend/src/leftoverMapPlotLayout.test.ts b/frontend/src/leftoverMapPlotLayout.test.ts
index c1b68cffd..8d0be0d3a 100644
--- a/frontend/src/leftoverMapPlotLayout.test.ts
+++ b/frontend/src/leftoverMapPlotLayout.test.ts
@@ -1375,6 +1375,12 @@ describe("leftover map comparison graphic labels", () => {
expect(LEFTOVER_MAP_COMPARE_PLOT_TICK).not.toBe(
"leftover map comparison graphic leftover-map axis {axis} tick {value} σ {singular}",
);
+ expect(LEFTOVER_MAP_COMPARE_PLOT_TICK).not.toBe(
+ "leftover map comparison graphic leftover-map axis {axis} tick {value} {share}%",
+ );
+ expect(LEFTOVER_MAP_COMPARE_PLOT_TICK).not.toBe(
+ "leftover map comparison graphic leftover-map axis {axis} tick {value} σ {singular} {share}%",
+ );
expect(LEFTOVER_MAP_COMPARE_PLOT_TICK).not.toBe(
"leftover map comparison leftover axis {axis} σ {value}",
);
diff --git a/frontend/src/leftoverMapPlotLayout.ts b/frontend/src/leftoverMapPlotLayout.ts
index 9d460a322..09eff6059 100644
--- a/frontend/src/leftoverMapPlotLayout.ts
+++ b/frontend/src/leftoverMapPlotLayout.ts
@@ -103,6 +103,9 @@
* ADR 0330 fail-closes leftover-map leftover-axis ticks leftover-map
* singular values through leftoverMapAxisTickBadge independently of leftover-map
* axis share, not this graphic.
+ * ADR 0331 fail-closes leftover-map comparison graphic leftover-map axis ticks leftover-map
+ * axis share through leftoverMapComparePlotTickAxisBadge independently of leftover-map
+ * singular values.
*/
import { formatLeftoverMapCoordinatePair } from "./leftoverMapCoordinates";
diff --git a/pyproject.toml b/pyproject.toml
index 4cbf8bd6e..db01d587c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "lineageweave"
-version = "2.87.0"
+version = "2.88.0"
description = "Reconstructs git-branch-style lineage DAGs from scattered short records using multi-channel score fusion and LLM adjudication."
readme = "README.md"
license = { text = "MIT" }