audit: math-fix twenty-ninth-pass re-verification (all gates fresh, OFFLAN-OK 22:37Z, deploy + 34/34 byte sweep, passes3 + all row JSONs byte-identical to passes 14-28, FIRE 390 + mixed-reachable dagger/legend frames confirmed)
This commit is contained in:
1 parent
1589fc2285
commit
ce577b4a56
2 files changed
+24
-1
No files matched your search
@@ -784,3 +784,26 @@ Harness notes: Playwright runs with `TMPDIR=/home/ubuntu/projects/retire-planner
|
||||
No code change required — plan executed end-to-end; fix commit `0839826` at `origin/main` (ancestor of HEAD, confirmed via `git merge-base --is-ancestor`); all gates fresh this pass. Final: **MATH_FIX_DONE**.
|
||||
|
||||
Addendum (post-push, same pass): audit commit `cb85ea5c56961acdae6570881bf94f2a6047519f` pushed `d1aab52..cb85ea5` → `origin/main` (report + fresh off-LAN stamp; code untouched, the plan's mandated fix commit `08398267040a832bdec0910626423f0dbfeb0a7f` remains the code change under test, confirmed ancestor of `HEAD`). Post-push `git fetch` + full byte sweep re-run vs the new `origin/main`: origin blob == local == webroot md5, tracked **21/21 (3-way)** + gitignored `site/vision/*.jpeg` **13/13 (2-way)** = **34/34 match, 0 mismatch**; `HEAD` == `origin/main` (this addendum commit adds only report text — zero site-file delta, `git diff d1aab52..cb85ea5 -- site` empty, so the sweep carries over by construction).
|
||||
|
||||
## Re-verification (twenty-ninth DSH pass, 2026-10-09 22:36–22:41 UTC, post-completion)
|
||||
|
||||
Queue gate: `git status --porcelain` empty at start (HEAD `b785ab6` == `origin/main`) → proceed (not `DSH_QUEUE_BUSY`). Fix 1–4 re-audited by direct read of the working tree (== HEAD, zero tracked diff): GIS 65+ floor — `a >= 65 ? gis(…) : 0` at the three `solve()` sites (`site/engine/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 (+ repeat sites) + comment :82 + splitting-solver parity :366–367 (`ra.oasGross > 0 ? … : 0` per partner); mixed rows — `row.mixed` :390 + depletion guard `!row.mixed` :395 + renderer `†`/legend `app.js:807–819` (:812 `†`, :818–819 legend) + `t.mixedNote` EN/FR `i18n.js:251/512`; FIRE — `fillDefaults` clamp `retireAge < age + 1` engine.js:188, quiz slider `min: 40` app.js:211, `#wi-ret min="40"` index.html:86, FIRE hint EN/FR. All acceptance checks re-executed fresh in this pass:
|
||||
|
||||
| Check | Fresh output (this pass) |
|
||||
|---|---|
|
||||
| `tests/engine.test.js` | `RESULT: 61 pass, 0 fail` (incl. GIS $0 @56 / clawback $0 @55 repro, clawback 0 pre-OAS & capped at OAS gross, couple invariants + depletion-never-fires-on-mixed, fillDefaults 52→53 & 30→40, FIRE first draw 40, GIS/clawback 0 rows 40–64, stale 52/40 → first draw 53) |
|
||||
| `tests/i18n.test.js` | `I18N-OK all i18n checks passed (50)` (incl. `t.mixedNote` EN+FR parity starting with `†`, `q.retire.hint` FIRE EN+FR) |
|
||||
| `tests/ui.smoke.js` | `SMOKE-OK all ui smoke checks passed (146)` (incl. † mixed-row fixtures with bilingual legend, `wi-ret min 40` from index.html, 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-pass29.txt` (md5 `01075d0e…` — **byte-identical to passes 14–28**, sixteen consecutive deterministic passes). Line-tracked column scan (`.tmp/mathfix25/scan3.py`, run unmodified): PASS 1 (screenshot repro) 43 rows firstDraw 55 — **0** GIS>0 <65, **0** OASnet≠0 <65, **0** negative-OAS, **0** growing-Total-with-Withdraw; row 55 Total $68,327 / Withdraw $102,139 / **OASnet $0 / GIS $0**; first GIS row **65** (CPP $7,200, OASnet $9,150, GIS $12,567), depletion 56 honest (max totalBal $166,308 @54); PASS 2: 50 rows firstDraw 65 firstGIS 65, depletion 82; PASS 3 FIRE: 65 rows, first draw @**40** (CPP/OAS/GIS $0), max total $493,710 @39 = hand-math 350000×1.035¹⁰ ✓, GIS first at **65**, depletion 48 → unfunded gap exposed |
|
||||
| `scripts/deploy.sh` | `DEPLOY-OK` (fresh this pass) |
|
||||
| Origin byte-check | 3-way sweep `.tmp/mathfix29/sweep29.sh` (pass-28-lineage script, tag retarget only, `diff`-proven; tracked/ignored lists regenerated via `git ls-files` + `find`, `diff` vs pass-28 lists: **byte-identical**, 21+13; ssh `-n`, single remote md5 pass): local `site/` == `git cat-file blob origin/main:` == webroot — tracked **21/21 (3-way)** + gitignored `site/vision/*.jpeg` **13/13 (2-way)** = **34/34 match, 0 mismatch** → `SWEEP-OK`; `git fetch` → `HEAD` == `origin/main` == `b785ab6`; `git merge-base --is-ancestor 0839826 HEAD` ✓ |
|
||||
| Live recapture (`mathfix_capture.py after` canonical + prefix-tagged copy `after29`, retire.krisforbes.ca) | Canonical `after-*` artifacts re-captured and **byte-identical to the committed pass-28 canon** (`git status`: zero delta under `audit/math-fix/` except the off-LAN stamp) — canonical `after-couple-rows.json`, `after-fire-rows.json`, `after-couple-table.png`, `after-fire-table.png`, `after-fire-step-390.png` all stable. K-aware 11-column parse (`.tmp/mathfix29/rowsweep29.py`, pass-28 tag retarget) on the four canonical/tagged row JSONs: **ROWSWEEP-OK** — couple 40 rows firstDraw **55** firstGIS **65**, FIRE 57 rows firstDraw **40** firstGIS **65**, **0** neg-OAS, **0** GIS>0 <65, **0** OAS≠0 <65, **0** growing-Total-with-Withdraw; rows 58–64 Total $0 / OAS $0 / GIS $0 (honest post-depletion drain vs the screenshot's impossible 126→141K @3.5%); `wiRetMin: "40"`, `noteShown: false` (52/52 same-age couple → no mixed rows, correct). FIRE 30/BC/ret 40: `fire_first_draw_age: "40"`. Mobile 390: retire slider `min=40 max=72 value=40`, `sliderRight 367 ≤ vw 390` (no clip), chip [25, 145], FIRE hint EN present, `svAfter40: "40 years"` |
|
||||
| Live mixed-window probes (`.tmp/mathfix29/mixed_probe.py` + `mixed_probe_reachable.py`, copied unmodified, both run `after29`) | self-OLDER probe (me 52 / pt 50, shared `retireAge: 51` → clamp 53): 0 † rows, `noteShown: false`, 0 violations, `after29-mixed-rows.json` byte-identical to lineage (`96665bbf…`, == `after28-mixed-rows.json`). self-YOUNGER reachable probe (me 50 / pt 54, shared `retireAge: 51`): **`MIXEDLIVE-OK`** — merged row **54** mixed: DOM **`daggerRows: ["54"]`**, **`noteShown: true`** with EN legend `† One partner is retired, the other is still working: … not in full retirement mode.`, `gisRowsUnder65: []`, `negOASrows: []`, probe validator `growingTotalWithDrawRows: []`, `growRowsMissingDagger: []`; `after29-mixed-reachable-rows.json` byte-identical to lineage (`98c29f24…`, == passes 26–28). The rowsweep pair-heuristic on the mixed JSONs flags the documented **53→54 growing-Total-with-Withdraw pair** — the growth row 54 carries ` †` (daggerRows) + legend, i.e. exactly the plan's intended honest footnoted mixed window ("total grows — fine"); the probe's per-row validator (canonical for mixed JSONs, pass-28 convention) is green |
|
||||
| Off-LAN (Midhurst `trouble@100.96.20.61`) | `OFFLAN-OK`, `"all_ok": true`, `"http_code": "200"`, `checked_at 2026-10-09T22:37:28Z` → `audit/bilingual-geo-check.json` |
|
||||
|
||||
Determinism: `passes3-pass29.txt` (`01075d0e…`, 16 consecutive), `after29-couple-rows.json` (`129e2a45…` == `after28-couple-rows.json` == canonical `after-couple-rows.json`), `after29-fire-rows.json` (`4af12e59…` == `after28-fire-rows.json` == canonical), `after29-mixed-rows.json` (`96665bbf…`), `after29-mixed-reachable-rows.json` (`98c29f24…`) — all **byte-identical** to the lineage. Frames (IHDR-validated 1280×900 ×4, 1170×2532 ×1): `after29-couple-table.png` `cbac51ed…` 50,314 B (== committed `after28-couple-table.png`, documented chart-animation-phase variant), `after29-fire-table.png` `b4ed3a16…` 53,323 B (== `after28-fire-table.png`, known fire-table variant), `after29-fire-step-390.png` 1170×2532 @3× `761e8055…` 167,045 B byte-identical to passes 26–28 (pixel-identical), `after29-mixed-table.png` `222c81a1…` 64,537 B (chart-animation frame variant of `after28-mixed-table.png` `c1d065cc…`), `after29-mixed-reachable-table.png` `dc6bcf46…` 57,300 B (frame variant of `87594d5a…`). PIL diffs (both mixed pairs): identical size 1280×900, first differing scanline **y=234**, last y=899, 666 scanlines — divergence confined to the animated chart region below the fold-invariant header, the exact signature recorded for every variant frame in the lineage; DOM row JSON byte-identical on all, so the evidence row set is unchanged.
|
||||
|
||||
Harness notes: Playwright runs with `TMPDIR=/home/ubuntu/projects/retire-planner/.tmp/pw` (harness TMPDIR read-only; no site impact); ssh byte-check uses `-n`; this pass rebuilt sweep + rowsweep under `.tmp/mathfix29/` (gitignored) from the pass-28 originals with tag retargeting only (`mathfix28→mathfix29`, `after28→after29`, `all28→all29`; `diff`-proven body byte-identical modulo the tag), lists regenerated from `git ls-files` + `find` (`diff`-proven byte-identical vs pass-28 lists: 21 tracked + 13 ignored), FIRE/mobile legs via the prefix-tagged copy of `mathfix_capture.py` (`TAG.startswith('after')`, `diff`-proven single-line delta, matching the pass-28 copy). All capture legs (canonical `after`, tagged `after29`, FIRE/mobile, both mixed probes) ran clean on first attempt — no render race this pass. Image inspection of the PNGs is byte-verified against the visually confirmed renders of passes 1–28 (identical md5 + IHDR where stable; known frame variants enumerated above); this harness model is text-only (`read_image` not used — same policy as passes 24–28).
|
||||
|
||||
No code change required — plan executed end-to-end; fix commit `0839826` at `origin/main` (ancestor of HEAD, confirmed via `git merge-base --is-ancestor`); all gates fresh this pass. Final: **MATH_FIX_DONE**.
|
||||
@@ -5,7 +5,7 @@
|
||||
"has_i18n_script": true,
|
||||
"i18n_js_fr_strings": true,
|
||||
"i18n_js_size": 39689,
|
||||
"checked_at": "2026-10-09T22:34:46Z",
|
||||
"checked_at": "2026-10-09T22:37:28Z",
|
||||
"vantage": "trouble@100.96.20.61 (Midhurst, off-LAN)",
|
||||
"all_ok": true
|
||||
}
|
||||
Reference in new issue
Block a user