From bcbb7ce03f92304ccdc34fb014a8db8e3bf8a659 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Mon, 31 Aug 2026 09:52:29 +0000 Subject: [PATCH] feat(reports): 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 (v2.99.0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit leftoverMapCompareListCriterionBadge (ADR 0342) names leftover-map comparison leftover-pair leftover-map criterion leftover-map item coordinates independently of leftover-map comparison leftover-pair leftover-map post leftover-map person coordinates. Rank-0 unused axes still name ζ (0.00, 0.00). Do not invent leftover-map item coordinates from ξ. UI-only. No SQL. Never invent a leftover score or a theta. --- AGENTS.md | 16 ++ ARCHITECTURE.md | 3 + ...-map-compare-list-criterion-coordinates.md | 27 +++ CHANGELOG.md | 24 +++ CLAUDE.md | 2 +- docs/adr/0267-leftover-map-coordinates.md | 4 +- .../0302-leftover-map-compare-coordinates.md | 4 +- ...tover-map-compare-list-post-coordinates.md | 3 + ...-map-compare-list-criterion-coordinates.md | 164 ++++++++++++++++++ docs/product-technical-gap-baseline.md | 23 +++ docs/storybook-inventory.md | 2 +- frontend/package.json | 2 +- frontend/src/App.test.tsx | 20 +++ frontend/src/App.tsx | 14 ++ frontend/src/components/LeftoverPairList.tsx | 2 + frontend/src/i18n.test.ts | 1 + frontend/src/i18n.ts | 8 + frontend/src/leftoverMapCoordinates.test.ts | 65 +++++++ frontend/src/leftoverMapCoordinates.ts | 16 ++ frontend/src/leftoverMapPlotLayout.test.ts | 5 +- frontend/src/leftoverMapPlotLayout.ts | 4 + pyproject.toml | 2 +- 22 files changed, 404 insertions(+), 7 deletions(-) create mode 100644 CHANGELOG.d/2.99.0-leftover-map-compare-list-criterion-coordinates.md create mode 100644 docs/adr/0342-leftover-map-compare-list-criterion-coordinates.md diff --git a/AGENTS.md b/AGENTS.md index 9f1f28318..b59185c85 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -814,6 +814,18 @@ person coordinates `(0.00, 0.00)`. Do not invent leftover-map person coordinates post leftover-map person coordinates stay `leftover pair leftover-map post {title} at ξ {person}` this increment. Leftover-map graphic leftover-map post markers stay `Open leftover-map post {title} at ξ {person}` this increment. Leftover-map comparison graphic leftover-map post markers stay `Open leftover map comparison graphic leftover-map post {title} at ξ {person}` this increment. +ADR 0342 captions leftover-map comparison leftover-pair leftover-map criterion with persisted leftover-map +item coordinates when leftoverMapCompareListCriterionBadge returns a usable leftover-map comparison leftover-pair leftover-map criterion leftover-map +item coordinate caption. Distinct accessible name +`leftover map comparison leftover pair leftover-map criterion {label} at ζ {item}`. +A missing or non-finite leftover-map item coordinate pair omits that leftover-map comparison leftover-pair leftover-map criterion leftover-map +item coordinate caption. Rank-0 unused axes still name leftover-map +item coordinates `(0.00, 0.00)`. Do not invent leftover-map item coordinates from leftover-map person coordinates +`ξ`. Do not invent leftover-map person coordinates `ξ` from leftover-map item coordinates `ζ`. Leftover-map comparison leftover-pair leftover-map +post leftover-map person coordinates stay `leftover map comparison leftover pair leftover-map post {title} at ξ {person}` this increment. Leftover-map pair leftover-map +criterion leftover-map item coordinates stay `leftover pair leftover-map criterion {label} at ζ {item}` this increment. Leftover-map graphic leftover-map +criterion markers stay `leftover-map criterion {label} at ζ {item}` this increment. Leftover-map comparison graphic leftover-map +criterion markers stay `leftover map comparison graphic leftover-map criterion {label} at ζ {item}` 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 @@ -983,6 +995,10 @@ Leftover-map comparison leftover-pair leftover-map post leftover-map person coor (ADR 0341) captions leftover-map comparison leftover-pair leftover-map post with persisted leftover-map person 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 criterion leftover-map item coordinates independently of leftover-map comparison leftover-pair leftover-map post leftover-map person coordinates +(ADR 0342) captions leftover-map comparison leftover-pair leftover-map criterion with persisted leftover-map +item coordinates when leftoverMapCompareListCriterionBadge returns a usable leftover-map comparison leftover-pair leftover-map criterion leftover-map +item coordinate 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 85fbab8b1..e2676db12 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -806,6 +806,9 @@ item coordinate caption independently of leftover-map pair leftover-map post lef ADR 0341 captions leftover-map comparison leftover-pair leftover-map post with persisted leftover-map person coordinates when leftoverMapCompareListPostBadge returns a usable leftover-map comparison leftover-pair leftover-map post leftover-map person coordinate caption independently of leftover-map comparison leftover-pair leftover-map criterion leftover-map item coordinates. +ADR 0342 captions leftover-map comparison leftover-pair leftover-map criterion with persisted leftover-map +item coordinates when leftoverMapCompareListCriterionBadge returns a usable leftover-map comparison leftover-pair leftover-map criterion leftover-map +item coordinate caption independently of leftover-map comparison leftover-pair leftover-map post leftover-map person 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 diff --git a/CHANGELOG.d/2.99.0-leftover-map-compare-list-criterion-coordinates.md b/CHANGELOG.d/2.99.0-leftover-map-compare-list-criterion-coordinates.md new file mode 100644 index 000000000..ec3024e44 --- /dev/null +++ b/CHANGELOG.d/2.99.0-leftover-map-compare-list-criterion-coordinates.md @@ -0,0 +1,27 @@ +## 2.99.0 — 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 + +- Caption leftover-map comparison leftover-pair leftover-map criterion with persisted leftover-map + item coordinates through leftoverMapCompareListCriterionBadge independently of leftover-map + comparison leftover-pair leftover-map post leftover-map person coordinates (ADR 0342). After `make seed`, leftover-map comparison leftover-pair leftover-map + criterion name persisted leftover-map item coordinates when leftoverMapCompareListCriterionBadge + returns a usable leftover-map comparison leftover-pair leftover-map criterion leftover-map item coordinate caption; click a leftover pair + or a leftover-map post marker opens that post. A missing or + non-finite leftover-map item coordinate pair omits that leftover-map comparison leftover-pair leftover-map criterion leftover-map + item coordinate caption. + Rank-0 unused + axes still name leftover-map item coordinates `(0.00, 0.00)`. Leftover-map comparison leftover-pair leftover-map + criterion stay + `leftover map comparison leftover pair leftover-map criterion {label} at ζ {item}` + when leftover-map item coordinates are finite so they stay distinct from leftover-map pair leftover-map criterion leftover-map item coordinates + `leftover pair leftover-map criterion {label} at ζ {item}`, leftover-map graphic leftover-map criterion markers + `leftover-map criterion {label} at ζ {item}`, leftover-map comparison graphic leftover-map criterion markers + `leftover map comparison graphic leftover-map criterion {label} at ζ {item}`, and leftover-map comparison leftover-pair leftover-map post leftover-map person coordinates + `leftover map comparison leftover pair leftover-map post {title} at ξ {person}`. Do not invent leftover-map + item coordinates from leftover-map person coordinates `ξ`. Do not invent leftover-map person coordinates `ξ` from leftover-map + item coordinates `ζ`. This increment does not change leftover-map pair leftover-map + post leftover-map person coordinates, leftover-map pair leftover-map criterion leftover-map item coordinates, leftover-map comparison leftover-pair leftover-map + post leftover-map person coordinates, leftover-map graphic leftover-map + post markers, leftover-map comparison graphic leftover-map post markers, leftover-map graphic leftover-map criterion markers, leftover-map comparison graphic leftover-map criterion markers, leftover-axis ticks, leftover-map graphic leftover-map axis ticks, + leftover-map comparison leftover-axis ticks, or leftover-map comparison graphic leftover-map axis ticks. + A finite negative leftover is shown, never clamped. Never invent a leftover score. + Never invent a theta. No new columns. diff --git a/CHANGELOG.md b/CHANGELOG.md index aa27921d7..907517f2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,30 @@ All notable changes to this project are documented here. Format follows ### Added +- Period leftover pairs now caption leftover-map comparison leftover-pair leftover-map + criterion with persisted leftover-map item coordinates through leftoverMapCompareListCriterionBadge + independently of leftover-map comparison leftover-pair leftover-map post leftover-map person coordinates (ADR 0342 / v2.99.0). After `make seed`, + leftover-map comparison leftover-pair leftover-map criterion name persisted leftover-map + item coordinates when leftoverMapCompareListCriterionBadge returns a usable leftover-map comparison leftover-pair leftover-map criterion + leftover-map item coordinate caption; click a leftover pair or a leftover-map post marker + opens that post. A missing or non-finite leftover-map item coordinate pair omits that leftover-map + comparison leftover-pair leftover-map criterion leftover-map item coordinate caption. + Rank-0 unused axes still name leftover-map item coordinates `(0.00, 0.00)`. Leftover-map comparison leftover-pair leftover-map + criterion stay + `leftover map comparison leftover pair leftover-map criterion {label} at ζ {item}` + when leftover-map item coordinates are finite so they stay distinct from leftover-map pair leftover-map criterion leftover-map item coordinates + `leftover pair leftover-map criterion {label} at ζ {item}`, leftover-map graphic leftover-map criterion markers + `leftover-map criterion {label} at ζ {item}`, leftover-map comparison graphic leftover-map criterion markers + `leftover map comparison graphic leftover-map criterion {label} at ζ {item}`, and leftover-map comparison leftover-pair leftover-map post leftover-map person coordinates + `leftover map comparison leftover pair leftover-map post {title} at ξ {person}`. Do not invent leftover-map + item coordinates from leftover-map person coordinates `ξ`. Do not invent leftover-map person coordinates `ξ` from leftover-map + item coordinates `ζ`. This increment does not change leftover-map pair leftover-map + post leftover-map person coordinates, leftover-map pair leftover-map criterion leftover-map item coordinates, leftover-map comparison leftover-pair leftover-map + post leftover-map person coordinates, leftover-map graphic leftover-map + post markers, leftover-map comparison graphic leftover-map post markers, leftover-map graphic leftover-map criterion markers, leftover-map comparison graphic leftover-map criterion markers, leftover-axis ticks, leftover-map graphic leftover-map axis ticks, + leftover-map comparison leftover-axis ticks, or leftover-map comparison graphic leftover-map axis ticks. A finite negative leftover + is shown, never clamped. Never invent a leftover score or a theta. No new columns. + - Period leftover pairs now caption leftover-map comparison leftover-pair leftover-map post with persisted leftover-map person coordinates through leftoverMapCompareListPostBadge independently of leftover-map comparison leftover-pair leftover-map criterion leftover-map item coordinates (ADR 0341 / v2.98.0). After `make seed`, diff --git a/CLAUDE.md b/CLAUDE.md index 12333cbd0..1e7abb757 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), 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), 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/0267-leftover-map-coordinates.md b/docs/adr/0267-leftover-map-coordinates.md index c831be7e8..27f71aa50 100644 --- a/docs/adr/0267-leftover-map-coordinates.md +++ b/docs/adr/0267-leftover-map-coordinates.md @@ -20,7 +20,9 @@ [ADR 0340](0340-leftover-map-list-criterion-coordinates.md) (leftover-map item coordinates on leftover-map pair leftover-map criterion independently of leftover-map pair leftover-map post leftover-map person coordinates); [ADR 0341](0341-leftover-map-compare-list-post-coordinates.md) -(leftover-map person coordinates on leftover-map comparison leftover pair leftover-map post independently of leftover-map comparison leftover pair leftover-map criterion leftover-map item coordinates) +(leftover-map person coordinates on leftover-map comparison leftover pair leftover-map post independently of leftover-map comparison leftover pair leftover-map criterion leftover-map item coordinates); +[ADR 0342](0342-leftover-map-compare-list-criterion-coordinates.md) +(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) Amends [ADR 0048](0048-persist-lsirm-leftover-pairs.md), [ADR 0049](0049-leftover-pair-report-ui.md), and diff --git a/docs/adr/0302-leftover-map-compare-coordinates.md b/docs/adr/0302-leftover-map-compare-coordinates.md index f491691b6..b4f39d5d8 100644 --- a/docs/adr/0302-leftover-map-compare-coordinates.md +++ b/docs/adr/0302-leftover-map-compare-coordinates.md @@ -4,7 +4,9 @@ **Date:** 2026-08-31 **Amended by:** [ADR 0341](0341-leftover-map-compare-list-post-coordinates.md) -(leftover-map person coordinates on leftover-map comparison leftover pair leftover-map post independently of leftover-map comparison leftover pair leftover-map criterion leftover-map item coordinates) +(leftover-map person coordinates on leftover-map comparison leftover pair leftover-map post independently of leftover-map comparison leftover pair leftover-map criterion leftover-map item coordinates); +[ADR 0342](0342-leftover-map-compare-list-criterion-coordinates.md) +(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) Amends leftover pairs on the grouping comparison strip ([ADR 0149](0149-leftover-pairs-on-comparison-strip.md)), leftover-map diff --git a/docs/adr/0341-leftover-map-compare-list-post-coordinates.md b/docs/adr/0341-leftover-map-compare-list-post-coordinates.md index 1045a2986..005c2e488 100644 --- a/docs/adr/0341-leftover-map-compare-list-post-coordinates.md +++ b/docs/adr/0341-leftover-map-compare-list-post-coordinates.md @@ -3,6 +3,9 @@ **Decision status:** Accepted **Date:** 2026-08-31 +**Amended by:** [ADR 0342](0342-leftover-map-compare-list-criterion-coordinates.md) +(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) + Amends leftover-map coordinates ([ADR 0267](0267-leftover-map-coordinates.md)) and leftover-map coordinates on grouping comparison strip pair rows ([ADR 0302](0302-leftover-map-compare-coordinates.md)). Independent of leftover-map diff --git a/docs/adr/0342-leftover-map-compare-list-criterion-coordinates.md b/docs/adr/0342-leftover-map-compare-list-criterion-coordinates.md new file mode 100644 index 000000000..0d7900c55 --- /dev/null +++ b/docs/adr/0342-leftover-map-compare-list-criterion-coordinates.md @@ -0,0 +1,164 @@ +# ADR 0342 — Name 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 + +**Decision status:** Accepted +**Date:** 2026-08-31 + +Amends leftover-map coordinates +([ADR 0267](0267-leftover-map-coordinates.md)) and leftover-map coordinates on grouping comparison strip pair rows +([ADR 0302](0302-leftover-map-compare-coordinates.md)). Independent of leftover-map +person coordinates on leftover-map comparison leftover pair leftover-map post independently of leftover-map comparison leftover pair leftover-map criterion leftover-map item coordinates +([ADR 0341](0341-leftover-map-compare-list-post-coordinates.md)). Independent of leftover-map +item coordinates on leftover-map pair leftover-map criterion independently of leftover-map pair leftover-map post leftover-map person coordinates +([ADR 0340](0340-leftover-map-list-criterion-coordinates.md)). Independent of leftover-map +pair leftover-map post leftover-map person coordinates independently of leftover-map pair leftover-map criterion leftover-map item coordinates +([ADR 0339](0339-leftover-map-list-post-coordinates.md)). Independent of leftover-map +graphic leftover-map post leftover-map person coordinates independently of leftover-map comparison graphic leftover-map post markers +([ADR 0338](0338-leftover-map-plot-post-coordinates.md)). Independent of leftover-map +comparison graphic leftover-map post leftover-map person coordinates independently of leftover-map criterion leftover-map item coordinates +([ADR 0337](0337-leftover-map-compare-plot-post-coordinates.md)). Independent of leftover-map +comparison graphic leftover-map criterion leftover-map item coordinates independently of leftover-map post ξ markers +([ADR 0336](0336-leftover-map-compare-plot-criterion-coordinates.md)). Independent of leftover-map +graphic leftover-map criterion leftover-map item coordinates independently of leftover-map post ξ markers +([ADR 0335](0335-leftover-map-plot-criterion-coordinates.md)). Independent of leftover-map +graphic display ([ADR 0268](0268-leftover-map-graphic-display.md)). Independent of leftover-map +comparison graphic ([ADR 0304](0304-leftover-map-compare-graphic.md)). + +## Context + +ADR 0267 already persists two-axis Gabriel person coordinates +`ξ_{1:2}` and item coordinates `ζ_{1:2}` on leftover pair rows so +`R̂ = ξ_{1:2} · ζ_{1:2}` and `d = ‖ξ_{1:2} − ζ_{1:2}‖` stay +auditable. ADR 0302 already names leftover-map coordinates on grouping +comparison leftover-pair buttons through `formatLeftoverMapCoordinates`, +which requires both leftover-map person coordinates `ξ` and leftover-map +item coordinates `ζ`. ADR 0341 already names leftover-map comparison leftover-pair leftover-map +post leftover-map person coordinates +`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. Grouping comparison leftover-pair leftover-map criterion leftover-map +item coordinates still interpolate leftover-map item coordinates only through +`formatLeftoverMapCoordinates`. A missing or non-finite leftover-map comparison leftover-pair leftover-map post leftover-map +person coordinate pair hides leftover-map comparison leftover-pair leftover-map criterion leftover-map +item coordinates. Rank-0 unused axes still persist leftover-map +item coordinates `(0.00, 0.00)`. A finite negative leftover is shown, never +clamped. Do not invent leftover-map item coordinates from leftover-map person +coordinates `ξ`. Do not invent leftover-map person coordinates `ξ` from leftover-map +item coordinates `ζ`. Leftover-map comparison leftover-pair leftover-map post leftover-map person coordinates stay +`leftover map comparison leftover pair leftover-map post {title} at ξ {person}` +this increment. Leftover-map pair leftover-map criterion leftover-map item coordinates stay +`leftover pair leftover-map criterion {label} at ζ {item}` +this increment. Leftover-map graphic leftover-map criterion markers stay +`leftover-map criterion {label} at ζ {item}` +this increment. Leftover-map comparison graphic leftover-map criterion markers stay +`leftover map comparison graphic leftover-map criterion {label} at ζ {item}` +this increment. + +This increment names leftover-map comparison leftover-pair leftover-map criterion leftover-map +item coordinates as leftoverMapCompareListCriterionBadge, matching leftover-map +pair leftover-map criterion leftover-map item coordinates independently of leftover-map +comparison leftover-pair leftover-map post leftover-map person coordinates. Leftover-map comparison leftover-pair leftover-map +criterion leftover-map item coordinates stay +`leftover map comparison leftover pair leftover-map criterion {label} at ζ {item}` +when leftover-map item coordinates are finite, so they stay distinct from leftover-map +pair leftover-map criterion leftover-map item coordinates +`leftover pair leftover-map criterion {label} at ζ {item}`, +leftover-map graphic leftover-map criterion markers +`leftover-map criterion {label} at ζ {item}`, +leftover-map comparison graphic leftover-map criterion markers +`leftover map comparison graphic leftover-map criterion {label} at ζ {item}`, +and leftover-map comparison leftover-pair leftover-map post leftover-map person coordinates +`leftover map comparison leftover pair leftover-map post {title} at ξ {person}`. +It does not add columns. Do not invent a leftover score. Do not invent a theta. + +This protected increment uses **0342** so it does not collide with leftover-map +person coordinates on leftover-map comparison leftover pair leftover-map post independently of leftover-map comparison leftover pair leftover-map criterion leftover-map item coordinates +(0341), leftover-map item coordinates on leftover-map pair leftover-map criterion independently of leftover-map pair leftover-map post leftover-map person coordinates +(0340), leftover-map pair leftover-map post leftover-map person coordinates independently of leftover-map pair leftover-map criterion leftover-map item coordinates +(0339), leftover-map graphic leftover-map post leftover-map person coordinates independently of leftover-map comparison graphic leftover-map post markers +(0338), leftover-map comparison graphic leftover-map post leftover-map person coordinates independently of leftover-map criterion leftover-map item coordinates +(0337), leftover-map comparison graphic leftover-map criterion leftover-map item coordinates independently of leftover-map post ξ markers +(0336), leftover-map graphic leftover-map criterion leftover-map item coordinates independently of leftover-map post ξ markers +(0335), leftover-map graphic display (0268), leftover-map coordinates (0267), leftover-map coordinates on grouping comparison strip pair rows +(0302), or the dashboard stacks. + +## Decision + +On leftover-map comparison leftover-pair leftover-map criterion, caption leftover-map +item coordinates `ζ_{1:2}` when leftoverMapCompareListCriterionBadge +returns a usable leftover-map comparison leftover-pair leftover-map criterion leftover-map item coordinate caption. +A missing or non-finite leftover-map item coordinate pair omits that leftover-map +comparison leftover-pair leftover-map criterion leftover-map item coordinate caption. Rank-0 unused axes still name leftover-map +item coordinates `(0.00, 0.00)`. Click a leftover pair or a leftover-map +post marker to open that post. Criterion captions are not post buttons. + +Leftover-map comparison leftover-pair leftover-map criterion leftover-map item coordinates omit +independently of leftover-map comparison leftover-pair leftover-map post leftover-map person +coordinates. This increment does not change leftover-map pair leftover-map +post leftover-map person coordinates, leftover-map pair leftover-map criterion leftover-map item coordinates, leftover-map comparison leftover-pair leftover-map +post leftover-map person coordinates, leftover-map graphic leftover-map +post markers, leftover-map comparison graphic leftover-map +post markers, leftover-map graphic leftover-map criterion markers, +leftover-map comparison graphic leftover-map criterion markers, +leftover-axis ticks, leftover-map graphic leftover-map axis ticks, leftover-map +comparison leftover-axis ticks, or leftover-map comparison graphic leftover-map +axis ticks. This increment does not persist leftover-map inner product, cosine, or length. + +Do not add SQL. Do not edit shipped migrations. Do not invent a leftover +score. Do not invent a theta. + +## Consequences + +After `make seed`, leftover-map comparison leftover-pair leftover-map criterion name persisted +leftover-map item coordinates when leftoverMapCompareListCriterionBadge returns a usable +leftover-map comparison leftover-pair leftover-map criterion leftover-map item coordinate caption; click a leftover pair +or a leftover-map post marker opens that post. Hidden posts stay hidden. Rank-0 unused +axes still name leftover-map comparison leftover-pair leftover-map criterion leftover-map item coordinates +`(0.00, 0.00)`. Leftover-map comparison leftover-pair leftover-map post leftover-map person coordinates stay +`leftover map comparison leftover pair leftover-map post {title} at ξ {person}`. Leftover-map pair leftover-map criterion leftover-map item coordinates stay +`leftover pair leftover-map criterion {label} at ζ {item}`. Leftover-map graphic leftover-map criterion markers stay +`leftover-map criterion {label} at ζ {item}`. Leftover-map comparison graphic leftover-map criterion markers stay +`leftover map comparison graphic leftover-map criterion {label} at ζ {item}`. Leftover-map comparison leftover-pair leftover-map post leftover-map person coordinates independently of leftover-map +comparison leftover-pair leftover-map criterion leftover-map item coordinates (ADR 0341), leftover-map pair leftover-map criterion leftover-map item coordinates independently of leftover-map +pair leftover-map post leftover-map person coordinates (ADR 0340), leftover-map pair leftover-map post leftover-map person coordinates independently of leftover-map +pair leftover-map criterion leftover-map item coordinates (ADR 0339), leftover-map graphic leftover-map post leftover-map person coordinates independently of leftover-map +comparison graphic leftover-map post markers (ADR 0338), leftover-map comparison graphic leftover-map post leftover-map person coordinates independently of leftover-map +criterion leftover-map item coordinates (ADR 0337), leftover-map comparison graphic leftover-map criterion leftover-map item coordinates independently of leftover-map +post ξ markers (ADR 0336), leftover-map graphic leftover-map criterion leftover-map item coordinates independently of leftover-map +post ξ markers (ADR 0335), leftover-map graphic display (ADR 0268), leftover-map +coordinates (ADR 0267), and leftover-map coordinates on grouping comparison strip pair rows (ADR 0302) remain. + +## Related + +Independent of leftover-map person coordinates on leftover-map comparison leftover pair leftover-map post independently of leftover-map +comparison leftover pair leftover-map criterion leftover-map item coordinates +([ADR 0341](0341-leftover-map-compare-list-post-coordinates.md)). Independent of leftover-map item coordinates on leftover-map pair leftover-map criterion independently of leftover-map +pair leftover-map post leftover-map person coordinates +([ADR 0340](0340-leftover-map-list-criterion-coordinates.md)). Independent of leftover-map pair leftover-map post leftover-map person coordinates independently of leftover-map +pair leftover-map criterion leftover-map item coordinates +([ADR 0339](0339-leftover-map-list-post-coordinates.md)). Independent of leftover-map graphic leftover-map post leftover-map person coordinates independently of leftover-map +comparison graphic leftover-map post markers +([ADR 0338](0338-leftover-map-plot-post-coordinates.md)). Independent of leftover-map comparison graphic leftover-map post leftover-map person coordinates independently of leftover-map +criterion leftover-map item coordinates +([ADR 0337](0337-leftover-map-compare-plot-post-coordinates.md)). Independent of leftover-map comparison graphic leftover-map criterion leftover-map item coordinates independently of leftover-map +post ξ markers +([ADR 0336](0336-leftover-map-compare-plot-criterion-coordinates.md)). Independent of leftover-map graphic leftover-map criterion leftover-map item coordinates independently of leftover-map +post ξ markers +([ADR 0335](0335-leftover-map-plot-criterion-coordinates.md)). Independent of leftover-map +graphic display ([ADR 0268](0268-leftover-map-graphic-display.md)). Independent of leftover-map +comparison graphic ([ADR 0304](0304-leftover-map-compare-graphic.md)). Independent of leftover-map +coordinates ([ADR 0267](0267-leftover-map-coordinates.md)). Independent of leftover-map +coordinates on grouping comparison strip pair rows +([ADR 0302](0302-leftover-map-compare-coordinates.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 9f6fc6ac7..40c935680 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -1,5 +1,28 @@ # Product & Technical Gap Baseline +> Exact-head loop overlay: 2026-08-31 18:50 KST. Protected `main` is +> `cb187cadee5fb6c46d8a944815ccc154a1e028d1`. Writes work. Do not +> self-approve. #883 leftover-map person coordinates on leftover-map comparison leftover-pair leftover-map +> post independently of leftover-map comparison leftover-pair leftover-map criterion leftover-map item coordinates (v2.98.0 / ADR 0341) is +> `bdd48e2`, stacked on #882 @ `094d1a0`. Independent APPROVE is missing (Devin COMMENTED, +> not APPROVE). Next buyer increment on this cycle: leftover-map comparison leftover-pair leftover-map +> criterion naming persisted leftover-map item coordinates independently of leftover-map +> comparison leftover-pair leftover-map post leftover-map person coordinates (ADR 0342 / v2.99.0) delivered locally on +> `feat/leftover-map-compare-list-criterion-coordinates-v2990`. Caption persisted leftover-map +> item coordinates on leftover-map comparison leftover-pair leftover-map criterion when leftoverMapCompareListCriterionBadge +> returns a usable leftover-map comparison leftover-pair leftover-map criterion leftover-map item coordinate caption. Distinct accessible name +> `leftover map comparison leftover pair leftover-map criterion {label} at ζ {item}`. +> Rank-0 unused axes still name leftover-map item coordinates `(0.00, 0.00)`. A missing or +> non-finite leftover-map item coordinate pair omits independently of leftover-map comparison leftover-pair leftover-map post leftover-map person `ξ`. Leftover-map comparison leftover-pair leftover-map post leftover-map person coordinates stay +> `leftover map comparison leftover pair leftover-map post {title} at ξ {person}` this increment. Leftover-map pair leftover-map criterion leftover-map item coordinates stay +> `leftover pair leftover-map criterion {label} at ζ {item}` this increment. Leftover-map graphic leftover-map criterion markers stay +> `leftover-map criterion {label} at ζ {item}` this increment. Leftover-map comparison graphic leftover-map criterion markers stay +> `leftover map comparison graphic leftover-map criterion {label} at ζ {item}` this increment. Do not invent leftover-map +> item coordinates from leftover-map person coordinates `ξ`. Do not invent leftover-map +> person coordinates `ξ` from leftover-map item coordinates `ζ`. Do not persist leftover-map inner product, cosine, or length. Stack onto #883. +> 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. Do not mix #877. + > Exact-head loop overlay: 2026-08-31 18:45 KST. Protected `main` is > `cb187cadee5fb6c46d8a944815ccc154a1e028d1`. Writes work. Do not > self-approve. #882 leftover-map item coordinates on leftover-map pair leftover-map diff --git a/docs/storybook-inventory.md b/docs/storybook-inventory.md index 970848374..bcea4a2a8 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 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/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 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. 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. | `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 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. 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 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. | `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 7aeceed61..cd5927230 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "frontend", "private": true, - "version": "2.98.0", + "version": "2.99.0", "type": "module", "scripts": { "dev": "vite", diff --git a/frontend/src/App.test.tsx b/frontend/src/App.test.tsx index 209031c70..0dde75a6a 100644 --- a/frontend/src/App.test.tsx +++ b/frontend/src/App.test.tsx @@ -4874,6 +4874,11 @@ describe("App, authenticated", () => { name: /open leftover closest pair from comparison: specification revision requested/i, }), ).not.toHaveTextContent("ξ"); + expect( + screen.getByRole("button", { + name: /open leftover closest pair from comparison: specification revision requested/i, + }), + ).not.toHaveTextContent(/leftover map comparison leftover pair leftover-map criterion/i); expect( screen.getByRole("button", { name: "Compare Business unit (PU): Demo Report High, mean θ 0.81" }), ).toHaveTextContent("mean θ 0.81"); @@ -4943,6 +4948,21 @@ describe("App, authenticated", () => { name: "leftover map comparison leftover pair leftover-map post Public post at ξ (+0.50, +0.10)", }), ).toHaveTextContent("ξ (+0.50, +0.10) ζ (+0.50, −0.02)"); + expect( + screen.getByLabelText( + "leftover map comparison leftover pair leftover-map criterion sales-lead at ζ (+0.50, −0.02)", + ), + ).toBeInTheDocument(); + expect( + screen.getByRole("button", { + name: "leftover map comparison leftover pair leftover-map post Public post at ξ (+0.50, +0.10)", + }), + ).toHaveTextContent( + "leftover map comparison leftover pair leftover-map criterion sales-lead at ζ (+0.50, −0.02)", + ); + expect( + screen.getByLabelText("leftover pair leftover-map criterion sales-lead at ζ (+0.50, −0.02)"), + ).toBeInTheDocument(); expect( screen.getByRole("button", { name: "leftover pair leftover-map post Public post at ξ (+0.50, +0.10)", diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index e766bb42b..03359960d 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -186,6 +186,7 @@ import { } from "./leftoverMapRank"; import { formatLeftoverMapCoordinates, + leftoverMapCompareListCriterionBadge, leftoverMapCompareListPostBadge, LEFTOVER_MAP_COMPARE_COORDINATES_LABEL, } from "./leftoverMapCoordinates"; @@ -4227,6 +4228,11 @@ function ReportsPanel({ pair.leftover_map_person_axis_1, pair.leftover_map_person_axis_2, ); + const listCriterionBadge = leftoverMapCompareListCriterionBadge( + criterion, + pair.leftover_map_item_axis_1, + pair.leftover_map_item_axis_2, + ); return (
  • ) : null} + {listCriterionBadge ? ( + + {tf(listCriterionBadge.key, listCriterionBadge.values)} + + ) : null}
  • ); diff --git a/frontend/src/components/LeftoverPairList.tsx b/frontend/src/components/LeftoverPairList.tsx index ed4a237d2..f08117f44 100644 --- a/frontend/src/components/LeftoverPairList.tsx +++ b/frontend/src/components/LeftoverPairList.tsx @@ -146,6 +146,8 @@ export type LeftoverPairListProps = { * independently of leftover-map pair leftover-map post leftover-map person coordinates. * ADR 0341 captions leftover-map comparison leftover-pair leftover-map post leftover-map person coordinates through leftoverMapCompareListPostBadge, * not this pair list. + * ADR 0342 captions leftover-map comparison leftover-pair leftover-map criterion leftover-map item coordinates through leftoverMapCompareListCriterionBadge, + * 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 6fc3ff2fe..a4a17689b 100644 --- a/frontend/src/i18n.test.ts +++ b/frontend/src/i18n.test.ts @@ -59,6 +59,7 @@ describe("i18n", () => { "leftover pair leftover-map post {title} at ξ {person}", "leftover pair leftover-map criterion {label} at ζ {item}", "leftover map comparison leftover pair leftover-map post {title} at ξ {person}", + "leftover map comparison leftover pair leftover-map criterion {label} at ζ {item}", "Open this post to read the criterion it sat closest to after main effects.", "Open this post to read the criterion it sat farthest from after main effects.", "Leftover map leaves unexplained U {value} after IRT main effects. Open this post to read {criterion}.", diff --git a/frontend/src/i18n.ts b/frontend/src/i18n.ts index bbcee8134..824ac57ef 100644 --- a/frontend/src/i18n.ts +++ b/frontend/src/i18n.ts @@ -649,6 +649,8 @@ const TRANSLATIONS: Partial>> = { "잔여 쌍 잔여 지도 기준 {label} (ζ {item})", "leftover map comparison leftover pair leftover-map post {title} at ξ {person}": "잔여 지도 비교 잔여 쌍 잔여 지도 글 {title} (ξ {person})", + "leftover map comparison leftover pair leftover-map criterion {label} at ζ {item}": + "잔여 지도 비교 잔여 쌍 잔여 지도 기준 {label} (ζ {item})", "Open this post to read the criterion it sat closest to after main effects.": "주효과 이후 가장 가깝게 앉은 기준을 읽으려면 이 글을 여세요.", "Open this post to read the criterion it sat farthest from after main effects.": @@ -1336,6 +1338,8 @@ const TRANSLATIONS: Partial>> = { "残差配对残差图准则 {label}(ζ {item})", "leftover map comparison leftover pair leftover-map post {title} at ξ {person}": "残差图比较残差配对残差图帖子 {title}(ξ {person})", + "leftover map comparison leftover pair leftover-map criterion {label} at ζ {item}": + "残差图比较残差配对残差图准则 {label}(ζ {item})", "Open this post to read the criterion it sat closest to after main effects.": "打开这篇帖子,阅读主效应后距离最近的准则。", "Open this post to read the criterion it sat farthest from after main effects.": @@ -2027,6 +2031,8 @@ const TRANSLATIONS: Partial>> = { "残差ペアの残差マップ基準 {label}(ζ {item})", "leftover map comparison leftover pair leftover-map post {title} at ξ {person}": "残差マップ比較の残差ペアの残差マップ投稿 {title}(ξ {person})", + "leftover map comparison leftover pair leftover-map criterion {label} at ζ {item}": + "残差マップ比較の残差ペアの残差マップ基準 {label}(ζ {item})", "Open this post to read the criterion it sat closest to after main effects.": "主効果後に最も近くなった基準を読むには、この投稿を開いてください。", "Open this post to read the criterion it sat farthest from after main effects.": @@ -2722,6 +2728,8 @@ const TRANSLATIONS: Partial>> = { "Cặp phần dư tiêu chí bản đồ phần dư {label} tại ζ {item}", "leftover map comparison leftover pair leftover-map post {title} at ξ {person}": "Cặp phần dư so sánh bản đồ phần dư bài viết {title} tại ξ {person}", + "leftover map comparison leftover pair leftover-map criterion {label} at ζ {item}": + "Cặp phần dư so sánh bản đồ phần dư tiêu chí {label} tại ζ {item}", "Open this post to read the criterion it sat closest to after main effects.": "Mở bài viết này để đọc tiêu chí nằm gần nhất sau hiệu ứng chính.", "Open this post to read the criterion it sat farthest from after main effects.": diff --git a/frontend/src/leftoverMapCoordinates.test.ts b/frontend/src/leftoverMapCoordinates.test.ts index a02a03412..f1a28c569 100644 --- a/frontend/src/leftoverMapCoordinates.test.ts +++ b/frontend/src/leftoverMapCoordinates.test.ts @@ -13,10 +13,12 @@ import { formatLeftoverMapCoordinatePair, formatLeftoverMapCoordinates, leftoverMapCompareListPostBadge, + leftoverMapCompareListCriterionBadge, leftoverMapListCriterionBadge, leftoverMapListPostBadge, LEFTOVER_MAP_COMPARE_COORDINATES_LABEL, LEFTOVER_MAP_COMPARE_LIST_POST_ACTION, + LEFTOVER_MAP_COMPARE_LIST_CRITERION, LEFTOVER_MAP_LIST_CRITERION, LEFTOVER_MAP_LIST_POST_ACTION, } from "./leftoverMapCoordinates"; @@ -161,6 +163,9 @@ describe("leftoverMapListCriterionBadge", () => { expect(leftoverMapListCriterionBadge("sales-lead", 0.5, -0.02)?.key).not.toBe( leftoverMapListPostBadge("Public post", 0.5, 0.1)?.key ?? "", ); + expect(leftoverMapListCriterionBadge("sales-lead", 0.5, -0.02)?.key).not.toBe( + leftoverMapCompareListCriterionBadge("sales-lead", 0.5, -0.02)?.key ?? "", + ); }); }); @@ -195,6 +200,7 @@ describe("leftoverMapCompareListPostBadge", () => { expect(formatLeftoverMapCoordinates(0.5, 0.1, null, -0.02)).toBeNull(); expect(formatLeftoverMapCoordinates(0.5, 0.1, 0.5, Number.NaN)).toBeNull(); expect(leftoverMapListCriterionBadge("sales-lead", 0.5, -0.02)).not.toBeNull(); + expect(leftoverMapCompareListCriterionBadge("sales-lead", 0.5, -0.02)).not.toBeNull(); }); it("stays distinct from leftover-map pair leftover-map post leftover-map person coordinates, leftover-map graphic leftover-map post markers, and leftover-map comparison graphic leftover-map post markers", () => { @@ -213,5 +219,64 @@ describe("leftoverMapCompareListPostBadge", () => { expect(leftoverMapCompareListPostBadge("Public post", 0.5, 0.1)?.key).not.toBe( leftoverMapComparePlotPostBadge("Public post", 0.5, 0.1)?.key ?? "", ); + expect(leftoverMapCompareListPostBadge("Public post", 0.5, 0.1)?.key).not.toBe( + leftoverMapCompareListCriterionBadge("sales-lead", 0.5, -0.02)?.key ?? "", + ); + }); +}); + +describe("leftoverMapCompareListCriterionBadge", () => { + it("names persisted leftover-map item coordinates without inventing a leftover score", () => { + expect(leftoverMapCompareListCriterionBadge("sales-lead", 0.5, -0.02)).toEqual({ + key: LEFTOVER_MAP_COMPARE_LIST_CRITERION, + values: { label: "sales-lead", item: "(+0.50, \u22120.02)" }, + }); + expect(leftoverMapCompareListCriterionBadge("negative", -0.7, -0.4)).toEqual({ + key: LEFTOVER_MAP_COMPARE_LIST_CRITERION, + values: { label: "negative", item: "(\u22120.70, \u22120.40)" }, + }); + }); + + it("names rank-0 origin leftover-map item coordinates as ζ (0.00, 0.00)", () => { + expect(leftoverMapCompareListCriterionBadge("sales-lead", 0, 0)).toEqual({ + key: LEFTOVER_MAP_COMPARE_LIST_CRITERION, + values: { label: "sales-lead", item: "(0.00, 0.00)" }, + }); + }); + + it("omits leftover-map item coordinates when ζ is missing or non-finite", () => { + expect(leftoverMapCompareListCriterionBadge("sales-lead", null, -0.02)).toBeNull(); + expect(leftoverMapCompareListCriterionBadge("sales-lead", 0.5, undefined)).toBeNull(); + expect(leftoverMapCompareListCriterionBadge("sales-lead", Number.NaN, -0.02)).toBeNull(); + expect(leftoverMapCompareListCriterionBadge("sales-lead", 0.5, Number.POSITIVE_INFINITY)).toBeNull(); + }); + + it("names leftover-map comparison leftover-pair leftover-map criterion leftover-map item coordinates independently of leftover-map comparison leftover-pair leftover-map post leftover-map person coordinates", () => { + expect(leftoverMapCompareListCriterionBadge("sales-lead", 0.5, -0.02)).not.toBeNull(); + expect(formatLeftoverMapCoordinates(null, 0.1, 0.5, -0.02)).toBeNull(); + expect(formatLeftoverMapCoordinates(Number.NaN, 0.1, 0.5, -0.02)).toBeNull(); + expect(leftoverMapCompareListPostBadge("Public post", null, 0.1)).toBeNull(); + }); + + it("stays distinct from leftover-map pair leftover-map criterion leftover-map item coordinates, leftover-map graphic leftover-map criterion markers, leftover-map comparison graphic leftover-map criterion markers, and leftover-map comparison leftover-pair leftover-map post leftover-map person coordinates", () => { + expect(LEFTOVER_MAP_COMPARE_LIST_CRITERION).toBe( + "leftover map comparison leftover pair leftover-map criterion {label} at ζ {item}", + ); + expect(LEFTOVER_MAP_COMPARE_LIST_CRITERION).not.toBe(LEFTOVER_MAP_LIST_CRITERION); + expect(LEFTOVER_MAP_COMPARE_LIST_CRITERION).not.toBe(LEFTOVER_MAP_PLOT_CRITERION); + expect(LEFTOVER_MAP_COMPARE_LIST_CRITERION).not.toBe(LEFTOVER_MAP_COMPARE_PLOT_CRITERION); + expect(LEFTOVER_MAP_COMPARE_LIST_CRITERION).not.toBe(LEFTOVER_MAP_COMPARE_LIST_POST_ACTION); + expect(leftoverMapCompareListCriterionBadge("sales-lead", 0.5, -0.02)?.key).not.toBe( + leftoverMapListCriterionBadge("sales-lead", 0.5, -0.02)?.key ?? "", + ); + expect(leftoverMapCompareListCriterionBadge("sales-lead", 0.5, -0.02)?.key).not.toBe( + leftoverMapPlotCriterionBadge("sales-lead", 0.5, -0.02)?.key ?? "", + ); + expect(leftoverMapCompareListCriterionBadge("sales-lead", 0.5, -0.02)?.key).not.toBe( + leftoverMapComparePlotCriterionBadge("sales-lead", 0.5, -0.02)?.key ?? "", + ); + expect(leftoverMapCompareListCriterionBadge("sales-lead", 0.5, -0.02)?.key).not.toBe( + leftoverMapCompareListPostBadge("Public post", 0.5, 0.1)?.key ?? "", + ); }); }); diff --git a/frontend/src/leftoverMapCoordinates.ts b/frontend/src/leftoverMapCoordinates.ts index 579fbf277..f505ad67e 100644 --- a/frontend/src/leftoverMapCoordinates.ts +++ b/frontend/src/leftoverMapCoordinates.ts @@ -17,6 +17,9 @@ export const LEFTOVER_MAP_LIST_CRITERION = export const LEFTOVER_MAP_COMPARE_LIST_POST_ACTION = "leftover map comparison leftover pair leftover-map post {title} at ξ {person}"; +export const LEFTOVER_MAP_COMPARE_LIST_CRITERION = + "leftover map comparison leftover pair leftover-map criterion {label} at ζ {item}"; + const PERSON_BADGE = "\u03BE"; const ITEM_BADGE = "\u03B6"; @@ -97,3 +100,16 @@ export function leftoverMapCompareListPostBadge( } return { key: LEFTOVER_MAP_COMPARE_LIST_POST_ACTION, values: { title, person } }; } + +/** ADR 0342 leftover-map comparison leftover-pair leftover-map criterion leftover-map item coordinates ζ. */ +export function leftoverMapCompareListCriterionBadge( + label: string, + axis1: number | null | undefined, + axis2: number | null | undefined, +): LeftoverMapListCriterionBadge | null { + const item = formatLeftoverMapCoordinatePair(axis1, axis2); + if (item === null) { + return null; + } + return { key: LEFTOVER_MAP_COMPARE_LIST_CRITERION, values: { label, item } }; +} diff --git a/frontend/src/leftoverMapPlotLayout.test.ts b/frontend/src/leftoverMapPlotLayout.test.ts index 11eadd3d8..d440003dd 100644 --- a/frontend/src/leftoverMapPlotLayout.test.ts +++ b/frontend/src/leftoverMapPlotLayout.test.ts @@ -33,7 +33,7 @@ import { PLOT_PADDING, PLOT_WIDTH, } from "./leftoverMapPlotLayout"; -import { leftoverMapCompareListPostBadge } from "./leftoverMapCoordinates"; +import { leftoverMapCompareListCriterionBadge, leftoverMapCompareListPostBadge } from "./leftoverMapCoordinates"; function pair( overrides: Partial = {}, @@ -1299,6 +1299,9 @@ describe("leftoverMapComparePlotCriterionBadge", () => { expect(leftoverMapComparePlotCriterionBadge("sales-lead", 0.5, -0.02)?.key).not.toBe( LEFTOVER_MAP_COMPARE_PLOT_POST_ACTION, ); + expect(leftoverMapComparePlotCriterionBadge("sales-lead", 0.5, -0.02)?.key).not.toBe( + leftoverMapCompareListCriterionBadge("sales-lead", 0.5, -0.02)?.key ?? "", + ); }); }); diff --git a/frontend/src/leftoverMapPlotLayout.ts b/frontend/src/leftoverMapPlotLayout.ts index dc2039867..74da067e2 100644 --- a/frontend/src/leftoverMapPlotLayout.ts +++ b/frontend/src/leftoverMapPlotLayout.ts @@ -143,6 +143,10 @@ * person coordinates ξ through leftoverMapCompareListPostBadge independently of leftover-map * comparison leftover-pair leftover-map criterion leftover-map item coordinates ζ, not leftover-map * pair-list leftover-map post leftover-map person coordinates. + * ADR 0342 fail-closes leftover-map comparison leftover-pair leftover-map criterion leftover-map + * item coordinates ζ through leftoverMapCompareListCriterionBadge independently of leftover-map + * comparison leftover-pair leftover-map post leftover-map person coordinates ξ, not leftover-map + * pair-list leftover-map criterion leftover-map item coordinates. */ import { formatLeftoverMapCoordinatePair } from "./leftoverMapCoordinates"; diff --git a/pyproject.toml b/pyproject.toml index b1f628c98..8a0596b01 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "lineageweave" -version = "2.98.0" +version = "2.99.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" }