Skip to content

R0610 remediation campaign (continued) — post-#45 - #63

Open
MateuszKubuszok wants to merge 35 commits into
masterfrom
more-improvements-3
Open

R0610 remediation campaign (continued) — post-#45#63
MateuszKubuszok wants to merge 35 commits into
masterfrom
more-improvements-3

Conversation

@MateuszKubuszok

Copy link
Copy Markdown
Member

Continues the R0610 remediation campaign on a fresh branch off the merged master (PR #45 landed the sbt 2.0 migration + campaign + DiagResult facades).

Constitution: docs/plans/remediation-2026-06.md · live state: docs/plans/HANDOFF-CAMPAIGN.md · ledger: docs/plans/remediation-progress.md.

Merge process: verified-merge (signed commits + linear history) per .claude/skills/verified-merge — do NOT use the GitHub UI merge buttons (rebase-merge re-signs and drops the signature).

Issues resolved so far

  • ISS-1365 [P2] — ssg-js reduce_vars single-use alias-collapse gap: routed single_use through the faithful Inference.isConstantExpression (terser reduce-vars.js:757-760 + inference.js:705-742) instead of a divergent Evaluate variant that dropped object/array literals. Un-pinned issue_3205_5 + 8 further compress fixtures (all byte-verified vs real terser). fail_marks_ssg-js 590→581. Green JVM/JS/Native. red:af115096 fix:1367f9f4 audit:PASS.

Follow-ups filed en route: ISS-1385, ISS-1386 (both pre-existing, low).

…SS-1365)

reduce_vars single_use used a divergent Evaluate.isConstantExpression that
returned false for object/array literals, so a single-use var/funarg bound to
{a:1} was never inlined and the inline->reduce_vars->unused collapse chain
stalled. Route single_use through the faithful Inference.isConstantExpression
(terser reduce-vars.js:757-760 + inference.js:705-742), preserving terser's
||/&& structure. Un-pins issue_3205_5 plus 8 further compress fixtures whose
expected output byte-matches real terser. fail_marks_ssg-js 590->581.

red:af115096 fix:1367f9f4 audit:PASS
ISS-1365 (ssg-js reduce_vars single_use / object-literal inline) resolved with
audit PASS evidence; filed follow-ups ISS-1385 (Inference AstObjectProperty
null-value) and ISS-1386 (CompressTestHelper pureGetters default). fail_marks_ssg-js
590->581.
…ready wired)

Adjudicated STALE by independent audit (Opus 4.8): both described gaps were
implemented by later work — nameCache (ISS-1045) and keep_quoted
reserve_quoted_keys pre-pass + keepQuoted tri-state (ISS-1217/1328), each with
passing load-bearing tests. Queue-hygiene close, no product change.
@codecov

codecov Bot commented Jul 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.83146% with 27 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...js/src/main/scala/ssg/js/compress/Compressor.scala 47.82% 24 Missing ⚠️
...ain/scala/ssg/mermaid/diagrams/gantt/GanttDb.scala 92.50% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

…la Native (ISS-1341)

Scala Native's URI.normalize() does not collapse empty path segments (and
truncates on '///') the way JVM/JS do, so relative-url results kept '//' on
Native. Factor collapseSlashes into a shared UrlUtil (byte-identical to the
ISS-1333 Absolute_Url copy) and apply it to the Relative_Url path BEFORE URI
construction. Un-skips 9 assume(isJVM) masks; RelativeUrlFilterSuite now 14/14
on JVM/JS/Native. assumes_ssg-liquid 19->10.

red:e18e76fe fix:de9cbf23 audit:PASS
…ISS-1302)

liqp's round appends decimal places only when the arg > 0 (Round.java:26); a
negative/zero arg formats to a scale-0 integer. SSG passed the negative scale
straight to BigDecimal.setScale, rounding to hundreds (round(12345.678,-2)=12300
vs liqp 12346). Read the arg as Long (longValue, matching liqp) and clamp
round<=0 to scale 0. RoundNegativeArgIss1302Suite 4/4 JVM+JS+Native.

red:3d921ec2 fix:1798ad7d audit:PASS
…ty (ISS-1139)

makeNum's three shortening branches were separate ifs (not terser's
if/else-if/else-if) plus an extra !contains('.')&&!contains('e') guard on the
trailing-zero branch, so 1.5e300/4.5e30/1.23e-10 fell through to exponent-
recombine and rendered the shorter-but-wrong 15e299/45e29/123e-12. Restructured
to a faithful else-if chain (output.js:2438-2447), removed the guard, made e+->e
a first-only replace (replaceFirstLiteral), and dropped the hex Long.MaxValue cap
(doubleToHexNonNeg renders exact hex at any magnitude, output.js:2430-2435).
Corrected MakeNumIss1135Suite's two bug-enshrined expectations (terser-cited).

red:aea7d1dc fix:52f9d315 audit:PASS
…(0) (ISS-1159)

Pie percentage labels rendered 1 decimal (FormatUtil.toFixed(percentage,1)) vs
upstream pieRenderer.ts:119 ((value/sum)*100).toFixed(0). Changed to toFixed(0);
1/3 slice now renders 33% not 33.3%. Restructured LocaleSvgIss1156JvmSuite: the
former dot-decimal-percentage vehicle is gone with integer labels, so the
locale-independence check moved to a direct FormatUtil.toFixed(33.333,1)=='33.3'
assertion + the preserved no-comma pie-SVG and svgDe==svgUs byte-identity guards.

