From c2a66a3fdbe074668f6ecce4a225b8ff198e00aa Mon Sep 17 00:00:00 2001 From: krisf Date: Fri, 9 Oct 2026 17:34:18 -0400 Subject: [PATCH] audit: math-fix twelfth-pass re-verification (all gates fresh, OFFLAN-OK 21:33Z, deploy + 34/34 byte sweep, first-attempt render determinism) --- MATH-FIX-REPORT.md | 23 +++++++++++++++++++++++ audit/bilingual-geo-check.json | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/MATH-FIX-REPORT.md b/MATH-FIX-REPORT.md index 363ac81..0f831e4 100644 --- a/MATH-FIX-REPORT.md +++ b/MATH-FIX-REPORT.md @@ -332,3 +332,26 @@ Determinism note: the first `after11` couple screenshot came out as a 63,753 B r Harness notes: Playwright run with `TMPDIR=/home/ubuntu/projects/retire-planner/.pwtmp` (harness TMPDIR read-only; no site impact); ssh byte-check loop uses `-n`; this model has no image input, so PNGs are validated by IHDR + byte-determinism + DOM row scrapes (content evidence). `audit/math-fix/` is gitignored by design — artifacts are local evidence, referenced by path. No code change required — plan executed end-to-end; fix commit `0839826` at `origin/main`; all gates fresh this pass. Final: **MATH_FIX_DONE**. + +## Re-verification (twelfth DSH pass, 2026-10-09 21:35 UTC, post-completion) + +Queue gate: `git status --porcelain` empty at start, HEAD `dc81260` == `origin/main` (post-fetch), no `dsh-run` process in flight → proceed (not `DSH_QUEUE_BUSY`). Fix 1–4 re-audited in HEAD by direct file read: GIS 65+ floor — `a >= 65 ? gis(…) : 0` at the three `solve()` sites (engine.js:249/260/265) + Service Canada source-fact comment (:88–91) + merge per-partner ≥65 gates (:379–380) + `if (yr < 65) gisSum = 0;` (:382); clawback only with OAS — `oasGross > 0 ? Math.min(clawback(…), oasGross) : 0` at :248/:259 + s.3(1) ETA comment :80–83 + splitting-solver parity :366–367; mixed rows — `row.mixed` :390 + depletion guard `!row.mixed` :395 + renderer `†`/legend app.js:807–819 + legend element index.html:95; FIRE — `fillDefaults` clamp `retireAge < age+1` :188, quiz slider `min: 40` app.js:211, `#wi-ret min="40"` index.html:86, FIRE hint EN/FR i18n.js:96/357, `t.mixedNote` EN/FR i18n.js:251/512. All acceptance checks re-executed fresh in this pass: + +| Check | Fresh output (this pass) | +|---|---| +| `tests/engine.test.js` | `RESULT: 61 pass, 0 fail` (§14 T1 repro: clawback $0 @55, GIS $0 @56, OAS gross 0 @56, net OAS ≥ 0 every row, no GIS<65 anywhere; §15: 100k RRSP draw @55 → cw 0, 67y 150k draw → cw > 0 capped at OAS gross; §16: couple GIS/clawback zero <65, net OAS ≥ 0, no growing-Total-with-Withdraw draw rows, household GIS @70, age-offset window, depletion guard intact; §17: fillDefaults 52→53 & 30→40, FIRE first draw 40, rows 40–64 GIS/clawback 0, stale 52/40 state first draw 53) | +| `tests/i18n.test.js` | `I18N-OK all i18n checks passed (50)` (incl. `t.mixedNote` EN+FR, `q.retire.hint` FIRE EN+FR) | +| `tests/ui.smoke.js` | `SMOKE-OK all ui smoke checks passed (146)` (incl. † mixed-row fixture ×3 + bilingual legend under table, control-single no †, `wi-ret min 40`, legend element present) | +| `tests/ps-pension.test.js` / `ps-auto-service.test.js` | `70 pass, 0 fail` / `21 pass, 0 fail` (unchanged files) | +| `passes3.js` rerun (live engine) | exit 0, `conservation: OK` ×3 → `audit/math-fix/passes3-thispass.log` (copy of `passes3-pass12.log`). PASS 1 (screenshot repro): rows 52–64 **OASnet $0 / GIS $0** (plan evidence −$3,501 @55 / $12,916 @56 / phantom $13,667/yr to 94 — all gone), first GIS row 65 (GIS $13,667, OASnet $9,150), depletion 56 honest (nest egg $170,465 vs $93k spend, finalBal $0); PASS 2 depletion 82, GIS 65+ only; PASS 3 FIRE: first draw @40 (Withdraw $62,837, CPP/OAS/GIS $0), max total $493,710 @39 = hand-math 350000×1.035¹⁰ ✓, GIS appears at 65 | +| `scripts/deploy.sh` | `DEPLOY-OK` (fresh this pass) | +| Origin byte-check | full sweep local == `git cat-file origin/main:` == webroot md5: tracked **21/21 (3-way)** + `site/vision/*.jpeg` **13/13** (2-way, gitignored generated assets) = **34/34 match, 0 mismatch** (`bash .tmp/sweep11.sh`, ssh `-n`) | +| Live recapture (`mathfix_capture.py after12` + `after`, retire.krisforbes.ca) | couple 52/52 ret 55 spend 93k CPP 60, DOM rows scraped: rows 58–64 **Total $0 / OAS $0 / GIS $0**, Withdraw $49K @58 then $0, Unfunded $47K–$93K — **0 negative-OAS cells, 0 GIS>0 rows <65, 0 growing-Total-with-Withdraw rows** (programmatic sweep of all 40 DOM rows); `wiRetMin: "40"`. FIRE 30/BC/ret 40: first Withdraw>0 row age **40** ($63K, OAS $0 / GIS $0), **0** pre-65 GIS/neg-OAS violations. Mobile 390: retire slider `min=40 max=72 value=40`, `sliderRight 367 ≤ vw 390` (no clip), FIRE hint present, `svAfter40: "40 years"` | +| Live mixed-window probe (re-run, `after12-mixed-*`) | couple me 52 / pt 50, `retireAge: 51` → `fillDefaults` clamps self to 53; partner inherits the shared clamped 53 → both draw from 53 (DOM row 53: Withdraw $96K) → **0 † rows**, `noteShown: false`, **0** GIS rows <65 — reconfirms Deviation 2 (age-axis merge + shared clamped `retireAge` ⇒ mixed draw windows unreachable live); † suffix + bilingual legend proven by the smoke fixture + engine §16 invariants | +| Off-LAN (Midhurst `trouble@100.96.20.61`) | `OFFLAN-OK`, `"all_ok": true`, `"http_code": "200"`, `checked_at 2026-10-09T21:33:55Z` → `audit/bilingual-geo-check.json` | + +Determinism: `after12-couple-table.png` 1280×900 50,314 B md5 `cbac51ed5089…` — byte-identical to the canonical renders of passes 1/8/9/10/11 on the FIRST attempt (no render-race variant this pass); `after-couple-table.png` regenerated fresh this pass matches the same md5. Fresh PNGs IHDR-validated: `after12-mixed-table.png` 1280×900 57,254 B, `after-fire-table.png` 1280×900 67,310 B, `after-fire-step-390.png` 1170×2532 167,045 B. + +Harness notes: Playwright run with `TMPDIR=/home/ubuntu/projects/retire-planner/.pwtmp` (harness TMPDIR read-only; no site impact); ssh byte-check loop uses `-n`; PNGs validated by IHDR + byte-determinism + DOM row scrapes (content evidence). `audit/math-fix/` is gitignored by design — artifacts are local evidence, referenced by path. + +No code change required — plan executed end-to-end; fix commit `0839826` at `origin/main`; all gates fresh this pass. Final: **MATH_FIX_DONE**. diff --git a/audit/bilingual-geo-check.json b/audit/bilingual-geo-check.json index 08008e4..84c7852 100644 --- a/audit/bilingual-geo-check.json +++ b/audit/bilingual-geo-check.json @@ -5,7 +5,7 @@ "has_i18n_script": true, "i18n_js_fr_strings": true, "i18n_js_size": 39689, - "checked_at": "2026-10-09T21:30:16Z", + "checked_at": "2026-10-09T21:33:55Z", "vantage": "trouble@100.96.20.61 (Midhurst, off-LAN)", "all_ok": true } \ No newline at end of file