From 4c8fcad8ad19ece8dc62b41d1b09232e6a306e1a Mon Sep 17 00:00:00 2001 From: krisf Date: Fri, 9 Oct 2026 13:22:42 -0400 Subject: [PATCH] PS pension report: post-deploy independent verification section (4 bugs found+fixed: stuck-Next, blank card, tbl-wrap float, EN month in FR) --- PS-PENSION-REPORT.md | 57 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/PS-PENSION-REPORT.md b/PS-PENSION-REPORT.md index ea832b1..991ed53 100644 --- a/PS-PENSION-REPORT.md +++ b/PS-PENSION-REPORT.md @@ -178,7 +178,7 @@ OAS clawback gating at 65+; pre-65 couple splitting lowers joint tax - [x] Results card with full breakdown + dated sources; insight; chart series - [x] Pension flows through income/tax/PIA/GIS/splitting incl. pre-65 life-annuity splitting - [x] Full EN + FR (parity 48/48, FR smoke green) -- [x] Tests: ps-pension 70/70 · engine 36/36 · i18n OK · smoke 74/74 +- [x] Tests: ps-pension 70/70 · engine 36/36 · i18n OK · smoke 92/92 (74 at DSH handoff + 18 added by Hermes verification, see §11) - [x] Audits EN+FR @320/360/390 + desktop + off-LAN (evidence in `audit/`) - [x] Deployed (DEPLOY-OK) and reachable off-LAN (OFFLAN-OK) - [x] This report + evidence committed & pushed @@ -190,3 +190,58 @@ OAS clawback gating at 65+; pre-65 couple splitting lowers joint tax - UI audit: `TMPDIR=$PWD/.tmp python3 audit/ps_audit.py` (expect `PS-AUDIT-OK`; screenshots land in `audit/ps-pension/`, gitignored) - Off-LAN: `python3 audit/ps_offlan.py` (expect `OFFLAN-OK`) + +## 11. Post-deploy independent verification (Hermes, 2026-10-09) — 4 real bugs found & fixed + +DSH's stage B was functionally complete (engine math, decision tree, IT table, bilingual +strings, module-off default all verified correct — see below), but independent verification +by Hermes (not trusting DSH's audit) caught **4 user-facing bugs**, all fixed, tested, deployed: + +**Verified correct (no change needed):** +- Engine math to the cent, 6 hand-checked cases incl. the subtlest branch — G1 age 55+ with + S≥25 applies PSPC's "compare Formula 1 and 2, apply the lowest reduction" (code correct in + `psEarlyReduction`; the §2 summary line was imprecise and is fixed). G2's comparison + threshold (60+) also correct per the live PSPC text. +- All 5 IT levels × all steps match the live TBS–PSAC agreement cell-for-cell + (IT-01 69,361…89,382 · IT-02 85,854…105,080 · IT-03 101,343…125,914 · IT-04 116,037…144,434 · + IT-05 133,582…174,076, 9 steps; Z row 2024-12-22). +- Module-off parity: default off, base flow = 15 steps, no PS card, legacy pension input intact. +- Stage-0 gate honest: no constants changed vs. the plan's fact base. + +**Bug 1 — stuck Next button on PS number steps (ed37f82).** `renderStep()` validated only at +render; typing into an initially-empty number input (PS join year / service / salary — the only +steps with no default) never re-enabled **Next**, so a real user enabling the module was STUCK +on "When did you join". Fix: `validate(s)` in the number-input `oninput` handlers. Regression +test added: full PS quiz click-through EN+FR (toggle→join→service→salary→occ→IT-03→step 3→ +results, asserts Next enables after typing). Smoke 74→88. + +**Bug 2 — PS card body blank (244f599).** The card's `` collided with the +existing `.cards{display:grid}` (gap-cards stat grid) — grid-on-a-table collapses the rows to +zero height: the card rendered its title over an empty box. Fix: table class renamed `ps-tbl` +with its own CSS. Smoke guard added (smoke 88→90). + +**Bug 3 — `.tbl-wrap::before` float pushed tables out of view (d53dd81).** At ≤560px the +fade pseudo-element was `float:right;height:340px` — a 340px in-flow float; a table may not +overlap floats, so the table was laid out 340px below the wrap's top, entirely clipped by +`overflow:auto;max-height:340px`. This broke **both** the PS card table **and the pre-existing +year-by-year table** on mobile (verified: yr-table at 320px had its first row at the wrap's +bottom edge). Fix: `position:absolute;right:0;top:0;height:100%` overlay (the wrap is already +`position:relative`); PS card also gets `max-height:none` (8 rows, show them all). Both tables +re-verified painting at 320/390px. + +**Bug 4 — English month in the French as-of line (cab6e3d).** `canada.js` `asOf` was +English-only, so the FR card/stamp read "constantes au October 2026 (CPP 2026, OAS/GIS Oct-Dec +2026, tax 2026)". Fix: `asOfFr` added to canada.js **and its generator** `build_canada.js`; +both render sites pick by `getLang()`. Smoke guard added (smoke 90→92). + +**Verification totals after fixes:** engine 36/36 · ps-pension 70/70 · i18n 48/48 · smoke 92/92 · +live Playwright battery 63/63 (seeded card values EN desk/320 + FR 390, module-on walks FR 390 + +EN 320 with app-shell geometry, module-off walk, card-body visibility: table display=table, +td heights, innerText, table-laid-out-inside-wrap) · off-LAN OK · vision-checked: FR+EN PS card +(9 rows, notes, 6 canada.ca source links with as-of dates), PS toggle step, IT level picker, +IT step picker, year-by-year table @320. + +**Test-coverage note:** case K (G1 55+ min(F1,F2)) added to `tests/ps-pension.test.js` (bef1f9e) — +the PSPC "lowest of F1/F2" branch was implemented correctly but untested. + +- Off-LAN: `python3 audit/ps_offlan.py` (expect `OFFLAN-OK`)