Skip to content

feat(reports): leftover residual on pair segments (v2.34.0) - #806

Open
seonghobae wants to merge 1 commit into
feat/leftover-map-segment-unexplained-leftover-v2330from
feat/leftover-map-segment-residual-v2340
Open

feat(reports): leftover residual on pair segments (v2.34.0)#806
seonghobae wants to merge 1 commit into
feat/leftover-map-segment-unexplained-leftover-v2330from
feat/leftover-map-segment-residual-v2340

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Caption leftover-map graphic-display pair segments with persisted leftover residual R = Y − E[Y|θ, item] (ADR 0277 / v2.34.0).
  • After make seed, closest and farthest leftover pairs sit above the member list with the Gabriel biplot of already-named coordinates, leftover-map axis share when finite, axis ticks that match ξ (x, y) ζ (x, y) on the pair row, pair segments that match d on the pair row, pair segments that match on the pair row, pair segments that match R̂²/R² on the pair row, pair segments that match U²/R² on the pair row, pair segments that match 2R̂U/R² on the pair row, pair segments that match U on the pair row, and pair segments that match R on the pair row; click a post marker or a pair button opens that post.
  • A missing or non-finite R omits that leftover residual caption and keeps the connecting line and any leftover-map distance, reconstruction, explained leftover share, unexplained leftover share, leftover-map cross share, or unexplained leftover caption. Rank-0 origin cells still name R 0.00 when that persisted leftover is finite. A finite negative leftover is shown; do not clamp to nonnegative. Do not invent R from Y and E, from U and , or from plotted coordinates.
  • UI-only; no SQL; no new columns. Never invent a leftover score. Never invent a theta. Do not persist leftover-map inner product, cosine, or length.
  • Stacked onto leftover-map unexplained leftover on pair segments (feat/leftover-map-segment-unexplained-leftover-v2330 / feat(reports): leftover-map unexplained leftover on pair segments (v2.33.0) #805 @ e3fdfd74). Leave this PR open for independent review. Do not squash-merge onto the unprotected leftover base. Do not self-approve. After independent review, retarget onto leftover-coordinates (feat/leftover-map-coordinates-v2240 / feat(reports): persist leftover-map coordinates (v2.24.0) #782) rather than squash-merging here.

Verification

  • frontend vitest: leftoverMapPlotLayout + LeftoverMapPlot + leftoverResidual + leftoverMapUnexplained + LeftoverPairList + i18n leftover keys (194 passed: 38 layout + 12 plot + 3 residual + 2 unexplained + 15 pair-list + 124 i18n)
  • oxlint on changed leftover-map files: 0 warnings, 0 errors
  • tests/test_leftover_pairs.py and PostgreSQL period-report tests were not executed here (UI-only; no schema change)

Evidence boundary

Authenticated PostgreSQL API and k6 runtime acceptance are not claimed. No real records or credentials. Synthetic fixtures only.

Independent approval is required. No self-approval, admin bypass, or force push.

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.

Gabriel, K. R. (1971). The biplot graphic display of matrices with application to principal component analysis. Biometrika, 58(3), 453–467.


Devin Review

Caption leftover-map graphic-display pair segments with persisted leftover residual R so U + R̂ = R is graphic-auditable. UI-only; no new columns. Do not invent R from Y and E, from U and R̂, or from plotted coordinates.
@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6312fd55-9df1-470f-accf-0e3018c34732

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Contributor Author

Leave open for independent review. Do not squash-merge onto the unprotected leftover base. Do not self-approve. Copilot review is not independent APPROVE. After independent review, retarget onto leftover-coordinates (#782) rather than squash-merging here.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 3 potential issues.

Devin Review

Comment thread frontend/package.json

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Runtime verification remains unavailable

Corepack rejected the pinned pnpm signature, so the focused frontend tests could not run locally. CI must provide the executable verification.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +387 to +395
const residualY = leftoverMapStackedCaptionY(
labelPosition.labelY,
(distanceLabel !== null ? 1 : 0) +
(reconstructionLabel !== null ? 1 : 0) +
(explainedShareLabel !== null ? 1 : 0) +
(unexplainedShareLabel !== null ? 1 : 0) +
(crossShareLabel !== null ? 1 : 0) +
(unexplainedLeftoverLabel !== null ? 1 : 0),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Bottom segment residuals are clipped

When a segment lies near the plot bottom, residualY places its residual label beyond the fixed SVG height. The new caption disappears.

Prompt for agents
The new residual caption uses the seventh downward stack position from the segment midpoint, but the SVG has a fixed 320-pixel height and 40-pixel plot padding. For segments whose endpoints are near the lowest plotted axis value, residualY can exceed the view box and the finite residual caption is clipped. Update the segment-label layout in frontend/src/leftoverMapPlotLayout.ts to choose a stack direction or reserve sufficient bounds based on the complete caption stack. Add a test with a segment near the lower plot boundary that verifies every finite label, including residualLabel, remains inside the SVG view box.
Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +16 to +20
export function formatLeftoverMapResidual(value: number | null | undefined): string | null {
if (value == null || !Number.isFinite(value)) {
return null;
}
return `R ${formatLeftoverResidual(value)}`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Persisted residual boundary remains intact

formatLeftoverMapResidual formats only the supplied finite residual. Missing values stay omitted, and no neighboring measurements reconstruct them.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Contributor Author

Independent APPROVE is still required on exact head 33f6c3dd. Devin COMMENT and Copilot review are not independent APPROVE. Do not self-approve. Do not squash-merge onto the unprotected leftover base. v2.35 leftover observed Y on pair segments stacks onto this head on feat/leftover-map-segment-observed-v2350 and will open as a follow-up PR; it does not mix into this stack until independent review of this exact head.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant