Skip to content

fix(core): certify exact alpha and typed Glow runtime - #269

Merged
lemone112 merged 13 commits into
mainfrom
agent/exact-glow-alpha-pr
Jul 11, 2026
Merged

fix(core): certify exact alpha and typed Glow runtime#269
lemone112 merged 13 commits into
mainfrom
agent/exact-glow-alpha-pr

Conversation

@lemone112

@lemone112 lemone112 commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Результат

Lab Colors теперь разделяет exact encoded-sRGB8 point composite и platform-dependent appearance decision как разные типизированные гарантии. Срез доводит release contract до Rust 0.2.0, @labpics/colors 0.10.0 и conformance pack 2.0.0, не ломая selective adaptive runtime.

Корневые причины

  • конечные sRGB8 states перечислялись точно, но Glow verdict выбирался naked CAM16/libm f64, а публичная alpha теряла найденный binary64 state при округлении;
  • Material опирался на слишком сильную глобальную monotonicity-гипотезу и не типизировал ordered backdrop boundary/certificate;
  • internal core failures могли схлопываться в client-invalid/unreachable;
  • emitted namespace reserve зависел от наличия value: Zero не резервировал primary token ID, поэтому его имя могло совпасть с Glow/Material satellite и затем получить CSS value;
  • tag workflow мог rebuild/repack-нуть mutable artifact вместо публикации уже проверенных exact-SHA bytes;
  • legacy muddiness/drab/n_pure compatibility proxy имел dead wasm32 test и документацию, выдававшую frozen arithmetic/heuristic за подтверждённую human-perception law.

Что изменено

  • source-over/screen определены конечным encoded-sRGB8 reference-профилем с exact half-tie order, canonical alphaCss и воспроизводимым composite certificate;
  • Glow требует explicit stable-v1 или legacy-platform-dependent-v1; exact no-op возвращает Determinate/bit-exact, а недоказуемый target/max — typed Indeterminate без CSS fallback;
  • Material использует typed ordered BackdropBox, interval enclosure и recomputable numerical guarantee вместо недоказанной global-alpha monotonicity;
  • exact composite profile, diagnostic profile, numerical decision guarantee и InternalInvariant проходят Rust → WASM/TS → UniFFI/Swift без collapse;
  • adaptive runtime валидирует evidence и селективно re-resolve-ит exact-no-op ↔ Indeterminate transitions;
  • config preflight резервирует primary IDs всех recipes, включая Zero, и полные Glow/Material satellite shapes до runtime projection;
  • public alpha/compositor/backdrop inputs отвергают invalid/reversed/non-finite values без clamp, swap, panic или silent fallback;
  • legacy proxy оставлен только как явно experimental compatibility surface; ложные provenance/JND/observer claims удалены, public browser regression теперь реально исполняет committed vectors;
  • publish использует только immutable exact-SHA tarball canonical successful CI run; rebuild/repack на tag удалён.

Граница продукта

Core не знает клиентские слова и component semantics: token/role IDs остаются opaque. Exact claim ограничен объявленным encoded-sRGB8 point-reference; PR не сертифицирует spatial blur/overlap, browser/display pipeline, HDR/WCG или произвольный generic dependency graph. Legacy proxy не является human cleanliness/dirty verdict или product decision; retirement/model scope остаётся в #231.

Миграция и distribution

Glow требует explicit decision profile; invalid alpha/backdrop и collisions со всеми зарезервированными primary/satellite keys теперь отклоняются до resolve. Migration: docs/migrations/exact-alpha-glow.md. Changelog: CHANGELOG.md.

npm publication входит в #259; crates.io publication явно вне этого release slice.

Review

Выполнены отдельные architecture, numerical, API, documentation и performance reviews. Свежий exact-range CodeRabbit review нашёл четыре cleanup-дефекта; все доказанные замечания исправлены на 416accc3e699fce4f02a46aceb8468f721fa3362. Финальная review-команда подтвердила исправления и завершилась без новых замечаний; 17/17 thread’ов resolved, прежние CHANGES_REQUESTED помечены superseded.

Доказательства на final head 416accc3e699fce4f02a46aceb8468f721fa3362

  • cargo test --workspace --locked: core 508 passed / 6 ignored; все workspace suites и doctests green;
  • cargo clippy --workspace --all-targets --locked -- -D warnings, rustfmt и rustdoc -D warnings: green;
  • Rust 1.85 MSRV cargo check --workspace --all-targets --locked: green;
  • RustSec audit: 159 dependencies, 0 findings;
  • extracted labcolors-core-0.2.0.crate: 83 files, LICENSE/README verified, 3 runnable + 1 compile-fail doctest green;
  • WASM host: 55 unit + 5 chain-invariant tests; headless Chrome: 12/12;
  • psychophysics: 56 unit + 4 end-to-end tests;
  • FFI: 17/17; conformance: 7/7 unit + 9/9 reference;
  • docs drift: 21/21; cleanliness/property/inventory gates green;
  • Node 24.14.0 и exact Node floor 22.11.0: 104/104 на каждом; packed runtime smoke на Node 22 green;
  • committed conformance: 82 vectors, digest 64a68cbd;
  • release verifier: two independent byte-identical npm pack passes;
  • npm tarball: 218,837 bytes, SHA-256 b683a96443ffd1208c1bed976da5193dade9e010dd42309c95106fbdf6ade51f;
  • WASM: 393,739 bytes, SHA-256 ec0a916d2534119994c997b7dd382d10377f7397f8cdf02c2a83b4a5e7cdf5bd;
  • build metadata SHA-256 188b6cf5a7c93064331cd7f62f8bf5cd723adf372cfa3cd3efd84b6830e353fb; sourceSha равен final head;
  • targeted mutation campaigns: Glow 13/13, Material 16/16, WASM mapping 2/2, Zero namespace 5/5 caught; conformance mapping 3 caught + 2 unviable, 0 missed.

