Skip to content

refactor(core)!: make the contrast-region engine explicit - #216

Merged
pbroom merged 3 commits into
mainfrom
refactor/core-explicit-contrast-engine
Oct 10, 2026
Merged

pbroom merged 3 commits into
mainfrom
refactor/core-explicit-contrast-engine

Conversation

@pbroom

@pbroom pbroom commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

Contrast regions keep both solvers, but the caller now selects one and the
engine never switches implicitly.

  • Add engine?: 'hybrid' | 'legacy' (default 'hybrid').
    ContrastRegionPathOptions is now a union discriminated by engine
    (ContrastRegionHybridOptions | ContrastRegionLegacyOptions, sharing
    ContrastRegionBaseOptions). The legacy-only options (samplingMode
    'uniform'/'adaptive', edgeInterpolation, adaptiveBaseSteps,
    adaptiveMaxDepth) require engine: 'legacy', and hybridMaxDepth /
    hybridErrorTolerance are hybrid-only. Mixing them is a type error and
    always throws a TypeError at runtime, as do unknown engines. Legacy
    samplingMode defaults to 'adaptive' when adaptive* is set, otherwise
    'uniform'; samplingMode 'hybrid' is gone.
  • Plane contrast queries (PlaneContrastQueryOptions and the
    contrastBoundary/contrastRegion query types, now type aliases over the
    union), driver ColorAreaContrastRegionOptions, and inspectPlaneQuery pass
    engine and the engine options through, so invalid combinations are
    rejected the same way instead of being dropped by a field whitelist.
    Scheduler budgets and telemetry signatures follow the selected engine.
  • The hybrid engine no longer hands failed queries to the legacy engine.
    It returns its best-effort paths and records
    trace.summary.degradedReason (ContrastHybridFallbackReason is renamed
    ContrastHybridDegradedReason). It bisects lightness intervals whose ends
    are root-free on opposite sides of the threshold, localizes branch ends
    a little past hybridMaxDepth, and keeps splitting (with the extra depth)
    while index-matched roots of neighbouring samples differ by more than
    0.03 chroma, half the branch join distance. Nearly constant-lightness
    contours previously stopped splitting there and left gaps; in a
    720-query brute-force sweep, crossings more than 0.03 from the traced
    path drop from 67 to 0 for about 1.7% more evaluations. Thin regions
    at the top of the lightness range (vertical boundary, no chroma roots)
    still degrade with 'unresolved-sign-change'; the legacy engine finds
    them.
  • ContrastRegionLayer passes engine: 'legacy' explicitly (it already ran
    the legacy solver through edgeInterpolation), keeping its fill accuracy
    and speed. Its samplingMode prop is 'uniform' (default) or 'adaptive',
    and the no-op hybridMaxDepth / hybridErrorTolerance props are removed.
  • Compute scheduler: only the JS backend exists, so drop the speculative
    webgpu backend kind, preferred-backend selection, warmup, baseline
    probes, circuit breakers, and their options/telemetry fields.
    PlaneComputeBackendKind is 'js' and every run reports 'default-js'.
    Also fix LRU eviction, which evicted the newly created bucket.
  • Tests: engine selection and validation (runtime and type level), plane
    query pass-through, regression cases checked against a brute-force
    grid of the public checks, and degraded-reason cases. Docs and benches
    cover both engines.

BREAKING CHANGE: legacy contrast options require engine: 'legacy' and
hybrid options are rejected with it; samplingMode 'hybrid' is removed;
the hybrid solver no longer falls back to the legacy solver; the
ContrastRegionLayer hybridMaxDepth/hybridErrorTolerance props, the
'webgpu' backend kind, and the scheduler's multi-backend options and
circuitBreakers telemetry are removed.

Part of a stacked set of PRs (#204 → #221) from the color-kit assessment. Validated per branch with pnpm build and pnpm test; lint, format, typecheck, size, artifact, preprod and agents checks pass at the top of the stack.

🤖 Generated with Claude Code

pbroom commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@greptile-apps

greptile-apps Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 4/5

[High risk] Refactors the contrast region computation engine and scheduler.

The PR should not merge until the React layer respects adaptive controls supplied without an explicit sampling mode.

Fix All in CursorFindings

  1. P1 Adaptive controls are ignored ▶
  2. P2 Zero bucket limit is exceeded ▶

Summary

This PR makes contrast-region engine selection explicit, returns trace-marked best-effort hybrid results instead of implicitly switching solvers, and simplifies plane compute scheduling to the JS backend.

  • Contrast options, plane queries, the driver, and the React layer now carry the selected engine.
  • Hybrid refinement and regression coverage expand; scheduler telemetry and eviction are simplified.
  • The React layer’s default suppresses adaptive controls supplied without a sampling mode, and zero-capacity telemetry is not honored.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Contrast region query] --> B{Engine}
  B -->|default hybrid| C[Root tracing]
  B -->|legacy| D{Sampling mode}
  D -->|uniform| E[Fixed grid]
  D -->|adaptive| F[Adaptive grid]
  C --> G[Paths and optional degraded reason]
  E --> H[Paths]
  F --> H
Loading

