diff --git a/.orchestration/remediation-issue-3350-item-pagination.md b/.orchestration/remediation-issue-3350-item-pagination.md new file mode 100644 index 000000000..6ab351f6f --- /dev/null +++ b/.orchestration/remediation-issue-3350-item-pagination.md @@ -0,0 +1,17 @@ +# Issue 3350 remediation evidence + +## Findings addressed + +- `item-pagination.test.tsx` now derives complete numbered-token inventories for each generated fixture and asserts every token exactly once. Sampled token-to-physical-page placement checks remain separate. +- Pagination fixtures snapshot `metadata.layout.pages` before rendering and assert authored layout pages are unchanged afterward. Overflow fixtures also assert physical PDF page count exceeds authored page count. +- Unsafe `wrap={false}` renderer coverage remains diagnostic-only; no item controls, schema flags, or runtime behavior were added. + +## Verification + +- `rtk proxy pnpm --filter @reactive-resume/pdf exec vitest run src/semantic/pagination.test.tsx src/templates/shared/item-pagination.test.tsx` — 2 files, 11 tests passed. +- `rtk proxy pnpm --filter @reactive-resume/pdf typecheck` — passed. +- `rtk proxy pnpm exec biome check packages/pdf/src/templates/shared/item-pagination.test.tsx` — passed. +- `rtk proxy pnpm exec turbo boundaries` — passed; 1109 files checked. +- `rtk git diff --check origin/main...HEAD` — passed. + +Only PDF test coverage and this evidence file changed; production behavior remains untouched. diff --git a/packages/pdf/src/templates/shared/item-pagination.test.tsx b/packages/pdf/src/templates/shared/item-pagination.test.tsx index c10376491..4d428a359 100644 --- a/packages/pdf/src/templates/shared/item-pagination.test.tsx +++ b/packages/pdf/src/templates/shared/item-pagination.test.tsx @@ -59,8 +59,13 @@ const makeFixture = (items: ResumeData["sections"]["experience"]["items"]): Resu return data; }; +const numberedTokens = (prefix: string, count: number) => + Array.from({ length: count }, (_value, index) => `${prefix}_${String(index + 1).padStart(3, "0")}`); + const numberedParagraphs = (prefix: string, count: number) => - Array.from({ length: count }, (_value, index) => `
${prefix}_${String(index + 1).padStart(3, "0")}
`).join(""); + numberedTokens(prefix, count) + .map((token) => `${token}
`) + .join(""); const expectTokensExactlyOnce = (pages: string[], tokens: string[]) => { const renderedText = pages.join(" "); @@ -75,9 +80,11 @@ describe("item pagination token matrix", () => { makeItem("boundary", numberedParagraphs("BOUNDARY", 26)), makeItem("fit", numberedParagraphs("FIT", 4)), ]), - tokens: ["FIT_001", "FIT_002", "FIT_003", "FIT_004"], + allTokens: [...numberedTokens("BOUNDARY", 26), ...numberedTokens("FIT", 4)], + sampledTokens: ["FIT_001", "FIT_002", "FIT_003", "FIT_004"], expectedPages: 1, expectedTokenPages: [0, 0, 0, 0], + expectsPhysicalOverflow: false, }, { name: "item fits a full page but not remaining space", @@ -85,16 +92,20 @@ describe("item pagination token matrix", () => { makeItem("boundary", numberedParagraphs("BOUNDARY", 48)), makeItem("full-page", numberedParagraphs("FULL_PAGE", 42)), ]), - tokens: ["FULL_PAGE_001", "FULL_PAGE_021", "FULL_PAGE_042"], + allTokens: [...numberedTokens("BOUNDARY", 48), ...numberedTokens("FULL_PAGE", 42)], + sampledTokens: ["FULL_PAGE_001", "FULL_PAGE_021", "FULL_PAGE_042"], expectedPages: 3, expectedTokenPages: [1, 1, 2], + expectsPhysicalOverflow: true, }, { name: "item taller than a page", data: makeFixture([makeItem("oversized", numberedParagraphs("OVERSIZED", 180))]), - tokens: ["OVERSIZED_001", "OVERSIZED_090", "OVERSIZED_180"], + allTokens: numberedTokens("OVERSIZED", 180), + sampledTokens: ["OVERSIZED_001", "OVERSIZED_090", "OVERSIZED_180"], expectedPages: 5, expectedTokenPages: [0, 2, 4], + expectsPhysicalOverflow: true, }, { name: "two-line paragraph near boundary", @@ -102,9 +113,11 @@ describe("item pagination token matrix", () => { makeItem("boundary", numberedParagraphs("BOUNDARY", 52)), makeItem("paragraph", "PARAGRAPH_001 first line
PARAGRAPH_002 second line
NESTED_001
NESTED_002
NESTED_003