diff --git a/AGENTS.md b/AGENTS.md
index 5046d3148..424852d97 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -629,6 +629,14 @@ and leftover-map comparison graphic incomplete items when those helpers return u
leftover-map distance from plotted coordinates, leftover-map rank, leftover expected, leftover observed, leftover residual, leftover-map unexplained leftover, leftover-map reconstruction, leftover-map axis share, leftover-map post coverage, leftover-map item coverage,
leftover-map incomplete post coverage, leftover-map incomplete item coverage, leftover pair
count, or the count of unused axes.
+ADR 0320 captions leftover-map coordinate ticks on that grouping comparison leftover-map
+graphic from already-named leftover-map coordinates; the origin and each unique finite
+persisted `ξ` / `ζ` projection still name leftover-map comparison graphic leftover-map axis
+ticks. Do not invent evenly spaced leftover-map comparison graphic leftover-map axis ticks
+that no persisted coordinate occupies. Do not invent leftover-map coordinate ticks from leftover-map
+distance, leftover-map rank, leftover expected, leftover observed, leftover residual, leftover-map unexplained leftover, leftover-map reconstruction, leftover-map axis share, leftover-map post coverage, leftover-map item coverage,
+leftover-map incomplete post coverage, leftover-map incomplete item coverage, leftover pair
+count, or the count of unused axes.
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
@@ -721,6 +729,9 @@ when formatLeftoverMapRank returns a usable badge.
Grouping comparison leftover-map distance (ADR 0319) captions
that grouping comparison leftover-map graphic with persisted leftover-map distance
`d` when formatLeftoverMapDistance returns a usable badge.
+Grouping comparison leftover-map coordinate ticks (ADR 0320) captions
+that grouping comparison leftover-map graphic with persisted leftover-map coordinate
+ticks at the origin and at each unique finite `ξ` / `ζ` projection.
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 ab7bf2425..39c96edb6 100644
--- a/ARCHITECTURE.md
+++ b/ARCHITECTURE.md
@@ -746,6 +746,8 @@ badge.
ADR 0319 captions leftover-map distance on that grouping
comparison leftover-map graphic when formatLeftoverMapDistance returns a usable
badge.
+ADR 0320 captions leftover-map coordinate ticks on that grouping
+comparison leftover-map graphic from already-named leftover-map coordinates.
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
@@ -794,7 +796,8 @@ graphic (ADR 0315), leftover observed on the grouping comparison leftover-map
graphic (ADR 0316), leftover expected on the grouping comparison leftover-map
graphic (ADR 0317), leftover-map rank on the grouping comparison leftover-map
graphic (ADR 0318), leftover-map distance on the grouping comparison leftover-map
-graphic (ADR 0319);
+graphic (ADR 0319), leftover-map coordinate ticks on the grouping comparison leftover-map
+graphic (ADR 0320);
`POST .../rebuild` scores every grouping kind (post_admin). `make seed`
folds A-100/B-200 Event Lineage fixtures (and the Riverbend calendar
post) that already have constructed IRT cells into the same shared
diff --git a/CHANGELOG.d/2.77.0-leftover-map-compare-plot-ticks.md b/CHANGELOG.d/2.77.0-leftover-map-compare-plot-ticks.md
new file mode 100644
index 000000000..d7f7cf3ee
--- /dev/null
+++ b/CHANGELOG.d/2.77.0-leftover-map-compare-plot-ticks.md
@@ -0,0 +1,17 @@
+## 2.77.0 — Leftover-map coordinate ticks on grouping comparison leftover-map graphic
+
+- Caption leftover-map coordinate ticks on the grouping comparison leftover-map
+ graphic (ADR 0320). After `make seed`, closest and farthest leftover pairs
+ sit above the member list with leftover-map coordinate ticks on that grouping
+ comparison leftover-map graphic at the origin and at each unique finite
+ persisted `ξ` / `ζ` projection; click a post marker or a pair button opens
+ that post. Rank-0 origin cells still name leftover-map comparison graphic
+ leftover-map axis tick `0.00`. Comparison copy uses
+ `leftover map comparison graphic leftover-map axis {axis} tick {value}` so it
+ stays distinct from `leftover-map axis {axis} tick {value}` and from
+ `leftover map comparison axis {axis} ({share}%)`. Do not invent evenly spaced
+ ticks that no persisted coordinate occupies. This increment does not caption
+ leftover-map singular values on the comparison graphic with a distinct name.
+ Do not invent leftover-map coordinate ticks from leftover-map distance.
+ 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 c9c68f5ab..c1acf56f5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,22 @@ All notable changes to this project are documented here. Format follows
### Added
+- Period leftover pairs now name leftover-map coordinate ticks on the grouping
+ comparison leftover-map graphic (ADR 0320 / v2.77.0). After `make seed`,
+ closest and farthest leftover pairs sit above the member list with leftover-map
+ coordinate ticks on that grouping comparison leftover-map graphic at the origin
+ and at each unique finite persisted `ξ` / `ζ` projection; click a post marker
+ or a pair button opens that post. Rank-0 origin cells still name leftover-map
+ comparison graphic leftover-map axis tick `0.00`. Comparison copy uses
+ `leftover map comparison graphic leftover-map axis {axis} tick {value}` so it
+ stays distinct from `leftover-map axis {axis} tick {value}` and from
+ `leftover map comparison axis {axis} ({share}%)`. Do not invent evenly spaced
+ ticks that no persisted coordinate occupies. This increment does not caption
+ leftover-map singular values on the comparison graphic with a distinct name.
+ Do not invent leftover-map coordinate ticks from leftover-map distance.
+ A finite negative leftover is shown, never clamped. Never invent a leftover
+ score or a theta. No new columns.
+
- Period leftover pairs now name leftover-map distance on the grouping
comparison leftover-map graphic (ADR 0319 / v2.76.0). After `make seed`,
closest and farthest leftover pairs sit above the member list with leftover-map
diff --git a/CLAUDE.md b/CLAUDE.md
index 5a57c0253..cd8a6d9bf 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), 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), 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/0319-leftover-map-compare-plot-distance.md b/docs/adr/0319-leftover-map-compare-plot-distance.md
index 546a2b3c4..5071a4e8b 100644
--- a/docs/adr/0319-leftover-map-compare-plot-distance.md
+++ b/docs/adr/0319-leftover-map-compare-plot-distance.md
@@ -3,6 +3,9 @@
**Decision status:** Accepted
**Date:** 2026-08-31
+**Amended by:** [ADR 0320](0320-leftover-map-compare-plot-ticks.md)
+(leftover-map coordinate ticks on the grouping comparison leftover-map graphic)
+
Amends leftover-map distance on graphic-display pair segments
([ADR 0271](0271-leftover-map-segment-distance.md)), leftover-map rank
on the grouping comparison leftover-map graphic
@@ -12,7 +15,7 @@ on the grouping comparison leftover-map graphic
display on the grouping comparison strip
([ADR 0304](0304-leftover-map-compare-graphic.md)), leftover-map coordinates
([ADR 0267](0267-leftover-map-coordinates.md)). Independent of leftover-map
-coordinate ticks on the grouping comparison leftover-map graphic.
+singular values on the grouping comparison leftover-map graphic.
## Context
@@ -61,9 +64,10 @@ Leftover-map distance omits independently of leftover-map rank captions.
A missing leftover-map distance omits leftover-map comparison graphic leftover-map distance and keeps
a usable leftover-map rank caption.
-This increment does not caption leftover-map coordinate ticks on the comparison graphic
-with a distinct comparison-graphic name. Those ticks already sit on the period-report
-graphic through ADR 0270.
+This increment does not caption leftover-map singular values on the comparison graphic
+with a distinct comparison-graphic name. Leftover-map coordinate ticks on that comparison
+graphic are [ADR 0320](0320-leftover-map-compare-plot-ticks.md). Those ticks already sit
+on the period-report graphic through ADR 0270.
Do not add SQL migrations. Do not edit shipped migrations. Do not invent a leftover
score. Do not invent a theta.
@@ -80,7 +84,7 @@ finite, `R̂ = ξ · ζ` and `d = ‖ξ − ζ‖`.
## Related
-Independent of leftover-map coordinate ticks on the grouping comparison leftover-map graphic.
+Independent of leftover-map singular values on the grouping comparison leftover-map graphic.
## References
diff --git a/docs/adr/0320-leftover-map-compare-plot-ticks.md b/docs/adr/0320-leftover-map-compare-plot-ticks.md
new file mode 100644
index 000000000..b4ba99385
--- /dev/null
+++ b/docs/adr/0320-leftover-map-compare-plot-ticks.md
@@ -0,0 +1,109 @@
+# ADR 0320 — Name leftover-map coordinate ticks on the grouping comparison leftover-map graphic
+
+**Decision status:** Accepted
+**Date:** 2026-08-31
+
+Amends leftover-map coordinate ticks on graphic-display axes
+([ADR 0270](0270-leftover-map-coordinate-ticks.md)), leftover-map distance
+on the grouping comparison leftover-map graphic
+([ADR 0319](0319-leftover-map-compare-plot-distance.md)), leftover-map rank
+on the grouping comparison leftover-map graphic
+([ADR 0318](0318-leftover-map-compare-plot-rank.md)), leftover-map graphic
+display on the grouping comparison strip
+([ADR 0304](0304-leftover-map-compare-graphic.md)), leftover-map coordinates
+([ADR 0267](0267-leftover-map-coordinates.md)). Independent of leftover-map
+singular values on the grouping comparison leftover-map graphic.
+
+## Context
+
+ADR 0267 already persists two-axis Gabriel person coordinates
+`ξ_{1:2}` and item coordinates `ζ_{1:2}` so `R̂ = ξ_{1:2} · ζ_{1:2}`
+and `d = ‖ξ_{1:2} − ζ_{1:2}‖` stay auditable. ADR 0270 already ticks
+period-report leftover-map axes at the origin and at each unique finite
+persisted `ξ` / `ζ` projection under accessible name
+`leftover-map axis {axis} tick {value}`. ADR 0319 already captions
+leftover-map distance on the grouping comparison leftover-map graphic.
+The comparison graphic still reuses `leftover-map axis {axis} tick {value}`,
+so a buyer who compares leftover pairs can treat the period-report graphic
+tick as the comparison graphic leftover-map coordinate even after the strip
+names `ξ` / `ζ`. Hiding a distinct comparison-graphic leftover-map coordinate
+tick lets leftover-map distance `d`, leftover-map rank, or leftover-map axis
+share be read as leftover-map location without a next action. When
+coordinates, reconstruction, and distance are finite, `R̂ = ξ · ζ` and
+`d = ‖ξ − ζ‖`; the comparison graphic must name the same persisted
+coordinates the pair row already shows. A finite negative leftover is shown,
+never clamped.
+
+This increment captions leftover-map coordinate ticks on the grouping
+comparison leftover-map graphic from already-named leftover-map coordinates.
+Comparison copy uses the accessible name
+`leftover map comparison graphic leftover-map axis {axis} tick {value}` so it
+stays distinct from `leftover-map axis {axis} tick {value}` on the
+period-report graphic and from comparison axis-share copy
+`leftover map comparison axis {axis} ({share}%)`. It does not add columns.
+It does not invent evenly spaced ticks that no persisted coordinate occupies.
+Do not invent a leftover score. Do not invent a theta.
+
+This protected increment uses **0320** so it does not collide with leftover-map
+distance on the grouping comparison leftover-map graphic (0319), leftover-map
+rank on that graphic (0318), leftover-map coordinate ticks on pair-segment
+graphic display (0270), leftover-map coordinates (0267), leftover-map graphic
+display (0268), leftover-map axis share on that comparison graphic (0305), or
+the dashboard stacks.
+
+## Decision
+
+On the grouping comparison leftover-map graphic, tick leftover-map axis 1 and
+leftover-map axis 2 at the origin and at each unique finite persisted `ξ` /
+`ζ` coordinate projected onto that axis. Use the distinct accessible name
+`leftover map comparison graphic leftover-map axis {axis} tick {value}` so the
+graphic tick is not the period-report graphic tick
+(`leftover-map axis {axis} tick {value}`) and is not comparison axis-share copy
+(`leftover map comparison axis {axis} ({share}%)`). Tick labels use the same
+signed leftover-map coordinate formatter as the pair-row badge. The origin is
+always named `0` because it is the rank-0 unused-axis location, not a leftover
+score. Duplicate coordinates share one tick. A rank-0 origin cell names only
+`0`; the unit drawing window used to keep that origin visible is drawing scale
+and must not sprout `−1` or `+1` ticks. Do not invent evenly spaced ticks that
+no persisted coordinate occupies. Click a post marker to open that post.
+Criterion markers are not post buttons.
+
+Leftover-map comparison graphic leftover-map axis ticks omit independently of
+leftover-map distance captions. A missing coordinate omits that leftover-map
+comparison graphic leftover-map axis tick and keeps a usable leftover-map
+distance caption, leftover-map rank caption, leftover expected `E`, leftover
+observed `Y`, leftover residual `R`, leftover-map unexplained leftover `U`,
+leftover-map reconstruction `R̂`, leftover-map comparison graphic coverage
+notes, plus the pair-row leftover-map coordinate badge.
+
+This increment does not caption leftover-map singular values on the comparison
+graphic with a distinct comparison-graphic name. Those leftover singular values
+already persist on leftover-map axes through ADR 0148.
+
+Do not add SQL migrations. Do not edit shipped migrations. Do not invent a leftover
+score. Do not invent a theta.
+
+## Consequences
+
+After `make seed`, grouping comparison leftover pairs that already show
+the leftover-map graphic of persisted `ξ` / `ζ` also name leftover-map
+coordinate ticks on that graphic at the origin and at each unique finite
+projection. Rank-0 unused axes still plot at the origin and still name
+leftover-map comparison graphic leftover-map axis tick `0.00`. Click a post
+marker or a pair button opens that post. When coordinates, reconstruction,
+and distance are finite, `R̂ = ξ · ζ` and `d = ‖ξ − ζ‖`.
+
+## Related
+
+Independent of leftover-map singular values on the grouping comparison leftover-map graphic.
+
+## References
+
+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
+
+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
diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md
index c64dab990..75be1a0d4 100644
--- a/docs/product-technical-gap-baseline.md
+++ b/docs/product-technical-gap-baseline.md
@@ -1,5 +1,23 @@
# Product & Technical Gap Baseline
+> Exact-head loop overlay: 2026-08-31 09:28 KST. Protected `main` is
+> `cb187cadee5fb6c46d8a944815ccc154a1e028d1`. Writes work. Do not
+> self-approve. #859 leftover-map distance on the grouping comparison leftover-map
+> graphic (v2.76.0 / ADR 0319) is `9ba8535`, stacked on #858 @ `4b9184f`. Independent
+> APPROVE is missing. Next buyer increment on this
+> cycle: leftover-map coordinate ticks on the grouping comparison leftover-map
+> graphic (ADR 0320 / v2.77.0) delivered locally on
+> `feat/leftover-map-compare-plot-ticks-v2770`. Caption persisted leftover-map
+> coordinate ticks on that comparison graphic from already-named leftover-map
+> coordinates. Distinct accessible name `leftover map comparison graphic leftover-map
+> axis {axis} tick {value}`. Origin and unique finite `ξ` / `ζ` projections only.
+> Do not invent evenly spaced ticks. Do not caption leftover-map singular values
+> on that comparison graphic with a distinct name this increment. Do not invent
+> leftover-map coordinate ticks from leftover-map distance. Stack onto #859.
+> Leave open for independent review. Do not squash-merge. Do not self-approve.
+> Issues #79 and #87 stay open. Do not merge #808 without independent APPROVE.
+> Never self-approve.
+
> Exact-head loop overlay: 2026-08-31 09:25 KST. Protected `main` is
> `cb187cadee5fb6c46d8a944815ccc154a1e028d1`. Writes work. Do not
> self-approve. #858 leftover-map rank on the grouping comparison leftover-map
diff --git a/frontend/package.json b/frontend/package.json
index 3b01a52da..2909efd65 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -1,7 +1,7 @@
{
"name": "frontend",
"private": true,
- "version": "2.76.0",
+ "version": "2.77.0",
"type": "module",
"scripts": {
"dev": "vite",
diff --git a/frontend/src/App.test.tsx b/frontend/src/App.test.tsx
index 7aa7adf09..313feda5b 100644
--- a/frontend/src/App.test.tsx
+++ b/frontend/src/App.test.tsx
@@ -4664,10 +4664,15 @@ describe("App, authenticated", () => {
),
).not.toBeInTheDocument();
expect(
- within(screen.getByLabelText("Grouping comparison")).getAllByLabelText(
- /leftover-map axis \d tick/,
- ).length,
- ).toBeGreaterThan(0);
+ within(screen.getByLabelText("Grouping comparison")).getByLabelText(
+ "leftover map comparison graphic leftover-map axis 1 tick +0.50",
+ ),
+ ).toBeInTheDocument();
+ expect(
+ within(screen.getByLabelText("Grouping comparison")).queryByLabelText(
+ "leftover-map axis 1 tick +0.50",
+ ),
+ ).not.toBeInTheDocument();
expect(
within(screen.getByLabelText("Grouping comparison")).getByLabelText(
"Leftover map comparison coordinates",
diff --git a/frontend/src/components/LeftoverMapPlot.test.tsx b/frontend/src/components/LeftoverMapPlot.test.tsx
index 890df2bb8..e3717a014 100644
--- a/frontend/src/components/LeftoverMapPlot.test.tsx
+++ b/frontend/src/components/LeftoverMapPlot.test.tsx
@@ -2548,4 +2548,158 @@ describe("LeftoverMapPlot", () => {
).toHaveTextContent("E 0.00");
expect(screen.getByText("leftover map comparison axis 1 (0%)")).toBeInTheDocument();
});
+
+ it("names leftover-map coordinate ticks on the comparison graphic with a distinct accessible name", () => {
+ render(
+ ,
+ );
+ expect(
+ screen.getByLabelText("leftover map comparison graphic leftover-map axis 1 tick +0.50"),
+ ).toBeInTheDocument();
+ expect(
+ screen.getByLabelText("leftover map comparison graphic leftover-map axis 2 tick −0.02"),
+ ).toBeInTheDocument();
+ expect(
+ screen.getByLabelText("leftover map comparison graphic leftover-map axis 1 tick 0.00"),
+ ).toBeInTheDocument();
+ expect(screen.queryByLabelText("leftover-map axis 1 tick +0.50")).not.toBeInTheDocument();
+ expect(screen.queryByLabelText("leftover-map axis 2 tick −0.02")).not.toBeInTheDocument();
+ expect(screen.queryByLabelText("leftover-map axis 1 tick 0.00")).not.toBeInTheDocument();
+ expect(
+ screen.getByLabelText("leftover map comparison graphic leftover-map distance d 0.12"),
+ ).toHaveTextContent("d 0.12");
+ expect(
+ screen.getAllByLabelText("leftover map comparison graphic leftover-map rank rank 1"),
+ ).toHaveLength(2);
+ expect(screen.getByText("leftover map comparison axis 1 (82%)")).toBeInTheDocument();
+ });
+
+ it("omits invented leftover-map comparison graphic leftover-map axis ticks that no persisted coordinate occupies", () => {
+ render(
+ ,
+ );
+ expect(
+ screen.getAllByLabelText("leftover map comparison graphic leftover-map axis 1 tick 0.00").length,
+ ).toBeGreaterThan(0);
+ expect(
+ screen.queryByLabelText("leftover map comparison graphic leftover-map axis 1 tick +1.00"),
+ ).not.toBeInTheDocument();
+ expect(screen.queryByLabelText("leftover-map axis 1 tick 0.00")).not.toBeInTheDocument();
+ expect(screen.queryByLabelText("leftover-map axis 1 tick +1.00")).not.toBeInTheDocument();
+ expect(
+ screen.getByLabelText("leftover map comparison graphic leftover-map rank rank 0"),
+ ).toHaveTextContent("rank 0");
+ expect(
+ screen.getByLabelText("leftover map comparison graphic leftover-map distance d 0.00"),
+ ).toHaveTextContent("d 0.00");
+ expect(screen.getByText("leftover map comparison axis 1 (0%)")).toBeInTheDocument();
+ });
+
+ it("names rank-0 origin leftover-map coordinate ticks on the comparison graphic", () => {
+ render(
+ ,
+ );
+ expect(
+ screen.getByLabelText("leftover map comparison graphic leftover-map axis 1 tick 0.00"),
+ ).toBeInTheDocument();
+ expect(
+ screen.getByLabelText("leftover map comparison graphic leftover-map axis 2 tick 0.00"),
+ ).toBeInTheDocument();
+ expect(screen.queryByLabelText("leftover-map axis 1 tick 0.00")).not.toBeInTheDocument();
+ expect(screen.queryByLabelText("leftover-map axis 2 tick 0.00")).not.toBeInTheDocument();
+ expect(
+ screen.getByLabelText("leftover map comparison graphic leftover-map rank rank 0"),
+ ).toHaveTextContent("rank 0");
+ expect(
+ screen.getByLabelText("leftover map comparison graphic leftover expected E 0.00"),
+ ).toHaveTextContent("E 0.00");
+ expect(screen.getByText("leftover map comparison axis 1 (0%)")).toBeInTheDocument();
+ });
});
diff --git a/frontend/src/components/LeftoverMapPlot.tsx b/frontend/src/components/LeftoverMapPlot.tsx
index 692d4ba1f..c0636c65c 100644
--- a/frontend/src/components/LeftoverMapPlot.tsx
+++ b/frontend/src/components/LeftoverMapPlot.tsx
@@ -43,6 +43,7 @@ import {
LEFTOVER_MAP_COMPARE_PLOT_SEGMENT_EXPECTED,
LEFTOVER_MAP_COMPARE_PLOT_SEGMENT_RANK,
LEFTOVER_MAP_COMPARE_PLOT_SEGMENT_DISTANCE,
+ LEFTOVER_MAP_COMPARE_PLOT_TICK,
LEFTOVER_MAP_PLOT_CAPTION,
LEFTOVER_MAP_PLOT_POST_ACTION,
LEFTOVER_MAP_PLOT_SEGMENT_CROSS_SHARE,
@@ -177,6 +178,9 @@ function leftoverMapPlotAxisText(
* labels. ADR 0319 captions leftover-map distance on that
* comparison graphic from already-named leftover-map distance
* with distinct leftover map comparison graphic leftover-map distance
+ * labels. ADR 0320 captions leftover-map coordinate ticks on that
+ * comparison graphic from already-named leftover-map coordinates
+ * with distinct leftover map comparison graphic leftover-map axis tick
* labels.
* Never invent a leftover score.
*/
@@ -305,7 +309,12 @@ export function LeftoverMapPlot({
{
"leftover map comparison graphic leftover-map rank {label}",
"Leftover map comparison rank",
"leftover map comparison graphic leftover-map distance {label}",
+ "leftover map comparison graphic leftover-map axis {axis} tick {value}",
"Leftover map comparison coordinates",
"Leftover map comparison graphic",
"Leftover map comparison",
@@ -669,6 +670,24 @@ describe("i18n", () => {
},
);
+ it.each([
+ ["ko", "잔여 지도 비교 그림 축 1 눈금 +0.50"],
+ ["zh", "残差地图比较图形轴 1 刻度 +0.50"],
+ ["ja", "残差マップの比較図軸 1 目盛 +0.50"],
+ ["vi", "vạch trục đồ họa so sánh bản đồ phần dư 1 +0.50"],
+ ] as const)(
+ "formats leftover map comparison graphic leftover-map axis ticks in %s",
+ (locale, expected) => {
+ setLocale(locale);
+ expect(
+ tf("leftover map comparison graphic leftover-map axis {axis} tick {value}", {
+ axis: 1,
+ value: "+0.50",
+ }),
+ ).toBe(expected);
+ },
+ );
+
it.each([
["ko", "잔여 지도 비교 설명 잔여 점유율"],
["zh", "残差地图比较已解释残差份额"],
diff --git a/frontend/src/i18n.ts b/frontend/src/i18n.ts
index 8bc25651c..e1fa05892 100644
--- a/frontend/src/i18n.ts
+++ b/frontend/src/i18n.ts
@@ -296,6 +296,7 @@ const TRANSLATIONS: Partial>> = {
"leftover map comparison graphic leftover-map rank {label}": "잔여 지도 비교 그림 순위 {label}",
"Leftover map comparison rank": "잔여 지도 비교 순위",
"leftover map comparison graphic leftover-map distance {label}": "잔여 지도 비교 그림 거리 {label}",
+ "leftover map comparison graphic leftover-map axis {axis} tick {value}": "잔여 지도 비교 그림 축 {axis} 눈금 {value}",
"Leftover map comparison coordinates": "잔여 지도 비교 좌표",
"Leftover map comparison graphic": "잔여 지도 비교 그림",
"Leftover map comparison": "잔여 지도 비교",
@@ -938,6 +939,7 @@ const TRANSLATIONS: Partial>> = {
"leftover map comparison graphic leftover-map rank {label}": "残差地图比较图形秩 {label}",
"Leftover map comparison rank": "残差地图比较秩",
"leftover map comparison graphic leftover-map distance {label}": "残差地图比较图形距离 {label}",
+ "leftover map comparison graphic leftover-map axis {axis} tick {value}": "残差地图比较图形轴 {axis} 刻度 {value}",
"Leftover map comparison coordinates": "残差地图比较坐标",
"Leftover map comparison graphic": "残差地图比较图形",
"Leftover map comparison": "残差地图比较",
@@ -1601,6 +1603,7 @@ const TRANSLATIONS: Partial>> = {
"leftover map comparison graphic leftover-map rank {label}": "残差マップの比較図階数 {label}",
"Leftover map comparison rank": "残差マップの比較階数",
"leftover map comparison graphic leftover-map distance {label}": "残差マップの比較図距離 {label}",
+ "leftover map comparison graphic leftover-map axis {axis} tick {value}": "残差マップの比較図軸 {axis} 目盛 {value}",
"Leftover map comparison coordinates": "残差マップの比較座標",
"Leftover map comparison graphic": "残差マップの比較図",
"Leftover map comparison": "残差マップの比較",
@@ -2243,6 +2246,7 @@ const TRANSLATIONS: Partial>> = {
"leftover map comparison graphic leftover-map rank {label}": "hạng đồ họa so sánh bản đồ phần dư {label}",
"Leftover map comparison rank": "Hạng so sánh bản đồ phần dư",
"leftover map comparison graphic leftover-map distance {label}": "khoảng cách đồ họa so sánh bản đồ phần dư {label}",
+ "leftover map comparison graphic leftover-map axis {axis} tick {value}": "vạch trục đồ họa so sánh bản đồ phần dư {axis} {value}",
"Leftover map comparison coordinates": "Tọa độ so sánh bản đồ phần dư",
"Leftover map comparison graphic": "Đồ họa so sánh bản đồ phần dư",
"Leftover map comparison": "So sánh bản đồ phần dư",
diff --git a/frontend/src/leftoverMapPlotLayout.test.ts b/frontend/src/leftoverMapPlotLayout.test.ts
index fdc08a435..d3d5481e0 100644
--- a/frontend/src/leftoverMapPlotLayout.test.ts
+++ b/frontend/src/leftoverMapPlotLayout.test.ts
@@ -17,7 +17,9 @@ import {
LEFTOVER_MAP_COMPARE_PLOT_SEGMENT_EXPECTED,
LEFTOVER_MAP_COMPARE_PLOT_SEGMENT_RANK,
LEFTOVER_MAP_COMPARE_PLOT_SEGMENT_DISTANCE,
+ LEFTOVER_MAP_COMPARE_PLOT_TICK,
LEFTOVER_MAP_COMPARE_PLOT_SVG,
+ LEFTOVER_MAP_PLOT_TICK,
PLOT_HEIGHT,
PLOT_PADDING,
PLOT_WIDTH,
@@ -1352,4 +1354,20 @@ describe("leftover map comparison graphic labels", () => {
LEFTOVER_MAP_COMPARE_PLOT_SEGMENT_RANK,
);
});
+
+ it("stays distinct from leftover-map coordinate tick copy", () => {
+ expect(LEFTOVER_MAP_COMPARE_PLOT_TICK).toBe(
+ "leftover map comparison graphic leftover-map axis {axis} tick {value}",
+ );
+ expect(LEFTOVER_MAP_COMPARE_PLOT_TICK).not.toBe(
+ "leftover-map axis {axis} tick {value}",
+ );
+ expect(LEFTOVER_MAP_COMPARE_PLOT_TICK).not.toBe(LEFTOVER_MAP_PLOT_TICK);
+ expect(LEFTOVER_MAP_COMPARE_PLOT_TICK).not.toBe(
+ "leftover map comparison axis {axis} ({share}%)",
+ );
+ expect(LEFTOVER_MAP_COMPARE_PLOT_TICK).not.toBe(
+ LEFTOVER_MAP_COMPARE_PLOT_SEGMENT_DISTANCE,
+ );
+ });
});
diff --git a/frontend/src/leftoverMapPlotLayout.ts b/frontend/src/leftoverMapPlotLayout.ts
index 103fa63c8..2c86013e5 100644
--- a/frontend/src/leftoverMapPlotLayout.ts
+++ b/frontend/src/leftoverMapPlotLayout.ts
@@ -46,8 +46,9 @@
* residual on that graphic (ADR 0315), and grouping comparison leftover
* observed on that graphic (ADR 0316), and grouping comparison leftover
* expected on that graphic (ADR 0317), and grouping comparison leftover-map
- * rank on that graphic (ADR 0318), and grouping comparison leftover-map
- * distance on that graphic (ADR 0319) caption the pair list or the grouping comparison
+ * rank on that graphic (ADR 0318), grouping comparison leftover-map
+ * distance on that graphic (ADR 0319), and grouping comparison leftover-map
+ * coordinate ticks on that graphic (ADR 0320) caption the pair list or the grouping comparison
* strip. ADR 0304 reuses this graphic layout on the grouping comparison
* strip. ADR 0305 captions leftover-map axis share on that comparison
* graphic from already-named leftover-map axes. ADR 0306 captions leftover-map
@@ -75,6 +76,8 @@
* already-named leftover-map rank.
* ADR 0319 captions leftover-map distance on that comparison graphic from
* already-named leftover-map distance.
+ * ADR 0320 captions leftover-map coordinate ticks on that comparison graphic from
+ * already-named leftover-map coordinates.
*/
import { formatLeftoverMapCoordinatePair } from "./leftoverMapCoordinates";
@@ -107,6 +110,9 @@ export const LEFTOVER_MAP_PLOT_POST_ACTION =
export const LEFTOVER_MAP_PLOT_TICK =
"leftover-map axis {axis} tick {value}";
+export const LEFTOVER_MAP_COMPARE_PLOT_TICK =
+ "leftover map comparison graphic leftover-map axis {axis} tick {value}";
+
export const LEFTOVER_MAP_PLOT_SEGMENT_DISTANCE =
"leftover-map distance {label}";
diff --git a/pyproject.toml b/pyproject.toml
index a373b486b..c1f5188d8 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "lineageweave"
-version = "2.76.0"
+version = "2.77.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" }
diff --git a/uv.lock b/uv.lock
index 09bd29321..2c2ec8c71 100644
--- a/uv.lock
+++ b/uv.lock
@@ -685,7 +685,7 @@ wheels = [
[[package]]
name = "lineageweave"
-version = "2.76.0"
+version = "2.77.0"
source = { editable = "." }
dependencies = [
{ name = "certifi" },