Skip to content

docs(spec): propose optional palette generation - #5800

Draft
cixzhang wants to merge 1 commit into
mainfrom
docs/palette-generator-spec
Draft

docs(spec): propose optional palette generation#5800
cixzhang wants to merge 1 commit into
mainfrom
docs/palette-generator-spec

Conversation

@cixzhang

@cixzhang cixzhang commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Why

Theme authors need a reproducible way to explore complete tonal ramps without treating generated color as approved theme output. Existing Core, Color Studio, preview, and package-local generators have different purposes and algorithms, so none can become a canonical contract by accident.

What

  • Adds draft system spec AST-008 on the per-theme knowledge and approval boundary now in main from docs(knowledge): add package-local theme records #5792.
  • Makes generation optional and separates candidate generation, palette validation, and adoption. Adoption exists only through a current theme:<name> record with authorized exact-head approval under repository knowledge policy; record frontmatter never grants authority.
  • Records Cindy’s approved API boundary: one public deterministic generateTonalPalette(request) library operation is canonical; a thin CLI is the primary human workflow. Both use identical normalized requests and produce byte-identical receipts and artifacts without duplicated algorithm code.
  • Uses a closed registry of explicit versioned algorithm and gamut names. New names are additive; changing behavior under an existing name is prohibited, unknown names fail, the CLI exposes the same registry, and plugin/arbitrary algorithm injection is out of scope.
  • Requires a version-pinned decision packet comparing experimental OKLCH and current CIELAB-based HCT-like paths on identical inputs before Ruby selects the initial algorithm recommendation/default in a later exact-head decision. Comparison outputs remain noncanonical candidates and cannot be adopted merely from the comparison.
  • Settles v1 gamut to the default and sole required srgb option, matching current fix(theme-neutral): remap colors to the approved palette #5628/feat(theme): add approved tonal palette metadata #5668 artifact evidence without inferring a generator color space. Wider-gamut options remain future additive named/versioned spec work; v1 requires no P3 auxiliary output.
  • Defines full reproducibility identity across implementation/build, schemas, gamut/fallback policies, selected option discriminants, and every canonical artifact digest while keeping generation out of runtime/default bundles.

Generation remains independent from localTokens and any new defineTheme field. This PR does not approve #5668 or #5628 and carries no Changeset.

Risk

Knowledge only. AST-008 remains draft / proposed; it does not authorize implementation, adopt a theme palette, select the initial algorithm recommendation/default, change theme output, or add runtime/package bytes.

Validation

  • npx --yes pnpm@11.10.0 check:knowledge -- --base origin/main
  • npx --yes pnpm@11.10.0 check:repo
  • Prettier, staged diff checks, one-file/no-Changeset checks, and public-content internal-reference scan

Remaining review question

  1. Ruby: After the required side-by-side evidence packet, which exact versioned algorithm option and fully pinned constants/schedules/mapping/rounding/vectors should ship first and be the recommendation/default? Compare-first is settled process, not an algorithm choice; neither OKLCH nor the HCT-like path may be selected without Ruby. Cindy owns API/distribution consequences and Ivor owns deterministic portable feasibility.

@vercel

vercel Bot commented Sep 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
astryx Ready Ready Preview Sep 1, 2026 3:19am UTC

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Sep 1, 2026
@cixzhang
cixzhang force-pushed the docs/palette-generator-spec branch from bc4c5a7 to adfbbf8 Compare September 1, 2026 00:15
@cixzhang
cixzhang changed the base branch from main to docs/theme-token-palette-spec September 1, 2026 00:15
@cixzhang
cixzhang force-pushed the docs/theme-token-palette-spec branch 3 times, most recently from 0566355 to 00f9597 Compare September 1, 2026 02:03
@cixzhang
cixzhang force-pushed the docs/palette-generator-spec branch from adfbbf8 to dddeed2 Compare September 1, 2026 02:55
@cixzhang
cixzhang changed the base branch from docs/theme-token-palette-spec to main September 1, 2026 02:55
@rubyycheung

Copy link
Copy Markdown
Contributor

Thanks—this is directionally right, but before I can make the OQ2 algorithm decision, I think AST-008 needs to capture several authoring requirements demonstrated by our existing themes and palette work.

Without these requirements, we could produce a reproducible OKLCH-versus-HCT comparison that still evaluates the wrong product.

Author controls

The generation request should support:

  • Versioned intensity profiles such as muted-v1, balanced-v1, and vibrant-v1. These must use hue-, tone-, and mode-aware chroma schedules rather than one universal multiplier.
  • Versioned neutral profiles: neutral, warm, cool/blue, or a custom anchored neutral.
  • Color anchors:
    • Exact: the requested color must appear unchanged at its assigned stop.
    • Bounded: adjustment is permitted only within a declared tolerance.
    • Preferred: adjustment is allowed, but the resulting difference must be reported.
  • Stop-layout presets:

A seed should influence generation without implying exact preservation. An anchor should create an explicit constraint.

Light and dark modes

A light palette must not automatically serve as the dark palette.

Requests should explicitly support:

  • Light-only
  • Dark-only
  • Independent light and dark inputs
  • A named, versioned dark transformation

The existing experimental dark treatment—85% chroma with a +5 tone lift through T80, tapering to zero by T95—is useful comparison evidence, but it should not become the final rule without evaluation.

The current shared strategy should not qualify as reviewed dark-mode output.

Coordinated palette evaluation

The decision packet should evaluate complete color-family sets, not only isolated ramps. Equal numeric settings do not make every hue feel equally strong.

Known Astryx regression cases should be mandatory fixtures:

  • Lighter blue stops must not drift toward purple.
  • Yellow must not become brown or bronze.
  • Green, cyan, purple, or other families must not become disproportionately dominant.
  • Blue/purple, yellow/green, and red/orange must remain distinguishable.
  • Adjacent stops must be perceptually distinguishable, not merely luminance-monotonic.
  • Important categorical families should be checked under common color-vision-deficiency simulations.

The approved Neutral blue work—including the hue-locked OKLCH H255 experiment—should be included as historical evidence. Existing themes should also form a reference corpus covering restrained, balanced, expressive, and dark-only treatments.

Constraint and failure behavior

The spec should distinguish hard constraints from preferences:

  • Gamut validity, monotonicity, exact anchors, and bounded-anchor tolerances are hard constraints.
  • Intensity targets, optical balance, and preferred anchors are optimization goals.
  • Conflicting hard constraints must fail clearly.
  • The generator must never silently move an exact anchor, weaken a tolerance, substitute a profile, or change the stop layout.
  • Every selected profile, anchor, stop layout, dark strategy, adjustment, and resulting deviation must be recorded in the receipt.

Scope

I do not think the production generator needs to be included in this PR. Version-pinned experimental generators are needed for the decision packet; the canonical library and CLI should follow after the recipe is selected and frozen.

The generator should output opaque palette colors. Transparency, semantic-token mapping, component usage, and contextual accessibility remain adoption concerns.

A palette alone cannot be labeled accessible. Rules such as avoiding pure-white body text on very dark backgrounds belong in dark-mode adoption guidance and rendered component evidence, not in the palette-generation math.

Could we add these requirements before asking for the final OKLCH-versus-HCT decision? The decision is really about the complete Astryx generation recipe, not only the underlying color-space name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants