[1.261.2] — 2026-10-28
The stability + polish patch: the geocode cache survives a mid-write crash (CAR-173), UI.md renders bullet continuations and nested lists, the help bundles' rendered-text key leaks are closed ×17, evaluate gets a per-locale token ceiling for ta (CAR-174), the RTL chrome mirrors via logical properties (85 findings), the map captures are re-framed ×19 and the map clusters pass contrast in dark — plus the first phase of the Lovable design integration (passive tokens-v3.css sheet), docs backfill (release review + specs), and CI-node coverage exemptions.
Fixed
- Geocode cache torn-write loss (CAR-173, #562): both flush paths (debounced insert-flush, exit-flush) wrote
.cache/geocode.jsonwith a barewriteFileSync— truncate-then-write — so a crash, OOM or SIGKILL mid-write left a torn file and the next boot'sJSON.parsethrew, silently discarding the whole persistent cache (weeks of Nominatim budget), not just the day's. Both write sites now go throughfile-lock.mjs::atomicWrite(same-directory temp → rename → unlink-on-failure) — the same contract FULL-R1/FULL-M1 applied topipeline.md,cv.md,profile.yml,career-plan, batch input and memory. The CAR-142 flush machinery itself (debounced insert-flush, exit-flush, bounded shutdown) was verified intact red-first: tests (a)/(b) lock that inserts reach the file within theGEOCODE_SAVE_MSwindow and it stays valid JSON; (c) is a mechanism gate plus behavioral runs of both flush paths asserting no temp litter and a parseable file. - UI.md list continuation (#563): the list handler only consumed consecutive
-/*lines, so an indented continuation line after a bullet fell out of the emitted<ul>and the paragraph pass skipped the chunk — the continuation leaked as raw prose with literal**/backtick markers (~95 dangling runs per locale across the help bundles; en.md 95, ru.md 104). A continuation line — leading whitespace, not a new block (heading, bullet, NUL-wrapped fence placeholder, blank) — now joins the previous<li>as<br/>-joined text, withinline()run per line so emphasis markers never pair across the join; the fence-placeholder guard is NUL-first-char, not a bare token match. Nested-bullets, numbered lists, fences inside lists and headings inside lists remain a documented separate gap (next docs wave). - Help rendered-text key leaks ×17 (#561): remote-QA found 85 raw i18n keys visible in the rendered help (root cause repro-proven: the same UI.md single-line-bullet consumption — a wrapped continuation emitted as raw text kept its backticks literal; the v1.260/261 help sections wrote multi-line bullets). 163 bullets unfolded to one line across 17 locales — whitespace-only, not a single translated word touched (old-vs-new verified). New gate
tests/help-rendered-keys.test.mjsrenders every bundle through the real chain (stripGithubOnlyBlocks+ vm-loadedUI.md) and fails on any of 1,711 keys appearing in the text; red-first 17 locales → green. Repro tooling ships in-repo:scripts/remote-qa/help-render-scan.mjs(vm) +help-render-crosscheck.mjs(real DOM). - Remote-QA Ctrl+K asserts the CAR-122 palette contract (#561):
prod-regression.mjsnow expects the command palette after Ctrl+K (.nav-v2-palette[role=dialog]+ focus innav-v2-input) OR the legacy search-focus as fallback, instead of silently accepting either; unittests/remote-qa-ctrl-k.test.mjslocks 6 scenarios on a mock DOM, red-first 0/6 → 6/6. - Map capture framing ×19 (#560): owner report on
images/job-map-en.png— half the topbar search + a cut h1 at the top, a grey sliver of the side list at the right edge, a marker cluster cut by the frame near London, and a white horizontal line across the map at ~2/3 height.capture-map-screenshots.mjsnow waits on the geocode queue drain (located + noLoc === total, not the N/N counter — Remote rows are structurally without a location, so the old wait could never complete), hidesheader.topbarand#notif-drawerfor the shot, clips the exact.job-map-pagebox (no panel cut by the frame edge), zooms out two steps so no cluster sits half-cut, pins the map height and takes a plain viewport screenshot (captureBeyondViewportresamples the composited tile layer and paints white strips at tile-row boundaries), and integer-aligns the map container. All 19 job-map captures re-shot. - Map cluster bubbles — dark-theme contrast + label fit (#572): owner-sweep P2/P3 — the dark-theme cluster rings sat on a fixed white fill (1.83:1); rings now take
var(--paper)with score-palette digits (measured 4.98:1+, filled 9.53:1; the lowest band is mathematically un-colorable on dark and keeps 6.1:1 via an honestdata-dimpath), and therelatedlabel fits its bubble (rAF font-fit, numbers never shrink). - #/scan language switch — skeleton re-arm (#534 follow-up): follow-up on the v1.261.0 owner fix (#534) — the re-armed skeletons on a language-switch repaint no longer survive a completed refetch.
- Docs drift (CAR-139, agent in flight, lands before tag): README ×19 counters, HANDOFF ×19, CONVENTIONS facts resynced with the live registry/test state.
Added
- Release review + spec backfill (docs, #559/#558):
docs/reviews/REVIEW-2026-10-28-v1.261.1.md(the v1.261.0/v1.261.1 wave reviewed against its specs) and the SDD spec backfill for the same wave — the BACKLOG tail now names the remaining gap (dedicated tests forsources/habr.mjs). - RTL deep sweep (#571): AR harness walks 39 routes × LTR-vs-RTL (X-mirror, overflow, clipping, text-align signatures) — 85 findings fixed: fixed chrome (toast, sidebar, drawer + its dismiss ×, docs-FAB, usage-HUD, skip-link) moved to
inset-inline-*/border-inline-*, tables totext-align: start/endacross 17 view files + 2 libs, the blanket[dir=rtl] text-align:rightremoved (it fought the scan star-column centering), the CAR-58 score-column isolation moved onto anltrNumspan. - Keyboard a11y harness (#570):
tests/playwright-a11y-keyboard.mjswalks 11 routes (Tab order/traps, focus indicators, Escape overlays, Enter/Space) — 0 production defects; regression coverage is new. - i18n untranslated sweep (#565): 36 en-identical values translated ×9 locales (
*.rolePh, config keys, ta manifesto) + a closed-allowlist sweep guard; site (cvstart.org) i18n audit (#568): 20 keys × 18 locales translated (the wholedemo.*/stats.t.*/showcase.tab*block was English everywhere), 1 dead key removed ×19. - Remote-QA observability (CAR-175, #567): the summary names failing scan sources (
stderr samples, redact-before-truncate) and printstok ~Nfrom provider usage; the logic lives in a puresummary-parts.mjswith a drift gate. - UI.md nested marker lists (one level, #564):
-bullets render as a nested<ul>(fence-placeholder-safe) — the last 2 dangling prose runs per locale are gone. - Lovable design integration — phases 1+2 (#566 +
feat/design-v3-active):public/css/tokens-v3.cssports the Lovable concept verbatim (oklch surfaces 0–3, AA-annotated ink pairs, accent family, ok/warn/danger/info/neutral soft+ink, score bands A–G ×2 themes, density + focus + shadows); phase 2 activates it on the existing token names (accent split blue/danger, score bands + callouts on cv3 tokens) with the contrast/role/dark gates updated. - Evaluate per-locale token ceiling (CAR-174, #569):
evalMaxTokens(lang)— ta/hi ask 32768 (the three SDK clients re-clamped at 16384; both layers fixed), plus a Tamil volume budget in the prompt (≤5 sentences per block, ≤900 words) — the v1.261.1 remote-QA ta report was cut off at the output-token limit (missing Block B–G + SCORE_SUMMARY). - CodeQL real-fix follow-through: the new QA render tooling replaced hand-rolled entity handling with structural split passes +
htmlToText({cap: Infinity}); redact assertions pin exact masked output; RTL harness unused constants dropped. - Coverage exempt-политика for CI-node variance (habr #558, states #561):
sources/habr.mjs(CI node-matrix branch 87.23 vs local ≥89) andstates.mjs(CI 86.49 vs local ≥89) join the exemptions inscripts/coverage-baseline.json— files whose CI measured branch coverage is structurally below the local floor due to node-version variance are exempted instead of ratcheting the whole gate down.
Notes
- Ctrl+K contract (CAR-122): the chord opens the command palette — it does NOT focus the search box directly; search is focused from the palette. The remote-QA prod regression now asserts exactly this (#561).
- CodeQL FP-dismiss ×5: the
js/missing-rate-limitingalerts on main await thesecurity_eventstoken — operator action, not a code change. - Landed after branch cut: #561/#562/#563/#564/#565/#566/#567/#569/#570/#571/#572 are all merged to main; the #534 follow-up landed (skeleton re-arm). Nested marker lists beyond one level and inline-heavy view geometry remain documented gaps.
- Tests 6655 on the release branch (+46 since v1.261.1); full suite 6649 pass / 0 fail / 6 env skips; no scanner sources touched (registry 121 = 116 EN + 5 RU · 116 adapters).