red:9bc6e221 fix:bf931254 audit:PASS
…o match upstream tick.toString() (ISS-1160)

XyChart y-tick labels rounded to integers (Math.round(value).toString) vs
upstream baseAxis.ts:201 tick.toString(), so fractional ticks 2.5/7.5 rendered
as 3/8. Emit via the locale-independent FormatUtil.formatNumber (integral ->
no .0, fractional -> trimmed dot-decimal), matching JS Number.toString for tick
values while preserving ISS-1156 locale-independence.

red:20cdd24d fix:3195370c audit:PASS
…uarded(TemplateContext) overloads (ISS-1149)

Add the two parent-context render overloads liqp Template.java:396-409 exposes:
renderUnguarded(parent) -> renderToObjectUnguarded(parent).toString, and the
private renderToObjectUnguarded(parent) -> renderToObjectUnguarded(empty, parent,
true). Delegates to the existing 3-arg form which applies parent scoping via
newChildContext. Public-API completeness; no internal callers in liqp either.

red:stash(compile-error without overloads) fix:b69b350a audit:PASS
…file ISS-1392 (Number-method folding gap) + ledger
…per upstream (ISS-1300)

drawNote emitted a single text element with no wrapping; upstream applies
wrapLabel to note labels and renders multi-line (sequenceRenderer.ts:1366-1426,
drawNote ~240-281). buildNoteModel now wraps the note message via the existing
wrapLabel when msg.wrap is set and recomputes the note box width/height for the
wrapped line count; drawNote splits the wrapped message on newlines and emits a
centered tspan per line. Wrap-off output is byte-identical (single-line path).
Note fonts hardcoded (SequenceConfig lacks note-font fields; ISS-1203).

red:stash(single-line without fix) fix:482acbb9 audit:PASS
…230)

ClassNode carried link/linkTarget (setLink, ISS-1059/1185) but renderClassBox
ignored them (0 anchor sites). Wrap the class TITLE in <a xlink:href target>
when the class has a link, mirroring class/svgDraw.js:176-183 (title-only, not
the whole node; SSG ports classRenderer-v2). link is used as-is (already
sanitized by ClassDb), target as-is (already resolved incl. sandbox->_top).
Non-link classes byte-identical. The ISS-1185 sandbox->_top + ISS-1059 sanitized
links are now observable in the SVG output.

red:stash(no anchor) fix:ec265d47 audit:PASS
inBooleanContext lacked terser's sequence-tail case (index.js:373, p.tail_node()
=== self) that in32BitContext already had, so a node in a comma-sequence tail in
boolean context was not recognized and boolean-context folds (e.g. !!x -> x)
didn't fire. Add the AstSequence-tail walk-through mirroring the in32BitContext
case. Un-pins CompressIssue640.wrongly_optimized + CompressIssue1639.issue_1639_2
(both now match terser). fail_marks_ssg-js 581->579.

red:070b1f48 fix:3a20ae68 audit:PASS
safeToFlatten's AstClass case required parent instanceof AstNew, but terser
safe_to_flatten (index.js:3521-3522) returns true for ANY Class (a Class is not
an AST_Lambda, so the Lambda-and-contains-this guard is false and it returns true
unconditionally, never reaching the parent-new check). SSG was thus stricter and
wouldn't flatten a class literal where terser would (e.g. [class{}][0]). Return
true for the Class case; the Lambda case is unchanged.

red:15a246be fix:10228670 audit:PASS
…aTimePattern (ISS-1232)

Reworked the gantt dayjs->java.time converter from char-by-char to a token
lexer (letter-runs + Xo ordinals) + mapDayjsToken. Port A/a->a (fixes the AM/PM
mis-parse where a bare A was read as milli-of-day), dd/ddd/dddd->EE/EEE/EEEE,
Z/ZZ->offset, Q->quarter; keep Y/M/D/H/h/m/s. Carve out (documented) the tokens
with no clean java.time ofPattern parse: ordinal Xo forms, X/x unix, W/w week,
bare d (DOW number) — they fall back to the lenient patterns as before.
Note: scala-java-time on Native lacks am/pm locale text (test gates positive
AM/PM to JVM/JS + graceful fallback on Native).

red:stash(A=milli-of-day) fix:a5ed2b93 audit:PASS
…ed) + file ISS-1394 (void-0->null fold) + ledger
The 'void 0 == x -> null == x' fold (Compressor.scala:3042) fired unconditionally,
but terser gates the whole equality switch (index.js:2280, fold at 2298-2302) on
option('comparisons'). Add the comparisons gate: with comparisons off SSG now
keeps 'void 0' like terser; with it on, still folds. Un-pins
CompressLhsConstantsSuite.lhs_constants (terser-verified). fail_marks_ssg-js 579->578.

red:c0d788c2 fix:f7c66e20 audit:PASS
…er) to un-pin bitwise_2 (ISS-1325)

Fold A: optimizeUnaryPrefix ~(x^y) now strips a left ~ via bitwiseNegate
(terser index.js:2179-2191) instead of always negating the right, so
~(~bar^baz) -> bar^baz (was ~bar^~baz). Fold B: reorder the bitwise binary
sub-optimizations to terser's order (index.js:2760-2911) — idempotent
collapse (x&x/x|x -> 0|x) now runs BEFORE the x|0 identity elimination, so
(same&same)|0 -> same|0 (was the garbled 0|0|same). Block-set unchanged, only
relocated. Un-pins CompressEvaluateFullSuite.bitwise_2. fail_marks_ssg-js 578->577.

red:e5980278 fix:8363bbbb audit:PASS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant