wai-vector: section 5 and the text layer, its checker, and the three-engine browser leg (D7-7, D7-8) #237
Loading…
Reference in a new issue
No description provided.
Delete branch "wai/d7-text-and-browser"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
D7-7 and D7-8 of
wai.graphics.vector(Draft), with the independent checker extended for the new section. Four commits on current main.1. Section 5, text and accessibility, and the text layer (D7-7)
graphics-vector.md§5.1–§5.8. What a sink exposes to assistive technology and to a text consumer: purposes and their roles, languages, directions and writing modes, groups, ruby, and the cluster rule. §5.4 defines each block's active set (the effective windows of the items that draw it, cut by enclosing groups and the document, sorted, with touching intervals merged), the projection at a frame and the transcript as exact JSON, and the text record: the transcript, then the projection at every frame of every listed rate, one value a line. Text-equivalence is byte equality of those values.wai-vector/src/text.rs,no_stdwith no dependency, in the sink's build; the CLI'sa11yandtextcommands;vectors verifyrecomputes every text record.a11ygroup, each payload with its text record (<name>.a11y.jsonl) and its digest (text_record) in the expected file; canonical and refusal vectors forTEXT. No existing expected file changes.tests/text_layer.rs: one test for each rule, with the expected JSON written by hand from §5.4 (two digests from an independent SHA-256), each falsified once by the mutation it guards against.2. The checker, from the extension text alone
tools/wai_vector_check.pylearns §5. It was extended by a session that read only the extension, the corpus and the checker, never the reference crate. It computes each text record by two derivations that share neither the interval code nor the JSON writer, compares every file underexpected/(the text records among them), and requires each canonical vector that names a rule to be refused under that rule. It agrees with every expected file of the corpus. Twenty deliberate changes to it each made it disagree.It found one gap, in an example rather than a rule: §5.4's worked example listed no block's string and no writing mode. The fourth commit states both for each block.
3. Wasm exports and the three-engine browser leg (D7-8)
wai-vector/wasm: the sink's exports,wv_alloc,wv_free,wv_open,wv_close,wv_render,wv_out_ptr,wv_out_len,wv_sha256,wv_cost,wv_transcriptandwv_projection. No i64 at any export, so an engine without BigInt at the interface can call it.wasm32-unknown-unknownthe precompiledcoreandallocbring in post-1.0 instructions even with an MVP CPU target, so the package is built forwasm32v1-noneand the crate isno_stdwith an allocator of its own.check-mvp.mjsreads the module and refuses any post-1.0 feature; CI shows it refusing thewasm32-unknown-unknownbuild.build-pkg.sh: the package a page serves.browser/: a harness that runs every vector in Chromium, WebKit and Firefox.a11ypayload's transcript and projections with its text record, byte for byte.wai-vector.ymlgainsbrowser: the harness in a Playwright 1.60.0 container pinned by digest, on thelinuxrunner.Evidence
Run on the build host (macOS, arm64) at this branch's head, with each job's own commands and paths:
native: tests debug and release,vectors verify, the sink's build withoutauthor,vectors genleaving the tree cleangenleaves the tree cleanwasip2: tests under wasmtime, the tool's build,vectors verifyunder wasmtimenode: the recomputation build,verify.mjsbrowser: the package (WebAssembly 1.0), the reader refusing the default target's build, the harness in all three enginesfuzz: corpus-seeded fuzz, peak allocation and comparison countchecker: every expected filesha256.jsonentrieswai-conformance.ymlfires)Falsifications (each committed first, mutated, shown red, restored through git, shown green):
div255's pre-bias at 127 (red in all three engines with identical failure lists); a page that reports the expected digest over a changed buffer (Node's re-hash catches it in every engine); a missing engine; purpose 7 written for 200 in the Wasm build only (all three engines red at the projection comparison, the native tests unaffected).Not verified until this runs in CI
The
browserjob itself has not run anywhere: the pinned image on thelinuxrunner, rustup inside it, the engines running as root, Linux WebKit'scrypto.subtleonhttp://127.0.0.1, and frame digests from an x86_64-built module. The harness passes in all three engines on macOS arm64.Known differences from the plan
clockvector, and the firstcompositevector it fails is the fourth: only two of the sevencompositevectors ever form a value ≡ 128 (mod 255). A composite vector built to form one would make that row exact.wasm32v1-none(above), and a site that builds the package needs that target installed.🤖 Generated with Claude Code