highway(operator-surface) wave 4: calm pixels, swap survival, rendered floors, empty states, CLI isolation — Freeze 5 met (0 red Core rows) - #85
Merged
Conversation
test_list_on_a_project_with_no_matching_items_exits_zero_with_empty_list
asserted `items == []` for `--status deferred` against the SESSION-scoped
`shared_project_name`, with no filter narrowing it to anything this test
controls: it requested `unique_lane` and never used it, because the CLI's
`list` has no lane filter to pass it to.
Measured on the untouched tree:
pytest tests/integration/test_defer_block.py <this test> -q
-> 1 failed, 21 passed (6 leaked deferred items)
<this test> alone -> 1 passed
Order-dependence, not a regression. Fixed by giving the test its own
project via `unique_project_name` (+ its existing teardown), matching what
the adapter-level siblings already do via `project_factory`
(test_work_list.py::test_list_bounded_on_empty_project...,
test_list_via_sql_equivalence.py::test_list_on_empty_project...). The
project deliberately holds one OPEN item, so the assertion still proves
the *filter* matched nothing rather than that the project is empty.
pytest tests/integration/test_defer_block.py <this test> -q
-> 22 passed
pytest tests/cli -q -> 93 passed, 1 pre-existing failure
(test_doctor_quick_succeeds_against_the_real_installed_bd)
Swept tests/cli and tests/integration for the same shape (exact
emptiness/count assertion on the shared project with no lane filter):
no other instance. Every other exact-count assertion is either on a
per-test project (unique_project_name / project_factory), lane-filtered,
membership-based, or an inequality.
…ors met in the render, OSV1-010 -> CONFORMS Core 7's Tier-B half asked for computed contrast ratios, target bounding boxes and a motion trace at 430/900/1280 in both themes, re-checked against the floors. Three of the four floors failed. All four now pass, measured in chromium 148 over 18 renders and recorded three times with `perception.floors` byte-identical on every asserted field. TEXT (4.5:1): 7 nodes below -> 0. Fixed at the TOKEN in all four declared blocks -- `--ink-quiet` #7c8798 -> #a1a8b5 dark, #596473 -> #4e5764 light; `--brand-cyan-ink` #0b6b80 -> #0a5e71 light. This is the honest limit OSV1-009 recorded: the same tokens cleared 4.5:1 as flat swatch pairs and sat at 3.13-4.35:1 on the real glass-over-glass chip and drawer surfaces. The ink ramp did not collapse to buy it (tertiary reads 7.33:1 / 5.75:1 on the same surface). TARGETS (44px): 26 of 34 controls on L0 -> 0, and 0 of 41 on L1 / 0 of 20 on L2 at every width. The pause control (26x26), nav icon buttons and theme toggle (34x34), window and status tabs (28px tall), activity-feed rows (37px), the L1 filter input (181x19), breadcrumb, wordmark and identity links (11.5-21px) all reach --u. For the link-shaped ones the HIT AREA grew and the type did not; the 62px header keeps its height and `elements_beyond_viewport` stays 0 at 430px. NON-TEXT (3:1): 16 of 79 on L0 -> 0 in both themes (L1 23/73 -> 0, L2 11/33 -> 0). One new token, `--control-edge` (rgba(255,255,255,.40) dark / rgba(11,18,32,.52) light), carries the boundary of an INTERACTIVE control; `--glass-hairline`/`-soft` keep painting the decorative panel edges WCAG 1.4.11 exempts, so a rim did not become a stroke everywhere. Worst case after: 3.35:1 dark, 3.23:1 light. Neutral by construction, no new hue. ONE BLOCKED RESIDUAL, enumerated and machine-checked: L1's status-mix donut BACKING RING (`.donut-track`/`.donut-hatch-gap`, 1.32:1 dark / 1.15:1 light) is exempt via `_probe.NON_TEXT_EXEMPT_CLASSES`. At the nearest passing colour the empty ring separates from a real --blocked arc by 1.60:1 dark / 2.25:1 light -- less than the floor being asked for -- so meeting it would make a five-status donut read as six. The exemption is subtracted by `below_non_text_floor`, returned by `exempt_below_non_text_floor`, counted per render as `non_text_exempt_below_floor`, and pinned twice: by the kit (`test_the_non_text_exemption_stays_narrow`) and by the row's own probe. LEDGER: OSV1-010 VIOLATION -> CONFORMS, `test_row_osv1_010` retargeted to the regression direction over all 18 renders, its four Tier-B xfail(strict) markers deleted, and its mutation replaced by two regressions (a control falling back under 44px; the exemption growing). OSV1-031 re-pinned 4 -> 3 red Core rows. `_mo009a/b` and `_mo011` re-anchored to the new token value and the new recording. OSV1-006's line-keyed exemption register re-anchored +82 lines (same three sites, no growth) -- the one out-of-scope edit, forced by comments added above them.
…2, OSV1-003)
A calm L1 -- nothing held past TTL, nothing blocked -- painted 97 `--blocked`
pixels in both themes. Core 2 reserves `--alarm`/`--blocked` for status that is
actually present, so every one of those pixels was the hue borrowed with no
meaning behind it.
MEASURED FIRST, pixel-by-pixel, before anything was changed. The sweep's own
matching coordinates were clustered and reconciled against every element's
computed style and page-space rect:
81 px `span.sw.mix-blocked` -- the status-donut legend's swatch for the
ZERO-count "Blocked" bucket (10x10 at 275,621)
16 px `span.dot` inside the Blocked status TAB (6px circle at 316,2167)
97 px total; the two clusters account for it exactly.
The row (and the xfail reason) also named `button.btn.danger`'s border as a
third painter. It is not one: all three `.btn.danger` controls sit inside a
CLOSED `<details class="actions-drawer">`, laid out but never painted, outside
the 2963px full-page capture entirely. Their contribution was ZERO. Recorded
rather than quietly inherited -- the attribution was plausible from the
stylesheet and wrong in the render, which is why this check is a pixel sweep.
THE FIX -- both real painters keep their SLOT and drop their HUE at zero
(`is-zero` -> `--ink-quiet`), the "alarm lamp present and switched off"
convention this surface already uses at `.kpi-card.is-blocked.is-zero` and
`.sw.fill-empty`. The danger border is fixed anyway (rest `--ink-quiet`,
reserved hue back on hover/focus-visible/active) because a conformance that
holds only while a drawer happens to be shut is an accident, not a property --
verified by re-sweeping with every `<details>` forced open: 0/0 in both themes.
RESULT, re-recorded twice on this tree (294 of 299 fields byte-identical; the
5 that move are `recorded_at` and the light-theme `--watch` counts nothing
reads):
L1 dark 0 --alarm, 0 --blocked (was 0 / 97)
L1 light 0 --alarm, 0 --blocked (was 0 / 97)
L0 both 0 --alarm, 0 --blocked (unchanged)
AND IT STILL DISCRIMINATES -- all three arms byte-identical to the pre-fix
recording: injected alarm chip 10 531 --alarm, genuinely-alarming fixture 264
--blocked, reinstated retired palette 16 681. `alarm.reserved_hue` on
`alarm/L1/dark` also unchanged at 2 669 / 734: the legend swatch takes its hue
straight back the moment the count is non-zero. A fix that had merely blinded
the sweep would have moved all of these.
Core 8 unaffected (both slots still render their word, count and percent),
Core 3 unaffected (neither was ever colour-only), Core 4 unaffected (three CSS
rules and two class names, zero literals).
LEDGER
- OSV1-003 VIOLATION -> CONFORMS (VIOLATION-MOVEMENT), probe retargeted from
the 97-px pin to the invariant, and it now also asserts the discriminating
arm and the alarming L1 -- "zero alarm pixels" is trivially satisfiable by a
sweep that has stopped measuring.
- Mutations reversed to REGRESSION: `_mo003_the_calm_page_paints_blocked_again`
(0 -> 97), plus a new `_mo003c_the_alarming_fixture_stops_painting_blocked`
that blinds the sweep. All three PROVEN; 64/64 overall.
- OSV1-031 (Freeze 5) re-pinned 4 -> 3 red Core-carrying rows on this tree.
- OSV1-006's three `webtheme.py` exemption pins moved +22 (4197/4216/4223 ->
4219/4238/4245). Same eight sites, same expressions -- the register neither
grew nor shrank, only the line numbers did, and both the register and the
row's notes say so.
- The Tier-B `xfail(strict)` for `calm.zero_alarm_pixels` at L1 XPASSed and was
deleted with the fix.
Tier-B: 54 passed, 33 xfailed (was 52 / 35). Tier-A: 39 passed, 3 xfailed.
ledger/checks 60 passed. No other row's recorded numbers moved -- L1
`non_text_below_floor` 23/73 and `text_below_floor` 3 dark / 4 light are
byte-identical to OSV1-010's pins.
…re 8)
OSV1-012 (Core 8) VIOLATION -> CONFORMS, OSV1-026 (Conformance 7) GAP ->
CONFORMS, OSV1-031 (Freeze 5) re-pinned 4 -> 3 red Core rows.
work_item_pipeline-aad.
Measured, same kit, same two fixtures (empty project vs populated ALARM):
BEFORE L0 1 problem -- 'Needs you -- ranked' keeps its slot, says nothing
L1 2 problems -- 'Agents on <project>', 'Status breakdown', same
Both good halves xfail(strict) against OSV1-012.
AFTER L0 0, L1 0. Markers deleted. Tier-A: 41 passed / 0 failed / 0 XPASS
(was 39 passed, 3 xfailed).
The three sentences all come from ONE helper, widgets._empty_note, so the
register cannot drift into three voices. It is the house's own register --
webapp.py's "Nothing is waiting to be claimed in this queue right now.",
chartsvg.py's "No activity in this window", webbrowse.py's "No items match
this filter." No numeral, no exclamation, no triumphant zero.
L0 <div class="attn-list"><p class="empty-note">No item needs you right
now.</p></div>
L1 <div class="agents-list"><p class="empty-note">No agent has held an item
in this project yet.</p></div>
L1 status-breakdown: the six-row legend of 0 / 0.0% becomes "No items to
break down yet." The DONUT stays on both renders (status_donut draws its
empty background track at total == 0), so the card's dominant 150px box
is identical either way.
The box lives in webtheme.py's .empty-note rule (Core 4 -- zero literal
colour/font/size outside the token module; existing tokens only, no new hue).
min-height is the load-bearing declaration: it stops a slot COLLAPSING when
its data goes away. It does NOT claim an empty 1-row list occupies the same
pixels as a populated 8-row one -- rendered pixel stability is Tier B and is
not claimed here.
Probes retargeted in the same change:
test_row_osv1_012 from "no empty branch exists" to "all three route through
_empty_note, with their sentence, carrying no numeral or
exclamation" + the .empty-note rule keeps its min-height
test_row_osv1_026 from "the good halves are deferred" to "neither half is
deferred and OSV1-012 is green"; both bad halves still
asserted, so flipping did not spend them
test_row_osv1_031 pinned count 4 -> 3 (red: OSV1-003, -008, -010)
Mutations turned round (both rows are green now, so the counterfactual is the
defect returning, not the fix arriving) -- make ledger-mutate 65/65, 0 unproven:
OSV1-012 the empty queue goes back to a bare container (words limb)
OSV1-012 .empty-note loses its min-height, so the slot collapses (box limb)
OSV1-026 the L1 good half is deferred again behind an xfail
OSV1-026 OSV1-012 reopens
OSV1-031 re-anchored onto test_row_osv1_003 (it used to move OSV1-012)
OUT-OF-SCOPE, MINIMAL, NAMED: OSV1-006's exemption register is pinned by
file:line, and adding _empty_note above them shifted two entries
widgets.py:837/839 -> 866/868. Same two declarations, same purpose, register
still 8. Recorded as a line-shift in the row's notes, because a line-shift is
otherwise indistinguishable from a new site.
Tier-B recording NOT touched: its conftest builds a working queue and is
"deliberately NOT an empty project", so this change is invisible to that sweep.
…scroll, the open disclosure, the pause control and a live announcement (Core 6) OSV1-008 (Core 6 / Conformance 3) VIOLATION -> CONFORMS. All four of Core 6's named survivals now hold, on BOTH L0 and L1, measured in chromium 148.0.7778.0 via the pinned playwright 1.60.0 and re-recorded on this tree. MEASURED, before -> after (calm/L0/dark and calm/L1/dark in LAST_RUN.json): scroll_preserved L0 true -> true L1 true -> true open_details_preserved L0 false -> true L1 false -> true pause_control_preserved L0 false -> true L1 false -> true pause_flag_preserved L0 true -> true L1 true -> true live_regions_before L0 1 -> 2 L1 0 -> 1 marked_live_regions_after L0 0 -> 1 L1 0 -> 1 announcement_preserved (new) true (new) true THE FIX, in the kernel (webtheme.py's `auto_refresh_js`), not per view: - DISCLOSURES. `restoreState` re-opened only `details[id]`, and no `<details>` on this surface carries an id -- the mechanism had ZERO targets and an open disclosure closed on every 20-second poll. It now records open disclosures by ORDINAL + class signature as well as by id. `details_with_id` stays pinned at 0 so the day the markup gains ids, the row is re-derived rather than silently switching mechanisms. - PAUSE CONTROL. The flag survived on `window`; the button came back server-rendered at `aria-pressed="false"` every tick with nothing re-applying it, so a paused page showed itself as running. `restorePauseControl` re-synchronises the control to the flag after every swap, delegating to the page's own `wtToggleRefresh` so the label/icon/title vocabulary stays declared in one place. Reads the flag at RESTORE time, not capture time -- the flag on `window` is the live truth. - ANNOUNCEMENT. `src/` had ZERO `aria-live` occurrences. Adds exactly one persistent region per polling level -- `#wt-live` (webapp.py's `_live_region_html`, id shared with the poller via `T.LIVE_REGION_ID`), L0 and L1 -- which the poller DETACHES before the swap and re-attaches in place of the server's fresh copy afterwards, so the NODE survives. Its text updates only when the render actually says something different, so a screen reader hears a state change and not the same sentence every 20 seconds. Screen-reader-only (webtheme.py's `.wt-live`): the hero already states the verdict, and a second visible copy is redundant ink on a calm surface. KIT. The three `xfail(strict)` markers naming OSV1-008 are gone (they XPASSed). The snapshot probe now records `surviving_marked_live_region_texts` and `live_message`, and the good half asserts BOTH node identity and text: the bad half destroys the region and the server re-renders the same sentence into a new one, so a text-only check would call that survival. The literal bad half now also asserts 0 survivors, so it discriminates on the announcement too. Headline records booleans, not the sentence -- the fixture's project name is random per run and would churn the committed summary. LEDGER. OSV1-008 flipped and its probe retargeted to the conforming shape, still pinned per survival. Its five mutations flipped to the REGRESSION direction (all five proven). OSV1-031 (Freeze 5) re-pinned 4 -> 3 red Core rows, measured on this tree (OSV1-003, -010, -012 remain). OUT OF DECLARED SCOPE, minimal and named: OSV1-022's probe pinned the good half's disclosure outcome as false and instructed "re-derive this row and OSV1-008 together" -- re-derived, now asserting the good half DIFFERS from the bad half rather than a fixed value. OSV1-006's exemption register is keyed by file:line and the webtheme.py edits shifted three entries (4197/4216/4223 -> 4275/4294/4301); same three sites, same census, line index only. Gates: ruff check + format, pyright src tests, make test-conformance-a, make test-conformance-b (re-recorded, run twice, every asserted field byte-identical), pytest ledger/checks (60 passed), make ledger-mutate (65/65 proven), make test (only pre-existing test_doctor_quick_succeeds_against_the_real_installed_bd fails).
…sured (widgets 866/868), OSV1-031 re-counted to 2, _mo031 re-anchored to OSV1-008
# Conflicts: # ledger/checks/test_operator_rows.py # ledger/rows.yaml # tests/conformance/operator_surface/browser/LAST_RUN.json
# Conflicts: # ledger/checks/test_operator_rows.py # ledger/rows.yaml # tests/conformance/operator_surface/browser/LAST_RUN.json
…-031 (Freeze 5) flipped to CONFORMS with 0 red Core rows, register re-measured
Merged lane/swap-survives (OSV1-008, Core 6) and lane/rendered-floors
(OSV1-010, Core 7 rendered half) onto the wave-4 integration branch, on
top of cli-isolation, empty-states and calm-pixels. Every conflict was
resolved as a UNION; nothing was picked over anything.
THE RECORDING. Three lanes had each re-recorded LAST_RUN.json against a
tree carrying only their own fix, so all three were discarded and the
browser tier was re-recorded ONCE on the union (pinned chromium
148.0.7778.0 / playwright 1.60.0). Run twice: 89 passed / 0 failed /
0 XPASS each time, and every field any ledger row asserts is
byte-identical between the two runs. The only fields that moved are the
light-theme --watch pixel buckets, which no row reads.
DISPOSITIONS THAT CHANGED, each re-derived from that run and not from a
file appearing:
OSV1-031 GAP -> CONFORMS. Freeze 5's condition is met: the probe
measures ZERO red Core-carrying rows (17 CONFORMS + 2
NOT-ASSERTABLE of 19). The four flips this wave are
OSV1-003 (a1o), OSV1-012 (aad), OSV1-008 (v3m) and
OSV1-010 (96f); each lane honestly counted 3 on its own
base because each could only see its own flip.
PROBES AND MUTATIONS RETARGETED IN THE SAME CHANGE:
test_row_osv1_031 now asserts len(red) == 0, direction REGRESSION —
any Core row going back to GAP/VIOLATION fails it.
_mo031 was rewritten from a FIXED mutation (flip a red Core row green)
into a REGRESSION one (push a green Core row back to VIOLATION),
anchored on OSV1-008's unique probe ref. The old counterfactual is
unbuildable now: there is no red Core row left to flip.
THE EXEMPTION REGISTER WAS RE-MEASURED, not transcribed. Its three
webtheme.py pins read 4379/4398/4405, +182 from main @065da04 — and
22 + 78 + 82 (calm-pixels, swap-survives, rendered-floors) = 182, so
every insertion is accounted for and no site is new. Register still
exactly 8. Both the probe's EXEMPTION_REGISTER and OSV1-006's own notes
table are re-pinned to the measured lines.
NOTES TRUED UP where the union moved a number a row had quoted:
OSV1-003 (swept areas 2 813 440 -> 3 002 880 px on L0, 3 792 640 ->
3 877 120 px on L1 — taller pages, verdicts still 0/0), OSV1-010 (text
census 136 -> 138 on L0, 183 -> 184 on L1, caused by the new persistent
live region; every floor still 0), OSV1-024 and OSV1-030 (kit run
counts; the browser tier now carries no deferrals at all), OSV1-034
(re-checked, still GAP — the kit has looked, the owner has not).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Final wave of the
hw-operator-surfacehighway: the four product defects the Tier-B browser kit found, plus one pre-existing CLI test-isolation bug. Integrated onto main @ 065da04; the browser recording re-recorded once on the union.--blockedpx (zero-count legend swatch, live dot, danger-button border). Zero-count swatches nowis-zero→--ink-quiet(Core 8: the row keeps its slot), the dot uses an ink token, the destructive control is neutral at rest. Calm L1: 97 → 0 both themes; the alarming arm still paints 264<details>, the pause CONTROL (aria-pressedre-applied), and a persistentaria-liveregion outside the swapped subtree — the repo had zeroaria-livebefore; L1 got a live region too.open_details/pause_control_preservedfalse → true,marked_live_regions_after0 → 1, announcement preserved.empty-note, min-height so the slot cannot collapse)test_list_on_a_project_with_no_matching_items_exits_zero_with_empty_listscoped to a project only it mutates; the 44 s two-file reproducer passesFreeze 5 (OSV1-031): GAP → CONFORMS by measurement — the probe computes the red set over the 19 Core-carrying rows on the union: empty (17 CONFORMS + 2 NOT-ASSERTABLE). Each of the four lanes honestly pinned "3 red" against its own base; the union is 0.
test_row_osv1_031now assertslen(red) == 0(regression direction) and its harness mutation flips a green Core row red.Integration notes:
webtheme.pywas touched by four lanes — verified line-by-line, all 308 added lines present, no selector collisions. OSV1-006 register re-measured on the union (webtheme sites +182 lines = the three insertions exactly; still 8 sites). Tier-B recording made twice on the union: 89 passed / 0 XPASS both runs, every asserted field byte-identical; the kit now carries zero row-naming xfails.Gates:
pytest ledger/checks60 ·make ledger-mutate69/69 · Tier-A 41 passed / 1 xfailed (OSV1-015's dead-function residual) · Tier-B 89 passed / 0 failed ×2 · pyright 0 · ruff clean · unit+integration+cli 1425 passed (1 failure = the documented live-service doctor probe). OSV1 tally → 32 CONFORMS / 3 NOT-ASSERTABLE / 1 GAP (Freeze 8, the owner's look) / 0 VIOLATION.🤖 Generated with Amplifier