From 75598f55b8743ef644a195a35a171afa91715d3d Mon Sep 17 00:00:00 2001 From: seonghobae Date: Tue, 1 Sep 2026 22:42:38 +0000 Subject: [PATCH 1/2] feat(reports): leftover-map origin on leftover-map pair leftover-map post leftover-map person coordinates independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates (v2.108.0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Caption leftover-map pair leftover-map post leftover-map origin leftover-map person coordinates through leftoverMapListPostBadge independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates (ADR 0351). Distinct accessible name leftover pair leftover-map post {title} at leftover-map origin ξ {person} when leftoverMapPlotCoordinatePairIsOrigin returns true. Rank-0 unused axes still name leftover-map origin (0.00, 0.00). leftoverMapComparePlotPostBadge stays leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinate keys. leftoverMapPlotPostBadge stays leftover-map graphic leftover-map post leftover-map origin leftover-map person coordinate keys. Do not invent leftover-map origin from leftover-map item coordinates ζ. Do not mix #877. --- AGENTS.md | 7 ++ ARCHITECTURE.md | 2 + ...8.0-leftover-map-list-post-origin-badge.md | 12 +++ CHANGELOG.md | 13 ++- ...0339-leftover-map-list-post-coordinates.md | 4 +- ...351-leftover-map-list-post-origin-badge.md | 90 +++++++++++++++++++ docs/product-technical-gap-baseline.md | 10 +++ frontend/package.json | 2 +- frontend/src/components/LeftoverMapPlot.tsx | 3 + .../src/components/LeftoverPairList.test.tsx | 7 +- frontend/src/components/LeftoverPairList.tsx | 2 + frontend/src/i18n.test.ts | 20 +++++ frontend/src/i18n.ts | 8 ++ frontend/src/leftoverMapAxisBadge.ts | 2 + frontend/src/leftoverMapCoordinates.test.ts | 36 +++++++- frontend/src/leftoverMapCoordinates.ts | 21 ++++- frontend/src/leftoverMapPlotAxisSingular.ts | 3 + frontend/src/leftoverMapPlotLayout.test.ts | 5 +- frontend/src/leftoverMapPlotLayout.ts | 4 + pyproject.toml | 2 +- 20 files changed, 242 insertions(+), 11 deletions(-) create mode 100644 CHANGELOG.d/2.108.0-leftover-map-list-post-origin-badge.md create mode 100644 docs/adr/0351-leftover-map-list-post-origin-badge.md diff --git a/AGENTS.md b/AGENTS.md index dd1c2c6d7..e3c5b4395 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -866,6 +866,11 @@ returns a leftover-map origin leftover-map item coordinate caption independently `leftover map comparison graphic leftover-map criterion {label} at leftover-map origin ζ {item}`. Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`. Do not invent leftover-map origin from leftover-map person coordinates `ξ`. leftoverMapPlotCriterionBadge stays leftover-map graphic leftover-map criterion leftover-map origin leftover-map item coordinate keys. leftoverMapComparePlotPostBadge stays leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinate keys this increment. +ADR 0351 captions leftover-map pair leftover-map post leftover-map origin leftover-map person coordinates with leftover-map origin when leftoverMapListPostBadge +returns a leftover-map origin leftover-map person coordinate caption independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates. Distinct accessible name +`leftover pair leftover-map post {title} at leftover-map origin ξ {person}`. Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`. +Do not invent leftover-map origin from leftover-map item coordinates `ζ`. leftoverMapComparePlotPostBadge stays leftover-map comparison graphic leftover-map +post leftover-map origin leftover-map person coordinate keys. leftoverMapPlotPostBadge stays leftover-map graphic leftover-map post leftover-map origin leftover-map person coordinate keys 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 @@ -1055,6 +1060,8 @@ Leftover-map comparison graphic leftover-map post leftover-map origin leftover-m (ADR 0349) captions leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates when leftoverMapComparePlotPostBadge returns a leftover-map origin leftover-map person coordinate caption. Leftover-map comparison graphic leftover-map criterion leftover-map origin leftover-map item coordinates independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates (ADR 0350) captions leftover-map comparison graphic leftover-map criterion leftover-map origin leftover-map item coordinates when leftoverMapComparePlotCriterionBadge returns a leftover-map origin leftover-map item coordinate caption. +Leftover-map pair leftover-map post leftover-map origin leftover-map person coordinates independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates +(ADR 0351) captions leftover-map pair leftover-map post leftover-map origin leftover-map person coordinates when leftoverMapListPostBadge returns a leftover-map origin leftover-map person 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 74d2633de..74e92a64b 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -825,6 +825,8 @@ ADR 0349 captions leftover-map comparison graphic leftover-map post leftover-map returns a leftover-map origin leftover-map person coordinate caption independently of leftover-map graphic leftover-map post leftover-map origin leftover-map person coordinates. ADR 0350 captions leftover-map comparison graphic leftover-map criterion leftover-map origin leftover-map item coordinates when leftoverMapComparePlotCriterionBadge returns a leftover-map origin leftover-map item coordinate caption independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates. +ADR 0351 captions leftover-map pair leftover-map post leftover-map origin leftover-map person coordinates when leftoverMapListPostBadge +returns a leftover-map origin leftover-map person coordinate caption independently of leftover-map comparison graphic leftover-map post leftover-map origin 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.108.0-leftover-map-list-post-origin-badge.md b/CHANGELOG.d/2.108.0-leftover-map-list-post-origin-badge.md new file mode 100644 index 000000000..51bb70350 --- /dev/null +++ b/CHANGELOG.d/2.108.0-leftover-map-list-post-origin-badge.md @@ -0,0 +1,12 @@ +## 2.108.0 — Leftover-map origin on leftover-map pair leftover-map post leftover-map person coordinates independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates + +- Caption leftover-map pair leftover-map post leftover-map origin leftover-map person coordinates through leftoverMapListPostBadge + independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates (ADR 0351). After `make seed`, leftover-map pair leftover-map + post leftover-map origin leftover-map person coordinates name leftover-map origin when leftoverMapPlotCoordinatePairIsOrigin returns true. Distinct accessible name + `leftover pair leftover-map post {title} at leftover-map origin ξ {person}`. Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`. + Non-origin leftover-map pair leftover-map post leftover-map person coordinates stay + `leftover pair leftover-map post {title} at ξ {person}`. leftoverMapComparePlotPostBadge stays leftover-map comparison graphic leftover-map + post leftover-map origin leftover-map person coordinate keys. leftoverMapPlotPostBadge stays leftover-map graphic leftover-map + post leftover-map origin leftover-map person coordinate keys this increment. Do not invent leftover-map origin from leftover-map item coordinates `ζ`. + Do not mix #877. 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 4839cc063..adad05d36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,17 @@ All notable changes to this project are documented here. Format follows ### Added -- Period leftover pairs now caption leftover-map comparison graphic leftover-map criterion leftover-map origin leftover-map item coordinates - through leftoverMapComparePlotCriterionBadge independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates (ADR 0350 / v2.107.0). After `make seed`, leftover-map comparison graphic leftover-map +- Period leftover pairs now caption leftover-map pair leftover-map post leftover-map origin leftover-map person coordinates + through leftoverMapListPostBadge independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates (ADR 0351 / v2.108.0). After `make seed`, leftover-map pair leftover-map + post leftover-map origin leftover-map person coordinates name leftover-map origin when leftoverMapPlotCoordinatePairIsOrigin returns true. Distinct accessible name + `leftover pair leftover-map post {title} at leftover-map origin ξ {person}`. Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`. + Non-origin leftover-map pair leftover-map post leftover-map person coordinates stay + `leftover pair leftover-map post {title} at ξ {person}`. leftoverMapComparePlotPostBadge stays leftover-map comparison graphic leftover-map + post leftover-map origin leftover-map person coordinate keys. leftoverMapPlotPostBadge stays leftover-map graphic leftover-map + post leftover-map origin leftover-map person coordinate keys this increment. Do not invent leftover-map origin from leftover-map item coordinates `ζ`. + Do not mix #877. A finite negative leftover is shown, never clamped. Never invent a leftover score or a theta. No new columns. + + criterion leftover-map origin leftover-map item coordinates name leftover-map origin when leftoverMapPlotCoordinatePairIsOrigin returns true. Distinct accessible name `leftover map comparison graphic leftover-map criterion {label} at leftover-map origin ζ {item}`. Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`. Non-origin leftover-map comparison graphic leftover-map criterion leftover-map item coordinates stay diff --git a/docs/adr/0339-leftover-map-list-post-coordinates.md b/docs/adr/0339-leftover-map-list-post-coordinates.md index 020598bbf..a37f33ab4 100644 --- a/docs/adr/0339-leftover-map-list-post-coordinates.md +++ b/docs/adr/0339-leftover-map-list-post-coordinates.md @@ -4,7 +4,9 @@ **Date:** 2026-08-31 **Amended by:** [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) +(leftover-map item coordinates on leftover-map pair leftover-map criterion independently of leftover-map pair leftover-map post leftover-map person coordinates); +[ADR 0351](0351-leftover-map-list-post-origin-badge.md) +(leftover-map origin on leftover-map pair leftover-map post leftover-map person coordinates independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates) Amends leftover-map coordinates ([ADR 0267](0267-leftover-map-coordinates.md)). Independent of leftover-map diff --git a/docs/adr/0351-leftover-map-list-post-origin-badge.md b/docs/adr/0351-leftover-map-list-post-origin-badge.md new file mode 100644 index 000000000..b8a493fb8 --- /dev/null +++ b/docs/adr/0351-leftover-map-list-post-origin-badge.md @@ -0,0 +1,90 @@ +# ADR 0351 — Name leftover-map origin on leftover-map pair leftover-map post leftover-map person coordinates independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates + +**Decision status:** Accepted +**Date:** 2026-09-02 + +Amends leftover-map person coordinates on leftover-map pair leftover-map post 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 comparison graphic leftover-map criterion leftover-map origin leftover-map item coordinates independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates +([ADR 0350](0350-leftover-map-compare-plot-criterion-origin-badge.md)). Independent of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates independently of leftover-map graphic leftover-map post leftover-map origin leftover-map person coordinates +([ADR 0349](0349-leftover-map-compare-plot-post-origin-badge.md)). Independent of leftover-map graphic leftover-map post leftover-map origin leftover-map person coordinates independently of leftover-map criterion leftover-map item coordinates +([ADR 0348](0348-leftover-map-plot-post-origin-badge.md)). Independent of leftover-map leftover-axis origin ticks on the competing origin-tick stack (do not mix #877). + +## Context + +ADR 0339 already names leftover-map pair leftover-map post leftover-map person coordinates +`leftover pair leftover-map post {title} at ξ {person}`. Rank-0 unused axes still persist leftover-map +origin `(0.00, 0.00)` (`formatSignedLeftoverValue(0)` emits no plus). Origin leftover-map +person coordinates still interpolate leftover-map origin only through leftover-map pair leftover-map post leftover-map +person coordinate keys. A missing or non-finite leftover-map person coordinate pair omits independently +of leftover-map item coordinates `ζ`. A finite negative leftover is shown, never clamped. +Do not invent leftover-map origin from leftover-map item coordinates `ζ`. leftoverMapComparePlotPostBadge stays +`Open leftover map comparison graphic leftover-map post {title} at leftover-map origin ξ {person}` +this increment. leftoverMapPlotPostBadge stays +`Open leftover-map post {title} at leftover-map origin ξ {person}` +this increment. leftoverMapListCriterionBadge stays leftover-map pair leftover-map criterion leftover-map +item coordinate keys this increment. leftoverMapCompareListPostBadge stays leftover-map comparison leftover-pair leftover-map +post leftover-map person coordinate keys this increment. + +This increment names leftover-map pair leftover-map post leftover-map origin leftover-map +person coordinates as leftoverMapListPostBadge. Leftover-map pair leftover-map post leftover-map origin leftover-map +person coordinates stay +`leftover pair leftover-map post {title} at leftover-map origin ξ {person}` +when leftoverMapPlotCoordinatePairIsOrigin returns true, so they stay distinct from leftover-map +pair leftover-map post leftover-map person coordinates +`leftover pair leftover-map post {title} at ξ {person}`, +leftover-map graphic leftover-map post leftover-map origin leftover-map person coordinates +`Open leftover-map post {title} at leftover-map origin ξ {person}`, +and leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates +`Open leftover map comparison graphic leftover-map post {title} at leftover-map origin ξ {person}`. +It does not add columns. Do not invent a leftover score. Do not invent a theta. + +This protected increment uses **0351** so it does not collide with leftover-map comparison graphic leftover-map +criterion leftover-map origin leftover-map item coordinates independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates +(0350) or leftover-map leftover-axis origin ticks (#877). + +## Decision + +On leftover-map pair leftover-map post, caption leftover-map origin +when leftoverMapPlotCoordinatePairIsOrigin returns true. Rank-0 unused axes still name leftover-map +origin `(0.00, 0.00)`. Non-origin leftover-map person coordinates stay leftover-map pair leftover-map post leftover-map +person coordinate keys. leftoverMapComparePlotPostBadge, leftoverMapPlotPostBadge, +leftoverMapListCriterionBadge, leftoverMapCompareListPostBadge, leftoverMapComparePlotCriterionBadge, +leftoverMapPlotTickAxisBadge, leftoverMapComparePlotTickAxisBadge, leftoverMapCompareAxisTickBadge, and leftoverMapAxisTickBadge +do not change leftover-map origin naming this increment. + +Do not add SQL. Do not edit shipped migrations. Do not invent a leftover +score. Do not invent a theta. + +## Consequences + +After `make seed`, leftover-map pair leftover-map post leftover-map origin leftover-map person +coordinates name leftover-map origin independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates. Rank-0 unused +axes still name leftover-map origin `(0.00, 0.00)`. leftoverMapComparePlotPostBadge stays leftover-map comparison graphic leftover-map +post leftover-map origin leftover-map person coordinate keys. leftoverMapPlotPostBadge stays leftover-map graphic leftover-map +post leftover-map origin leftover-map person coordinate keys. leftover-map person coordinates on leftover-map pair leftover-map +post independently of leftover-map pair leftover-map criterion leftover-map item coordinates +(ADR 0339) remain. + +## Related + +Independent of leftover-map comparison graphic leftover-map criterion leftover-map origin leftover-map item +coordinates independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates +([ADR 0350](0350-leftover-map-compare-plot-criterion-origin-badge.md)). Independent of leftover-map +person coordinates on leftover-map pair leftover-map post 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 +comparison graphic leftover-map post leftover-map origin leftover-map person coordinates independently of leftover-map graphic leftover-map post leftover-map origin leftover-map person coordinates +([ADR 0349](0349-leftover-map-compare-plot-post-origin-badge.md)). Independent of leftover-map leftover-axis origin ticks independently of leftover-map axis share and leftover-map singular values +([ADR 0346](0346-leftover-map-axis-tick-origin-badge.md)). + +## 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 efad46f55..dbd99539b 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -1,5 +1,15 @@ # Product & Technical Gap Baseline +> Exact-head loop overlay: 2026-09-02 07:40 KST. Protected `main` is +> `3f61c8242b9c02dec307a7396e83e28f7cdd9f3d`. Writes work. Do not +> self-approve. #912 leftover-map comparison graphic leftover-map criterion leftover-map origin leftover-map +> item coordinates independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates (v2.107.0 / ADR 0350) is +> `2ac677b`, stacked on #893 @ `f2a1860`. Independent APPROVE is missing (Devin COMMENTED, +> not APPROVE). Next buyer increment on this cycle: leftover-map pair leftover-map post leftover-map origin leftover-map +> person coordinates independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates as leftoverMapListPostBadge (ADR 0351 / v2.108.0) delivered locally on +> `feat/leftover-map-list-post-origin-badge-v21080`. Distinct accessible name +> `leftover pair leftover-map post {title} at leftover-map origin ξ {person}`. Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`. leftoverMapComparePlotPostBadge stays leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinate keys. leftoverMapPlotPostBadge stays leftover-map graphic leftover-map post leftover-map origin leftover-map person coordinate keys. Do not invent leftover-map origin from leftover-map item coordinates `ζ`. Do not mix #877. Stack onto #912. Leave open for independent review. Do not squash-merge. Do not self-approve. Issues #79 and #87 stay open. Do not merge #808 without independent APPROVE. #96 closed as weaker duplicate of #91. + > Exact-head loop overlay: 2026-09-02 07:32 KST. Protected `main` is > `3f61c8242b9c02dec307a7396e83e28f7cdd9f3d`. Writes work. Do not > self-approve. #893 leftover-map comparison graphic leftover-map post leftover-map origin leftover-map diff --git a/frontend/package.json b/frontend/package.json index b8468a54c..7839ded0c 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "frontend", "private": true, - "version": "2.107.0", + "version": "2.108.0", "type": "module", "scripts": { "dev": "vite", diff --git a/frontend/src/components/LeftoverMapPlot.tsx b/frontend/src/components/LeftoverMapPlot.tsx index 1d2cef010..69957a8e9 100644 --- a/frontend/src/components/LeftoverMapPlot.tsx +++ b/frontend/src/components/LeftoverMapPlot.tsx @@ -313,6 +313,9 @@ function leftoverMapPlotPostText( * ADR 0350 fail-closes leftover-map comparison graphic leftover-map criterion leftover-map origin leftover-map * item coordinates through leftoverMapComparePlotCriterionBadge independently of leftover-map * comparison graphic leftover-map post leftover-map origin leftover-map person coordinates. + * ADR 0351 fail-closes leftover-map pair leftover-map post leftover-map origin leftover-map + * person coordinates through leftoverMapListPostBadge independently of leftover-map + * comparison graphic leftover-map post leftover-map origin leftover-map person coordinates, not this graphic. * Never invent a leftover score. */ export function LeftoverMapPlot({ diff --git a/frontend/src/components/LeftoverPairList.test.tsx b/frontend/src/components/LeftoverPairList.test.tsx index 36de3d5cb..77e609040 100644 --- a/frontend/src/components/LeftoverPairList.test.tsx +++ b/frontend/src/components/LeftoverPairList.test.tsx @@ -233,9 +233,14 @@ describe("LeftoverPairList", () => { expect( screen.getByRole("button", { - name: "leftover pair leftover-map post Public post at ξ (0.00, 0.00)", + name: "leftover pair leftover-map post Public post at leftover-map origin ξ (0.00, 0.00)", }), ).toBeInTheDocument(); + expect( + screen.queryByRole("button", { + name: "leftover pair leftover-map post Public post at ξ (0.00, 0.00)", + }), + ).not.toBeInTheDocument(); expect( screen.getByLabelText("leftover pair leftover-map criterion sales-lead at ζ (0.00, 0.00)"), ).toBeInTheDocument(); diff --git a/frontend/src/components/LeftoverPairList.tsx b/frontend/src/components/LeftoverPairList.tsx index f08117f44..acfe67639 100644 --- a/frontend/src/components/LeftoverPairList.tsx +++ b/frontend/src/components/LeftoverPairList.tsx @@ -142,6 +142,8 @@ export type LeftoverPairListProps = { * coordinates and leftover-map post leftover-map person coordinates, not this pair list. * ADR 0339 captions leftover-map pair leftover-map post leftover-map person coordinates through leftoverMapListPostBadge * independently of leftover-map pair leftover-map criterion leftover-map item coordinates. + * ADR 0351 captions leftover-map origin on leftover-map pair leftover-map post leftover-map person coordinates through leftoverMapListPostBadge + * independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates. * ADR 0340 captions leftover-map pair leftover-map criterion leftover-map item coordinates through leftoverMapListCriterionBadge * 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, diff --git a/frontend/src/i18n.test.ts b/frontend/src/i18n.test.ts index 2115d077f..58f812205 100644 --- a/frontend/src/i18n.test.ts +++ b/frontend/src/i18n.test.ts @@ -61,6 +61,7 @@ describe("i18n", () => { "Leftover residual R {residual} after IRT main effects. Open this post to read {criterion}.", "Open leftover {kind} pair: {title} · {criterion}", "leftover pair leftover-map post {title} at ξ {person}", + "leftover pair leftover-map post {title} at leftover-map origin ξ {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}", @@ -177,6 +178,7 @@ describe("i18n", () => { "Open leftover map comparison graphic leftover-map post {title} at ξ {person}", "Open leftover map comparison graphic leftover-map post {title} at leftover-map origin ξ {person}", "leftover map comparison graphic leftover-map criterion {label} at leftover-map origin ζ {item}", + "leftover pair leftover-map post {title} at leftover-map origin ξ {person}", "Read observed Y {observed} and expected E {expected} after IRT main effects, then open this post.", "Leftover map has no leftover structure after IRT main effects. Open this post.", "Leftover map rank {rank} after IRT main effects. Open this post.", @@ -510,6 +512,24 @@ describe("i18n", () => { }, ); + it.each([ + ["ko", "잔여 쌍 잔여 지도 원점 글 Public post (ξ (0.00, 0.00))"], + ["zh", "残差配对残差图原点帖子 Public post(ξ (0.00, 0.00))"], + ["ja", "残差ペアの残差マップ原点投稿 Public post(ξ (0.00, 0.00))"], + ["vi", "Cặp phần dư bài gốc bản đồ phần dư Public post tại ξ (0.00, 0.00)"], + ] as const)( + "formats leftover-map pair leftover-map post leftover-map origin ξ in %s", + (locale, expected) => { + setLocale(locale); + expect( + tf("leftover pair leftover-map post {title} at leftover-map origin ξ {person}", { + title: "Public post", + person: "(0.00, 0.00)", + }), + ).toBe(expected); + }, + ); + it.each([ ["ko", "잔여 지도 원점 글 Public post 열기 (ξ (0.00, 0.00))"], ["zh", "打开残差图原点帖子 Public post(ξ (0.00, 0.00))"], diff --git a/frontend/src/i18n.ts b/frontend/src/i18n.ts index d84245cbd..69784f1d0 100644 --- a/frontend/src/i18n.ts +++ b/frontend/src/i18n.ts @@ -667,6 +667,8 @@ const TRANSLATIONS: Partial>> = { "잔여 {kind} 쌍 열기: {title} · {criterion}", "leftover pair leftover-map post {title} at ξ {person}": "잔여 쌍 잔여 지도 글 {title} (ξ {person})", + "leftover pair leftover-map post {title} at leftover-map origin ξ {person}": + "잔여 쌍 잔여 지도 원점 글 {title} (ξ {person})", "leftover pair leftover-map criterion {label} at ζ {item}": "잔여 쌍 잔여 지도 기준 {label} (ζ {item})", "leftover map comparison leftover pair leftover-map post {title} at ξ {person}": @@ -1393,6 +1395,8 @@ const TRANSLATIONS: Partial>> = { "打开残余 {kind} 配对:{title} · {criterion}", "leftover pair leftover-map post {title} at ξ {person}": "残差配对残差图帖子 {title}(ξ {person})", + "leftover pair leftover-map post {title} at leftover-map origin ξ {person}": + "残差配对残差图原点帖子 {title}(ξ {person})", "leftover pair leftover-map criterion {label} at ζ {item}": "残差配对残差图准则 {label}(ζ {item})", "leftover map comparison leftover pair leftover-map post {title} at ξ {person}": @@ -2123,6 +2127,8 @@ const TRANSLATIONS: Partial>> = { "残差 {kind} ペアを開く: {title} · {criterion}", "leftover pair leftover-map post {title} at ξ {person}": "残差ペアの残差マップ投稿 {title}(ξ {person})", + "leftover pair leftover-map post {title} at leftover-map origin ξ {person}": + "残差ペアの残差マップ原点投稿 {title}(ξ {person})", "leftover pair leftover-map criterion {label} at ζ {item}": "残差ペアの残差マップ基準 {label}(ζ {item})", "leftover map comparison leftover pair leftover-map post {title} at ξ {person}": @@ -2857,6 +2863,8 @@ const TRANSLATIONS: Partial>> = { "Mở cặp phần dư {kind}: {title} · {criterion}", "leftover pair leftover-map post {title} at ξ {person}": "Cặp phần dư bài viết bản đồ phần dư {title} tại ξ {person}", + "leftover pair leftover-map post {title} at leftover-map origin ξ {person}": + "Cặp phần dư bài gốc bản đồ phần dư {title} tại ξ {person}", "leftover pair leftover-map criterion {label} at ζ {item}": "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}": diff --git a/frontend/src/leftoverMapAxisBadge.ts b/frontend/src/leftoverMapAxisBadge.ts index 7d44fdcf6..09463b99c 100644 --- a/frontend/src/leftoverMapAxisBadge.ts +++ b/frontend/src/leftoverMapAxisBadge.ts @@ -38,6 +38,8 @@ * person coordinates as leftoverMapComparePlotPostBadge, not this helper. * ADR 0350 names leftover-map origin on leftover-map comparison graphic leftover-map criterion leftover-map * item coordinates as leftoverMapComparePlotCriterionBadge, not this helper. + * ADR 0351 names leftover-map origin on leftover-map pair leftover-map post leftover-map + * person coordinates as leftoverMapListPostBadge, not this helper. */ import type { LeftoverMapAxis } from "./api"; diff --git a/frontend/src/leftoverMapCoordinates.test.ts b/frontend/src/leftoverMapCoordinates.test.ts index 0a920507a..4ca8cae41 100644 --- a/frontend/src/leftoverMapCoordinates.test.ts +++ b/frontend/src/leftoverMapCoordinates.test.ts @@ -26,6 +26,7 @@ import { LEFTOVER_MAP_COMPARE_LIST_CRITERION, LEFTOVER_MAP_LIST_CRITERION, LEFTOVER_MAP_LIST_POST_ACTION, + LEFTOVER_MAP_LIST_POST_ACTION_ORIGIN, } from "./leftoverMapCoordinates"; describe("formatLeftoverMapCoordinates", () => { @@ -112,10 +113,18 @@ describe("leftoverMapPlotCoordinatePairIsOrigin", () => { expect(leftoverMapListCriterionBadge("sales-lead", 0, 0)?.key).not.toBe( LEFTOVER_MAP_COMPARE_PLOT_CRITERION_ORIGIN, ); + expect(leftoverMapListPostBadge("Public post", 0, 0)?.key).toBe(LEFTOVER_MAP_LIST_POST_ACTION_ORIGIN); expect(leftoverMapListPostBadge("Public post", 0, 0)?.key).not.toBe(LEFTOVER_MAP_PLOT_POST_ACTION_ORIGIN); expect(leftoverMapListPostBadge("Public post", 0, 0)?.key).not.toBe( LEFTOVER_MAP_COMPARE_PLOT_POST_ACTION_ORIGIN, ); + expect(leftoverMapListPostBadge("Public post", 0, 0)?.key).not.toBe(LEFTOVER_MAP_LIST_POST_ACTION); + expect(leftoverMapCompareListPostBadge("Public post", 0, 0)?.key).not.toBe( + LEFTOVER_MAP_LIST_POST_ACTION_ORIGIN, + ); + expect(leftoverMapComparePlotPostBadge("Public post", 0, 0)?.key).not.toBe( + LEFTOVER_MAP_LIST_POST_ACTION_ORIGIN, + ); }); }); @@ -131,15 +140,22 @@ describe("leftoverMapListPostBadge", () => { }); }); - it("names rank-0 origin leftover-map person coordinates as ξ (0.00, 0.00)", () => { + it("names rank-0 leftover-map origin leftover-map person coordinates independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates", () => { expect(leftoverMapListPostBadge("Public post", 0, 0)).toEqual({ - key: LEFTOVER_MAP_LIST_POST_ACTION, + key: LEFTOVER_MAP_LIST_POST_ACTION_ORIGIN, values: { title: "Public post", person: "(0.00, 0.00)" }, }); + expect(leftoverMapListPostBadge("Public post", 0, 0)?.key).not.toBe(LEFTOVER_MAP_LIST_POST_ACTION); expect(leftoverMapListPostBadge("Public post", 0, 0)?.key).not.toBe(LEFTOVER_MAP_PLOT_POST_ACTION_ORIGIN); expect(leftoverMapListPostBadge("Public post", 0, 0)?.key).not.toBe( LEFTOVER_MAP_COMPARE_PLOT_POST_ACTION_ORIGIN, ); + expect(leftoverMapComparePlotPostBadge("Public post", 0, 0)?.key).not.toBe( + LEFTOVER_MAP_LIST_POST_ACTION_ORIGIN, + ); + expect(leftoverMapCompareListPostBadge("Public post", 0, 0)?.key).not.toBe( + LEFTOVER_MAP_LIST_POST_ACTION_ORIGIN, + ); }); it("omits leftover-map person coordinates when ξ is missing or non-finite", () => { @@ -159,6 +175,12 @@ describe("leftoverMapListPostBadge", () => { expect(LEFTOVER_MAP_LIST_POST_ACTION).toBe( "leftover pair leftover-map post {title} at ξ {person}", ); + expect(LEFTOVER_MAP_LIST_POST_ACTION_ORIGIN).toBe( + "leftover pair leftover-map post {title} at leftover-map origin ξ {person}", + ); + expect(LEFTOVER_MAP_LIST_POST_ACTION_ORIGIN).not.toBe(LEFTOVER_MAP_LIST_POST_ACTION); + expect(LEFTOVER_MAP_LIST_POST_ACTION_ORIGIN).not.toBe(LEFTOVER_MAP_PLOT_POST_ACTION_ORIGIN); + expect(LEFTOVER_MAP_LIST_POST_ACTION_ORIGIN).not.toBe(LEFTOVER_MAP_COMPARE_PLOT_POST_ACTION_ORIGIN); expect(LEFTOVER_MAP_LIST_POST_ACTION).not.toBe(LEFTOVER_MAP_PLOT_POST_ACTION); expect(LEFTOVER_MAP_LIST_POST_ACTION).not.toBe(LEFTOVER_MAP_PLOT_POST_ACTION_ORIGIN); expect(LEFTOVER_MAP_LIST_POST_ACTION).not.toBe(LEFTOVER_MAP_COMPARE_PLOT_POST_ACTION_ORIGIN); @@ -173,6 +195,9 @@ describe("leftoverMapListPostBadge", () => { expect(leftoverMapListPostBadge("Public post", 0.5, 0.1)?.key).not.toBe( leftoverMapCompareListPostBadge("Public post", 0.5, 0.1)?.key ?? "", ); + expect(leftoverMapListPostBadge("Public post", 0.5, 0.1)?.key).not.toBe( + LEFTOVER_MAP_LIST_POST_ACTION_ORIGIN, + ); }); }); @@ -199,6 +224,9 @@ describe("leftoverMapListCriterionBadge", () => { expect(leftoverMapListCriterionBadge("sales-lead", 0, 0)?.key).not.toBe( LEFTOVER_MAP_PLOT_CRITERION_ORIGIN, ); + expect(leftoverMapListCriterionBadge("sales-lead", 0, 0)?.key).not.toBe( + LEFTOVER_MAP_LIST_POST_ACTION_ORIGIN, + ); }); it("omits leftover-map item coordinates when ζ is missing or non-finite", () => { @@ -260,6 +288,9 @@ describe("leftoverMapCompareListPostBadge", () => { expect(leftoverMapCompareListPostBadge("Public post", 0, 0)?.key).not.toBe( LEFTOVER_MAP_COMPARE_PLOT_POST_ACTION_ORIGIN, ); + expect(leftoverMapCompareListPostBadge("Public post", 0, 0)?.key).not.toBe( + LEFTOVER_MAP_LIST_POST_ACTION_ORIGIN, + ); }); it("omits leftover-map person coordinates when ξ is missing or non-finite", () => { @@ -285,6 +316,7 @@ describe("leftoverMapCompareListPostBadge", () => { expect(LEFTOVER_MAP_COMPARE_LIST_POST_ACTION).not.toBe(LEFTOVER_MAP_PLOT_POST_ACTION); expect(LEFTOVER_MAP_COMPARE_LIST_POST_ACTION).not.toBe(LEFTOVER_MAP_COMPARE_PLOT_POST_ACTION); expect(LEFTOVER_MAP_COMPARE_LIST_POST_ACTION).not.toBe(LEFTOVER_MAP_COMPARE_PLOT_POST_ACTION_ORIGIN); + expect(LEFTOVER_MAP_COMPARE_LIST_POST_ACTION).not.toBe(LEFTOVER_MAP_LIST_POST_ACTION_ORIGIN); expect(leftoverMapCompareListPostBadge("Public post", 0.5, 0.1)?.key).not.toBe( leftoverMapListPostBadge("Public post", 0.5, 0.1)?.key ?? "", ); diff --git a/frontend/src/leftoverMapCoordinates.ts b/frontend/src/leftoverMapCoordinates.ts index 228e832df..3ba947f73 100644 --- a/frontend/src/leftoverMapCoordinates.ts +++ b/frontend/src/leftoverMapCoordinates.ts @@ -15,6 +15,10 @@ * criterion leftover-map item coordinates as leftoverMapComparePlotCriterionBadge independently of leftover-map * comparison graphic leftover-map post leftover-map origin leftover-map person coordinates. leftoverMapListCriterionBadge stays leftover-map pair leftover-map * criterion leftover-map item coordinate keys. + * ADR 0351 names leftover-map origin on leftover-map pair leftover-map post leftover-map + * person coordinates as leftoverMapListPostBadge independently of leftover-map comparison graphic leftover-map post leftover-map + * origin leftover-map person coordinates. leftoverMapCompareListPostBadge stays leftover-map comparison leftover-pair leftover-map + * post leftover-map person coordinate keys. */ import { formatSignedLeftoverValue } from "./leftoverMapUnexplained"; @@ -28,6 +32,9 @@ export const LEFTOVER_MAP_COMPARE_COORDINATES_LABEL = export const LEFTOVER_MAP_LIST_POST_ACTION = "leftover pair leftover-map post {title} at ξ {person}"; +export const LEFTOVER_MAP_LIST_POST_ACTION_ORIGIN = + "leftover pair leftover-map post {title} at leftover-map origin ξ {person}"; + export const LEFTOVER_MAP_LIST_CRITERION = "leftover pair leftover-map criterion {label} at ζ {item}"; @@ -94,6 +101,9 @@ export function formatLeftoverMapCoordinates( * person coordinates as leftoverMapPlotPostBadge, not this helper. * ADR 0349 names leftover-map origin on leftover-map comparison graphic leftover-map post leftover-map * person coordinates as leftoverMapComparePlotPostBadge, not this helper. + * ADR 0351 names leftover-map origin on leftover-map pair leftover-map post leftover-map + * person coordinates as leftoverMapListPostBadge independently of leftover-map comparison graphic leftover-map post leftover-map + * origin leftover-map person coordinates. */ export function leftoverMapListPostBadge( title: string, @@ -104,7 +114,11 @@ export function leftoverMapListPostBadge( if (person === null) { return null; } - return { key: LEFTOVER_MAP_LIST_POST_ACTION, values: { title, person } }; + const origin = leftoverMapPlotCoordinatePairIsOrigin(person); + return { + key: origin ? LEFTOVER_MAP_LIST_POST_ACTION_ORIGIN : LEFTOVER_MAP_LIST_POST_ACTION, + values: { title, person }, + }; } /** ADR 0340 leftover-map pair leftover-map criterion leftover-map item coordinates ζ. @@ -125,7 +139,10 @@ export function leftoverMapListCriterionBadge( return { key: LEFTOVER_MAP_LIST_CRITERION, values: { label, item } }; } -/** ADR 0341 leftover-map comparison leftover-pair leftover-map post leftover-map person coordinates ξ. */ +/** ADR 0341 leftover-map comparison leftover-pair leftover-map post leftover-map person coordinates ξ. + * ADR 0351 names leftover-map origin on leftover-map pair leftover-map post leftover-map + * person coordinates as leftoverMapListPostBadge, not this helper. + */ export function leftoverMapCompareListPostBadge( title: string, axis1: number | null | undefined, diff --git a/frontend/src/leftoverMapPlotAxisSingular.ts b/frontend/src/leftoverMapPlotAxisSingular.ts index 99d8fc3df..c3cd6eb47 100644 --- a/frontend/src/leftoverMapPlotAxisSingular.ts +++ b/frontend/src/leftoverMapPlotAxisSingular.ts @@ -52,6 +52,9 @@ * ADR 0350 names leftover-map origin on leftover-map comparison graphic leftover-map criterion leftover-map * item coordinates as leftoverMapComparePlotCriterionBadge independently of leftover-map comparison graphic leftover-map post leftover-map * origin leftover-map person coordinates, not leftoverMapPlotTickAxisBadge. + * ADR 0351 names leftover-map origin on leftover-map pair leftover-map post leftover-map + * person coordinates as leftoverMapListPostBadge independently of leftover-map comparison graphic leftover-map post leftover-map + * origin leftover-map person coordinates, not leftoverMapPlotTickAxisBadge. */ import type { LeftoverMapAxis } from "./api"; diff --git a/frontend/src/leftoverMapPlotLayout.test.ts b/frontend/src/leftoverMapPlotLayout.test.ts index 0e78fd2cf..c1ef0c795 100644 --- a/frontend/src/leftoverMapPlotLayout.test.ts +++ b/frontend/src/leftoverMapPlotLayout.test.ts @@ -37,7 +37,7 @@ import { PLOT_PADDING, PLOT_WIDTH, } from "./leftoverMapPlotLayout"; -import { leftoverMapCompareListCriterionBadge, leftoverMapCompareListPostBadge } from "./leftoverMapCoordinates"; +import { leftoverMapCompareListCriterionBadge, leftoverMapCompareListPostBadge, leftoverMapListPostBadge } from "./leftoverMapCoordinates"; function pair( overrides: Partial = {}, @@ -1435,6 +1435,9 @@ describe("leftoverMapComparePlotPostBadge", () => { expect(leftoverMapComparePlotPostBadge("Public post", 0, 0)?.key).not.toBe( LEFTOVER_MAP_COMPARE_PLOT_CRITERION_ORIGIN, ); + expect(leftoverMapComparePlotPostBadge("Public post", 0, 0)?.key).not.toBe( + leftoverMapListPostBadge("Public post", 0, 0)?.key ?? "", + ); }); it("omits leftover-map person coordinates when ξ is missing or non-finite", () => { diff --git a/frontend/src/leftoverMapPlotLayout.ts b/frontend/src/leftoverMapPlotLayout.ts index b9b7c930e..2324542a0 100644 --- a/frontend/src/leftoverMapPlotLayout.ts +++ b/frontend/src/leftoverMapPlotLayout.ts @@ -175,6 +175,10 @@ * item coordinates through leftoverMapComparePlotCriterionBadge independently of leftover-map * comparison graphic leftover-map post leftover-map origin leftover-map person coordinates ξ, not leftover-map graphic leftover-map criterion leftover-map * item coordinates. + * ADR 0351 fail-closes leftover-map pair leftover-map post leftover-map origin leftover-map + * person coordinates through leftoverMapListPostBadge independently of leftover-map + * comparison graphic leftover-map post leftover-map origin leftover-map person coordinates ξ, not leftover-map comparison graphic leftover-map post leftover-map + * person coordinates. */ import { formatLeftoverMapCoordinatePair, leftoverMapPlotCoordinatePairIsOrigin } from "./leftoverMapCoordinates"; diff --git a/pyproject.toml b/pyproject.toml index c6a696c7d..3f8a85dde 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "lineageweave" -version = "2.107.0" +version = "2.108.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" } From 371bb82cea8437f907249d6e8b166f63dfe5bb8e Mon Sep 17 00:00:00 2001 From: seonghobae Date: Tue, 1 Sep 2026 22:44:05 +0000 Subject: [PATCH 2/2] docs(changelog): restore leftover-map origin Unreleased headings for v2.107.0 and v2.106.0 Keep the v2.108.0 leftoverMapListPostBadge origin bullet above intact leftover-map comparison graphic leftover-map criterion leftover-map origin leftover-map item coordinates (ADR 0350 / v2.107.0) and leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates (ADR 0349 / v2.106.0) bullets. Do not leave orphaned continuations. --- CHANGELOG.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index adad05d36..cee432c28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,8 @@ All notable changes to this project are documented here. Format follows post leftover-map origin leftover-map person coordinate keys this increment. Do not invent leftover-map origin from leftover-map item coordinates `ζ`. Do not mix #877. 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 graphic leftover-map criterion leftover-map origin leftover-map item coordinates + through leftoverMapComparePlotCriterionBadge independently of leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates (ADR 0350 / v2.107.0). After `make seed`, leftover-map comparison graphic leftover-map criterion leftover-map origin leftover-map item coordinates name leftover-map origin when leftoverMapPlotCoordinatePairIsOrigin returns true. Distinct accessible name `leftover map comparison graphic leftover-map criterion {label} at leftover-map origin ζ {item}`. Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`. Non-origin leftover-map comparison graphic leftover-map criterion leftover-map item coordinates stay @@ -27,7 +28,8 @@ All notable changes to this project are documented here. Format follows post leftover-map origin leftover-map person coordinate keys this increment. Do not invent leftover-map origin from leftover-map person coordinates `ξ`. Do not mix #877. 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 graphic leftover-map post leftover-map origin leftover-map person coordinates + through leftoverMapComparePlotPostBadge independently of leftover-map graphic leftover-map post leftover-map origin leftover-map person coordinates (ADR 0349 / v2.106.0). After `make seed`, leftover-map comparison graphic leftover-map post leftover-map origin leftover-map person coordinates name leftover-map origin when leftoverMapPlotCoordinatePairIsOrigin returns true. Distinct accessible name `Open leftover map comparison graphic leftover-map post {title} at leftover-map origin ξ {person}`. Rank-0 unused axes still name leftover-map origin `(0.00, 0.00)`. Non-origin leftover-map comparison graphic leftover-map post leftover-map person coordinates stay