Локальная macOS-машина успешно собрала Rust FFI и сгенерировала Swift/UniFFI bindings, но не содержит XCTest/Xcode SDK, поэтому локальный swift test не стартовал и не считается evidence. Канонический pinned Linux Swift 6.1.3 gate, CI и native-conformance зелёные на PR merge-ref f5646a7c017011415cfd9d4478943dbda837d881 (base f82300d… + head 416accc…); macOS-only reference job штатно skipped и не подменяет Linux evidence.

Issues

Resolves #282.
Resolves #286.
Implements release gate #259.
Completes a bounded #231 quarantine slice while keeping #231 open.
Keeps #258, #280 and #291 open with remaining scope.
Updates #228 after merge and again after registry verification.

Summary by CodeRabbit

  • Новые возможности

    • Добавлены точные encoded-sRGB8 screen/composite вычисления и строгая проверка alpha.
    • Glow расширен: раздельные результаты halo/core, профили/гарантии/диагностика, новый итог glow-indeterminate.
    • Добавлен API проверки stable glow no-op и поддержка решения Glow в Swift/JavaScript.
  • Несовместимые изменения

    • Для Glow-рецептов требуется явный decision_profile.
    • Публичные вычисления переходят на Result/типизированные ошибки вместо Option/clamp-подмен.
    • Обновлены TypeScript-контракты и conformance pack до версии 2.0.0.
  • Документация

    • Добавлено руководство по миграции и обновлены сведения о гарантиях/ограничениях и публикации пакета.

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

PR вводит строгие encoded-sRGB8-контракты для alpha, Glow и Material, типизированные determinate/indeterminate outcomes, обновлённые Rust/WASM/TypeScript/Swift API, CSS namespace validation, conformance pack v2 и воспроизводимую release-проверку.

Changes

Конечный alpha, Glow и Material pipeline