Reviews (1) · Last reviewed commit: "refactor(core)!: make the contrast-regio..."

Comment thread packages/react/src/contrast-region-layer.tsx
Comment thread packages/core/src/compute/scheduler.ts
@pbroom
pbroom force-pushed the refactor/core-explicit-contrast-engine branch from d9f427e to d127833 Compare October 8, 2026 02:44
@pbroom
pbroom force-pushed the refactor/core-trim-api-surface branch from bfeb62f to acf5fa7 Compare October 8, 2026 02:44

pbroom commented Oct 10, 2026 •

Copy link
Copy Markdown
Owner Author

Merge activity

  • Oct 10, 6:47 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Oct 10, 7:22 PM UTC: Graphite rebased this pull request as part of a merge.
  • Oct 10, 7:22 PM UTC: @pbroom merged this pull request with Graphite.

@pbroom
pbroom changed the base branch from refactor/core-trim-api-surface to graphite-base/216 October 10, 2026 19:19
@pbroom
pbroom changed the base branch from graphite-base/216 to main October 10, 2026 19:20
pbroom and others added 3 commits October 10, 2026 19:21
Contrast regions keep both solvers, but the caller now selects one and the
engine never switches implicitly.

- Add `engine?: 'hybrid' | 'legacy'` (default 'hybrid').
  ContrastRegionPathOptions is now a union discriminated by `engine`
  (ContrastRegionHybridOptions | ContrastRegionLegacyOptions, sharing
  ContrastRegionBaseOptions). The legacy-only options (samplingMode
  'uniform'/'adaptive', edgeInterpolation, adaptiveBaseSteps,
  adaptiveMaxDepth) require engine: 'legacy', and hybridMaxDepth /
  hybridErrorTolerance are hybrid-only. Mixing them is a type error and
  always throws a TypeError at runtime, as do unknown engines. Legacy
  samplingMode defaults to 'adaptive' when adaptive* is set, otherwise
  'uniform'; samplingMode 'hybrid' is gone.
- Plane contrast queries (PlaneContrastQueryOptions and the
  contrastBoundary/contrastRegion query types, now type aliases over the
  union), driver ColorAreaContrastRegionOptions, and inspectPlaneQuery pass
  `engine` and the engine options through, so invalid combinations are
  rejected the same way instead of being dropped by a field whitelist.
  Scheduler budgets and telemetry signatures follow the selected engine.
- The hybrid engine no longer hands failed queries to the legacy engine.
  It returns its best-effort paths and records
  trace.summary.degradedReason (ContrastHybridFallbackReason is renamed
  ContrastHybridDegradedReason). It bisects lightness intervals whose ends
  are root-free on opposite sides of the threshold, localizes branch ends
  a little past hybridMaxDepth, and keeps splitting (with the extra depth)
  while index-matched roots of neighbouring samples differ by more than
  0.03 chroma, half the branch join distance. Nearly constant-lightness
  contours previously stopped splitting there and left gaps; in a
  720-query brute-force sweep, crossings more than 0.03 from the traced
  path drop from 67 to 0 for about 1.7% more evaluations. Thin regions
  at the top of the lightness range (vertical boundary, no chroma roots)
  still degrade with 'unresolved-sign-change'; the legacy engine finds
  them.
- ContrastRegionLayer passes engine: 'legacy' explicitly (it already ran
  the legacy solver through edgeInterpolation), keeping its fill accuracy
  and speed. Its samplingMode prop is 'uniform' (default) or 'adaptive',
  and the no-op hybridMaxDepth / hybridErrorTolerance props are removed.
- Compute scheduler: only the JS backend exists, so drop the speculative
  webgpu backend kind, preferred-backend selection, warmup, baseline
  probes, circuit breakers, and their options/telemetry fields.
  PlaneComputeBackendKind is 'js' and every run reports 'default-js'.
  Also fix LRU eviction, which evicted the newly created bucket.
- Tests: engine selection and validation (runtime and type level), plane
  query pass-through, regression cases checked against a brute-force
  grid of the public checks, and degraded-reason cases. Docs and benches
  cover both engines.

BREAKING CHANGE: legacy contrast options require engine: 'legacy' and
hybrid options are rejected with it; samplingMode 'hybrid' is removed;
the hybrid solver no longer falls back to the legacy solver; the
ContrastRegionLayer hybridMaxDepth/hybridErrorTolerance props, the
'webgpu' backend kind, and the scheduler's multi-backend options and
circuitBreakers telemetry are removed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Since contrast regions measure against the unmapped reference (as the
public metrics do), the brute-force baseline must not chroma-reduce an
out-of-gamut reference either.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@pbroom
pbroom force-pushed the refactor/core-explicit-contrast-engine branch from d127833 to 8bdcb76 Compare October 10, 2026 19:21
@pbroom
pbroom merged commit e213de1 into main Oct 10, 2026
6 of 7 checks passed
@pbroom
pbroom deleted the refactor/core-explicit-contrast-engine branch October 10, 2026 19:22

This branch was successfully deployed

1 active deployment
Preview — 8bdcb764 Deployed Oct 10, 2026 by vercel[bot]
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