P1: production WCAG hard-path для joint component - #365
Conversation
WalkthroughДобавлена поддержка WCAG 2.2 ограничений в joint-программах: новые варианты ограничений и evidence, классификация pass/violation, обработка ошибок оценивателя, выбор кандидатов и recheck. Также удалён атрибут подавления dead_code у ChangesИнтеграция WCAG 2.2
Компиляционная очистка appearance
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant JointPointProgramV1
participant assess_visible_point_hard
participant JointConstraintDecisionV1
participant SelectedJointTupleV1
JointPointProgramV1->>assess_visible_point_hard: оценивает Wcag22Srgb8V1
assess_visible_point_hard->>JointConstraintDecisionV1: возвращает WCAG 2.2 evidence
JointConstraintDecisionV1-->>JointPointProgramV1: предоставляет pass/violation и цвета
JointPointProgramV1->>SelectedJointTupleV1: передаёт выполнимый кортеж
SelectedJointTupleV1->>SelectedJointTupleV1: выполняет recheck
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
9fc4254 to
e64e8f8
Compare
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/joint_tests.rs`:
- Around line 155-189: Добавьте в joint-тесты helper `wcag_lower` и happy-path
тест для `JointVisibleTargetV1::Lower`, проверяющий корректные Pass/Violation
решения и выбранного кандидата на derived lower surface. Также добавьте тест,
объявляющий критерий как `not applicable`/`ReportOnly`, который вызывает
`ApplicableWcag22EvaluationErrorV1::ReportOnly`, и проверьте распространение
ошибки евалюатора через `evaluate()` и `recheck()` как
`JointReportErrorV1::Evaluator` и `SelectedRecheckErrorV1::Evaluator`
соответственно.
In `@crates/labcolors-core/src/joint.rs`:
- Around line 324-357: Добавьте поясняющий комментарий непосредственно перед
веткой JointHardConstraintV1::Wcag22 в вычислении decision, документируя, что
ошибки WCAG-евалюатора через JointReportErrorV1::Evaluator намеренно прерывают
execute() и аннулируют весь joint-отчёт, а не только текущую ячейку; объясните,
что такие ошибки указывают на недействительный результат оценки (например,
ReportOnly или CriterionMismatch), поэтому частичный отчёт недопустим. Не
изменяйте существующее поведение и обработку ветки Exact.
🪄 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: b05a895f-3f5d-4e60-8007-1bd8310be276
📒 Files selected for processing (5)
crates/labcolors-core/src/appearance.rscrates/labcolors-core/src/constraints/mod.rscrates/labcolors-core/src/constraints/wcag22.rscrates/labcolors-core/src/joint.rscrates/labcolors-core/src/joint_tests.rs
💤 Files with no reviewable changes (1)
- crates/labcolors-core/src/appearance.rs
| #[test] | ||
| fn production_wcag_constraint_classifies_real_upper_on_derived_surface() { | ||
| let report = program(vec![wcag_upper(1, Wcag22CriterionV1::Sc143TextDefault)]) | ||
| .evaluate( | ||
| candidates(vec![ | ||
| candidate(0, ([0x20; 3], 1.0), ([0x20; 3], 1.0)), | ||
| candidate(1, ([0x20; 3], 1.0), ([0xFF; 3], 1.0)), | ||
| ]), | ||
| observation(20, vec![(1, [0; 3])]), | ||
| ) | ||
| .unwrap(); | ||
|
|
||
| assert!(matches!( | ||
| report.cells()[0].decision(), | ||
| JointConstraintDecisionV1::Wcag22Violation(_) | ||
| )); | ||
| assert!(matches!( | ||
| report.cells()[1].decision(), | ||
| JointConstraintDecisionV1::Wcag22Pass(_) | ||
| )); | ||
| assert_eq!(report.cells()[1].decision().actual(), Srgb8::new([0xFF; 3])); | ||
| assert_eq!(report.cells()[1].decision().target(), Srgb8::new([0x20; 3])); | ||
|
|
||
| let HardFeasibilityV1::NonEmpty(feasible) = report.classify() else { | ||
| panic!("white label must be feasible on the emitted dark fill"); | ||
| }; | ||
| let policy = DeclaredTotalOrderV1::new( | ||
| feasible.candidate_set(), | ||
| vec![CandidateOrdinalV1::new(0), CandidateOrdinalV1::new(1)], | ||
| ) | ||
| .unwrap(); | ||
| let verified = feasible.select(policy).recheck().unwrap(); | ||
| assert_eq!(verified.ordinal(), CandidateOrdinalV1::new(1)); | ||
| assert!(verified.fresh_executions()[0].derived_surface_is_exact()); | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win
Добавить тесты для Lower-таргета WCAG22 и для пути ошибки евалюатора.
Текущий тест покрывает только JointVisibleTargetV1::Upper + Pass/Violation happy-path. Согласно описанию PR, WCAG-путь должен обрабатывать также нижние ("derived lower") поверхности, и производственный код явно проносит JointReportErrorV1::Evaluator/SelectedRecheckErrorV1::Evaluator через execute()/recheck() — но ни один тест не проверяет этот путь (например, через объявление критерия как "not applicable" / ReportOnly, дающее ApplicableWcag22EvaluationErrorV1::ReportOnly).
Хотите, чтобы я подготовил недостающие тесты (wcag_lower helper + happy-path на Lower, и тест на распространение ошибки евалюатора через evaluate()/recheck())?
🤖 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/joint_tests.rs` around lines 155 - 189, Добавьте в
joint-тесты helper `wcag_lower` и happy-path тест для
`JointVisibleTargetV1::Lower`, проверяющий корректные Pass/Violation решения и
выбранного кандидата на derived lower surface. Также добавьте тест, объявляющий
критерий как `not applicable`/`ReportOnly`, который вызывает
`ApplicableWcag22EvaluationErrorV1::ReportOnly`, и проверьте распространение
ошибки евалюатора через `evaluate()` и `recheck()` как
`JointReportErrorV1::Evaluator` и `SelectedRecheckErrorV1::Evaluator`
соответственно.
| let target = constraint.target(); | ||
| let occurrence = match target { | ||
| JointVisibleTargetV1::Lower => &lower, | ||
| JointVisibleTargetV1::Upper => &upper, | ||
| }; | ||
| let decision = match assess_visible_point_hard( | ||
| occurrence, | ||
| &ExactSrgb8IdentityV1, | ||
| constraint.invocation, | ||
| ) { | ||
| Ok(HardDecision::Pass(evidence)) => { | ||
| JointConstraintDecisionV1::Pass(evidence) | ||
| let decision = match constraint { | ||
| JointHardConstraintV1::Exact { invocation, .. } => { | ||
| match assess_visible_point_hard( | ||
| occurrence, | ||
| &ExactSrgb8IdentityV1, | ||
| invocation, | ||
| ) { | ||
| Ok(HardDecision::Pass(evidence)) => { | ||
| JointConstraintDecisionV1::Pass(evidence) | ||
| } | ||
| Ok(HardDecision::Violation(evidence)) => { | ||
| JointConstraintDecisionV1::Violation(evidence) | ||
| } | ||
| Err(error) => match error {}, | ||
| } | ||
| } | ||
| Ok(HardDecision::Violation(evidence)) => { | ||
| JointConstraintDecisionV1::Violation(evidence) | ||
| JointHardConstraintV1::Wcag22 { criterion, .. } => { | ||
| match assess_visible_point_hard(occurrence, &Wcag22Srgb8V1, criterion) | ||
| .map_err(JointReportErrorV1::Evaluator)? | ||
| { | ||
| HardDecision::Pass(evidence) => { | ||
| JointConstraintDecisionV1::Wcag22Pass(evidence) | ||
| } | ||
| HardDecision::Violation(evidence) => { | ||
| JointConstraintDecisionV1::Wcag22Violation(evidence) | ||
| } | ||
| } | ||
| } | ||
| Err(error) => match error {}, | ||
| }; |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Добавить комментарий, объясняющий закрытие всего отчёта при ошибке WCAG-евалюатора.
Ветка Wcag22 через .map_err(JointReportErrorV1::Evaluator)? обрывает выполнение execute() целиком (все кандидаты/кейсы), в отличие от ветки Exact, где ошибка типобезопасно необитаема (match error {}). Само поведение оправдано (PR-описание: "closes the full report on evaluator errors"), но инвариант не задокументирован — почему единичная ошибка евалюатора (например, ReportOnly/CriterionMismatch) должна аннулировать весь joint-отчёт, а не только текущую ячейку.
💬 Пример поясняющего комментария
+ // Ошибка евалюатора WCAG22 (ReportOnly/CriterionMismatch/Kernel)
+ // не зависит от конкретного кандидата: критерий конфигурируется на
+ // уровне программы, поэтому она детерминированно повторится для
+ // любого кандидата/кейса — отчёт закрывается сразу, без частичных
+ // результатов.
JointHardConstraintV1::Wcag22 { criterion, .. } => {
match assess_visible_point_hard(occurrence, &Wcag22Srgb8V1, criterion)
.map_err(JointReportErrorV1::Evaluator)?Как указано в coding guidelines: "Комментарии в коде должны объяснять почему и инвариант, а не пересказывать оператор."
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| let target = constraint.target(); | |
| let occurrence = match target { | |
| JointVisibleTargetV1::Lower => &lower, | |
| JointVisibleTargetV1::Upper => &upper, | |
| }; | |
| let decision = match assess_visible_point_hard( | |
| occurrence, | |
| &ExactSrgb8IdentityV1, | |
| constraint.invocation, | |
| ) { | |
| Ok(HardDecision::Pass(evidence)) => { | |
| JointConstraintDecisionV1::Pass(evidence) | |
| let decision = match constraint { | |
| JointHardConstraintV1::Exact { invocation, .. } => { | |
| match assess_visible_point_hard( | |
| occurrence, | |
| &ExactSrgb8IdentityV1, | |
| invocation, | |
| ) { | |
| Ok(HardDecision::Pass(evidence)) => { | |
| JointConstraintDecisionV1::Pass(evidence) | |
| } | |
| Ok(HardDecision::Violation(evidence)) => { | |
| JointConstraintDecisionV1::Violation(evidence) | |
| } | |
| Err(error) => match error {}, | |
| } | |
| } | |
| Ok(HardDecision::Violation(evidence)) => { | |
| JointConstraintDecisionV1::Violation(evidence) | |
| JointHardConstraintV1::Wcag22 { criterion, .. } => { | |
| match assess_visible_point_hard(occurrence, &Wcag22Srgb8V1, criterion) | |
| .map_err(JointReportErrorV1::Evaluator)? | |
| { | |
| HardDecision::Pass(evidence) => { | |
| JointConstraintDecisionV1::Wcag22Pass(evidence) | |
| } | |
| HardDecision::Violation(evidence) => { | |
| JointConstraintDecisionV1::Wcag22Violation(evidence) | |
| } | |
| } | |
| } | |
| Err(error) => match error {}, | |
| }; | |
| let target = constraint.target(); | |
| let occurrence = match target { | |
| JointVisibleTargetV1::Lower => &lower, | |
| JointVisibleTargetV1::Upper => &upper, | |
| }; | |
| let decision = match constraint { | |
| JointHardConstraintV1::Exact { invocation, .. } => { | |
| match assess_visible_point_hard( | |
| occurrence, | |
| &ExactSrgb8IdentityV1, | |
| invocation, | |
| ) { | |
| Ok(HardDecision::Pass(evidence)) => { | |
| JointConstraintDecisionV1::Pass(evidence) | |
| } | |
| Ok(HardDecision::Violation(evidence)) => { | |
| JointConstraintDecisionV1::Violation(evidence) | |
| } | |
| Err(error) => match error {}, | |
| } | |
| } | |
| // Ошибка евалюатора WCAG22 (ReportOnly/CriterionMismatch/Kernel) | |
| // не зависит от конкретного кандидата: критерий конфигурируется на | |
| // уровне программы, поэтому она детерминированно повторится для | |
| // любого кандидата/кейса — отчёт закрывается сразу, без частичных | |
| // результатов. | |
| JointHardConstraintV1::Wcag22 { criterion, .. } => { | |
| match assess_visible_point_hard(occurrence, &Wcag22Srgb8V1, criterion) | |
| .map_err(JointReportErrorV1::Evaluator)? | |
| { | |
| HardDecision::Pass(evidence) => { | |
| JointConstraintDecisionV1::Wcag22Pass(evidence) | |
| } | |
| HardDecision::Violation(evidence) => { | |
| JointConstraintDecisionV1::Wcag22Violation(evidence) | |
| } | |
| } | |
| } | |
| }; |
🤖 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/joint.rs` around lines 324 - 357, Добавьте
поясняющий комментарий непосредственно перед веткой
JointHardConstraintV1::Wcag22 в вычислении decision, документируя, что ошибки
WCAG-евалюатора через JointReportErrorV1::Evaluator намеренно прерывают
execute() и аннулируют весь joint-отчёт, а не только текущую ячейку; объясните,
что такие ошибки указывают на недействительный результат оценки (например,
ReportOnly или CriterionMismatch), поэтому частичный отчёт недопустим. Не
изменяйте существующее поведение и обработку ветки Exact.
Source: Coding guidelines
|
Закрываю: WCAG hard-path foundation этого среза целиком включён в чистый P1 #372. Generated by Claude Code |
Срез
Private foundation для P1 Pair lowering: общий linked point-component получил production WCAG 2.2 hard evaluator рядом с exact identity, без Pair-семантики и без второго solver.
Что изменено
JointHardConstraintV1поддерживаетExactиWcag22в одной canonical constraint matrix;allow-маскировки.RED → GREEN
Границы
e64e8f84поверх C8cb023defc.Финальные gates — PASS
-D warnings;Summary by CodeRabbit
Новые возможности
Исправления