Layer / File(s) Summary
Строгая alpha/material и numerical resolution
crates/labcolors-core/src/alpha.rs, crates/labcolors-core/src/material.rs, crates/labcolors-core/src/numerics.rs
Композитинг, инверсия и material solver используют строгую проверку домена, byte-scale affine порядок операций, typed errors и numerical outcomes.
Glow solver и semantic outcomes
crates/labcolors-core/src/glow.rs, crates/labcolors-core/src/semantic.rs, crates/labcolors-core/src/solve.rs
Glow перечисляет достижимые sRGB8 states, разделяет stable/legacy decisions и возвращает determinate либо typed Indeterminate outcomes.
Конфигурация и CSS namespace
crates/labcolors-core/src/config.rs, crates/labcolors-wasm/src/config_dto.rs, crates/labcolors-wasm/tests/data/*
Glow требует явный decision_profile, а роли, алиасы и satellites резервируются в общем CSS namespace с отказом при коллизиях.
WASM, TypeScript и UniFFI boundary
crates/labcolors-wasm/src/*, crates/labcolors-ffi/src/lib.rs, packages/colors/index.d.ts
Profiles, guarantees, statuses, evidence и indeterminate outcomes передаются через DTO, JSON, TypeScript, WASM parity и UniFFI.
JavaScript runtime и adaptive Glow
packages/colors/adapt-theme.js, packages/colors/test/*, packages/colors/effective-bg.js
JS boundary проверяет точные alpha/composites, а adaptive runtime выборочно пересогласует stable Glow satellites без сброса текущей цветовой анимации.
Conformance, release и CI
conformance/*, scripts/*, .github/workflows/*, packages/colors/package.json
Conformance pack v2, pinned toolchains, build metadata, tarball validation, clean-consumer smoke и publication guards формируют воспроизводимый release pipeline.
Документация и supporting changes
docs/*, README.md, CHANGELOG.md, bindings/swift/*, Cargo.toml, LICENSE
ADR, migration, README, changelog и Swift/conformance-документация фиксируют API, гарантии, ограничения и версии контрактов.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related issues

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed PR закрывает #282 и #286: exact no-op/legacy Glow разделены по typed profiles, а BackdropBox стал validated value object с typed errors.
Out of Scope Changes check ✅ Passed Явных изменений вне целей PR не видно; все затронутые области поддерживают release, conformance или typed Glow/alpha контракты.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Заголовок кратко и точно отражает основные изменения: точный alpha-контракт и типизированный Glow runtime в core.
✨ 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/exact-glow-alpha-pr

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

Copy link
Copy Markdown
Collaborator Author

Roadmap/merge gate после аудита 5-дневного среза

Направление PR соответствует текущему correctness-root: доказанный finite sRGB8 boundary, final emitted-state verification и explicit certificates усиливают существующий adaptive resolver, а не заменяют его статическим generator-ом.

До ready/merge обязательны:

  1. RELEASE: опубликовать exact-alpha/glow как breaking pre-1.0 версии #259: согласованный Rust/npm version bump, migration/changelog и release manifest.
  2. Full Rust/WASM/JS/Swift/package-smoke CI на финальном head.
  3. Public API/wire review новых обязательных полей, compatibility aliases и shortest-roundtrip alpha.
  4. Differential evidence, что все изменения вне заявленных 24 alpha leaves сохраняют прежние bytes/statuses/contracts.
  5. Явное принятие WASM size delta и измерений; correctness не ослаблять ради старого размера.
  6. Не расширять point encoded-sRGB8 claim на spatial blur/HDR/WCG/browser certification (ARCH/NUMERICS: точный glow recipe и отдельный SpatialField analysis #221/PLATFORM/CONFORMANCE: один core contract для Rust, WASM/JS, Swift и CLI #258).
  7. Обновить CURRENT STATUS: M2a/M2b merged (#514) - next: semantic verifier / O1b #228 после финального head и перед squash merge.

PR остаётся draft до выполнения release/migration gate; после этого ready → review → squash merge. Он не блокирует параллельное исследование #219/#261, но эти исследования не входят в его scope.

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

@lemone112, understood — noted the merge-gate roadmap. I'll proceed with a review of the current head now. Given the PR remains in draft and several gating items (release/version bump via #259, full CI matrix, differential evidence beyond the 24 alpha leaves, WASM size acceptance) are still open, I'll flag any findings inline but won't treat draft status as blocking the review itself.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

coderabbitai[bot]
coderabbitai Bot previously requested changes Jul 11, 2026

@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 (3)
docs/empirical-inventory.md (1)

106-107: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Не смешивайте открытый статус с терминальным классом.

В docs/empirical-residue.md указано, что существует ровно четыре терминальных класса (a)/(b)/(c)/(e) и каждая константа закрыта одним из них. Здесь ОТКРЫТО находится в колонке класс, поэтому две gamma-константы не входят в заявленные итоги (a)=6, (b)=1, (c)=7, (e)=11. Добавьте явный нетерминальный статус и пересчитайте инвентарь либо вынесите открытые модели из таблицы терминальной классификации.

🤖 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 `@docs/empirical-inventory.md` around lines 106 - 107, В разделе про
`PAIR_CROSSOVER_Y` не используйте `ОТКРЫТО` как терминальный класс: добавьте
отдельный явный нетерминальный статус для двух gamma-констант и пересчитайте
итоги `(a)=6, (b)=1, (c)=7, (e)=11`, либо вынесите открытые модели из таблицы
терминальной классификации, согласовав данные с `docs/empirical-residue.md`.
crates/labcolors-core/src/alpha.rs (1)

406-434: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Несовместимо с заявленным MSRV 1.85

if requested_alpha > 0.0 && let Some(tint) = ... требует Rust 1.88+, а в workspace сейчас указан rust-version = "1.85". Либо поднимите MSRV, либо перепишите условие без let-chain.

🤖 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-core/src/alpha.rs` around lines 406 - 434, Update
resolve_alpha_analog to remain compatible with the workspace MSRV 1.85 by
replacing the let-chain in the requested_alpha/invert_composite_encoded check
with an equivalent nested if or separate conditional binding; do not change the
function’s behavior or raise the MSRV.
crates/labcolors-core/src/semantic.rs (1)

2613-2647: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Уберите мёртвую ветку Ok(None) в crates/labcolors-core/src/semantic.rs:2635resolve_alpha_analog_srgb8 сейчас возвращает только Err(...) или Ok(Some(...)), поэтому этот arm не нужен. Если резервного кейса на будущее нет, упростите контракт до Result<([u8; 3], f64), String>.

🤖 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-core/src/semantic.rs` around lines 2613 - 2647, Remove the
unreachable Ok(None) match arm in resolve_rgba_inverted because
resolve_alpha_analog_srgb8 currently returns only Err or Ok(Some). Prefer
simplifying the alpha resolver contract to Result<([u8; 3], f64), String> if no
future empty-result case is required, then update resolve_rgba_inverted and all
affected callers to match the simplified result.
🤖 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 `@docs/decisions/0004-finite-alpha-glow-reference.md`:
- Around line 128-130: Экранируйте ссылку на issue `#258` в начале физической
строки, добавив обратный слеш перед символом `#` в соответствующем абзаце
документа.

---

Outside diff comments:
In `@crates/labcolors-core/src/alpha.rs`:
- Around line 406-434: Update resolve_alpha_analog to remain compatible with the
workspace MSRV 1.85 by replacing the let-chain in the
requested_alpha/invert_composite_encoded check with an equivalent nested if or
separate conditional binding; do not change the function’s behavior or raise the
MSRV.

In `@crates/labcolors-core/src/semantic.rs`:
- Around line 2613-2647: Remove the unreachable Ok(None) match arm in
resolve_rgba_inverted because resolve_alpha_analog_srgb8 currently returns only
Err or Ok(Some). Prefer simplifying the alpha resolver contract to Result<([u8;
3], f64), String> if no future empty-result case is required, then update
resolve_rgba_inverted and all affected callers to match the simplified result.

In `@docs/empirical-inventory.md`:
- Around line 106-107: В разделе про `PAIR_CROSSOVER_Y` не используйте `ОТКРЫТО`
как терминальный класс: добавьте отдельный явный нетерминальный статус для двух
gamma-констант и пересчитайте итоги `(a)=6, (b)=1, (c)=7, (e)=11`, либо вынесите
открытые модели из таблицы терминальной классификации, согласовав данные с
`docs/empirical-residue.md`.
🪄 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: 679907d8-98c2-4888-bb25-a151774fd995

📥 Commits

Reviewing files that changed from the base of the PR and between c72fbc7 and 46c47b5.

📒 Files selected for processing (33)
  • crates/labcolors-core/Cargo.toml
  • crates/labcolors-core/benches/glow_alpha.rs
  • crates/labcolors-core/examples/figma_anchor_provenance.rs
  • crates/labcolors-core/src/alpha.rs
  • crates/labcolors-core/src/config.rs
  • crates/labcolors-core/src/config/tests.rs
  • crates/labcolors-core/src/glow.rs
  • crates/labcolors-core/src/lib.rs
  • crates/labcolors-core/src/material.rs
  • crates/labcolors-core/src/neutral.rs
  • crates/labcolors-core/src/semantic.rs
  • crates/labcolors-core/src/solve.rs
  • crates/labcolors-core/src/spaces/oklch.rs
  • crates/labcolors-core/src/spaces/p3.rs
  • crates/labcolors-core/src/spaces/srgb.rs
  • crates/labcolors-core/tests/data/labui_emission_golden.txt
  • crates/labcolors-wasm/src/dto.rs
  • crates/labcolors-wasm/src/engine.rs
  • crates/labcolors-wasm/src/lib.rs
  • crates/labcolors-wasm/src/projection.rs
  • crates/labcolors-wasm/tests/wasm_parity.rs
  • docs/NAMING.md
  • docs/decisions/0004-finite-alpha-glow-reference.md
  • docs/empirical-inventory.md
  • docs/empirical-residue.md
  • docs/whitepaper.md
  • packages/colors/README.md
  • packages/colors/effective-bg.js
  • packages/colors/index.d.ts
  • packages/colors/test/chain-invariants.test.mjs
  • packages/colors/test/runtime.test.mjs
  • packages/colors/test/wasm-boundary-parity.test.mjs
  • packages/colors/test/wasm-boundary.golden.json

Comment thread docs/decisions/0004-finite-alpha-glow-reference.md Outdated
@lemone112

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

coderabbitai[bot]
coderabbitai Bot previously requested changes Jul 11, 2026

@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: 13

Caution

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

⚠️ Outside diff range comments (2)
crates/labcolors-core/src/agnostic_gates.rs (1)

40-50: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Дублирование repr() между файлами.

Эта функция почти байт-в-байт повторяет repr() в crates/labcolors-core/src/config/tests.rs (обе получили идентичную новую ветку GlowIndeterminate). Если в будущем в Resolved добавится вариант и кто-то обновит только один repr, голден-тесты по двум разным файлам молча разойдутся по покрытию.

Стоит вынести общий repr(&Resolved) -> String в единый тестовый helper-модуль и импортировать его в обоих местах.

🤖 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-core/src/agnostic_gates.rs` around lines 40 - 50, Вынесите
дублирующуюся функцию repr из agnostic_gates.rs и config/tests.rs в общий
тестовый helper-модуль, сохранив сигнатуру и все варианты сопоставления
Resolved, включая GlowIndeterminate. Импортируйте единый helper в обоих местах и
удалите локальные реализации, чтобы дальнейшие изменения Resolved обрабатывались
централизованно.
crates/labcolors-wasm/src/projection.rs (1)

88-155: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Вынести сериализацию decisionGuarantee в отдельный хелпер.

Проверка canonical_alpha корректна и по делу (защищает от рассинхронизации alpha/alphaCss структурной ошибкой, а не паникой). Но inline-match по DecisionGuaranteeV1 внутри и без того большой ветки RoleOutcome::Glow (уже отмеченной как high complexity) усложняет чтение resolved_json. Аналогичный паттерн повторяется чуть ниже для NumericalIndeterminacyV1 (строки 164-180) — оба можно вынести в приватные функции по образцу field_opt_str.

♻️ Пример выделения хелпера
+fn push_decision_guarantee(
+    out: &mut String,
+    guarantee: labcolors_core::DecisionGuaranteeV1,
+) -> Result<(), BindingError> {
+    out.push_str(",\"decisionGuarantee\":{\"kind\":");
+    match guarantee {
+        labcolors_core::DecisionGuaranteeV1::BitExact => {
+            push_str_lit(out, "bit-exact");
+        }
+        labcolors_core::DecisionGuaranteeV1::OutwardIntervalV1(interval) => {
+            push_str_lit(out, "outward-interval-v1");
+            field_num(out, "lower", interval.lower())?;
+            field_num(out, "upper", interval.upper())?;
+        }
+        labcolors_core::DecisionGuaranteeV1::LegacyPlatformDependentV1 => {
+            push_str_lit(out, "legacy-platform-dependent-v1");
+        }
+        _ => {
+            return Err(BindingError::Internal {
+                reason: "проекция: неизвестный DecisionGuaranteeV1".to_string(),
+            });
+        }
+    }
+    out.push('}');
+    Ok(())
+}
🤖 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/projection.rs` around lines 88 - 155, Вынесите
inline-match по DecisionGuaranteeV1 из сериализации RoleOutcome::Glow в
отдельный приватный helper по образцу field_opt_str, сохранив текущие JSON-поля,
обработку неизвестных вариантов и возврат BindingError. Аналогично вынесите
повторяющийся match по NumericalIndeterminacyV1 в соседней сериализации, чтобы
resolved_json содержал прежний результат при упрощённой основной ветке.
🤖 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 @.github/workflows/ci.yml:
- Line 36: Configure the actions/checkout step in the msrv job with
persist-credentials set to false, while preserving the existing pinned action
reference and all other job behavior.

In @.github/workflows/publish.yml:
- Around line 19-23: Добавьте настройку concurrency в workflow publish для
ограничения параллельных запусков по текущему ref, используя группу, зависящую
от github.ref. Не изменяйте существующий триггер push для тегов colors-v* и
сохраните поведение публикации.
- Around line 308-311: Update the npm publish step to pass the verified-artifact
tarball through an environment variable, then reference that variable in the run
command instead of directly interpolating
steps.verified-artifact.outputs.tarball. Keep the existing NODE_AUTH_TOKEN and
publish options unchanged.

In `@bindings/swift/README.md`:
- Around line 40-44: Remove the conditional future-plan wording about the
swift-conformance-macos-reference job from the README section describing pack
1.0.0 and pack 2.0.0. Keep only currently accurate attestation and CI
information, and move the macOS-runner plan to an Issue rather than documenting
it as an ongoing README contract.

In `@crates/labcolors-core/src/alpha.rs`:
- Around line 578-585: Update the debug_assert! for floor > requested_alpha in
the surrounding alpha-selection function to include a diagnostic message and a
brief comment explaining that floor is the first passing alpha after the
already-failed requested value; preserve the existing assertion condition and
control flow.

In `@crates/labcolors-core/src/config/preset.rs`:
- Around line 254-258: Добавьте короткий комментарий рядом с замыканием glow в
preset, поясняющий, что явный выбор LegacyPlatformDependentV1 сохраняет
byte-identical CSS-эмиссию существующих labui-фикстур и не допускает неявного
перехода к Indeterminate под stable-v1. Не меняйте саму настройку
decision_profile или остальную логику RoleRecipe::Glow.

In `@crates/labcolors-core/src/material.rs`:
- Around line 92-100: Make BackdropBox fields private so invalid struct literals
cannot bypass its invariant, and expose a try_new constructor that validates
encoded-sRGB bounds and rejects any min channel greater than max. Return a typed
error distinguishing invalid encoded values from reversed bounds, and update
callers to construct instances through try_new while preserving is_valid’s
validation contract.

In `@crates/labcolors-core/src/numerics.rs`:
- Around line 138-155: Добавь в тесты glow кросс-проверку, что поле
row.legacy_profile совпадает с
Some(GlowDecisionProfileV1::LegacyPlatformDependentV1.key()). Замени проверку
отдельного строкового литерала в numerics.rs либо дополни её через этот символ,
сохранив существующие проверки реестра.

In `@docs/migrations/exact-alpha-glow.md`:
- Around line 120-134: Экранируйте внутренние символы `|` в ячейках `targetDj`,
`haloAchievedDj` и `coreAchievedDj` таблицы полей `glow`, чтобы Markdown
воспринимал `|ΔJ′|` как обычный текст и сохранял одинаковое число столбцов.

In `@packages/colors/adapt-theme.js`:
- Line 287: Use the existing stableVarKeys helper as the single source for Glow
satellite keys: update stableGlowsFrom to obtain emittedKeys through
stableVarKeys instead of constructing the role.cssVar, -core, and -alpha entries
inline, preserving the current key order and behavior.

In `@packages/colors/test/release-provenance.test.mjs`:
- Around line 26-44: Изолируйте переменную окружения GITHUB_SHA в тесте “prepack
source guard is clean-tree and exact-SHA executable evidence”: сохраните
исходное значение, удалите его либо установите в SHA временного
fixture-репозитория до вызова verifiedSourceSha(), а затем обязательно
восстановите значение в блоке finally, включая корректную обработку
отсутствующей переменной.

In `@scripts/prepare-npm-package.mjs`:
- Around line 101-104: Вынеси единый helper workspaceVersion в общий модуль
scripts и используй его в prepare-npm-package.mjs вместо локального
regex-парсинга coreVersion, а также замени дублирующую реализацию в
verify-package-release.mjs. Ограничь разбор секцией [workspace.package] до
следующей TOML-секции, сохрани проверку отсутствующей версии с ошибкой
“workspace core version is absent” и передавай одинаковый результат обоим
скриптам.

In `@scripts/verify-package-release.mjs`:
- Around line 50-64: Update command() and the related npm() call paths to pass
an explicit timeout to execFileSync for every external command, including npm
install, npm pack, and tsc. Use the existing release-script timeout
configuration if available, and preserve the current structured fail() handling
when a command exceeds the limit or otherwise fails.

---

Outside diff comments:
In `@crates/labcolors-core/src/agnostic_gates.rs`:
- Around line 40-50: Вынесите дублирующуюся функцию repr из agnostic_gates.rs и
config/tests.rs в общий тестовый helper-модуль, сохранив сигнатуру и все
варианты сопоставления Resolved, включая GlowIndeterminate. Импортируйте единый
helper в обоих местах и удалите локальные реализации, чтобы дальнейшие изменения
Resolved обрабатывались централизованно.

In `@crates/labcolors-wasm/src/projection.rs`:
- Around line 88-155: Вынесите inline-match по DecisionGuaranteeV1 из
сериализации RoleOutcome::Glow в отдельный приватный helper по образцу
field_opt_str, сохранив текущие JSON-поля, обработку неизвестных вариантов и
возврат BindingError. Аналогично вынесите повторяющийся match по
NumericalIndeterminacyV1 в соседней сериализации, чтобы resolved_json содержал
прежний результат при упрощённой основной ветке.
🪄 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: a9ef5f7c-4919-4201-b1e5-a52ab2c2ecb6

📥 Commits

Reviewing files that changed from the base of the PR and between 46c47b5 and 1826d96.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • packages/colors/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (79)
  • .cargo/mutants.toml
  • .github/workflows/ci.yml
  • .github/workflows/mutation.yml
  • .github/workflows/native-conformance.yml
  • .github/workflows/publish.yml
  • .gitignore
  • CHANGELOG.md
  • Cargo.toml
  • LICENSE
  • README.md
  • bindings/swift/Package.swift
  • bindings/swift/README.md
  • bindings/swift/Tests/LabColorsConformanceTests/ConformanceTests.swift
  • bindings/swift/ci/run-conformance.sh
  • conformance/README.md
  • conformance/vectors/alpha.json
  • conformance/vectors/manifest.json
  • conformance/vectors/muddiness.json
  • crates/labcolors-conformance/Cargo.toml
  • crates/labcolors-conformance/src/lib.rs
  • crates/labcolors-conformance/tests/reference_runner.rs
  • crates/labcolors-core/Cargo.toml
  • crates/labcolors-core/LICENSE
  • crates/labcolors-core/README.md
  • crates/labcolors-core/benches/glow_alpha.rs
  • crates/labcolors-core/src/accent_surface.rs
  • crates/labcolors-core/src/agnostic_gates.rs
  • crates/labcolors-core/src/alpha.rs
  • crates/labcolors-core/src/config.rs
  • crates/labcolors-core/src/config/preset.rs
  • crates/labcolors-core/src/config/tests.rs
  • crates/labcolors-core/src/continuity_tests.rs
  • crates/labcolors-core/src/glow.rs
  • crates/labcolors-core/src/lib.rs
  • crates/labcolors-core/src/lpc.rs
  • crates/labcolors-core/src/material.rs
  • crates/labcolors-core/src/neutral.rs
  • crates/labcolors-core/src/numerics.rs
  • crates/labcolors-core/src/pair.rs
  • crates/labcolors-core/src/semantic.rs
  • crates/labcolors-core/src/sentiment.rs
  • crates/labcolors-core/src/solve.rs
  • crates/labcolors-core/tests/empirical_inventory.rs
  • crates/labcolors-ffi/Cargo.toml
  • crates/labcolors-ffi/src/lib.rs
  • crates/labcolors-preview/Cargo.toml
  • crates/labcolors-wasm/Cargo.toml
  • crates/labcolors-wasm/LICENSE
  • crates/labcolors-wasm/src/config_dto.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/tests/data/labui.config.json
  • crates/labcolors-wasm/tests/wasm_parity.rs
  • docs/NAMING.md
  • docs/conformance/local-swift-attestation.md
  • docs/decisions/0004-finite-alpha-glow-reference.md
  • docs/empirical-inventory.md
  • docs/empirical-residue.md
  • docs/migrations/exact-alpha-glow.md
  • docs/whitepaper.md
  • experiments/psychophysics/Cargo.toml
  • experiments/psychophysics/src/stimulus.rs
  • packages/colors/README.md
  • packages/colors/adapt-theme.d.ts
  • packages/colors/adapt-theme.js
  • packages/colors/apply-theme.js
  • packages/colors/index.d.ts
  • packages/colors/package.json
  • packages/colors/smoke.consumer.ts
  • packages/colors/test/adapt-theme.test.mjs
  • packages/colors/test/chain-invariants.test.mjs
  • packages/colors/test/release-contract.test.mjs
  • packages/colors/test/release-provenance.test.mjs
  • scripts/docs-drift.test.mjs
  • scripts/prepare-npm-package.mjs
  • scripts/verify-package-release.mjs

Comment thread .github/workflows/ci.yml
Comment thread .github/workflows/publish.yml
Comment thread .github/workflows/publish.yml Outdated
Comment thread bindings/swift/README.md Outdated
Comment thread crates/labcolors-core/src/alpha.rs
Comment thread docs/migrations/exact-alpha-glow.md Outdated
Comment thread packages/colors/adapt-theme.js Outdated
Comment thread packages/colors/test/release-provenance.test.mjs Outdated
Comment thread scripts/prepare-npm-package.mjs Outdated
Comment thread scripts/verify-package-release.mjs Outdated

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Collaborator Author

Thread audit on final head de5e86e:

  • publish concurrency is resolved with the stricter global npm-publish group (cancel-in-progress: false), serializing both reruns and competing release tags for the single registry package;
  • numerical registry now derives legacy_profile directly from GlowDecisionProfileV1::LegacyPlatformDependentV1.key(), so the duplicated string contract no longer exists.

All 14 review threads are now resolved; fresh incremental CodeRabbit review and exact-head CI/native remain required before merge.

coderabbitai[bot]
coderabbitai Bot previously requested changes Jul 11, 2026

@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: 3

Caution

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

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

929-953: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Магическая константа 0.5 без локального комментария.

let alpha = 0.5; в точной no-op ветке — валидное каноническое значение (весь домен [0,1] эквивалентен для точечного no-op, поэтому берётся середина), но само число не сопровождено комментарием на месте использования; обоснование разбросано по doc-строке функции выше. В крейте, где path instructions явно требуют комментировать магические константы, стоит добавить короткую пометку прямо у строки.

💬 Предлагаемое пояснение
     if slopes_are_exact_srgb8_noop(slopes) {
+        // Весь домен [0,1] даёт одинаковый байтовый composite (точный no-op);
+        // 0.5 — канонический медианный представитель, а не измеренная величина.
         let alpha = 0.5;

As per path instructions for crates/labcolors-core/**/*.rs: «Отсутствие магических констант без комментариев».

