diff --git a/AGENTS.md b/AGENTS.md
index 4ec20b075..5b117b16d 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -898,7 +898,11 @@ Do not invent leftover-map origin from leftover-map item coordinates `ζ`. lefto
ADR 0357 captions leftover-map comparison leftover-axis leftover-map origin with leftover-map origin when leftoverMapCompareAxisOriginBadge
returns a leftover-map origin caption independently of leftover-map comparison graphic leftover-map origin, leftover-map graphic leftover-map origin, leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates, leftover-map axis origin ticks, leftover-map axis share, and leftover-map singular values. Distinct accessible name
`leftover map comparison leftover axis leftover-map origin {origin}`. Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`.
-Do not invent leftover-map origin from leftover-map item coordinates `ζ`. leftoverMapComparePlotOriginBadge stays leftover-map comparison graphic leftover-map origin keys. leftoverMapCompareAxisTickBadge stays leftover-map comparison leftover-axis origin tick keys this increment. leftoverMapAxisOriginBadge stays unnamed this increment.
+Do not invent leftover-map origin from leftover-map item coordinates `ζ`. leftoverMapComparePlotOriginBadge stays leftover-map comparison graphic leftover-map origin keys. leftoverMapCompareAxisTickBadge stays leftover-map comparison leftover-axis origin tick keys this increment.
+ADR 0358 captions leftover-map leftover-axis leftover-map origin with leftover-map origin when leftoverMapAxisOriginBadge
+returns a leftover-map origin caption independently of leftover-map comparison leftover-axis leftover-map origin, leftover-map comparison graphic leftover-map origin, leftover-map graphic leftover-map origin, leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates, leftover-map axis origin ticks, leftover-map axis share, and leftover-map singular values. Distinct accessible name
+`leftover axis leftover-map origin {origin}`. Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`.
+Do not invent leftover-map origin from leftover-map item coordinates `ζ`. leftoverMapCompareAxisOriginBadge stays leftover-map comparison leftover-axis leftover-map origin keys. leftoverMapAxisTickBadge stays leftover-map leftover-axis origin tick keys this increment. leftoverMapListOriginBadge stays unnamed 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
@@ -1102,6 +1106,8 @@ Leftover-map comparison graphic leftover-map origin independently of leftover-ma
(ADR 0356) captions leftover-map comparison graphic leftover-map origin when leftoverMapComparePlotOriginBadge returns a leftover-map origin caption.
Leftover-map comparison leftover-axis leftover-map origin independently of leftover-map comparison graphic leftover-map origin
(ADR 0357) captions leftover-map comparison leftover-axis leftover-map origin when leftoverMapCompareAxisOriginBadge returns a leftover-map origin caption.
+Leftover-map leftover-axis leftover-map origin independently of leftover-map comparison leftover-axis leftover-map origin
+(ADR 0358) captions leftover-map leftover-axis leftover-map origin when leftoverMapAxisOriginBadge returns a leftover-map origin 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 2bbbef79c..b0b4942ee 100644
--- a/ARCHITECTURE.md
+++ b/ARCHITECTURE.md
@@ -839,6 +839,8 @@ ADR 0356 captions leftover-map comparison graphic leftover-map origin when lefto
returns a leftover-map origin caption independently of leftover-map graphic leftover-map origin, leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates, leftover-map axis origin ticks, leftover-map axis share, and leftover-map singular values.
ADR 0357 captions leftover-map comparison leftover-axis leftover-map origin when leftoverMapCompareAxisOriginBadge
returns a leftover-map origin caption independently of leftover-map comparison graphic leftover-map origin, leftover-map graphic leftover-map origin, leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates, leftover-map axis origin ticks, leftover-map axis share, and leftover-map singular values.
+ADR 0358 captions leftover-map leftover-axis leftover-map origin when leftoverMapAxisOriginBadge
+returns a leftover-map origin caption independently of leftover-map comparison leftover-axis leftover-map origin, leftover-map comparison graphic leftover-map origin, leftover-map graphic leftover-map origin, leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates, leftover-map axis origin ticks, leftover-map axis share, and 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
diff --git a/CHANGELOG.d/2.115.0-leftover-map-axis-origin-badge.md b/CHANGELOG.d/2.115.0-leftover-map-axis-origin-badge.md
new file mode 100644
index 000000000..7592bb59e
--- /dev/null
+++ b/CHANGELOG.d/2.115.0-leftover-map-axis-origin-badge.md
@@ -0,0 +1,15 @@
+## 2.115.0 — Leftover-map origin on leftover-map leftover-axis independently of leftover-map comparison leftover-axis leftover-map origin
+
+- Caption leftover-map leftover-axis leftover-map origin through leftoverMapAxisOriginBadge
+ independently of leftover-map comparison leftover-axis leftover-map origin, leftover-map comparison graphic leftover-map origin, leftover-map graphic leftover-map origin, leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates, leftover-map axis origin ticks, leftover-map axis share, and leftover-map singular values (ADR 0358). After `make seed`, leftover-map leftover-axis leftover-map
+ origin names leftover-map origin when leftoverMapAxisOriginBadge returns a usable leftover-map origin caption. Distinct accessible name
+ `leftover axis leftover-map origin {origin}`. Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`. leftoverMapCompareAxisOriginBadge stays leftover-map comparison leftover-axis leftover-map origin keys. leftoverMapComparePlotOriginBadge stays leftover-map comparison graphic leftover-map origin keys. leftoverMapPlotOriginBadge stays leftover-map graphic leftover-map origin keys. leftoverMapCompareListCriterionBadge stays leftover-map comparison leftover-pair leftover-map
+ criterion leftover-map origin leftover-map item coordinate keys. leftoverMapListCriterionBadge stays leftover-map pair leftover-map
+ criterion leftover-map origin leftover-map item coordinate keys. leftoverMapPlotTickAxisBadge stays leftover-map graphic leftover-map
+ axis origin tick keys. leftoverMapComparePlotTickAxisBadge stays leftover-map comparison graphic leftover-map
+ axis origin tick keys. leftoverMapCompareAxisTickBadge stays leftover-map comparison leftover-axis origin tick keys.
+ leftoverMapAxisTickBadge stays leftover-map leftover-axis origin tick keys this increment.
+ leftoverMapListOriginBadge stays unnamed this increment.
+ Do not invent leftover-map origin from leftover-map item coordinates `ζ`, leftover-map axis share, or leftover-map singular values `σ_k`.
+ Do not mix #877. Do not mix #890 stale ADR 0347 / v2.104.0 identity. 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 96d71df50..813ec9d34 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,19 @@ All notable changes to this project are documented here. Format follows
### Added
+- Period leftover pairs now caption leftover-map leftover-axis leftover-map origin
+ through leftoverMapAxisOriginBadge independently of leftover-map comparison leftover-axis leftover-map origin, leftover-map comparison graphic leftover-map origin, leftover-map graphic leftover-map origin, leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates, leftover-map axis origin ticks, leftover-map axis share, and leftover-map singular values (ADR 0358 / v2.115.0). After `make seed`, leftover-map leftover-axis leftover-map
+ origin names leftover-map origin when leftoverMapAxisOriginBadge returns a usable leftover-map origin caption. Distinct accessible name
+ `leftover axis leftover-map origin {origin}`. Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`. leftoverMapCompareAxisOriginBadge stays leftover-map comparison leftover-axis leftover-map origin keys. leftoverMapComparePlotOriginBadge stays leftover-map comparison graphic leftover-map origin keys. leftoverMapPlotOriginBadge stays leftover-map graphic leftover-map origin keys. leftoverMapCompareListCriterionBadge stays leftover-map comparison leftover-pair leftover-map
+ criterion leftover-map origin leftover-map item coordinate keys. leftoverMapListCriterionBadge stays leftover-map pair leftover-map
+ criterion leftover-map origin leftover-map item coordinate keys. leftoverMapPlotTickAxisBadge stays leftover-map graphic leftover-map
+ axis origin tick keys. leftoverMapComparePlotTickAxisBadge stays leftover-map comparison graphic leftover-map
+ axis origin tick keys. leftoverMapCompareAxisTickBadge stays leftover-map comparison leftover-axis origin tick keys.
+ leftoverMapAxisTickBadge stays leftover-map leftover-axis origin tick keys this increment.
+ leftoverMapListOriginBadge stays unnamed this increment.
+ Do not invent leftover-map origin from leftover-map item coordinates `ζ`, leftover-map axis share, or leftover-map singular values `σ_k`.
+ Do not mix #877. Do not mix #890 stale ADR 0347 / v2.104.0 identity. 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-map comparison leftover-axis leftover-map origin
through leftoverMapCompareAxisOriginBadge independently of leftover-map comparison graphic leftover-map origin, leftover-map graphic leftover-map origin, leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates, leftover-map axis origin ticks, leftover-map axis share, and leftover-map singular values (ADR 0357 / v2.114.0). After `make seed`, leftover-map comparison leftover-axis leftover-map
origin names leftover-map origin when leftoverMapCompareAxisOriginBadge returns a usable leftover-map origin caption. Distinct accessible name
diff --git a/CLAUDE.md b/CLAUDE.md
index b822e4ae6..6bd330142 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 / 0331 / 0332 / 0333 / 0334 / 0335 / 0336 / 0337 / 0338 / 0339 / 0340 / 0341 / 0342 / 0343 / 0344 / 0345 / 0346 / 0347 / 0348 / 0349 / 0350 / 0351 / 0352 / 0353 / 0354 / 0355 / 0356 / 0357), 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 / 0332 / 0333 / 0334 / 0335 / 0336 / 0337 / 0338 / 0339 / 0340 / 0341 / 0342 / 0343 / 0344 / 0345 / 0346 / 0347 / 0348 / 0349 / 0350 / 0351 / 0352 / 0353 / 0354 / 0355 / 0356 / 0357 / 0358), 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/0346-leftover-map-axis-tick-origin-badge.md b/docs/adr/0346-leftover-map-axis-tick-origin-badge.md
index 19aa222e2..7995ba991 100644
--- a/docs/adr/0346-leftover-map-axis-tick-origin-badge.md
+++ b/docs/adr/0346-leftover-map-axis-tick-origin-badge.md
@@ -3,6 +3,8 @@
**Decision status:** Accepted
**Date:** 2026-08-31
+**Amended by:** [ADR 0358](0358-leftover-map-axis-origin-badge.md)
+
Amends leftover-axis ticks leftover-map singular values
([ADR 0330](0330-leftover-map-axis-tick-badge.md)) and leftover-axis ticks leftover-map axis share
([ADR 0334](0334-leftover-map-axis-tick-share-badge.md)). Independent of leftover-map
diff --git a/docs/adr/0357-leftover-map-compare-axis-origin-badge.md b/docs/adr/0357-leftover-map-compare-axis-origin-badge.md
index c53891b72..ba2950c40 100644
--- a/docs/adr/0357-leftover-map-compare-axis-origin-badge.md
+++ b/docs/adr/0357-leftover-map-compare-axis-origin-badge.md
@@ -3,6 +3,8 @@
**Decision status:** Proposed
**Date:** 2026-09-03
+**Amended by:** [ADR 0358](0358-leftover-map-axis-origin-badge.md)
+
Amends leftover-map origin on leftover-map comparison graphic independently of leftover-map graphic leftover-map origin
([ADR 0356](0356-leftover-map-compare-plot-origin-badge.md)). Independent of leftover-map comparison leftover-axis origin ticks independently of leftover-map axis share and leftover-map singular values
([ADR 0345](0345-leftover-map-compare-axis-tick-origin-badge.md)). Independent of leftover-map leftover-axis origin ticks independently of leftover-map axis share and leftover-map singular values
diff --git a/docs/adr/0358-leftover-map-axis-origin-badge.md b/docs/adr/0358-leftover-map-axis-origin-badge.md
new file mode 100644
index 000000000..723cce700
--- /dev/null
+++ b/docs/adr/0358-leftover-map-axis-origin-badge.md
@@ -0,0 +1,122 @@
+# ADR 0358 — Name leftover-map origin on leftover-map leftover-axis independently of leftover-map comparison leftover-axis leftover-map origin
+
+**Decision status:** Proposed
+**Date:** 2026-09-03
+
+Amends leftover-map origin on leftover-map comparison leftover-axis independently of leftover-map comparison graphic leftover-map origin
+([ADR 0357](0357-leftover-map-compare-axis-origin-badge.md)). Independent of leftover-map leftover-axis origin ticks independently of leftover-map axis share and leftover-map singular values
+([ADR 0346](0346-leftover-map-axis-tick-origin-badge.md)). Independent of leftover-map comparison leftover-axis origin ticks independently of leftover-map axis share and leftover-map singular values
+([ADR 0345](0345-leftover-map-compare-axis-tick-origin-badge.md)). Independent of leftover-map leftover-axis origin ticks on the competing origin-tick stack (do not mix #877). Independent of dirty draft leftoverMapPlotOriginBadge reconstruction (do not mix #890 stale ADR 0347 / v2.104.0 identity).
+
+## Context
+
+ADR 0357 already names leftover-map comparison leftover-axis leftover-map origin
+`leftover map comparison leftover axis leftover-map origin {origin}` when leftoverMapCompareAxisOriginBadge returns a usable leftover-map origin caption.
+Rank-0 unused axes still persist leftover-map origin `(0.00, 0.00)`
+(`formatLeftoverMapCoordinatePair(0, 0)`). Leftover-map leftover-axis leftover-map origin stayed unnamed
+that increment (`leftoverMapAxisOriginBadge` was not exported).
+Do not invent leftover-map origin from leftover-map comparison leftover-pair leftover-map
+criterion leftover-map origin leftover-map item coordinates `ζ`. leftoverMapCompareAxisOriginBadge stays leftover-map comparison leftover-axis leftover-map origin keys from ADR 0357.
+leftoverMapComparePlotOriginBadge stays leftover-map comparison graphic leftover-map origin keys from ADR 0356.
+leftoverMapPlotOriginBadge stays leftover-map graphic leftover-map origin keys from ADR 0355.
+leftoverMapCompareListCriterionBadge stays leftover-map comparison leftover-pair leftover-map
+criterion leftover-map origin leftover-map item coordinate keys from ADR 0354.
+leftoverMapListCriterionBadge stays leftover-map pair leftover-map criterion leftover-map origin leftover-map item coordinate keys from ADR 0352.
+leftoverMapComparePlotCriterionBadge stays leftover-map comparison graphic leftover-map criterion leftover-map origin leftover-map item coordinate keys from ADR 0350.
+leftoverMapPlotCriterionBadge stays leftover-map graphic leftover-map criterion leftover-map origin leftover-map item coordinate keys from ADR 0347.
+leftoverMapPlotTickAxisBadge stays leftover-map graphic leftover-map axis origin tick keys from ADR 0343.
+leftoverMapComparePlotTickAxisBadge stays leftover-map comparison graphic leftover-map axis origin tick keys from ADR 0344.
+leftoverMapCompareAxisTickBadge stays leftover-map comparison leftover-axis origin tick keys from ADR 0345.
+leftoverMapAxisTickBadge stays leftover-map leftover-axis origin tick keys from ADR 0346.
+
+This increment names leftover-map leftover-axis leftover-map origin as leftoverMapAxisOriginBadge.
+Leftover-map leftover-axis leftover-map origin stays
+`leftover axis leftover-map origin {origin}`
+when leftoverMapAxisOriginBadge returns a usable leftover-map origin caption, so it stays distinct from leftover-map
+comparison leftover-axis leftover-map origin
+`leftover map comparison leftover axis leftover-map origin {origin}`,
+leftover-map comparison graphic leftover-map origin
+`leftover map comparison graphic leftover-map origin {origin}`,
+leftover-map graphic leftover-map origin
+`leftover-map origin {origin}`,
+leftover-map graphic leftover-map axis origin ticks
+`leftover-map axis {axis} origin tick {value}`,
+leftover-map comparison graphic leftover-map axis origin ticks
+`leftover map comparison graphic leftover-map axis {axis} origin tick {value}`,
+leftover-map comparison leftover-axis origin ticks
+`leftover map comparison leftover axis {axis} origin tick {value}`,
+leftover-map leftover-axis origin ticks
+`leftover axis {axis} origin tick {value}`,
+leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates
+`leftover map comparison leftover pair leftover-map criterion {label} at leftover-map origin ζ {item}`,
+leftover-map pair leftover-map criterion leftover-map origin leftover-map item coordinates
+`leftover pair leftover-map criterion {label} at leftover-map origin ζ {item}`,
+leftover-map comparison graphic leftover-map criterion leftover-map origin leftover-map item coordinates
+`leftover map comparison graphic leftover-map criterion {label} at leftover-map origin ζ {item}`,
+and leftover-map graphic leftover-map criterion leftover-map origin leftover-map item coordinates
+`leftover-map criterion {label} at leftover-map origin ζ {item}`.
+Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`
+(`formatLeftoverMapCoordinatePair(0, 0)`). leftoverMapListOriginBadge stays unnamed
+this increment. It does not add columns. Do not invent a leftover score. Do not invent a theta.
+
+This protected increment uses **0358** / **v2.115.0** so it does not collide with leftover-map comparison leftover-axis leftover-map origin independently of leftover-map comparison graphic leftover-map origin
+(0357 / v2.114.0), leftover-map comparison graphic leftover-map origin independently of leftover-map graphic leftover-map origin
+(0356 / v2.113.0), leftover-map graphic leftover-map origin independently of leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates
+(0355 / v2.112.0), leftover-map graphic leftover-map criterion leftover-map origin leftover-map item coordinates (0347 / v2.104.0), leftover-map leftover-axis origin ticks (#877), or dirty draft #890.
+
+## Decision
+
+On leftover-map leftover-axis, caption leftover-map origin
+when leftoverMapAxisOriginBadge returns a usable leftover-map origin caption. Rank-0 unused axes still name leftover-map
+origin `(0.00, 0.00)`. Do not invent leftover-map origin from leftover-map item coordinates `ζ`, leftover-map axis share, or leftover-map singular values `σ_k`.
+leftoverMapCompareAxisOriginBadge, leftoverMapComparePlotOriginBadge, leftoverMapPlotOriginBadge, leftoverMapCompareListCriterionBadge, leftoverMapListCriterionBadge, leftoverMapComparePlotCriterionBadge, leftoverMapPlotCriterionBadge,
+leftoverMapPlotTickAxisBadge, leftoverMapComparePlotTickAxisBadge, leftoverMapCompareAxisTickBadge, and leftoverMapAxisTickBadge
+do not change leftover-map origin naming this increment.
+
+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 leftover-axis leftover-map origin names
+leftover-map origin independently of leftover-map comparison leftover-axis leftover-map origin, leftover-map comparison graphic leftover-map origin, leftover-map graphic leftover-map origin, leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates, leftover-map axis origin ticks, leftover-map axis share, and leftover-map
+singular values. Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`.
+leftoverMapCompareAxisOriginBadge stays leftover-map comparison leftover-axis leftover-map origin keys.
+leftoverMapComparePlotOriginBadge stays leftover-map comparison graphic leftover-map origin keys.
+leftoverMapPlotOriginBadge stays leftover-map graphic leftover-map origin keys.
+leftoverMapCompareListCriterionBadge stays leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinate keys.
+leftoverMapListCriterionBadge stays leftover-map pair leftover-map criterion leftover-map origin leftover-map item coordinate keys.
+leftoverMapPlotTickAxisBadge stays leftover-map graphic leftover-map axis origin tick keys.
+leftoverMapComparePlotTickAxisBadge stays leftover-map comparison graphic leftover-map axis origin tick keys.
+leftoverMapCompareAxisTickBadge stays leftover-map comparison leftover-axis origin tick keys.
+leftoverMapAxisTickBadge stays leftover-map leftover-axis origin tick keys.
+leftover-map comparison leftover-axis leftover-map origin independently of leftover-map comparison graphic leftover-map origin
+(ADR 0357) remain.
+
+## Related
+
+Independent of leftover-map comparison leftover-axis leftover-map origin independently of leftover-map comparison graphic leftover-map origin
+([ADR 0357](0357-leftover-map-compare-axis-origin-badge.md)). Independent of leftover-map comparison graphic leftover-map origin independently of leftover-map graphic leftover-map origin
+([ADR 0356](0356-leftover-map-compare-plot-origin-badge.md)). Independent of leftover-map graphic leftover-map origin independently of leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates
+([ADR 0355](0355-leftover-map-plot-origin-badge.md)). Independent of leftover-map leftover-axis origin ticks independently of leftover-map
+axis share and leftover-map singular values
+([ADR 0346](0346-leftover-map-axis-tick-origin-badge.md)). Independent of leftover-map
+comparison leftover-axis origin ticks independently of leftover-map axis share and leftover-map singular values
+([ADR 0345](0345-leftover-map-compare-axis-tick-origin-badge.md)). Independent of leftover-map
+comparison graphic leftover-map axis origin ticks independently of leftover-map axis share and leftover-map singular values
+([ADR 0344](0344-leftover-map-compare-plot-tick-origin-badge.md)). Independent of leftover-map
+graphic leftover-map axis origin ticks independently of leftover-map axis share and leftover-map singular values
+([ADR 0343](0343-leftover-map-plot-tick-origin-badge.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 d347844b0..04ad22f85 100644
--- a/docs/product-technical-gap-baseline.md
+++ b/docs/product-technical-gap-baseline.md
@@ -1,5 +1,13 @@
# Product & Technical Gap Baseline
+> Exact-head loop overlay: 2026-09-03 17:15 KST. Protected `main` is
+> `b0e94aa2a6f7a943f96dc5c4f2fdecd0021978a1`. Writes work (git push of v2.114.0 + REST Draft #926; git X-OAuth-Scopes still empty). Do not
+> self-approve. #926 leftover-map comparison leftover-axis leftover-map origin independently of leftover-map comparison graphic leftover-map origin (v2.114.0 / ADR 0357) is
+> `ede308929b20f24a56c5ff3ae2211dd84d20f3ae`, stacked on #921 @ `76ebcb10a72955a68c616c02e6e0732db0800f93`. Independent APPROVE is missing.
+> This increment: leftover-map leftover-axis leftover-map origin independently of leftover-map comparison leftover-axis leftover-map origin as leftoverMapAxisOriginBadge (ADR 0358 / v2.115.0) on
+> `feat/leftover-map-axis-origin-badge-v21150`. Distinct accessible name
+> `leftover axis leftover-map origin {origin}`. Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`. leftoverMapCompareAxisOriginBadge stays leftover-map comparison leftover-axis leftover-map origin keys. leftoverMapComparePlotOriginBadge stays leftover-map comparison graphic leftover-map origin keys. leftoverMapPlotOriginBadge stays leftover-map graphic leftover-map origin keys. leftoverMapCompareListCriterionBadge stays leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinate keys. leftoverMapAxisTickBadge stays leftover-map leftover-axis origin tick keys. leftoverMapListOriginBadge stays unnamed this increment. Do not invent leftover-map origin from leftover-map item coordinates `ζ`. Do not mix #877. Do not mix #890 stale ADR 0347 / v2.104.0 identity. Stack onto #926. 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. #96 already closed as weaker duplicate of #91. Next buyer increment after this stack: leftoverMapListOriginBadge independently of leftover-map leftover-axis leftover-map origin (ADR 0359 / v2.116.0).
+
> Exact-head loop overlay: 2026-09-03 17:08 KST. Protected `main` is
> `b0e94aa2a6f7a943f96dc5c4f2fdecd0021978a1`. Writes work (MCP comment on #921 + REST close of #96; git X-OAuth-Scopes still empty). Do not
> self-approve. #921 leftover-map comparison graphic leftover-map origin independently of leftover-map graphic leftover-map origin (v2.113.0 / ADR 0356) is
diff --git a/docs/storybook-inventory.md b/docs/storybook-inventory.md
index c4b700d45..f9753f73a 100644
--- a/docs/storybook-inventory.md
+++ b/docs/storybook-inventory.md
@@ -6,7 +6,7 @@ operator-facing control you can click before changing product CSS.
| Story | Operator next action | Token / module |
|---|---|---|
| `Reports/LeftoverMapPlot` | Read the leftover-map graphic display of persisted `ξ` (posts) and `ζ` (criteria), match leftover-map graphic leftover-map post markers to `Open leftover-map post {title} at ξ {person}`, match leftover-map graphic leftover-map criterion markers to `leftover-map criterion {label} at ζ {item}`, match leftover-map graphic leftover-map origin to `leftover-map origin {origin}` when leftoverMapPlotOriginBadge returns a usable leftover-map origin caption, match axis ticks to those coordinates, pair-segment `d` to leftover-map distance, pair-segment `R̂` to leftover-map reconstruction, pair-segment `R̂²/R²` to leftover-map explained leftover share, pair-segment `U²/R²` to leftover-map unexplained leftover share, pair-segment `2R̂U/R²` to leftover-map cross share, pair-segment `U` to leftover-map unexplained leftover, pair-segment `R` to leftover residual, pair-segment `Y` to leftover observed, pair-segment `E` to leftover expected, and pair-segment leftover-map rank, then click a post marker to open that post. Leftover-map axes name persisted leftover-map singular values `σ_k` and leftover-map axis share when finite. The plot names leftover-map complete-case coverage, leftover-map item complete-case coverage, leftover-map incomplete post coverage, and leftover-map incomplete item coverage when persisted. The comparison variant names leftover-map complete-case coverage under `Leftover map comparison graphic coverage` and leftover-map item complete-case coverage under `Leftover map comparison graphic item coverage` and leftover-map incomplete post coverage under `Leftover map comparison graphic incomplete posts` and leftover-map incomplete item coverage under `Leftover map comparison graphic incomplete items` and leftover-map comparison graphic leftover-map criterion markers under `leftover map comparison graphic leftover-map criterion {label} at ζ {item}` and leftover-map comparison graphic leftover-map post markers under `Open leftover map comparison graphic leftover-map post {title} at ξ {person}` and leftover-map comparison graphic leftover-map origin under `leftover map comparison graphic leftover-map origin {origin}` when leftoverMapComparePlotOriginBadge returns a usable leftover-map origin caption. `ClosestAndFarthest`, `RankZeroOrigin`, `MissingCoordinates`, `MissingAxisShare`, `Comparison`, `ComparisonMissingCoverage`, `ComparisonMissingItemCoverage`, `ComparisonMissingIncompletePosts`, and `ComparisonMissingIncompleteItems` cover two-pair maps, rank-0 origin with 0% share, a `0` tick, `d 0.00`, `R̂ 0.00`, `R̂²/R² 0.00`, `U²/R² 0.00`, `2R̂U/R² 0.00`, `U 0.00`, `R 0.00`, `Y 0.00`, `E 0.00`, and `rank 0`, omitted plots, missing share that keeps leftover-map axis `σ` without share, grouping comparison leftover-map graphic coverage that matches leftover map used N of M scored posts, omitted comparison graphic coverage when leftoverMapCoverageCounts fail-closes, grouping comparison leftover-map graphic item coverage that matches leftover map used N of M scored criteria, omitted comparison graphic item coverage when leftoverMapItemCoverageCounts fail-closes, grouping comparison leftover-map graphic incomplete posts that matches leftover map dropped N incomplete posts, omitted comparison graphic incomplete posts when leftoverMapIncompletePostCount fail-closes, grouping comparison leftover-map graphic incomplete items that matches leftover map dropped N incomplete criteria, and omitted comparison graphic incomplete items when leftoverMapIncompleteItemCount fail-closes. The plot does not invent a leftover score. | `LeftoverMapPlot`, `leftoverMapPlotLayout`, `leftoverMapPlotAxisShare`, `--color-primary`, `--color-palette-blue-mid` |
-| `Reports/LeftoverPairList` | Read closest/farthest leftover pairs with named `R`, `Y`/`E`, rank, `U`, `s`, `e`, `x`, `R̂`, `ξ`/`ζ`, and `d`, then open that post. Leftover-map pair leftover-map post name persisted leftover-map person coordinates under `leftover pair leftover-map post {title} at ξ {person}` independently of leftover-map pair leftover-map criterion leftover-map item coordinates when leftoverMapListPostBadge returns a usable leftover-map pair leftover-map post leftover-map person coordinate caption. Leftover-map pair leftover-map post leftover-map origin leftover-map person coordinates name leftover-map origin under `leftover pair leftover-map post {title} at leftover-map origin ξ {person}` when leftoverMapPlotCoordinatePairIsOrigin returns true. Leftover-map pair leftover-map criterion name persisted leftover-map item coordinates under `leftover pair leftover-map criterion {label} at ζ {item}` independently of leftover-map pair leftover-map post leftover-map person coordinates when leftoverMapListCriterionBadge returns a usable leftover-map pair leftover-map criterion leftover-map item coordinate caption. Leftover-map pair leftover-map criterion leftover-map origin leftover-map item coordinates name leftover-map origin under `leftover pair leftover-map criterion {label} at leftover-map origin ζ {item}` when leftoverMapPlotCoordinatePairIsOrigin returns true. The leftover-map graphic display sits above the pair buttons when coordinates are finite, leftover-map axes name persisted leftover-map singular values and leftover-map axis share, leftover-map axis ticks name persisted coordinates, leftover-map graphic leftover-map post markers name persisted leftover-map person coordinates under `Open leftover-map post {title} at ξ {person}`, leftover-map graphic leftover-map criterion markers name persisted leftover-map item coordinates under `leftover-map criterion {label} at ζ {item}`, leftover-axis ticks name persisted leftover-map singular values and leftover-map axis share independently under `leftover axis {axis} tick {value} σ {singular} {share}%`, pair segments name persisted leftover-map distance, pair segments name persisted leftover-map reconstruction, pair segments name persisted leftover-map explained leftover share, pair segments name persisted leftover-map unexplained leftover share, pair segments name persisted leftover-map cross share, pair segments name persisted leftover-map unexplained leftover, pair segments name persisted leftover residual, pair segments name persisted leftover observed, pair segments name persisted leftover expected, and pair segments name persisted leftover-map rank. The pair-list note names leftover-map complete-case coverage only when leftoverMapCoverageCounts returns usable complete-case integers, leftover-map item complete-case coverage, leftover-map incomplete post coverage, and leftover-map incomplete item coverage when persisted. The grouping comparison strip names leftover-map complete-case coverage, leftover-map item complete-case coverage, leftover-map incomplete post coverage, leftover-map incomplete item coverage, leftover-axis report badges with persisted leftover-map singular values under `leftover map comparison leftover axis {axis} σ {value}`, leftover-map comparison leftover-axis leftover-map origin under `leftover map comparison leftover axis leftover-map origin {origin}` when leftoverMapCompareAxisOriginBadge returns a usable leftover-map origin caption, leftover-axis ticks with persisted leftover-map singular values and leftover-map axis share under `leftover map comparison leftover axis {axis} tick {value} σ {singular} {share}%` independently of leftover-map singular values, and leftover-map comparison graphic leftover-map criterion markers under `leftover map comparison graphic leftover-map criterion {label} at ζ {item}` and leftover-map comparison graphic leftover-map post markers under `Open leftover map comparison graphic leftover-map post {title} at ξ {person}` with distinct comparison labels when leftoverMapCoverageCounts / leftoverMapItemCoverageCounts / leftoverMapIncompletePostCount / leftoverMapIncompleteItemCount / leftoverMapCompareAxisBadge / leftoverMapCompareAxisOriginBadge / leftoverMapCompareAxisTickBadge / leftoverMapComparePlotCriterionBadge / leftoverMapComparePlotPostBadge return usable values. Leftover-map comparison leftover-pair leftover-map post name persisted leftover-map person coordinates under `leftover map comparison leftover pair leftover-map post {title} at ξ {person}` independently of leftover-map comparison leftover-pair leftover-map criterion leftover-map item coordinates when leftoverMapCompareListPostBadge returns a usable leftover-map comparison leftover-pair leftover-map post leftover-map person coordinate caption. Leftover-map comparison leftover-pair leftover-map post leftover-map origin leftover-map person coordinates name leftover-map origin under `leftover map comparison leftover pair leftover-map post {title} at leftover-map origin ξ {person}` when leftoverMapPlotCoordinatePairIsOrigin returns true. Leftover-map comparison leftover-pair leftover-map criterion name persisted leftover-map item coordinates under `leftover map comparison leftover pair leftover-map criterion {label} at ζ {item}` independently of leftover-map comparison leftover-pair leftover-map post leftover-map person coordinates when leftoverMapCompareListCriterionBadge returns a usable leftover-map comparison leftover-pair leftover-map criterion leftover-map item coordinate caption. Leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates name leftover-map origin under `leftover map comparison leftover pair leftover-map criterion {label} at leftover-map origin ζ {item}` when leftoverMapPlotCoordinatePairIsOrigin returns true. | `LeftoverPairList`, `LeftoverMapPlot`, `leftoverMapCoordinates`, `ticket-list`, `post-badge` |
+| `Reports/LeftoverPairList` | Read closest/farthest leftover pairs with named `R`, `Y`/`E`, rank, `U`, `s`, `e`, `x`, `R̂`, `ξ`/`ζ`, and `d`, then open that post. Leftover-map pair leftover-map post name persisted leftover-map person coordinates under `leftover pair leftover-map post {title} at ξ {person}` independently of leftover-map pair leftover-map criterion leftover-map item coordinates when leftoverMapListPostBadge returns a usable leftover-map pair leftover-map post leftover-map person coordinate caption. Leftover-map pair leftover-map post leftover-map origin leftover-map person coordinates name leftover-map origin under `leftover pair leftover-map post {title} at leftover-map origin ξ {person}` when leftoverMapPlotCoordinatePairIsOrigin returns true. Leftover-map pair leftover-map criterion name persisted leftover-map item coordinates under `leftover pair leftover-map criterion {label} at ζ {item}` independently of leftover-map pair leftover-map post leftover-map person coordinates when leftoverMapListCriterionBadge returns a usable leftover-map pair leftover-map criterion leftover-map item coordinate caption. Leftover-map pair leftover-map criterion leftover-map origin leftover-map item coordinates name leftover-map origin under `leftover pair leftover-map criterion {label} at leftover-map origin ζ {item}` when leftoverMapPlotCoordinatePairIsOrigin returns true. The leftover-map graphic display sits above the pair buttons when coordinates are finite, leftover-map axes name persisted leftover-map singular values and leftover-map axis share, leftover-map axis ticks name persisted coordinates, leftover-map graphic leftover-map post markers name persisted leftover-map person coordinates under `Open leftover-map post {title} at ξ {person}`, leftover-map graphic leftover-map criterion markers name persisted leftover-map item coordinates under `leftover-map criterion {label} at ζ {item}`, leftover-axis ticks name persisted leftover-map singular values and leftover-map axis share independently under `leftover axis {axis} tick {value} σ {singular} {share}%`, leftover-map leftover-axis leftover-map origin under `leftover axis leftover-map origin {origin}` when leftoverMapAxisOriginBadge returns a usable leftover-map origin caption, pair segments name persisted leftover-map distance, pair segments name persisted leftover-map reconstruction, pair segments name persisted leftover-map explained leftover share, pair segments name persisted leftover-map unexplained leftover share, pair segments name persisted leftover-map cross share, pair segments name persisted leftover-map unexplained leftover, pair segments name persisted leftover residual, pair segments name persisted leftover observed, pair segments name persisted leftover expected, and pair segments name persisted leftover-map rank. The pair-list note names leftover-map complete-case coverage only when leftoverMapCoverageCounts returns usable complete-case integers, leftover-map item complete-case coverage, leftover-map incomplete post coverage, and leftover-map incomplete item coverage when persisted. The grouping comparison strip names leftover-map complete-case coverage, leftover-map item complete-case coverage, leftover-map incomplete post coverage, leftover-map incomplete item coverage, leftover-axis report badges with persisted leftover-map singular values under `leftover map comparison leftover axis {axis} σ {value}`, leftover-map comparison leftover-axis leftover-map origin under `leftover map comparison leftover axis leftover-map origin {origin}` when leftoverMapCompareAxisOriginBadge returns a usable leftover-map origin caption, leftover-map leftover-axis leftover-map origin under `leftover axis leftover-map origin {origin}` when leftoverMapAxisOriginBadge returns a usable leftover-map origin caption, leftover-axis ticks with persisted leftover-map singular values and leftover-map axis share under `leftover map comparison leftover axis {axis} tick {value} σ {singular} {share}%` independently of leftover-map singular values, and leftover-map comparison graphic leftover-map criterion markers under `leftover map comparison graphic leftover-map criterion {label} at ζ {item}` and leftover-map comparison graphic leftover-map post markers under `Open leftover map comparison graphic leftover-map post {title} at ξ {person}` with distinct comparison labels when leftoverMapCoverageCounts / leftoverMapItemCoverageCounts / leftoverMapIncompletePostCount / leftoverMapIncompleteItemCount / leftoverMapCompareAxisBadge / leftoverMapCompareAxisOriginBadge / leftoverMapAxisOriginBadge / leftoverMapCompareAxisTickBadge / leftoverMapComparePlotCriterionBadge / leftoverMapComparePlotPostBadge return usable values. Leftover-map comparison leftover-pair leftover-map post name persisted leftover-map person coordinates under `leftover map comparison leftover pair leftover-map post {title} at ξ {person}` independently of leftover-map comparison leftover-pair leftover-map criterion leftover-map item coordinates when leftoverMapCompareListPostBadge returns a usable leftover-map comparison leftover-pair leftover-map post leftover-map person coordinate caption. Leftover-map comparison leftover-pair leftover-map post leftover-map origin leftover-map person coordinates name leftover-map origin under `leftover map comparison leftover pair leftover-map post {title} at leftover-map origin ξ {person}` when leftoverMapPlotCoordinatePairIsOrigin returns true. Leftover-map comparison leftover-pair leftover-map criterion name persisted leftover-map item coordinates under `leftover map comparison leftover pair leftover-map criterion {label} at ζ {item}` independently of leftover-map comparison leftover-pair leftover-map post leftover-map person coordinates when leftoverMapCompareListCriterionBadge returns a usable leftover-map comparison leftover-pair leftover-map criterion leftover-map item coordinate caption. Leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates name leftover-map origin under `leftover map comparison leftover pair leftover-map criterion {label} at leftover-map origin ζ {item}` when leftoverMapPlotCoordinatePairIsOrigin returns true. | `LeftoverPairList`, `LeftoverMapPlot`, `leftoverMapCoordinates`, `ticket-list`, `post-badge` |
| `Workspace/OperationsDashboard` | Compare Event and post counts, inspect external-information coverage, then open the cited source behind a claim, handover, or repeat-issue fact. `EvidenceReady`, `NarrowViewport`, `AnalysisPendingAndMissingEvidence`, `AnalysisFailed`, and `LoadError` cover populated, mobile, unavailable-evidence, analysis-pending, retryable failure, and transport-error states. | `--color-dashboard-*`, `OperationsDashboard` |
| `Post/SimilarVocPanel` | Compare ontology/semantic similar VOC and prior action evidence, then open the source; unavailable states show no fabricated TEPP theta or weight. | `SimilarVocPanel.css`, `SimilarVocPanel` |
| `Post/Recorded perspectives` | Read the imported primary and every evidence-connected additional Voice with its recorded truth state instead of flattening them into one compound category. `CombinedEvidence`, `RejectedEvidence`, and `NarrowViewport` cover desktop, rejected-evidence, and narrow layouts. | `VoicePerspectiveList`, `ticket-list`, `post-meta` |
diff --git a/frontend/package.json b/frontend/package.json
index 4bc7f60b8..b9ba8569a 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -1,7 +1,7 @@
{
"name": "frontend",
"private": true,
- "version": "2.114.0",
+ "version": "2.115.0",
"type": "module",
"scripts": {
"dev": "vite",
diff --git a/frontend/src/App.test.tsx b/frontend/src/App.test.tsx
index 0def33059..648af53c8 100644
--- a/frontend/src/App.test.tsx
+++ b/frontend/src/App.test.tsx
@@ -4187,8 +4187,10 @@ describe("App, authenticated", () => {
expect(
screen.getByLabelText("leftover map comparison leftover axis leftover-map origin (0.00, 0.00)"),
).toBeInTheDocument();
- expect(screen.queryByText("leftover axis leftover-map origin (0.00, 0.00)")).not.toBeInTheDocument();
- expect(screen.queryByLabelText("leftover axis leftover-map origin (0.00, 0.00)")).not.toBeInTheDocument();
+ expect(screen.getAllByText("leftover axis leftover-map origin (0.00, 0.00)").length).toBeGreaterThan(0);
+ expect(screen.getAllByLabelText("leftover axis leftover-map origin (0.00, 0.00)").length).toBeGreaterThan(0);
+ expect(screen.queryByText("leftover pair leftover-map origin (0.00, 0.00)")).not.toBeInTheDocument();
+ expect(screen.queryByLabelText("leftover pair leftover-map origin (0.00, 0.00)")).not.toBeInTheDocument();
expect(screen.getByText("leftover map comparison leftover axis 1 tick +0.50 σ 1.84 82%")).toBeInTheDocument();
expect(screen.getByText("leftover map comparison leftover axis 2 tick −0.02 σ 0.86 18%")).toBeInTheDocument();
expect(screen.getByText("leftover map comparison leftover axis 1 origin tick 0.00 σ 1.84 82%")).toBeInTheDocument();
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 73ad1f6c4..a1d0ca228 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -144,6 +144,7 @@ import {
import {
leftoverMapCompareAxisBadge,
leftoverMapCompareAxisOriginBadge,
+ leftoverMapAxisOriginBadge,
leftoverMapCompareAxisTickBadge,
leftoverSingularForAxis,
LEFTOVER_MAP_COMPARE_AXIS_CAPTION,
@@ -3954,6 +3955,23 @@ function ReportsPanel({
);
})}
+ {(() => {
+ const originBadge = leftoverMapAxisOriginBadge();
+ const leftoverAxisTicks =
+ layoutLeftoverMapPlot(report.leftover_pairs ?? [], criterionShortLabel)?.ticks ?? [];
+ const leftoverAxisSurface =
+ (report.leftover_map_axes != null && report.leftover_map_axes.length > 0) ||
+ leftoverAxisTicks.length > 0;
+ if (originBadge === null || !leftoverAxisSurface) {
+ return null;
+ }
+ const originText = tf(originBadge.key, originBadge.values);
+ return (
+
+ {originText}
+
+ );
+ })()}
{report.leftover_map_axes?.some(
(axis) =>
leftoverMapAxisBadge(
diff --git a/frontend/src/components/LeftoverMapPlot.tsx b/frontend/src/components/LeftoverMapPlot.tsx
index ec25dd78d..05def6d9d 100644
--- a/frontend/src/components/LeftoverMapPlot.tsx
+++ b/frontend/src/components/LeftoverMapPlot.tsx
@@ -350,6 +350,12 @@ function leftoverMapPlotPostText(
* leftover-map graphic leftover-map origin, leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item
* coordinates, leftover-map axis origin ticks, leftover-map axis share, and leftover-map
* singular values, not this graphic.
+ * ADR 0358 fail-closes leftover-map leftover-axis leftover-map origin through
+ * leftoverMapAxisOriginBadge independently of leftover-map comparison leftover-axis leftover-map origin,
+ * leftover-map comparison graphic leftover-map origin, leftover-map graphic leftover-map origin,
+ * leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item
+ * coordinates, leftover-map axis origin ticks, leftover-map axis share, and leftover-map
+ * singular values, not this graphic.
* Never invent a leftover score.
*/
export function LeftoverMapPlot({
diff --git a/frontend/src/components/LeftoverPairList.tsx b/frontend/src/components/LeftoverPairList.tsx
index 3767b2546..1fe13b6b0 100644
--- a/frontend/src/components/LeftoverPairList.tsx
+++ b/frontend/src/components/LeftoverPairList.tsx
@@ -162,6 +162,8 @@ export type LeftoverPairListProps = {
* not this pair list.
* ADR 0357 captions leftover-map comparison leftover-axis leftover-map origin through leftoverMapCompareAxisOriginBadge,
* not this pair list.
+ * ADR 0358 captions leftover-map leftover-axis leftover-map origin through leftoverMapAxisOriginBadge,
+ * not this pair list.
* Every badge still
* renders together before opening the named post.
*/
diff --git a/frontend/src/i18n.test.ts b/frontend/src/i18n.test.ts
index 6ae7c3ddd..889d806d5 100644
--- a/frontend/src/i18n.test.ts
+++ b/frontend/src/i18n.test.ts
@@ -160,6 +160,7 @@ describe("i18n", () => {
"leftover map comparison leftover axis {axis} origin tick {value} {share}%",
"leftover map comparison leftover axis {axis} origin tick {value} σ {singular} {share}%",
"leftover map comparison leftover axis leftover-map origin {origin}",
+ "leftover axis leftover-map origin {origin}",
"Leftover map comparison leftover axis",
"Leftover map comparison leftover-axis share is Gabriel inertia of residual SVD axes 1 and 2. Open a leftover pair to read the post–criterion cell. The shares do not invent a leftover score.",
"Leftover map comparison coordinates",
@@ -1633,6 +1634,23 @@ describe("i18n", () => {
},
);
+ it.each([
+ ["ko", "잔차 축 원점 (0.00, 0.00)"],
+ ["zh", "残差轴原点 (0.00, 0.00)"],
+ ["ja", "残差軸原点 (0.00, 0.00)"],
+ ["vi", "gốc trục phần dư (0.00, 0.00)"],
+ ] as const)(
+ "formats leftover-map leftover-axis leftover-map origin in %s",
+ (locale, expected) => {
+ setLocale(locale);
+ expect(
+ tf("leftover axis leftover-map origin {origin}", {
+ origin: "(0.00, 0.00)",
+ }),
+ ).toBe(expected);
+ },
+ );
+
it.each([
["ko", "잔여 지도 축 1 원점 눈금 0.00 σ 0.00 0%"],
["zh", "残差图轴 1 原点刻度 0.00 σ 0.00 0%"],
diff --git a/frontend/src/i18n.ts b/frontend/src/i18n.ts
index 0356916f1..8dc85ce92 100644
--- a/frontend/src/i18n.ts
+++ b/frontend/src/i18n.ts
@@ -657,6 +657,7 @@ const TRANSLATIONS: Partial>> = {
"leftover axis {axis} origin tick {value} {share}%": "잔차 축 {axis} 원점 눈금 {value} {share}%",
"leftover axis {axis} origin tick {value} σ {singular} {share}%":
"잔차 축 {axis} 원점 눈금 {value} σ {singular} {share}%",
+ "leftover axis leftover-map origin {origin}": "잔차 축 원점 {origin}",
"Leftover-map axis share": "잔차 지도 축 비율",
"Leftover-map axis share is Gabriel inertia of residual SVD axes 1 and 2. Leftover-map singular values are the Gabriel scale of those axes. Open a leftover pair to read the post–criterion cell. The shares and singular values do not invent a leftover score.":
"잔차 지도 축 비율은 잔차 SVD 축 1과 2의 Gabriel 관성입니다. 잔차 지도 특이값은 그 축의 Gabriel 척도입니다. 글–기준 셀을 읽으려면 잔차 쌍을 여세요. 이 비율과 특이값은 잔차 점수를 만들어내지 않습니다.",
@@ -1395,6 +1396,7 @@ const TRANSLATIONS: Partial>> = {
"leftover axis {axis} origin tick {value} {share}%": "残差轴 {axis} 原点刻度 {value} {share}%",
"leftover axis {axis} origin tick {value} σ {singular} {share}%":
"残差轴 {axis} 原点刻度 {value} σ {singular} {share}%",
+ "leftover axis leftover-map origin {origin}": "残差轴原点 {origin}",
"Leftover-map axis share": "残差图轴占比",
"Leftover-map axis share is Gabriel inertia of residual SVD axes 1 and 2. Leftover-map singular values are the Gabriel scale of those axes. Open a leftover pair to read the post–criterion cell. The shares and singular values do not invent a leftover score.":
"残差图轴占比是残差 SVD 第 1、2 轴的 Gabriel 惯量。残差图奇异值是这些轴的 Gabriel 尺度。打开一个残差配对可查看文章–准则单元格。这些占比和奇异值不会虚构残差分数。",
@@ -2137,6 +2139,7 @@ const TRANSLATIONS: Partial>> = {
"leftover axis {axis} origin tick {value} {share}%": "残差軸 {axis} 原点目盛 {value} {share}%",
"leftover axis {axis} origin tick {value} σ {singular} {share}%":
"残差軸 {axis} 原点目盛 {value} σ {singular} {share}%",
+ "leftover axis leftover-map origin {origin}": "残差軸原点 {origin}",
"Leftover-map axis share": "残差マップ軸の比率",
"Leftover-map axis share is Gabriel inertia of residual SVD axes 1 and 2. Leftover-map singular values are the Gabriel scale of those axes. Open a leftover pair to read the post–criterion cell. The shares and singular values do not invent a leftover score.":
"残差マップ軸の比率は、残差 SVD の第1軸と第2軸の Gabriel 慣性です。残差マップ特異値はそれらの軸の Gabriel 尺度です。投稿–基準セルを読むには残差ペアを開いてください。この比率と特異値から残差スコアを作りません。",
@@ -2883,6 +2886,7 @@ const TRANSLATIONS: Partial>> = {
"leftover axis {axis} origin tick {value} {share}%": "vạch gốc trục phần dư {axis} {value} {share}%",
"leftover axis {axis} origin tick {value} σ {singular} {share}%":
"vạch gốc trục phần dư {axis} {value} σ {singular} {share}%",
+ "leftover axis leftover-map origin {origin}": "gốc trục phần dư {origin}",
"Leftover-map axis share": "Tỷ trọng trục bản đồ phần dư",
"Leftover-map axis share is Gabriel inertia of residual SVD axes 1 and 2. Leftover-map singular values are the Gabriel scale of those axes. Open a leftover pair to read the post–criterion cell. The shares and singular values do not invent a leftover score.":
"Tỷ trọng trục bản đồ phần dư là quán tính Gabriel của các trục SVD phần dư 1 và 2. Giá trị kỳ dị bản đồ phần dư là thang Gabriel của các trục đó. Mở một cặp phần dư để đọc ô bài viết–tiêu chí. Các tỷ trọng và giá trị kỳ dị này không tạo ra điểm phần dư.",
diff --git a/frontend/src/leftoverMapAxisBadge.ts b/frontend/src/leftoverMapAxisBadge.ts
index 78697c40f..85a7d8517 100644
--- a/frontend/src/leftoverMapAxisBadge.ts
+++ b/frontend/src/leftoverMapAxisBadge.ts
@@ -52,6 +52,10 @@
* not this helper.
* ADR 0357 names leftover-map comparison leftover-axis leftover-map origin as leftoverMapCompareAxisOriginBadge,
* not this helper.
+ * ADR 0358 names leftover-map leftover-axis leftover-map origin as leftoverMapAxisOriginBadge,
+ * independently of leftover-map comparison leftover-axis leftover-map origin, leftover-map comparison graphic leftover-map origin,
+ * leftover-map graphic leftover-map origin, leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map
+ * item coordinates, leftover-map axis origin ticks, leftover-map axis share, and leftover-map singular values.
*/
import type { LeftoverMapAxis } from "./api";
diff --git a/frontend/src/leftoverMapCoordinates.ts b/frontend/src/leftoverMapCoordinates.ts
index b42df0923..88972166e 100644
--- a/frontend/src/leftoverMapCoordinates.ts
+++ b/frontend/src/leftoverMapCoordinates.ts
@@ -37,6 +37,8 @@
* graphic leftover-map origin. Do not invent leftover-map origin from leftover-map item coordinates ζ.
* ADR 0357 names leftover-map comparison leftover-axis leftover-map origin as leftoverMapCompareAxisOriginBadge independently of leftover-map
* comparison graphic leftover-map origin. Do not invent leftover-map origin from leftover-map item coordinates ζ.
+ * ADR 0358 names leftover-map leftover-axis leftover-map origin as leftoverMapAxisOriginBadge independently of leftover-map
+ * comparison leftover-axis leftover-map origin. Do not invent leftover-map origin from leftover-map item coordinates ζ.
*/
import { formatSignedLeftoverValue } from "./leftoverMapUnexplained";
@@ -140,6 +142,7 @@ export function formatLeftoverMapCoordinates(
* ADR 0355 names leftover-map graphic leftover-map origin as leftoverMapPlotOriginBadge, not this helper.
* ADR 0356 names leftover-map comparison graphic leftover-map origin as leftoverMapComparePlotOriginBadge, not this helper.
* ADR 0357 names leftover-map comparison leftover-axis leftover-map origin as leftoverMapCompareAxisOriginBadge, not this helper.
+ * ADR 0358 names leftover-map leftover-axis leftover-map origin as leftoverMapAxisOriginBadge, not this helper.
*/
export function leftoverMapListPostBadge(
title: string,
diff --git a/frontend/src/leftoverMapPlotAxisSingular.test.ts b/frontend/src/leftoverMapPlotAxisSingular.test.ts
index b3f8779fb..03089cec6 100644
--- a/frontend/src/leftoverMapPlotAxisSingular.test.ts
+++ b/frontend/src/leftoverMapPlotAxisSingular.test.ts
@@ -9,6 +9,7 @@ import {
leftoverMapPlotOriginBadge,
leftoverMapComparePlotOriginBadge,
leftoverMapCompareAxisOriginBadge,
+ leftoverMapAxisOriginBadge,
leftoverMapPlotTickAxisBadge,
leftoverMapPlotTickIsOrigin,
leftoverSingularForAxis,
@@ -39,6 +40,7 @@ import {
LEFTOVER_MAP_PLOT_ORIGIN,
LEFTOVER_MAP_COMPARE_PLOT_ORIGIN,
LEFTOVER_MAP_COMPARE_AXIS_ORIGIN,
+ LEFTOVER_MAP_AXIS_ORIGIN,
LEFTOVER_MAP_PLOT_ORIGIN_TICK,
LEFTOVER_MAP_PLOT_ORIGIN_TICK_SHARE,
LEFTOVER_MAP_PLOT_ORIGIN_TICK_SINGULAR,
@@ -1122,6 +1124,9 @@ describe("leftover-map comparison graphic leftover-map origin independently of l
expect(leftoverMapComparePlotOriginBadge()?.key).not.toBe(
leftoverMapCompareAxisOriginBadge()?.key,
);
+ expect(leftoverMapComparePlotOriginBadge()?.key).not.toBe(
+ leftoverMapAxisOriginBadge()?.key,
+ );
expect(leftoverMapComparePlotOriginBadge()?.key).not.toBe(
leftoverMapPlotTickAxisBadge(1, "0.00", null).key,
);
@@ -1213,5 +1218,67 @@ describe("leftover-map comparison leftover-axis leftover-map origin independentl
expect(leftoverMapCompareAxisOriginBadge()?.key).not.toBe(
leftoverMapPlotCriterionBadge("sales-lead", 0, 0)?.key ?? "",
);
+ expect(leftoverMapCompareAxisOriginBadge()?.key).not.toBe(leftoverMapAxisOriginBadge()?.key);
+ });
+});
+
+describe("leftover-map leftover-axis leftover-map origin independently of leftover-map comparison leftover-axis leftover-map origin", () => {
+ it("names leftover-map leftover-axis leftover-map origin independently of leftover-map comparison leftover-axis leftover-map origin, leftover-map axis origin ticks, leftover-map axis share, and leftover-map singular values", () => {
+ expect(leftoverMapAxisOriginBadge()).toEqual({
+ key: LEFTOVER_MAP_AXIS_ORIGIN,
+ values: { origin: "(0.00, 0.00)" },
+ });
+ });
+
+ it("names rank-0 leftover-map leftover-axis leftover-map origin (0.00, 0.00)", () => {
+ expect(leftoverMapAxisOriginBadge()?.values.origin).toBe("(0.00, 0.00)");
+ });
+
+ it("does not invent leftover-map leftover-axis leftover-map origin from leftover-map item coordinates, leftover-map axis share, or leftover-map singular values", () => {
+ expect(leftoverMapAxisOriginBadge()?.values).toEqual({ origin: "(0.00, 0.00)" });
+ expect(leftoverMapAxisOriginBadge()?.key).toBe(LEFTOVER_MAP_AXIS_ORIGIN);
+ });
+
+ it("stays distinct from leftover-map comparison leftover-axis leftover-map origin, leftover-map comparison graphic leftover-map origin, leftover-map graphic leftover-map origin, leftover-map graphic leftover-map axis origin ticks, leftover-map comparison graphic leftover-map axis origin ticks, leftover-map comparison leftover-axis origin ticks, leftover-axis origin ticks, leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates, leftover-map pair leftover-map criterion leftover-map origin leftover-map item coordinates, leftover-map comparison graphic leftover-map criterion leftover-map origin leftover-map item coordinates, and leftover-map graphic leftover-map criterion leftover-map origin leftover-map item coordinates", () => {
+ expect(LEFTOVER_MAP_AXIS_ORIGIN).toBe("leftover axis leftover-map origin {origin}");
+ expect(LEFTOVER_MAP_AXIS_ORIGIN).not.toBe(LEFTOVER_MAP_COMPARE_AXIS_ORIGIN);
+ expect(LEFTOVER_MAP_AXIS_ORIGIN).not.toBe(LEFTOVER_MAP_COMPARE_PLOT_ORIGIN);
+ expect(LEFTOVER_MAP_AXIS_ORIGIN).not.toBe(LEFTOVER_MAP_PLOT_ORIGIN);
+ expect(LEFTOVER_MAP_AXIS_ORIGIN).not.toBe(LEFTOVER_MAP_PLOT_ORIGIN_TICK);
+ expect(LEFTOVER_MAP_AXIS_ORIGIN).not.toBe(LEFTOVER_MAP_COMPARE_PLOT_ORIGIN_TICK);
+ expect(LEFTOVER_MAP_AXIS_ORIGIN).not.toBe(LEFTOVER_MAP_COMPARE_AXIS_ORIGIN_TICK);
+ expect(leftoverMapAxisOriginBadge()?.key).not.toBe(leftoverMapCompareAxisOriginBadge()?.key);
+ expect(leftoverMapAxisOriginBadge()?.key).not.toBe(leftoverMapComparePlotOriginBadge()?.key);
+ expect(leftoverMapAxisOriginBadge()?.key).not.toBe(leftoverMapPlotOriginBadge()?.key);
+ expect(leftoverMapAxisOriginBadge()?.key).not.toBe(
+ leftoverMapPlotTickAxisBadge(1, "0.00", null).key,
+ );
+ expect(leftoverMapAxisOriginBadge()?.key).not.toBe(
+ leftoverMapPlotTickAxisBadge(1, "0.00", 0, 0).key,
+ );
+ expect(leftoverMapAxisOriginBadge()?.key).not.toBe(
+ leftoverMapComparePlotTickAxisBadge(1, "0.00", null).key,
+ );
+ expect(leftoverMapAxisOriginBadge()?.key).not.toBe(
+ leftoverMapCompareAxisTickBadge(1, "0.00", null).key,
+ );
+ expect(leftoverMapAxisOriginBadge()?.key).not.toBe(
+ leftoverMapAxisTickBadge(1, "0.00", null).key,
+ );
+ expect(leftoverMapAxisOriginBadge()?.key).not.toBe(
+ leftoverMapPlotAxisBadge(1, 0, 0)?.key,
+ );
+ expect(leftoverMapAxisOriginBadge()?.key).not.toBe(
+ leftoverMapCompareListCriterionBadge("sales-lead", 0, 0)?.key ?? "",
+ );
+ expect(leftoverMapAxisOriginBadge()?.key).not.toBe(
+ leftoverMapListCriterionBadge("sales-lead", 0, 0)?.key ?? "",
+ );
+ expect(leftoverMapAxisOriginBadge()?.key).not.toBe(
+ leftoverMapComparePlotCriterionBadge("sales-lead", 0, 0)?.key ?? "",
+ );
+ expect(leftoverMapAxisOriginBadge()?.key).not.toBe(
+ leftoverMapPlotCriterionBadge("sales-lead", 0, 0)?.key ?? "",
+ );
});
});
diff --git a/frontend/src/leftoverMapPlotAxisSingular.ts b/frontend/src/leftoverMapPlotAxisSingular.ts
index ba94dc8ae..9bf5fc661 100644
--- a/frontend/src/leftoverMapPlotAxisSingular.ts
+++ b/frontend/src/leftoverMapPlotAxisSingular.ts
@@ -76,6 +76,10 @@
* independently of leftover-map comparison graphic leftover-map origin, leftover-map graphic leftover-map origin,
* leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates,
* leftover-map axis origin ticks, leftover-map axis share, and leftover-map singular values.
+ * ADR 0358 names leftover-map leftover-axis leftover-map origin as leftoverMapAxisOriginBadge
+ * independently of leftover-map comparison leftover-axis leftover-map origin, leftover-map comparison graphic leftover-map origin,
+ * leftover-map graphic leftover-map origin, leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map
+ * item coordinates, leftover-map axis origin ticks, leftover-map axis share, and leftover-map singular values.
*/
import type { LeftoverMapAxis } from "./api";
@@ -152,6 +156,9 @@ export const LEFTOVER_MAP_COMPARE_PLOT_ORIGIN =
export const LEFTOVER_MAP_COMPARE_AXIS_ORIGIN =
"leftover map comparison leftover axis leftover-map origin {origin}";
+export const LEFTOVER_MAP_AXIS_ORIGIN =
+ "leftover axis leftover-map origin {origin}";
+
export const LEFTOVER_MAP_COMPARE_AXIS_SINGULAR =
"leftover map comparison leftover axis {axis} σ {value}";
@@ -215,6 +222,11 @@ export type LeftoverMapCompareAxisOriginBadge = {
values: { origin: string };
};
+export type LeftoverMapAxisOriginBadge = {
+ key: string;
+ values: { origin: string };
+};
+
export function leftoverSingularForAxis(
axes: ReadonlyArray | null | undefined,
axisIndex: number,
@@ -263,7 +275,7 @@ export function leftoverMapComparePlotOriginBadge(): LeftoverMapComparePlotOrigi
/** Caption leftover-map comparison leftover-axis leftover-map origin independently of leftover-map comparison graphic leftover-map origin.
* Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`.
- * leftoverMapAxisOriginBadge stays unnamed this increment.
+ * leftoverMapAxisOriginBadge stays leftover-map leftover-axis leftover-map origin keys from ADR 0358.
* Do not invent leftover-map origin from leftover-map item coordinates, leftover-map axis share, or leftover-map singular values.
*/
export function leftoverMapCompareAxisOriginBadge(): LeftoverMapCompareAxisOriginBadge | null {
@@ -274,6 +286,19 @@ export function leftoverMapCompareAxisOriginBadge(): LeftoverMapCompareAxisOrigi
return { key: LEFTOVER_MAP_COMPARE_AXIS_ORIGIN, values: { origin } };
}
+/** Caption leftover-map leftover-axis leftover-map origin independently of leftover-map comparison leftover-axis leftover-map origin.
+ * Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`.
+ * leftoverMapListOriginBadge stays unnamed this increment.
+ * Do not invent leftover-map origin from leftover-map item coordinates, leftover-map axis share, or leftover-map singular values.
+ */
+export function leftoverMapAxisOriginBadge(): LeftoverMapAxisOriginBadge | null {
+ const origin = formatLeftoverMapCoordinatePair(0, 0);
+ if (origin === null) {
+ return null;
+ }
+ return { key: LEFTOVER_MAP_AXIS_ORIGIN, values: { origin } };
+}
+
export function leftoverMapPlotAxisBadge(
axisIndex: number,
leftoverSingular: number | null | undefined,
diff --git a/frontend/src/leftoverMapPlotLayout.ts b/frontend/src/leftoverMapPlotLayout.ts
index 7f9ad378e..e1d053b3f 100644
--- a/frontend/src/leftoverMapPlotLayout.ts
+++ b/frontend/src/leftoverMapPlotLayout.ts
@@ -200,6 +200,10 @@
* ADR 0357 fail-closes leftover-map comparison leftover-axis leftover-map origin through leftoverMapCompareAxisOriginBadge independently of leftover-map
* comparison graphic leftover-map origin, leftover-map graphic leftover-map origin, leftover-map comparison leftover-pair leftover-map
* criterion leftover-map origin leftover-map item coordinates, leftover-map axis origin ticks, leftover-map axis share, and leftover-map singular values.
+ * ADR 0358 fail-closes leftover-map leftover-axis leftover-map origin through leftoverMapAxisOriginBadge independently of leftover-map
+ * comparison leftover-axis leftover-map origin, leftover-map comparison graphic leftover-map origin, leftover-map graphic leftover-map origin,
+ * leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates, leftover-map axis origin ticks,
+ * leftover-map axis share, and leftover-map singular values.
*/
import { formatLeftoverMapCoordinatePair, leftoverMapPlotCoordinatePairIsOrigin } from "./leftoverMapCoordinates";
diff --git a/pyproject.toml b/pyproject.toml
index 4cc6ad3df..54f0ddd99 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "lineageweave"
-version = "2.114.0"
+version = "2.115.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" }