Skip to content

C5.1: клиентские theme-ключи → VcPreset (снос fixed Theme из рантайма) - #343

Merged
lemone112 merged 7 commits into
mainfrom
agent/c5-theme-keys-vcpreset
Jul 17, 2026
Merged

C5.1: клиентские theme-ключи → VcPreset (снос fixed Theme из рантайма)#343
lemone112 merged 7 commits into
mainfrom
agent/c5-theme-keys-vcpreset

Conversation

@lemone112

@lemone112 lemone112 commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

Роадмап §16 C5.1 — первый из двух PR среза C5 (следом C5.2: вырез legacy cleanliness-прокси).

Что сделано

  • Канонический путь: client key → themes-словарь конфига → VcPreset → ViewingConditions. Fixed-словарь light/dark/*-ic из рантайма вырезан; встроенных имён тем у движка больше нет.
  • Engine: иммутабельные key→preset биндинги; ключ кэша — слот биндинга (без аллокации) + отпечаток конфига; результат сохраняет исходный клиентский ключ.
  • Recheck теперь требует конфиг наравне с resolve (раньше работал без словаря — дыра); неизвестный ключ → типизированный unknown_theme; пустой словарь themes отклоняется на загрузке (EmptyThemes — симметрия с EmptyContract у ролей: поздний unknown_theme был бы неотличим от опечатки).
  • Atomic reload: чистка result-кэша и projection-memo только после полной валидации; неудачный reload не трогает state/cache/memo (пин-тест).
  • Вырезано: wasm theme.rs, TS-union ThemeName (теперь string), контекст-мост в cleanliness.rs. Scope-заметка: DefectContext/*_in_context/vc_for_context/y_pct_from_hex числятся в списках C5.2, но вырезаны здесь — они параметризованы удаляемым Theme, переписывать их на VcPreset ради нескольких часов жизни было бы хуже; замороженная координата muddiness_from_hex/oklch остаётся до C5.2. Новый публичный Core Theme не создан (физический тип — VcPreset).
  • FFI/conformance — локальные adapter/fixture словари (4 ключа → VcPreset); байты пака не тронуты.
  • Контракт-тесты C5.1: клиентские имена; два ключа одного пресета = одна физика, разные имена; пустой словарь = отказ загрузки; дубликат имени темы = DuplicateKey (mutation-bite); recheck-требует-конфиг; атомарный reload.

Байты

Budget v12: 459657B (+416B — словарь-лукап вместо enum), канонический размер снят draft-CI (run 29606827872), подтверждён зелёным прогоном; v11 — в неизменяемой истории.

Ревью

Hostile-ревью (read-only, полный прогон гейтов): GO; оба обязательных допила (стейл-док ThemeName в published d.ts, тест дубликата имени темы) и все минорки внесены, включая выравнивание пустого словаря под прецедент EmptyContract.

Локальные гейты

Workspace-тесты (37 таргетов), clippy -D warnings, fmt, MSRV 1.85 check, rustdoc -D warnings, wasm32-check тестов, tsc, npm 169/169 — зелёные.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Новые возможности
    • Темы теперь выбираются по ключам из загруженного клиентского словаря; имена могут быть произвольными, а результаты возвращают исходный ключ.
  • Исправления
    • При пустом наборе тем загрузка корректно завершается ошибкой.
    • Улучшены сообщения и отказоустойчивость для неизвестных тем и вызовов до загрузки конфигурации.
    • Кэш пересчитывается с учётом темы и обновлённой конфигурации.
  • Документация
    • Уточнены соответствия клиентских имён физическим настройкам и описание публичного API.
  • Контроль качества
    • Обновлены WASM контракты и сценарии тестов, включая размерный бюджет v12.

Канонический путь: client key → словарь themes загруженного конфига →
VcPreset → ViewingConditions. Engine хранит иммутабельные key→preset
биндинги; ключ кэша несёт СЛОТ биндинга (без аллокации), отпечаток конфига
разводит словари; результат сохраняет исходный клиентский ключ. Resolve и
recheck одинаково требуют конфиг (recheck без конфига был дырой — теперь
ConfigRequired); неизвестный ключ и любой ключ при пустом словаре —
типизированный UnknownTheme. Успешный reload чистит result-кэш и
projection-memo только после полной валидации; неудачный не трогает
state/cache/memo (пин-тест).

Вырезано: wasm-модуль theme.rs (fixed parse), TS-union ThemeName
(теперь string — ключ клиентского словаря), контекст-мост legacy-прокси в
cleanliness.rs (enum Theme, DefectContext, muddiness_in_context,
drab_in_context, vc_for_context, y_pct_from_hex + их Zone-G тесты — это
машинерия fixed-theme, её место занял канонический путь; замороженная
координата muddiness_from_hex/oklch остаётся до C5.2). Новый публичный
Core Theme не создан: физический тип — VcPreset.

FFI и conformance держат ЛОКАЛЬНЫЕ adapter/fixture словари (маппинг своих
четырёх ключей в VcPreset) — байты пака не тронуты. Пять новых
контракт-тестов C5.1 в engine.rs (клиентские имена, два ключа одного
пресета, пустой словарь, recheck-требует-конфиг, атомарный reload).

Гейты: workspace-тесты (37 таргетов), clippy -D warnings, fmt, MSRV 1.85
check, rustdoc -D warnings, tsc, npm 169/169. Runtime-wasm байты изменятся
(лукап вместо enum) — budget v12 по каноническому CI-размеру следующим
коммитом.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: bf3a1b28-97a4-46cd-af75-16c91856c111

📥 Commits

Reviewing files that changed from the base of the PR and between e299728 and 9bee4d2.

📒 Files selected for processing (1)
  • crates/labcolors-core/src/config.rs

Walkthrough

Встроенные имена тем удалены: WASM использует ключи клиентского конфига, сопоставляет их с VcPreset и индексирует кэш слотами. Добавлена проверка пустого словаря тем, удалён legacy Zone G и обновлён WASM size budget до v12.

Changes

Граница клиентских тем

Layer / File(s) Summary
Удаление legacy Zone G
crates/labcolors-core/cleanliness.rs, crates/labcolors-core/lib.rs, crates/labcolors-core/tests/*, crates/labcolors-ffi/src/lib.rs
Удалены контекстные API Zone G, связанные re-export’ы и тесты; FFI использует VcPreset напрямую.
Валидация словаря themes
crates/labcolors-core/config.rs, crates/labcolors-core/config/tests.rs
Добавлена ошибка EmptyThemes, ранняя проверка пустого словаря и тест дубликатов ключей тем.
Сопоставление ключей и VC-пресетов
crates/labcolors-conformance/src/lib.rs, conformance/README.md, docs/decisions/*, packages/colors/README.md
Ключи тем описаны как клиентские или fixture-словарные; условия просмотра получаютcя через VcPreset.
WASM-контракт клиентских ключей
crates/labcolors-wasm/src/{cache,dto,engine,error,lib,projection}.rs
resolveTheme, recheck и recheckMulti используют ключи конфигурации; DTO сохраняет исходное имя, а кэш индексируется слотом и fingerprint.
Проверки нового контракта
crates/labcolors-wasm/src/engine.rs, crates/labcolors-wasm/src/projection.rs, crates/labcolors-wasm/tests/wasm_parity.rs
Тесты покрывают клиентские имена, конфигурационные ошибки, reload-кэш, проекцию и соответствие VcPreset.

WASM-бюджет v12

Layer / File(s) Summary
Переход size budget на v12
packages/colors/bench/*, packages/colors/test/release-contract.test.mjs, scripts/check-wasm-size-budget.mjs
Добавлен документ v12, связанный с v11; обновлены проверки SHA-256, истории, runtime-рецепта и ограничений размера.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Заголовок точно отражает главный смысл PR: переход от fixed Theme к клиентским theme-ключам и VcPreset в рантайме.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/c5-theme-keys-vcpreset

Comment @coderabbitai help to get the list of available commands.

lemone112 and others added 5 commits July 17, 2026 22:22
Канонический Linux-x64 размер снят draft-CI (run 29606827872): словарь
клиентских ключей вместо fixed enum стоит +416B. v11 уходит в неизменяемую
историю с SHA-пином; ratchet v12 = точное измерение, zero headroom.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
theme_vc парити-теста маппит kebab-ключи labui-паспорта в VcPreset напрямую —
локальный fixture-словарь вместо удалённого core Theme. Таргет wasm32 не
покрывался локальным check --all-targets, поймано draft-CI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Без конфига словаря тем не существует — resolve отвечает config_required;
unknown_theme проверяется с загруженным labui-паспортом (ключ вне словаря).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ст, доки

- Пустой словарь themes теперь отклоняется НА ЗАГРУЗКЕ (ConfigError::EmptyThemes)
  — симметрия с EmptyContract у ролей: поздний unknown_theme был неотличим от
  опечатки; прежнее состояние движка не тронуто (тест).
- Тест на дубликат имени темы (mutation-bite для check_unique("themes") —
  единственный непокушенный мутант новой поверхности).
- Стейл-док «all four spellings are fully supported» над ThemeName удалён
  (утекал потребителям в published d.ts).
- Вакуумная ассерция invalid-fg-hex в recheck-тесте: теперь с загруженным
  конфигом и точным матчем InvalidBackground.
- Сообщения границы: UnknownTheme на английском (язык поверхности),
  ConfigRequired упоминает recheck (новая достижимость).
- README: recheckContrast требует конфиг (явно, не только в «Темах»);
  строка unknown_theme в таблице ошибок; ADR-0001 приведён к C5.1
  (fixed-enum вырезан, канон — словарь конфига).
- wasm_parity: стейл-коммент «recheck is stateless» заменён правдой.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Допилы ревью (EmptyThemes на загрузке + строки границы) стоили +108B поверх
словаря-лукапа. v12 ещё не в неизменяемой истории (тот же PR) — перепин
на месте по прецеденту v10; канонический размер снят текущим draft-CI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lemone112
lemone112 marked this pull request as ready for review July 17, 2026 20:18

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/labcolors-wasm/src/engine.rs (1)

139-163: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Сначала проверяйте конфиг и ключ темы.

Сейчас невалидный bg_hex возвращает invalid_background даже без конфига или при неизвестной теме. Это противоречит документированному config_required до loadConfig и отличается от порядка recheck_vc. Перенесите нормализацию фона после theme_binding.

Предлагаемое исправление
-        let normalised = normalise_hex(bg_hex)?;
-        let bg = BgInput::solid(&normalised).map_err(|u| BindingError::InvalidBackground {
-            reason: u.to_string(),
-        })?;
-
         if let Some(named) = &self.named {
             let (slot, preset) =
                 named
                     .theme_binding(theme_key)
                     .ok_or_else(|| BindingError::UnknownTheme {
                         requested: theme_key.to_string(),
                     })?;
+            let normalised = normalise_hex(bg_hex)?;
+            let bg =
+                BgInput::solid(&normalised).map_err(|u| BindingError::InvalidBackground {
+                    reason: u.to_string(),
+                })?;
             let vc = preset.viewing_conditions();

As per coding guidelines, «Проверяйте hostile input, порядок событий и reentrancy там, где применимы соответствующие риски».

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/labcolors-wasm/src/engine.rs` around lines 139 - 163, In
resolve_theme, validate the loaded configuration and resolve
theme_binding(theme_key) before normalising bg_hex or constructing BgInput, so
missing configuration or an unknown theme returns its existing error regardless
of background validity. Move the normalise_hex and BgInput validation block
after the named/theme-binding checks while preserving the cache-key and
resolved-theme flow.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/labcolors-core/src/config.rs`:
- Around line 1282-1287: Обновите публичный `# Errors` doc-комментарий у метода,
содержащего проверку `self.themes.entries.is_empty()`, добавив
`ConfigError::EmptyThemes` наряду с `ConfigError::EmptyContract`. Не изменяйте
логику проверки или другие варианты ошибок.

---

Outside diff comments:
In `@crates/labcolors-wasm/src/engine.rs`:
- Around line 139-163: In resolve_theme, validate the loaded configuration and
resolve theme_binding(theme_key) before normalising bg_hex or constructing
BgInput, so missing configuration or an unknown theme returns its existing error
regardless of background validity. Move the normalise_hex and BgInput validation
block after the named/theme-binding checks while preserving the cache-key and
resolved-theme flow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 24bf1032-2986-4bcb-9e11-4e8021a48464

📥 Commits

Reviewing files that changed from the base of the PR and between c2c7763 and e299728.

📒 Files selected for processing (21)
  • conformance/README.md
  • crates/labcolors-conformance/src/lib.rs
  • crates/labcolors-core/src/cleanliness.rs
  • crates/labcolors-core/src/config.rs
  • crates/labcolors-core/src/config/tests.rs
  • crates/labcolors-core/src/lib.rs
  • crates/labcolors-core/tests/property_invariants.rs
  • crates/labcolors-ffi/src/lib.rs
  • crates/labcolors-wasm/src/cache.rs
  • crates/labcolors-wasm/src/dto.rs
  • crates/labcolors-wasm/src/engine.rs
  • crates/labcolors-wasm/src/error.rs
  • crates/labcolors-wasm/src/lib.rs
  • crates/labcolors-wasm/src/projection.rs
  • crates/labcolors-wasm/src/theme.rs
  • crates/labcolors-wasm/tests/wasm_parity.rs
  • docs/decisions/0001-config-boundary.md
  • packages/colors/README.md
  • packages/colors/bench/wasm-size-budget-v12.json
  • packages/colors/test/release-contract.test.mjs
  • scripts/check-wasm-size-budget.mjs
💤 Files with no reviewable changes (2)
  • crates/labcolors-wasm/src/theme.rs
  • crates/labcolors-core/src/cleanliness.rs

Comment thread crates/labcolors-core/src/config.rs
@lemone112
lemone112 merged commit 2c41dab into main Jul 17, 2026
10 checks passed
@lemone112
lemone112 deleted the agent/c5-theme-keys-vcpreset branch July 17, 2026 20:37
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