🤖 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-core/src/glow.rs` around lines 929 - 953, Добавьте короткий
локальный комментарий непосредственно перед присваиванием alpha в ветке
slopes_are_exact_srgb8_noop, поясняющий, что 0.5 — каноническое среднее
значение, поскольку при точном no-op любое alpha из диапазона [0,1] даёт тот же
результат. Не изменяйте вычисления или остальную структуру NumericalDecisionV1.

Source: Path instructions

🤖 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/glow.rs`:
- Around line 398-413: Переместите doc-комментарий с блоком `# Errors` от
приватной функции `screen_channel_over_srgb8` к публичной функции
`screen_layer_over_srgb8`, расположенной ниже. Оставьте у
`screen_channel_over_srgb8` только документацию о вычислении канала, а описание
`Err` прикрепите непосредственно к функции, возвращающей `Result` и выполняющей
валидацию `alpha`.

In `@crates/labcolors-core/src/solve.rs`:
- Around line 1321-1330: Переместите тест
internal_invariant_failure_is_not_reported_as_invalid_client_input ниже всех
import-строк внутри модуля tests, включая use crate::lpc::lpc_with_vc, чтобы
блок импортов оставался непрерывным.

In `@crates/labcolors-core/src/wcag.rs`:
- Around line 17-25: Update LEGACY_CHANNEL_SPLIT_RIGHT to derive the next
binary64 value directly from LEGACY_CHANNEL_SPLIT instead of maintaining a
separate hexadecimal literal, preserving its role as the first power-branch
value.

