Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 8 additions & 14 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -249,10 +249,7 @@ jobs:
"labcolors-conformance",
)
core = packages["labcolors-core"]
if core["features"].get("default") != [
"wcag22-feasibility",
"wcag22-explicit-feasibility",
]:
if core["features"].get("default") != ["wcag22-feasibility"]:
raise SystemExit("labcolors-core default capability set drifted")

protocol_core = [
Expand Down Expand Up @@ -303,12 +300,11 @@ jobs:
raise SystemExit(
f"{consumer} did not resolve protocol-owned wcag22-feasibility"
)
# C4a: атомарная explicit-selection операция вырезана. Explicit-домен
# остаётся внутрикорной способностью (до C4b) и заморожен: ни один
# потребитель не смеет резолвить его заново.
if 'labcolors-core feature "wcag22-explicit-feasibility"' in feature_tree:
# Explicit-домен вырезан целиком: анти-воскрешение — сама фича
# больше не существует, потребительские деревья обязаны быть чисты.
if "wcag22-explicit" in feature_tree:
raise SystemExit(
f"{consumer} resolved the frozen explicit-domain capability"
f"{consumer} resolved a deleted explicit-domain capability"
)

runtime_dependencies = packages["labcolors-wasm"]["dependencies"]
Expand All @@ -332,7 +328,7 @@ jobs:
for forbidden in (
"labcolors-protocol",
'labcolors-core feature "wcag22-feasibility"',
'labcolors-core feature "wcag22-explicit-feasibility"',
"wcag22-explicit",
):
if forbidden in runtime_tree:
raise SystemExit(f"runtime role resolved forbidden capability: {forbidden}")
Expand All @@ -349,8 +345,8 @@ jobs:
raise SystemExit("compiler role resolved the theme/runtime engine")
if 'labcolors-core feature "wcag22-feasibility"' not in compiler_tree:
raise SystemExit("compiler role lacks protocol-owned wcag22-feasibility")
if 'labcolors-core feature "wcag22-explicit-feasibility"' in compiler_tree:
raise SystemExit("compiler role resolved the frozen explicit capability")
if "wcag22-explicit" in compiler_tree:
raise SystemExit("compiler role resolved a deleted explicit capability")

print("core capability projection: PASS")
PY
Expand All @@ -362,8 +358,6 @@ jobs:
run: python3 scripts/verify_wcag22_neutral_axis.py
- name: verify WCAG22 feasibility identity byte grammar
run: python3 scripts/verify_wcag22_feasibility_identity.py
- name: verify explicit WCAG22 feasibility identity and anti-vacuum mutations
run: python3 scripts/verify_wcag22_explicit_feasibility_identity.py --self-test

audit:
name: cargo audit (rustsec)
Expand Down
7 changes: 1 addition & 6 deletions crates/labcolors-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ rust-version.workspace = true
[features]
# Direct core consumers receive the stable default capability set. A transport
# adapter may disable defaults and then enable only capabilities it projects.
default = ["wcag22-feasibility", "wcag22-explicit-feasibility"]
default = ["wcag22-feasibility"]
wcag22-feasibility = []
wcag22-explicit-feasibility = ["wcag22-feasibility"]

[dev-dependencies]
pretty_assertions = "1.4"
Expand Down Expand Up @@ -58,7 +57,3 @@ harness = false
name = "wcag22_feasibility"
required-features = ["wcag22-feasibility"]

[[test]]
name = "wcag22_explicit_feasibility"
required-features = ["wcag22-explicit-feasibility"]

80 changes: 20 additions & 60 deletions crates/labcolors-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,36 +42,32 @@ boundary details.
`NotEvaluated`. `Infeasible` означает отсутствие решения только в проверенном
конечном домене; это не утверждение об отсутствии цвета вне него.

Прямой Core по умолчанию включает `wcag22-feasibility` и зависящую от неё
возможность `wcag22-explicit-feasibility`. Protocol и адаптеры публикуют одну
offline-операцию — complete feasibility; все поверхности используют один
математический компилятор и не входят в runtime WASM.

В V1 доступны две формы одного компилятора. Совместимый вход `evaluate`
перечисляет зарегистрированную нейтральную ось: ровно 256 кодов `[v, v, v]`,
где `v` принимает каждое целое значение от 0 до 255. Вход
`explicit::evaluate` принимает непустой клиентский набор пар «непрозрачный ID +
неизменяемый финальный `Srgb8`». Core сортирует точные UTF-8-байты ID, отклоняет
их повторы и сам выводит мощность, digest, матрицу и partition. Разные ID с
одинаковыми физическими байтами остаются разными кандидатами. Ни один из входов
не выводит размер текста, компонентную семантику, применимость или предпочтение
из ID. Feasibility сам ничего не ранжирует и ничего не выбирает: он доказывает
допустимость каждого кандидата в объявленном конечном домене, и только.
Прямой Core по умолчанию включает возможность `wcag22-feasibility`. Protocol
и адаптеры публикуют одну offline-операцию — complete feasibility; все
поверхности используют один математический компилятор и не входят в runtime
WASM.

Совместимый вход `evaluate` перечисляет зарегистрированную нейтральную ось:
ровно 256 кодов `[v, v, v]`, где `v` принимает каждое целое значение от 0
до 255. Вход не выводит размер текста, компонентную семантику, применимость
или предпочтение из ID. Feasibility сам ничего не ранжирует и ничего не
выбирает: он доказывает допустимость каждого кандидата в объявленном конечном
домене, и только.

Для `C` кандидатов и `E` канонических применимых рёбер выполняется ровно
`W=C×E` атомарных проверок. При `E>0` единственный упакованный буфер имеет
`B=ceil(C×E/8)+ceil(C/8)` байт; при `E=0` он пуст. Эти величины выводятся и
проверяются до выделения памяти. Остальная стоимость не маскируется формулой
`C×E`: отдельно выполняются линейный просмотр деклараций, сортировка кандидатов
и связей сравнением точных байтов ID, сортировка соседей внутри каждой связи и
линейное хеширование канонического результата. Превышение ресурсов,
противоречивая декларация, ошибка выделения памяти и нарушение инварианта
вычислителя или компилятора возвращаются типизированными ошибками; частичного
или запасного результата нет.
`C×E`: отдельно выполняются линейный просмотр деклараций, сортировка связей
сравнением точных байтов ID, сортировка соседей внутри каждой связи и линейное
хеширование канонического результата. Превышение ресурсов, противоречивая
декларация, ошибка выделения памяти и нарушение инварианта вычислителя или
компилятора возвращаются типизированными ошибками; частичного или запасного
результата нет.

Формулы `C×E`, случай `E=0`, повторы ID, ресурсные отказы и запрет частичного
результата исполняются непосредственно в `src/wcag22_feasibility_tests.rs`,
`tests/wcag22_feasibility.rs` и `tests/wcag22_explicit_feasibility.rs`.
Формулы `C×E`, случай `E=0`, ресурсные отказы и запрет частичного результата
исполняются непосредственно в `src/wcag22_feasibility_tests.rs` и
`tests/wcag22_feasibility.rs`.

```rust
# #[cfg(feature = "wcag22-feasibility")]
Expand Down Expand Up @@ -111,42 +107,6 @@ if let Some(evaluated) = result.evaluated() {
# fn main() {}
```

Клиентский конечный набор использует те же `RelationV1` и атомарный WCAG-путь:

```rust
# #[cfg(feature = "wcag22-explicit-feasibility")]
# fn explicit_feasibility_example() -> Result<(), Box<dyn std::error::Error>> {
use labcolors_core::{
Srgb8,
wcag22::Wcag22CriterionV1,
wcag22_feasibility::{
OccurrenceId, RelationId, RelationV1, ResourceProfileIdV1,
explicit::{CandidateId, CandidateV1, DomainRequestV1, RequestV1, evaluate},
},
};

let domain = DomainRequestV1::try_new(vec![
CandidateV1::new(CandidateId::try_new("brand/ink")?, Srgb8::new([18, 52, 86])),
CandidateV1::new(CandidateId::try_new("brand/paper")?, Srgb8::new([245, 247, 250])),
])?;
let relation = RelationV1::applicable(
RelationId::try_new("content-on-canvas")?,
OccurrenceId::try_new("article/body")?,
Wcag22CriterionV1::Sc143TextDefault,
vec![Srgb8::new([255; 3])],
)?;
let result = evaluate(RequestV1::try_new(
domain,
vec![relation],
ResourceProfileIdV1::Compile,
)?)?;

assert_eq!(result.evaluated().map(|value| value.candidates().len()), Some(2));
# Ok(())
# }
# fn main() {}
```

В примере `Sc143TextDefault` означает явно объявленный клиентом критерий
SC 1.4.3 для обычного текста с отношением 4.5:1; Core не угадывает его по ID или
типографике. `0x75` и `0x76` — вычисленные граничные результаты именно для двух
Expand Down

This file was deleted.

Loading
Loading