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
365 changes: 272 additions & 93 deletions ledger/checks/mutation_harness.py

Large diffs are not rendered by default.

497 changes: 347 additions & 150 deletions ledger/checks/test_operator_rows.py

Large diffs are not rendered by default.

824 changes: 686 additions & 138 deletions ledger/rows.yaml

Large diffs are not rendered by default.

45 changes: 45 additions & 0 deletions src/amplifier_work_tracker/webapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -3528,6 +3528,38 @@ def _observatory_glossary_dl(extra_dt_dd: str = "") -> str:
)


def _live_region_html(message: str) -> str:
"""The ONE persistent live region a self-polling Observatory page renders.

Core 6 asks that "an assistive-technology announcement pending at the
moment of the swap is not silently destroyed by it". The 20-second poll
replaces `document.body.innerHTML` wholesale, so ANY live region rendered
inside that body is destroyed and rebuilt empty every tick -- measured, on
the verdict hero's own `role="status"`: 0 of the 1 tagged node survived
(ledger row OSV1-008). A region that is rebuilt is a region that never
finishes announcing.

This one is different only because `T.auto_refresh_js` KNOWS it: it is
detached before the swap and re-attached afterwards, so the node survives
and its text changes only when the surface's own state changed. Hence the
shared `T.LIVE_REGION_ID` -- the poller and the view must name the same
node or the mechanism silently does nothing.

`aria-live="polite"` and not `assertive`: a monitor that interrupts is a
monitor nobody leaves running. `role="status"` is carried too, for the
assistive technologies that map the role rather than the attribute.

Screen-reader-only by design (see webtheme.py's `.wt-live`): `message` is
the verdict the hero already states in full, and a second visible copy
would be redundant ink on a surface whose discipline is that calm is
reported, never decorated.
"""
return (
f'<p class="wt-live" id="{T.LIVE_REGION_ID}" role="status" '
f'aria-live="polite" aria-atomic="true">{_esc(message)}</p>'
)


def _observatory_nav_extras_html(*, reconcile_html: str = "", extra_dt_dd: str = "") -> str:
"""The nav's Observatory-only chrome, appended after
`_nav_actions_html`'s existing search/bell/+New: a LIVE auto-refresh
Expand All @@ -3553,6 +3585,15 @@ def _observatory_nav_extras_html(*, reconcile_html: str = "", extra_dt_dd: str =
'title="This page polls for fresh data on an interval">'
'<span class="icon sm"><svg><use href="#i-clock"/></svg></span>'
'<span class="refresh-text">Refreshes 20s</span>'
# Server-rendered at `aria-pressed="false"` deliberately and
# permanently: the pause is a per-tab client-side flag
# (`window.__wtRefreshPaused`), and the server has no way to know it.
# What USED to be wrong is that nothing re-applied the flag after the
# body-swap re-rendered this button, so a paused page showed itself as
# running (Core 6 / OSV1-008). `T.auto_refresh_js`'s
# `restorePauseControl` now re-synchronises it to the flag after every
# swap, by calling `wtToggleRefresh` below -- so the label, icon and
# title vocabulary stays declared in exactly one place.
'<button class="refresh-toggle" id="refreshToggle" aria-pressed="false" '
'onclick="wtToggleRefresh()" title="Pause auto-refresh">'
'<span class="icon sm" id="refreshIcon"><svg><use href="#i-pause"/></svg></span>'
Expand Down Expand Up @@ -4737,9 +4778,13 @@ async def dashboard(request: Request): # type: ignore[no-untyped-def]
)
)

# Core 6's announcement half. Composed outside the body f-string for
# the same reason `webbrowse.py`'s is -- see its comment.
announce_html = _live_region_html(f"Environment status: {verdict['headline']}")
body = f"""
{_observatory_icon_sprite_html()}
<div class="container">
{announce_html}
{_flash(request)}
<div id="verdict-hero" class="section">{hero_html}</div>
<div class="two-up section">
Expand Down
17 changes: 16 additions & 1 deletion src/amplifier_work_tracker/webbrowse.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
_item_facts_kv_html,
_item_held_chip_html,
_item_time_kv_html,
_live_region_html,
_not_found_body,
_observatory_help_and_theme_html,
_observatory_icon_sprite_html,
Expand Down Expand Up @@ -141,7 +142,15 @@ def _status_tabs_html(name: str, status: str, counts: dict[str, int]) -> str:
for key, label in _STATUS_TABS:
active = " is-active" if key == status else ""
blocked_cls = " tab-blocked" if key == "blocked" else ""
dot = '<span class="dot"></span> ' if key == "blocked" else ""
# The Blocked tab's dot keeps its SLOT at every count (Core 8) and
# its hue only while there is something blocked (Core 2 -- OSV1-003:
# a calm L1 painted 16 --blocked pixels here with nothing blocked).
# The class rides the DOT, not the tab, so `.status-tab tab-blocked
# is-active` stays exactly the string the tab tests already pin.
dot = ""
if key == "blocked":
zero_cls = " is-zero" if not counts.get(key, 0) else ""
dot = f'<span class="dot{zero_cls}"></span> '
title = (
' title="Newly filed, not yet triaged into ready or deferred"'
if key == "intake"
Expand Down Expand Up @@ -568,6 +577,11 @@ def _page_href(p: int) -> str:
if not shown
else ""
)
# Core 6's announcement half. Composed OUTSIDE the body f-string
# below: `requires-python = ">=3.11"`, and 3.11 forbids a nested
# same-quoted f-string inside a `{...}` expression part -- the same
# real constraint `_EM_DASH` above exists for.
announce_html = _live_region_html(f"{name} status: {verdict['headline']}")
tabs_html = _status_tabs_html(name, status, _status_tab_counts(summary))
search_value = f' value="{_esc(q)}"' if q else ""
manage_html = f"""
Expand Down Expand Up @@ -614,6 +628,7 @@ def _page_href(p: int) -> str:
body = f"""
{_observatory_icon_sprite_html()}
<div class="container">
{announce_html}
{_flash(request)}
<div class="breadcrumb">{crumb}</div>
<div class="section">{hero_html}</div>
Expand Down
Loading
Loading