---

Outside diff comments:
In `@crates/labcolors-core/src/glow.rs`:
- Around line 929-953: Добавьте короткий локальный комментарий непосредственно
перед присваиванием alpha в ветке slopes_are_exact_srgb8_noop, поясняющий, что
0.5 — каноническое среднее значение, поскольку при точном no-op любое alpha из
диапазона [0,1] даёт тот же результат. Не изменяйте вычисления или остальную
структуру NumericalDecisionV1.
🪄 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: 694912f0-2f14-4ae5-87ba-a87a783f0308

📥 Commits

Reviewing files that changed from the base of the PR and between 1826d96 and de5e86e.

⛔ Files ignored due to path filters (1)
  • packages/colors/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (64)
  • .cargo/mutants.toml
  • .github/workflows/ci.yml
  • .github/workflows/mutation.yml
  • .github/workflows/native-conformance.yml
  • .github/workflows/publish.yml
  • CHANGELOG.md
  • bindings/swift/README.md
  • bindings/swift/Tests/LabColorsConformanceTests/ConformanceTests.swift
  • conformance/README.md
  • crates/labcolors-conformance/src/bin/gen.rs
  • crates/labcolors-conformance/src/lib.rs
  • crates/labcolors-conformance/tests/reference_runner.rs
  • crates/labcolors-core/benches/glow_alpha.rs
  • crates/labcolors-core/examples/unique_yellow_provenance.rs
  • crates/labcolors-core/src/agnostic_gates.rs
  • crates/labcolors-core/src/alpha.rs
  • crates/labcolors-core/src/cleanliness.rs
  • crates/labcolors-core/src/config.rs
  • crates/labcolors-core/src/config/preset.rs
  • crates/labcolors-core/src/config/test_support.rs
  • crates/labcolors-core/src/config/tests.rs
  • crates/labcolors-core/src/glow.rs
  • crates/labcolors-core/src/lib.rs
  • crates/labcolors-core/src/material.rs
  • crates/labcolors-core/src/numerics.rs
  • crates/labcolors-core/src/semantic.rs
  • crates/labcolors-core/src/solve.rs
  • crates/labcolors-core/src/spaces/vc.rs
  • crates/labcolors-core/src/wcag.rs
  • crates/labcolors-core/tests/data/labui_emission_golden.txt
  • crates/labcolors-core/tests/empirical_inventory.rs
  • crates/labcolors-core/tests/property_invariants.rs
  • crates/labcolors-ffi/src/lib.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/tests/wasm_parity.rs
  • docs/decisions/0001-config-boundary.md
  • docs/decisions/0004-finite-alpha-glow-reference.md
  • docs/empirical-inventory.md
  • docs/empirical-residue.md
  • docs/migrations/exact-alpha-glow.md
  • docs/whitepaper.md
  • packages/colors/README.md
  • packages/colors/adapt-theme.d.ts
  • packages/colors/adapt-theme.js
  • packages/colors/effective-bg.d.ts
  • packages/colors/effective-bg.js
  • packages/colors/index.d.ts
  • packages/colors/package.json
  • packages/colors/smoke.consumer.ts
  • packages/colors/test/adapt-theme.test.mjs
  • packages/colors/test/chain-invariants.test.mjs
  • packages/colors/test/hotpath-parity.test.mjs
  • packages/colors/test/release-contract.test.mjs
  • packages/colors/test/release-provenance.test.mjs
  • packages/colors/test/runtime.test.mjs
  • packages/colors/test/wasm-boundary.golden.json
  • scripts/cargo-workspace.mjs
  • scripts/docs-drift.test.mjs
  • scripts/prepare-npm-package.mjs
  • scripts/verify-package-release.mjs

