Skip to content

Correct suggestion descriptions and contrast display precision#10

Merged
Artsen merged 2 commits into
mainfrom
fix/output-precision-corrections
Jul 25, 2026
Merged

Correct suggestion descriptions and contrast display precision#10
Artsen merged 2 commits into
mainfrom
fix/output-precision-corrections

Conversation

@Artsen

@Artsen Artsen commented Jul 25, 2026

Copy link
Copy Markdown
Owner

Summary

Correct two post-merge precision edge cases without reversing any behavior accepted in PR #9:

  • derive every suggested-color description and directional name from the final canonical RGB/HSL color returned by the API
  • preserve contrast-ratio precision through the API and prevent displayed ratios from contradicting threshold results
  • distinguish network-status loading from metadata failure and expose the explanation through aria-describedby

Base commit: 15aa737bc4cb11f8bdf92d0dc90d74d939b2152d

Root causes

Suggestion generators attached strings that described requested intermediate HSL adjustments before range limits and RGB-to-HSL canonicalization. Those strings could therefore disagree with the returned color or state the wrong direction near minimum and maximum limits.

Contrast pass/fail used the calculated float, but wcag_rating serialized a two-decimal rounded ratio. A value immediately below 3.0, 4.5, or 7.0 could fail correctly while appearing equal to the threshold in the interface.

The shell also used one null value for both metadata loading and failure, which could briefly show an unavailable state during normal startup.

Suggestion corrections

  • Converts each candidate to returned RGB and canonical HSL before constructing its description.
  • Compares final canonical HSL with the canonical base color in one centralized formatter.
  • Uses shortest circular hue direction, including wraparound near 0° and 360°.
  • Uses percentage point(s) for saturation and lightness differences.
  • Reports unchanged channels explicitly and never reports an increase or decrease that the final values do not contain.
  • Corrects directional names when range limits or canonicalization make names such as Tint, Shade, Lighter, Darker, Saturated, or Desaturated materially false.
  • Preserves the commonAssociations and useCases guidance contract from PR Align ColorCraft’s trust-sensitive copy and analysis behavior #9.

Contrast precision corrections

  • Stops rounding API contrast ratios to two decimals before serialization.
  • Keeps all threshold booleans based on the original calculated value.
  • Adds one shared frontend formatContrastRatio function used by role checks, the advanced all-pairs matrix, and analysis-result displays.
  • Normally shows two decimals for readability.
  • Uses decimal-string truncation to four places when ordinary two-decimal rounding would make a failing value appear equal to or above a relevant 3.0, 4.5, or 7.0 threshold.
  • Does not add a positive floating-point tolerance before truncation.
  • Explicitly guarantees that when a ratio is below a threshold and fails, parsing the formatted output also produces a value below that threshold.
  • Keeps exact-threshold values clear and passing.

Network-status polish

The shell now models loading, available, and unavailable separately. Normal startup shows Checking network status; actual metadata failure shows Network status unavailable. Loopback and LAN explanations are attached with aria-describedby instead of relying on a title tooltip.

Contract effects

There are no field additions, removals, or renames.

Behavioral response changes:

  • ratio now retains calculated floating-point precision instead of a value rounded to two decimals.
  • suggested-color description and, where necessary, name strings now describe the final canonical returned color.
  • saturation and lightness differences in suggestion descriptions use percentage points.

Existing PR #9 contracts and behavior remain intact, including commonAssociations, transitional temperature evidence, typed contrast roles, runtime networkMode, the 10 MB upload limit, and measured SVG label contrast.

Validation

Passed the complete repository gate from the final committed LF-clean tree:

python check.py
[1] frontend format
[2] frontend lint
[3] frontend typecheck
[4] frontend coverage — 84 passed, 91.58% statements
[5] frontend build
[6] backend format
[7] backend lint
[8] backend typecheck
[9] backend tests and coverage — 78 passed, 86% total
[10] browser E2E and accessibility — 3 passed
ColorCraft validation passed.

Additional validation:

  • focused backend correction suite: 41 passed
  • focused final formatter and Review suite: 13 passed
  • deterministic screenshot workflow: 1 passed
  • git diff --check: passed
  • known sRGB vectors remain aligned between frontend and backend
  • boundary coverage includes threshold - 0.0001, one scaled machine epsilon below, exactly at, and one scaled machine epsilon above 3.0, 4.5, and 7.0
  • every failing formatted boundary value parses below its threshold
  • suggestion tests cover saturation/lightness extremes, min/max range limits, RGB canonicalization, and hue wraparound
  • ColorCraft remains assigned to web port 5174 and API port 4100

Remaining limitations

  • Canonical suggestion HSL values remain integer values because that is the existing ColorCraft color contract.
  • Ordinary ratios that are not at risk of crossing a threshold remain a readable two-decimal display; the API retains the precise value.
  • Floating-point API values can contain more decimal digits than earlier responses, so consumers should format for presentation rather than comparing formatted strings.
  • This PR does not change contrast roles, temperature modeling, suggestion approaches, or API versioning.

@Artsen
Artsen marked this pull request as ready for review July 25, 2026 21:31
@Artsen
Artsen merged commit 8e1361c into main Jul 25, 2026
1 check passed
@Artsen
Artsen deleted the fix/output-precision-corrections branch July 25, 2026 21:32
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