diff --git a/AGENTS.md b/AGENTS.md
index f093d738a..e60e9e23d 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -886,6 +886,11 @@ returns a leftover-map origin leftover-map item coordinate caption independently
`leftover map comparison leftover pair leftover-map criterion {label} at leftover-map origin ζ {item}`. Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`.
Do not invent leftover-map origin from leftover-map person coordinates `ξ`. leftoverMapCompareListPostBadge stays leftover-map comparison leftover-pair leftover-map
post leftover-map origin leftover-map person coordinate keys. leftoverMapListCriterionBadge stays leftover-map pair leftover-map criterion leftover-map origin leftover-map item coordinate keys this increment.
+ADR 0355 captions leftover-map graphic leftover-map origin with leftover-map origin when leftoverMapPlotOriginBadge
+returns a leftover-map origin caption independently of 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 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 `ζ`. leftoverMapCompareListCriterionBadge stays leftover-map comparison leftover-pair leftover-map
+criterion leftover-map origin leftover-map item coordinate keys. leftoverMapPlotTickAxisBadge stays leftover-map graphic leftover-map axis origin tick keys this increment. leftover-map comparison graphic leftover-map origin 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
@@ -1083,6 +1088,8 @@ Leftover-map comparison leftover-pair leftover-map post leftover-map origin left
(ADR 0353) captions leftover-map comparison leftover-pair leftover-map post leftover-map origin leftover-map person coordinates when leftoverMapCompareListPostBadge returns a leftover-map origin leftover-map person coordinate caption.
Leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates independently of leftover-map comparison leftover-pair leftover-map post leftover-map origin leftover-map person coordinates
(ADR 0354) captions leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates when leftoverMapCompareListCriterionBadge returns a leftover-map origin leftover-map item coordinate caption.
+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) captions leftover-map graphic leftover-map origin when leftoverMapPlotOriginBadge 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 053f3c13d..aeaf9ea70 100644
--- a/ARCHITECTURE.md
+++ b/ARCHITECTURE.md
@@ -833,6 +833,8 @@ ADR 0353 captions leftover-map comparison leftover-pair leftover-map post leftov
returns a leftover-map origin leftover-map person coordinate caption independently of leftover-map pair leftover-map post leftover-map origin leftover-map person coordinates.
ADR 0354 captions leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates when leftoverMapCompareListCriterionBadge
returns a leftover-map origin leftover-map item coordinate caption independently of leftover-map comparison leftover-pair leftover-map post leftover-map origin leftover-map person coordinates.
+ADR 0355 captions leftover-map graphic leftover-map origin when leftoverMapPlotOriginBadge
+returns a leftover-map origin caption independently of 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.112.0-leftover-map-plot-origin-badge.md b/CHANGELOG.d/2.112.0-leftover-map-plot-origin-badge.md
new file mode 100644
index 000000000..3fec314e3
--- /dev/null
+++ b/CHANGELOG.d/2.112.0-leftover-map-plot-origin-badge.md
@@ -0,0 +1,14 @@
+## 2.112.0 — Leftover-map origin on leftover-map graphic independently of leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates
+
+- Caption leftover-map graphic leftover-map origin through leftoverMapPlotOriginBadge
+ independently of 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 0355). After `make seed`, leftover-map graphic leftover-map
+ origin names leftover-map origin when leftoverMapPlotOriginBadge returns a usable leftover-map origin caption. Distinct accessible name
+ `leftover-map origin {origin}`. Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`. 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. leftover-map comparison graphic leftover-map origin 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 9a71ba4c8..4f2be3f93 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,18 @@ All notable changes to this project are documented here. Format follows
### Added
+- Period leftover pairs now caption leftover-map graphic leftover-map origin
+ through leftoverMapPlotOriginBadge independently of 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 0355 / v2.112.0). After `make seed`, leftover-map graphic leftover-map
+ origin names leftover-map origin when leftoverMapPlotOriginBadge returns a usable leftover-map origin caption. Distinct accessible name
+ `leftover-map origin {origin}`. Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`. 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. leftover-map comparison graphic leftover-map origin 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-pair leftover-map criterion leftover-map origin leftover-map item coordinates
through leftoverMapCompareListCriterionBadge independently of leftover-map comparison leftover-pair leftover-map post leftover-map origin leftover-map person coordinates (ADR 0354 / v2.111.0). After `make seed`, leftover-map comparison leftover-pair leftover-map
criterion leftover-map origin leftover-map item coordinates name leftover-map origin when leftoverMapPlotCoordinatePairIsOrigin returns true. Distinct accessible name
diff --git a/CLAUDE.md b/CLAUDE.md
index 8205d9587..605efbe56 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), 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), 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/0343-leftover-map-plot-tick-origin-badge.md b/docs/adr/0343-leftover-map-plot-tick-origin-badge.md
index f2c1f24c2..bc3527071 100644
--- a/docs/adr/0343-leftover-map-plot-tick-origin-badge.md
+++ b/docs/adr/0343-leftover-map-plot-tick-origin-badge.md
@@ -4,7 +4,9 @@
**Date:** 2026-08-31
**Amended by:** [ADR 0344](0344-leftover-map-compare-plot-tick-origin-badge.md)
-(leftover-map origin on leftover-map comparison graphic leftover-map axis ticks independently of leftover-map axis share and leftover-map singular values)
+(leftover-map origin on leftover-map comparison graphic leftover-map axis ticks independently of leftover-map axis share and leftover-map singular values);
+[ADR 0355](0355-leftover-map-plot-origin-badge.md)
+(leftover-map origin on leftover-map graphic independently of leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates)
Amends leftover-map coordinate ticks
([ADR 0270](0270-leftover-map-coordinate-ticks.md)), leftover-map graphic leftover-map axis ticks leftover-map singular values
diff --git a/docs/adr/0354-leftover-map-compare-list-criterion-origin-badge.md b/docs/adr/0354-leftover-map-compare-list-criterion-origin-badge.md
index 9245dc9c9..456de135b 100644
--- a/docs/adr/0354-leftover-map-compare-list-criterion-origin-badge.md
+++ b/docs/adr/0354-leftover-map-compare-list-criterion-origin-badge.md
@@ -3,6 +3,9 @@
**Decision status:** Accepted
**Date:** 2026-09-02
+**Amended by:** [ADR 0355](0355-leftover-map-plot-origin-badge.md)
+(leftover-map origin on leftover-map graphic independently of leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates)
+
Amends leftover-map item coordinates on leftover-map comparison leftover pair leftover-map criterion independently of leftover-map comparison leftover pair leftover-map post leftover-map person coordinates
([ADR 0342](0342-leftover-map-compare-list-criterion-coordinates.md)). Independent of leftover-map comparison leftover-pair leftover-map post leftover-map origin leftover-map person coordinates independently of leftover-map pair leftover-map post leftover-map origin leftover-map person coordinates
([ADR 0353](0353-leftover-map-compare-list-post-origin-badge.md)). Independent of leftover-map pair leftover-map criterion leftover-map origin leftover-map item coordinates independently of leftover-map pair leftover-map post leftover-map origin leftover-map person coordinates
diff --git a/docs/adr/0355-leftover-map-plot-origin-badge.md b/docs/adr/0355-leftover-map-plot-origin-badge.md
new file mode 100644
index 000000000..6b8083b67
--- /dev/null
+++ b/docs/adr/0355-leftover-map-plot-origin-badge.md
@@ -0,0 +1,113 @@
+# ADR 0355 — Name leftover-map origin on leftover-map graphic independently of leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates
+
+**Decision status:** Proposed
+**Date:** 2026-09-03
+
+Amends leftover-map origin on leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates independently of leftover-map comparison leftover-pair leftover-map post leftover-map origin leftover-map person coordinates
+([ADR 0354](0354-leftover-map-compare-list-criterion-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)). 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 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 0343 already names leftover-map graphic leftover-map axis origin ticks
+`leftover-map axis {axis} origin tick {value}` when leftoverMapPlotTickIsOrigin returns true.
+Rank-0 unused axes still persist leftover-map origin `0.00`
+(`formatSignedLeftoverValue(0)` emits no plus). Leftover-map origin on leftover-map
+graphic still interpolates leftover-map origin only through leftover-map axis origin tick keys.
+Share and singular omit independently. A finite negative leftover is shown,
+never clamped. Do not invent leftover-map origin from leftover-map comparison leftover-pair leftover-map
+criterion leftover-map origin leftover-map item coordinates `ζ`. 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 graphic leftover-map origin as leftoverMapPlotOriginBadge.
+Leftover-map graphic leftover-map origin stays
+`leftover-map origin {origin}`
+when leftoverMapPlotOriginBadge returns a usable leftover-map origin caption, so it stays distinct from 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)`). leftoverMapComparePlotOriginBadge stays unnamed
+this increment. It does not add columns. Do not invent a leftover score. Do not invent a theta.
+
+This protected increment uses **0355** / **v2.112.0** so it does not collide with leftover-map comparison leftover-pair leftover-map
+criterion leftover-map origin leftover-map item coordinates independently of leftover-map comparison leftover-pair leftover-map post leftover-map origin leftover-map person coordinates
+(0354 / v2.111.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 graphic, caption leftover-map origin
+when leftoverMapPlotOriginBadge 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`.
+leftoverMapCompareListCriterionBadge, leftoverMapListCriterionBadge, leftoverMapComparePlotCriterionBadge, leftoverMapPlotCriterionBadge,
+leftoverMapPlotTickAxisBadge, leftoverMapComparePlotTickAxisBadge, leftoverMapCompareAxisTickBadge, and leftoverMapAxisTickBadge
+do not change leftover-map origin naming this increment. leftover-map comparison graphic leftover-map origin stays unnamed 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 graphic leftover-map origin names
+leftover-map origin independently of 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)`.
+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-pair leftover-map criterion leftover-map origin leftover-map item coordinates independently of leftover-map comparison leftover-pair leftover-map post leftover-map origin leftover-map person coordinates
+(ADR 0354) remain.
+
+## Related
+
+Independent of leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item
+coordinates independently of leftover-map comparison leftover-pair leftover-map post leftover-map origin leftover-map person coordinates
+([ADR 0354](0354-leftover-map-compare-list-criterion-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)). 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)).
+
+## 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 ca12bcc06..eb0d952a2 100644
--- a/docs/product-technical-gap-baseline.md
+++ b/docs/product-technical-gap-baseline.md
@@ -1,5 +1,15 @@
# Product & Technical Gap Baseline
+> Exact-head loop overlay: 2026-09-03 09:15 KST. Protected `main` is
+> `3f61c8242b9c02dec307a7396e83e28f7cdd9f3d`. Writes work (MCP comment + git push). Do not
+> self-approve. #918 leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map
+> item coordinates independently of leftover-map comparison leftover-pair leftover-map post leftover-map origin leftover-map person coordinates (v2.111.0 / ADR 0354) is
+> `a91d2ec`, stacked on #917 @ `8192b485`. Independent APPROVE is missing (Devin COMMENT is
+> not APPROVE). This increment: leftover-map graphic leftover-map origin independently of leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map
+> item coordinates as leftoverMapPlotOriginBadge (ADR 0355 / v2.112.0) on
+> `feat/leftover-map-plot-origin-badge-v21120`. Distinct accessible name
+> `leftover-map origin {origin}`. Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`. 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. leftover-map comparison graphic leftover-map origin 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 #918. 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: leftoverMapComparePlotOriginBadge reconstruction independently of leftover-map graphic leftover-map origin (ADR 0356 / v2.113.0).
+
> Exact-head loop overlay: 2026-09-02 20:20 KST. Protected `main` is
> `3f61c8242b9c02dec307a7396e83e28f7cdd9f3d`. Writes work (MCP comment + git push). Do not
> self-approve. #917 leftover-map comparison leftover-pair leftover-map post leftover-map origin leftover-map
diff --git a/docs/storybook-inventory.md b/docs/storybook-inventory.md
index 66f85cded..ba4362196 100644
--- a/docs/storybook-inventory.md
+++ b/docs/storybook-inventory.md
@@ -5,7 +5,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 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}`. `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/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 does not name leftover-map comparison graphic leftover-map origin this increment. `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-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 / 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` |
diff --git a/frontend/package.json b/frontend/package.json
index 6e52693ba..e7a00b389 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -1,7 +1,7 @@
{
"name": "frontend",
"private": true,
- "version": "2.111.0",
+ "version": "2.112.0",
"type": "module",
"scripts": {
"dev": "vite",
diff --git a/frontend/src/components/LeftoverMapPlot.css b/frontend/src/components/LeftoverMapPlot.css
index 45bfe213e..4c63f9fb0 100644
--- a/frontend/src/components/LeftoverMapPlot.css
+++ b/frontend/src/components/LeftoverMapPlot.css
@@ -73,6 +73,10 @@
stroke-width: 1;
}
+.leftover-map-plot-origin circle {
+ fill: var(--color-text);
+}
+
.leftover-map-plot-tick line {
stroke: var(--color-text);
stroke-width: 1;
diff --git a/frontend/src/components/LeftoverMapPlot.test.tsx b/frontend/src/components/LeftoverMapPlot.test.tsx
index 34740d19f..28539fd38 100644
--- a/frontend/src/components/LeftoverMapPlot.test.tsx
+++ b/frontend/src/components/LeftoverMapPlot.test.tsx
@@ -74,6 +74,7 @@ describe("LeftoverMapPlot", () => {
expect(screen.getByLabelText("leftover-map axis 1 tick +0.50")).toBeInTheDocument();
expect(screen.getByLabelText("leftover-map axis 2 tick −0.02")).toBeInTheDocument();
expect(screen.getByLabelText("leftover-map axis 1 origin tick 0.00")).toBeInTheDocument();
+ expect(screen.getByLabelText("leftover-map origin (0.00, 0.00)")).toBeInTheDocument();
expect(screen.getByLabelText("leftover-map distance d 0.12")).toBeInTheDocument();
expect(screen.getByLabelText("leftover-map distance d 1.84")).toBeInTheDocument();
expect(screen.getByLabelText("leftover-map reconstruction R̂ +0.25")).toBeInTheDocument();
@@ -2848,6 +2849,10 @@ describe("LeftoverMapPlot", () => {
expect(
screen.getByLabelText("leftover map comparison graphic leftover-map axis 1 origin tick 0.00 σ 1.84 82%"),
).toBeInTheDocument();
+ expect(screen.queryByLabelText("leftover-map origin (0.00, 0.00)")).not.toBeInTheDocument();
+ expect(
+ screen.queryByLabelText("leftover map comparison graphic leftover-map origin (0.00, 0.00)"),
+ ).not.toBeInTheDocument();
expect(
screen.queryByLabelText("leftover map comparison graphic leftover-map axis 1 tick +0.50"),
).not.toBeInTheDocument();
diff --git a/frontend/src/components/LeftoverMapPlot.tsx b/frontend/src/components/LeftoverMapPlot.tsx
index c100e0fc9..12db2062b 100644
--- a/frontend/src/components/LeftoverMapPlot.tsx
+++ b/frontend/src/components/LeftoverMapPlot.tsx
@@ -27,6 +27,7 @@ import {
leftoverMapComparePlotAxisBadge,
leftoverMapComparePlotTickAxisBadge,
leftoverMapPlotAxisBadge,
+ leftoverMapPlotOriginBadge,
leftoverMapPlotTickAxisBadge,
leftoverSingularForAxis,
} from "../leftoverMapPlotAxisSingular";
@@ -101,6 +102,17 @@ function leftoverMapPlotAxisText(
return tf(badge.key, badge.values);
}
+function leftoverMapPlotOriginText(variant: LeftoverMapPlotVariant): string | null {
+ if (variant === "comparison") {
+ return null;
+ }
+ const badge = leftoverMapPlotOriginBadge();
+ if (badge === null) {
+ return null;
+ }
+ return tf(badge.key, badge.values);
+}
+
function leftoverMapPlotTickText(
axisIndex: number,
tickLabel: string,
@@ -325,6 +337,10 @@ function leftoverMapPlotPostText(
* ADR 0354 fail-closes leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map
* item coordinates through leftoverMapCompareListCriterionBadge independently of leftover-map
* comparison leftover-pair leftover-map post leftover-map origin leftover-map person coordinates, not this graphic.
+ * ADR 0355 fail-closes leftover-map graphic leftover-map origin through
+ * leftoverMapPlotOriginBadge independently of 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.
* Never invent a leftover score.
*/
export function LeftoverMapPlot({
@@ -343,6 +359,7 @@ export function LeftoverMapPlot({
const itemCoverageCounts = leftoverMapItemCoverageCounts(leftoverMapCoverage);
const incompletePostCount = leftoverMapIncompletePostCount(leftoverMapCoverage);
const incompleteItemCount = leftoverMapIncompleteItemCount(leftoverMapCoverage);
+ const originLabel = leftoverMapPlotOriginText(variant);
const openPost = (postId: string) => {
const pair = firstPlottablePairForPost(pairs, postId);
@@ -448,6 +465,11 @@ export function LeftoverMapPlot({
{leftoverMapPlotAxisText(2, leftoverMapAxes, variant)}
+ {originLabel !== null ? (
+
+
+
+ ) : null}
{layout.ticks.map((tick) => (
{
"leftover-map axis {axis} origin tick {value} σ {singular}",
"leftover-map axis {axis} origin tick {value} {share}%",
"leftover-map axis {axis} origin tick {value} σ {singular} {share}%",
+ "leftover-map origin {origin}",
"leftover-map distance {label}",
"leftover-map reconstruction {label}",
"leftover-map explained leftover share {label}",
@@ -1585,6 +1586,16 @@ describe("i18n", () => {
expect(tf("leftover-map axis {axis} origin tick {value}", { axis: 1, value: "0.00" })).toBe(expected);
});
+ it.each([
+ ["ko", "잔여 지도 원점 (0.00, 0.00)"],
+ ["zh", "残差图原点 (0.00, 0.00)"],
+ ["ja", "残差マップ原点 (0.00, 0.00)"],
+ ["vi", "gốc bản đồ phần dư (0.00, 0.00)"],
+ ] as const)("formats leftover-map graphic leftover-map origin in %s", (locale, expected) => {
+ setLocale(locale);
+ expect(tf("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 84aa84d22..33c0510c6 100644
--- a/frontend/src/i18n.ts
+++ b/frontend/src/i18n.ts
@@ -730,6 +730,7 @@ const TRANSLATIONS: Partial>> = {
"잔여 지도 축 {axis} 원점 눈금 {value} {share}%",
"leftover-map axis {axis} origin tick {value} σ {singular} {share}%":
"잔여 지도 축 {axis} 원점 눈금 {value} σ {singular} {share}%",
+ "leftover-map origin {origin}": "잔여 지도 원점 {origin}",
"leftover-map distance {label}": "잔여 지도 거리 {label}",
"leftover-map reconstruction {label}": "잔여 지도 재구성 {label}",
"leftover-map explained leftover share {label}": "잔여 지도 설명 잔여 점유율 {label}",
@@ -1464,6 +1465,7 @@ const TRANSLATIONS: Partial>> = {
"残差图轴 {axis} 原点刻度 {value} {share}%",
"leftover-map axis {axis} origin tick {value} σ {singular} {share}%":
"残差图轴 {axis} 原点刻度 {value} σ {singular} {share}%",
+ "leftover-map origin {origin}": "残差图原点 {origin}",
"leftover-map distance {label}": "残差图距离 {label}",
"leftover-map reconstruction {label}": "残差图重建 {label}",
"leftover-map explained leftover share {label}": "残差图已解释残差份额 {label}",
@@ -2202,6 +2204,7 @@ const TRANSLATIONS: Partial>> = {
"残差マップ軸 {axis} 原点目盛 {value} {share}%",
"leftover-map axis {axis} origin tick {value} σ {singular} {share}%":
"残差マップ軸 {axis} 原点目盛 {value} σ {singular} {share}%",
+ "leftover-map origin {origin}": "残差マップ原点 {origin}",
"leftover-map distance {label}": "残差マップ距離 {label}",
"leftover-map reconstruction {label}": "残差マップ再構成 {label}",
"leftover-map explained leftover share {label}": "残差マップ説明済み残差割合 {label}",
@@ -2945,6 +2948,7 @@ const TRANSLATIONS: Partial>> = {
"vạch gốc trục bản đồ phần dư {axis} {value} {share}%",
"leftover-map axis {axis} origin tick {value} σ {singular} {share}%":
"vạch gốc trục bản đồ phần dư {axis} {value} σ {singular} {share}%",
+ "leftover-map origin {origin}": "gốc bản đồ phần dư {origin}",
"leftover-map distance {label}": "khoảng cách bản đồ phần dư {label}",
"leftover-map reconstruction {label}": "tái dựng bản đồ phần dư {label}",
"leftover-map explained leftover share {label}": "phần dư giải thích bản đồ phần dư {label}",
diff --git a/frontend/src/leftoverMapAxisBadge.ts b/frontend/src/leftoverMapAxisBadge.ts
index f45c9b22f..28ff23835 100644
--- a/frontend/src/leftoverMapAxisBadge.ts
+++ b/frontend/src/leftoverMapAxisBadge.ts
@@ -46,6 +46,8 @@
* person coordinates as leftoverMapCompareListPostBadge, not this helper.
* ADR 0354 names leftover-map origin on leftover-map comparison leftover-pair leftover-map criterion leftover-map
* item coordinates as leftoverMapCompareListCriterionBadge, not this helper.
+ * ADR 0355 names leftover-map graphic leftover-map origin as leftoverMapPlotOriginBadge,
+ * not this helper.
*/
import type { LeftoverMapAxis } from "./api";
diff --git a/frontend/src/leftoverMapCoordinates.ts b/frontend/src/leftoverMapCoordinates.ts
index 188305002..8a59fd845 100644
--- a/frontend/src/leftoverMapCoordinates.ts
+++ b/frontend/src/leftoverMapCoordinates.ts
@@ -30,6 +30,9 @@
* ADR 0354 names leftover-map origin on leftover-map comparison leftover-pair leftover-map criterion leftover-map
* item coordinates as leftoverMapCompareListCriterionBadge independently of leftover-map comparison leftover-pair leftover-map post leftover-map
* origin leftover-map person coordinates.
+ * ADR 0355 names leftover-map graphic leftover-map origin as leftoverMapPlotOriginBadge independently of leftover-map
+ * comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates. Do not invent leftover-map
+ * origin from leftover-map item coordinates ζ.
*/
import { formatSignedLeftoverValue } from "./leftoverMapUnexplained";
@@ -130,6 +133,7 @@ export function formatLeftoverMapCoordinates(
* person coordinates as leftoverMapCompareListPostBadge, not this helper.
* ADR 0354 names leftover-map origin on leftover-map comparison leftover-pair leftover-map criterion leftover-map
* item coordinates as leftoverMapCompareListCriterionBadge, not this helper.
+ * ADR 0355 names leftover-map graphic leftover-map origin as leftoverMapPlotOriginBadge, not this helper.
*/
export function leftoverMapListPostBadge(
title: string,
diff --git a/frontend/src/leftoverMapPlotAxisSingular.test.ts b/frontend/src/leftoverMapPlotAxisSingular.test.ts
index ba519a87e..cb2a91bf9 100644
--- a/frontend/src/leftoverMapPlotAxisSingular.test.ts
+++ b/frontend/src/leftoverMapPlotAxisSingular.test.ts
@@ -6,6 +6,7 @@ import {
leftoverMapComparePlotAxisBadge,
leftoverMapComparePlotTickAxisBadge,
leftoverMapPlotAxisBadge,
+ leftoverMapPlotOriginBadge,
leftoverMapPlotTickAxisBadge,
leftoverMapPlotTickIsOrigin,
leftoverSingularForAxis,
@@ -33,6 +34,7 @@ import {
LEFTOVER_MAP_COMPARE_PLOT_ORIGIN_TICK_SINGULAR_SHARE,
LEFTOVER_MAP_PLOT_AXIS_SINGULAR,
LEFTOVER_MAP_PLOT_AXIS_SINGULAR_SHARE,
+ LEFTOVER_MAP_PLOT_ORIGIN,
LEFTOVER_MAP_PLOT_ORIGIN_TICK,
LEFTOVER_MAP_PLOT_ORIGIN_TICK_SHARE,
LEFTOVER_MAP_PLOT_ORIGIN_TICK_SINGULAR,
@@ -45,7 +47,8 @@ import {
LEFTOVER_MAP_COMPARE_PLOT_AXIS_SHARE,
LEFTOVER_MAP_PLOT_AXIS_SHARE,
} from "./leftoverMapPlotAxisShare";
-import { LEFTOVER_MAP_COMPARE_PLOT_TICK, LEFTOVER_MAP_PLOT_TICK } from "./leftoverMapPlotLayout";
+import { LEFTOVER_MAP_COMPARE_PLOT_TICK, LEFTOVER_MAP_PLOT_TICK, leftoverMapComparePlotCriterionBadge, leftoverMapPlotCriterionBadge } from "./leftoverMapPlotLayout";
+import { leftoverMapCompareListCriterionBadge, leftoverMapListCriterionBadge } from "./leftoverMapCoordinates";
import { LEFTOVER_MAP_AXIS_BADGE_SINGULAR, LEFTOVER_MAP_AXIS_BADGE_SINGULAR_ONLY, leftoverMapAxisTickBadge } from "./leftoverMapAxisBadge";
describe("leftoverSingularForAxis", () => {
@@ -1030,3 +1033,58 @@ describe("leftover-map comparison leftover-axis tick leftover-map axis share", (
);
});
});
+
+describe("leftover-map graphic leftover-map origin independently of leftover-map comparison leftover-pair leftover-map criterion leftover-map origin leftover-map item coordinates", () => {
+ it("names leftover-map origin independently of leftover-map axis origin ticks, leftover-map axis share, and leftover-map singular values", () => {
+ expect(leftoverMapPlotOriginBadge()).toEqual({
+ key: LEFTOVER_MAP_PLOT_ORIGIN,
+ values: { origin: "(0.00, 0.00)" },
+ });
+ });
+
+ it("names rank-0 leftover-map origin (0.00, 0.00)", () => {
+ expect(leftoverMapPlotOriginBadge()?.values.origin).toBe("(0.00, 0.00)");
+ });
+
+ it("does not invent leftover-map origin from leftover-map item coordinates, leftover-map axis share, or leftover-map singular values", () => {
+ expect(leftoverMapPlotOriginBadge()?.values).toEqual({ origin: "(0.00, 0.00)" });
+ expect(leftoverMapPlotOriginBadge()?.key).toBe(LEFTOVER_MAP_PLOT_ORIGIN);
+ });
+
+ it("stays distinct from 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_PLOT_ORIGIN).toBe("leftover-map origin {origin}");
+ expect(LEFTOVER_MAP_PLOT_ORIGIN).not.toBe(LEFTOVER_MAP_PLOT_ORIGIN_TICK);
+ expect(LEFTOVER_MAP_PLOT_ORIGIN).not.toBe(LEFTOVER_MAP_COMPARE_PLOT_ORIGIN_TICK);
+ expect(LEFTOVER_MAP_PLOT_ORIGIN).not.toBe(LEFTOVER_MAP_COMPARE_AXIS_ORIGIN_TICK);
+ expect(leftoverMapPlotOriginBadge()?.key).not.toBe(
+ leftoverMapPlotTickAxisBadge(1, "0.00", null).key,
+ );
+ expect(leftoverMapPlotOriginBadge()?.key).not.toBe(
+ leftoverMapPlotTickAxisBadge(1, "0.00", 0, 0).key,
+ );
+ expect(leftoverMapPlotOriginBadge()?.key).not.toBe(
+ leftoverMapComparePlotTickAxisBadge(1, "0.00", null).key,
+ );
+ expect(leftoverMapPlotOriginBadge()?.key).not.toBe(
+ leftoverMapCompareAxisTickBadge(1, "0.00", null).key,
+ );
+ expect(leftoverMapPlotOriginBadge()?.key).not.toBe(
+ leftoverMapAxisTickBadge(1, "0.00", null).key,
+ );
+ expect(leftoverMapPlotOriginBadge()?.key).not.toBe(
+ leftoverMapPlotAxisBadge(1, 0, 0)?.key,
+ );
+ expect(leftoverMapPlotOriginBadge()?.key).not.toBe(
+ leftoverMapCompareListCriterionBadge("sales-lead", 0, 0)?.key ?? "",
+ );
+ expect(leftoverMapPlotOriginBadge()?.key).not.toBe(
+ leftoverMapListCriterionBadge("sales-lead", 0, 0)?.key ?? "",
+ );
+ expect(leftoverMapPlotOriginBadge()?.key).not.toBe(
+ leftoverMapComparePlotCriterionBadge("sales-lead", 0, 0)?.key ?? "",
+ );
+ expect(leftoverMapPlotOriginBadge()?.key).not.toBe(
+ leftoverMapPlotCriterionBadge("sales-lead", 0, 0)?.key ?? "",
+ );
+ });
+});
\ No newline at end of file
diff --git a/frontend/src/leftoverMapPlotAxisSingular.ts b/frontend/src/leftoverMapPlotAxisSingular.ts
index 99a542a72..362b3cbde 100644
--- a/frontend/src/leftoverMapPlotAxisSingular.ts
+++ b/frontend/src/leftoverMapPlotAxisSingular.ts
@@ -64,9 +64,14 @@
* ADR 0354 names leftover-map origin on leftover-map comparison leftover-pair leftover-map criterion leftover-map
* item coordinates as leftoverMapCompareListCriterionBadge independently of leftover-map comparison leftover-pair leftover-map post leftover-map
* origin leftover-map person coordinates, not leftoverMapPlotTickAxisBadge.
+ * ADR 0355 names leftover-map graphic leftover-map origin as leftoverMapPlotOriginBadge
+ * independently of 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";
+import { formatLeftoverMapCoordinatePair } from "./leftoverMapCoordinates";
import {
formatLeftoverMapPlotAxisShare,
LEFTOVER_MAP_COMPARE_PLOT_AXIS_SHARE,
@@ -131,6 +136,8 @@ export const LEFTOVER_MAP_COMPARE_PLOT_ORIGIN_TICK_SHARE =
export const LEFTOVER_MAP_COMPARE_PLOT_ORIGIN_TICK_SINGULAR_SHARE =
"leftover map comparison graphic leftover-map axis {axis} origin tick {value} σ {singular} {share}%";
+export const LEFTOVER_MAP_PLOT_ORIGIN = "leftover-map origin {origin}";
+
export const LEFTOVER_MAP_COMPARE_AXIS_SINGULAR =
"leftover map comparison leftover axis {axis} σ {value}";
@@ -179,6 +186,11 @@ export type LeftoverMapCompareAxisBadge = {
values: { axis: number; value?: string; share?: string; singular?: string };
};
+export type LeftoverMapPlotOriginBadge = {
+ key: string;
+ values: { origin: string };
+};
+
export function leftoverSingularForAxis(
axes: ReadonlyArray | null | undefined,
axisIndex: number,
@@ -209,6 +221,14 @@ export function leftoverMapPlotTickIsOrigin(tickLabel: string): boolean {
return originLabel !== null && tickLabel === originLabel;
}
+export function leftoverMapPlotOriginBadge(): LeftoverMapPlotOriginBadge | null {
+ const origin = formatLeftoverMapCoordinatePair(0, 0);
+ if (origin === null) {
+ return null;
+ }
+ return { key: LEFTOVER_MAP_PLOT_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 5d13d8a69..ae3e37af2 100644
--- a/frontend/src/leftoverMapPlotLayout.ts
+++ b/frontend/src/leftoverMapPlotLayout.ts
@@ -191,6 +191,9 @@
* item coordinates through leftoverMapCompareListCriterionBadge independently of leftover-map
* comparison leftover-pair leftover-map post leftover-map origin leftover-map person coordinates ξ, not leftover-map pair leftover-map criterion leftover-map
* item coordinates.
+ * ADR 0355 fail-closes leftover-map graphic leftover-map origin through leftoverMapPlotOriginBadge independently of 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 leftover-map comparison graphic leftover-map origin.
*/
import { formatLeftoverMapCoordinatePair, leftoverMapPlotCoordinatePairIsOrigin } from "./leftoverMapCoordinates";
diff --git a/pyproject.toml b/pyproject.toml
index f70ea4a5f..edc042343 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "lineageweave"
-version = "2.111.0"
+version = "2.112.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" }