Comment thread crates/labcolors-core/src/glow.rs Outdated
Comment thread crates/labcolors-core/src/solve.rs Outdated
Comment thread crates/labcolors-core/src/wcag.rs Outdated

lemone112 commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator Author

Fresh-review findings are verified and fixed in 416accc3e699fce4f02a46aceb8468f721fa3362:

  • screen_layer_over_srgb8 now owns its truthful public # Errors; the private channel helper no longer claims Err.
  • the solve.rs test module has one contiguous import block.
  • the legacy seam right-neighbour is derived from the frozen split; the existing bit-relation test and an explicit Rust 1.85 check prove identical bits.
  • exact no-op alpha = 0.5 now has local provenance as a canonical representative, not a measurement.

Local exact-head evidence: full Rust workspace green; Rust 1.85 core check green; clippy/rustfmt/rustdoc green; Node 24 and Node 22.11 each 104/104; Chrome 150 12/12; release verifier green; two independent release builds produced the same WASM SHA-256 ec0a916d2534119994c997b7dd382d10377f7397f8cdf02c2a83b4a5e7cdf5bd. Remote CI and native-conformance are green on PR merge-ref f5646a7c017011415cfd9d4478943dbda837d881 (base f82300d… + head 416accc…).

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

@lemone112, acknowledged — noted the fixes in 416accc3e699fce4f02a46aceb8468f721fa3362:

  • screen_layer_over_srgb8's public # Errors doc now matches actual behavior, with the private channel helper's doc corrected to no longer claim Err.
  • solve.rs test module imports consolidated into one contiguous block.
  • Legacy seam right-neighbour now derived from the frozen split, backed by the existing bit-relation test plus an explicit Rust 1.85 check.
  • Exact no-op alpha = 0.5 now carries local provenance as a canonical representative rather than an empirical measurement.

Along with the exact-head CI evidence (full Rust workspace, Rust 1.85 core check, clippy/rustfmt/rustdoc, Node 24/22.11 104/104, Chrome 150 12/12, release verifier, reproducible WASM SHA-256 across two independent builds, and green native-conformance) — I'll run a full review against this head now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

@lemone112, acknowledged — noted the fixes in 416accc3e699fce4f02a46aceb8468f721fa3362:

  • screen_layer_over_srgb8 public # Errors doc now matches actual behavior; private channel helper's doc no longer claims Err.
  • solve.rs test module imports consolidated into one contiguous block.
  • Legacy seam right-neighbour now derived from the frozen split, backed by the existing bit-relation test plus an explicit Rust 1.85 check.
  • Exact no-op alpha = 0.5 now carries local provenance as a canonical representative rather than an empirical measurement.

Combined with the exact-head evidence (full Rust workspace, Rust 1.85 core check, clippy/rustfmt/rustdoc, Node 24/22.11, Chrome 150, release verifier, reproducible WASM SHA-256 across two independent builds, and green remote CI/native-conformance on merge-ref f5646a7c017011415cfd9d4478943dbda837d881), I'll run a full review against this head now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

Labels

None yet

Projects

None yet

1 participant