Skip to content

feat(tri): tri harness -- a page measured at 375px and 1024px, every visible frame - #5828

Merged
gHashTag merged 4 commits into
masterfrom
feat/tri-harness
Oct 4, 2026
Merged

gHashTag merged 4 commits into
masterfrom
feat/tri-harness

Conversation

@gHashTag

@gHashTag gHashTag commented Oct 3, 2026 •

Copy link
Copy Markdown
Owner

What

tri harness URL -- the 375px / 1024px layout pass the Queen board loop wrote by hand three times, as one command (scripts/tri_loop/harness.py, dispatched by scripts/tri with no compiler).

Per width, a fresh browser context (under 768 = phone: touch, coarse pointer), and in every visible frame:

check when finding
viewport-meta top document, coarse pointer no <meta name="viewport"> (phone lays out at 980)
overflow always scrollWidth > clientWidth; names up to 5 elements past the edge, never content inside its own scroller
small-target coarse pointer control under 44x44; sentence links exempt and counted; 1px elements skipped and counted
field-zoom coarse pointer text field / select / contenteditable under 16px

Exit 0 clean, 1 findings, 2 could not measure (no playwright, no browser, load failure, HTTP >= 400, --wait-for never visible, a visible frame refused, the measurement threw). Headless, temporary profile, and a private TMPDIR removed on exit; the browser used is printed. The tool downloads nothing -- the browser may fetch its own components (see CI below).

Two defects in the first draft (both now mutations the test catches)

  1. Under phone emulation Chromium grows innerWidth to the content: a 550px bar at 375 read innerWidth 550, scrollWidth 550 -- "no overflow". clientWidth stays 375 and is the reference.
  2. app.t27.ai/game/browser draws its body in a same-origin iframe. The top document alone was the tab bar; the first run called the page clean while a screenshot showed two controls it had never measured.

Real run (BrowserOS headless, 2026-10-04)

375x812 phone (touch, coarse pointer): 2 frame(s) measured, 0 hidden frame(s) skipped
  frame 0  https://app.t27.ai/game/browser?spec=specs%2Fdemos%2Fhello_world.t27
    ok       small-target: 9 controls >= 44x44 (inline links exempt: 0, 1px skipped: 0)
  frame 1  https://app.t27.ai/queen/?lang=en#/queen?tab=browser&spec=specs%2Fdemos%2Fhello_world.t27
    ok       small-target: 2 controls >= 44x44 (inline links exempt: 0, 1px skipped: 0)
    ok       field-zoom: 0 text fields >= 16px
RESULT: clean -- 0 at 375; 0 at 1024

Signed out, the BROWSER view is a sign-in sentence and one button -- clean, and also nearly empty. The chat and the browser itself are behind sign-in and were not measured.

Tests

  • scripts/ci/test_a_page_is_measured_at_both_widths.py -- new harness job in loop-tools-gate (installs playwright==1.58.0 only, drives the runner's Google Chrome; a missing browser FAILS, never skips). 7 fixture pages over HTTP on 127.0.0.1: broken, clean, nometa, framed (+ a 0x0 frame), delayed, hostile, and a 404, plus a wrapper browser that writes into its TMPDIR. 36 passed, 0 failed locally (~37 s). Every run must leave its TMPDIR empty; the check is shown to see one byte.
  • 13 mutations, each red: innerWidth for clientWidth; top frame only; no sentence-link exemption; 12px for 16px; checks on a fine pointer; scrollers not containing; 404 measured; failed top-frame measurement not reported; temp dir left behind; 0x0 frame measured; 1px not skipped; 40px for 44px; (m11, cd68eb4) browser launched without the private TMPDIR -> 34 passed, 2 failed.
  • loop-tools-tracked.sh: harness.py present, tracked, routed -- PASS.

CI, first run on GitHub (98e421f)

The harness job passed every functional check on the runner's Google Chrome and failed one: TMPDIR empty afterwards, with com.google.Chrome.chrome_chrome_url_fetcher_.CHvS5y/fbdd96f4... left behind -- a component fetch by Chrome itself that BrowserOS on the Mac never makes, so the local run could not see it. Fixed in cd68eb4: the browser gets a private TMPDIR, removed on exit, and test section 8 reproduces the leak on any machine. Second run (cd68eb4): harness pass (55 s); 29 pass, 2 skipping, 1 fail -- the ratchet below.

Corpus ratchet (expected-failure ledger) is red here and on master's last four pushes (62c105e, d995a31, 17f0986, 188884e): ledger 77 vs observed 81, new conflicted type names CounterState, LRUCache, TestCase, TestRunner. Not from this change.

Census

shell: jobs 85 -> 86, run: steps 283 -> 284, runner bash 262 -> 263 (the new job + its step). tri census explain --max 1100 named .github/workflows/loop-tools-gate.yml as the only mover of 1058 changed files since 769f325. Blessed in the same commit. #5787, #5824 and #5826 also bless shell.txt: whichever merges second re-blesses.

Not established

First load only (no interaction states); Chromium emulation, not iOS Safari; content behind sign-in; what Chrome's url_fetcher downloads (only its leftover was seen).

Closes #5827
Refs #5786

🤖 Generated with Claude Code

…visible frame

A loop helper (scripts/tri_loop/harness.py) that runs the layout pass the
Queen board loop wrote by hand three times: viewport meta, horizontal
overflow (naming what pushes past the edge), controls under 44x44 and text
fields under 16px on a coarse pointer. Exit 0 clean, 1 findings, 2 could not
measure -- a 404, a missing browser or a broken measurement is never "clean".

Two defects in the first draft, both now mutations the test catches:
innerWidth grows to the content under phone emulation (a 550px bar read as
no overflow -- clientWidth is the reference), and app.t27.ai/game/browser
draws its body in an iframe, so the top document alone is not the page.

CI: scripts/ci/test_a_page_is_measured_at_both_widths.py in a new `harness`
job of loop-tools-gate (playwright package only, the runner's Chrome);
33 checks over 7 fixture pages served on 127.0.0.1; 12 mutations red.

Census: shell jobs 85 -> 86, run: steps 283 -> 284, runner bash 262 -> 263
-- the new job and its one step; `tri census explain` names
loop-tools-gate.yml as the only mover of 1058 changed files. Blessed here.

Closes #5827
Refs #5786

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

This notebook contains session context, decisions, and artifacts for this work.

@github-actions

github-actions Bot commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-03 22:00:23 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 43
PRs with All Checks Green 7
READY 6
FAILING 43
PENDING 0
NO CHECKS YET 0

These columns do not partition: 6 + 43 + 0 + 0 = 49, and there are 50 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=b45a356c2eb6 != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

… CI left a url_fetcher download

The harness job's first run on GitHub passed every functional check on the
runner's Google Chrome and failed one: TMPDIR empty afterwards. Chrome left
com.google.Chrome.chrome_chrome_url_fetcher_.CHvS5y/<sha256> behind, a
component fetch of the browser's own that BrowserOS on the Mac never makes.

- harness.py launches the browser with TMPDIR set to a tri-harness-* dir and
  removes it on exit (measuring split into measure()/render()). The docstring
  no longer says "nothing is downloaded": the tool downloads nothing, the
  browser may.
- The test gains section 8: a wrapper browser that writes the same file into
  its TMPDIR, so the leak is visible on any machine. 36 checks; mutation m11
  (launch without the private TMPDIR) turns 2 of them red locally.

Corpus ratchet is red here and on master's last four pushes; not this change.

Closes #5827
Refs #5786

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-03 22:19:19 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 43
PRs with All Checks Green 7
READY 6
FAILING 43
PENDING 0
NO CHECKS YET 0

These columns do not partition: 6 + 43 + 0 + 0 = 49, and there are 50 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=b45a356c2eb6 != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@github-actions

github-actions Bot commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

This notebook contains session context, decisions, and artifacts for this work.

This was referenced Oct 4, 2026
This was referenced Oct 4, 2026
…storage-state, sessionStorage included (#5849)

* feat(tri): tri harness measures a page signed in -- --save-state / --storage-state, sessionStorage included

app.t27.ai keeps its sign-in in sessionStorage, which Playwright's storage
state does not carry, so a plain --storage-state would have measured the
signed-out BROWSER view under the signed-in name. --save-state lets the person
sign in in a visible window and writes FILE 600 with sessionStorage; --storage-state
loads it read-only, puts sessionStorage back before page scripts in its own
origin only, refuses a group-readable file or one holding nothing live for the
host, never prints values, and says the sign-in is not established without
--wait-for. Test sections 9-10: 28 new checks, nine mutations each red.

Closes #5848
Refs #5827

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(tri harness): make the fake sign-in value per run, not a literal

GitGuardian flagged the fixture constant as a generic high-entropy secret.
It was a fake marker the test uses to prove stored values are never printed;
nothing real leaked and nothing needs rotating. It is now built from uuid4 at
run time, so no secret-shaped literal sits in the source. 64 passed.

Refs #5848

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
… it)

#5849 (tri harness --save-state / --storage-state) was merged into this
branch as 18a7212; this merge brings master in so #5828 can land both.
tools/census/shell.txt conflicted (master moved to 284 steps with #5826)
and was re-blessed with `tri census pin --bless`: jobs 85 -> 86, run: steps
284 -> 285, the +1/+1 this PR pinned. `tri census pin --gate` PASS;
scripts/ci/test_a_page_is_measured_at_both_widths.py 64 passed.

Refs #5827

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

This notebook contains session context, decisions, and artifacts for this work.

@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-04 08:43:13 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 44
PRs with All Checks Green 6
READY 2
FAILING 44
PENDING 0
NO CHECKS YET 0

These columns do not partition: 2 + 44 + 0 + 0 = 46, and there are 50 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=46f5599e58f6 != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@gHashTag
gHashTag merged commit 4499e27 into master Oct 4, 2026
32 of 33 checks passed
gHashTag added a commit that referenced this pull request Oct 4, 2026
Catch-up for the squash merge of #5787 (carries #5824, #5864, #5868, #5896).
Conflicts: .github/workflows/loop-tools-gate.yml path filters -- both sides
added test files, kept all four; tools/census/shell.txt -- master's side,
then `tri census pin --bless`.

Census vs master after the bless: fetches.txt bounded reads in
scripts/tri_loop/*.py 4 -> 5 (pr_state.py reads the GitHub API, bounded);
shell.txt run: steps 285 -> 288 and runner-without-container 264 -> 267 (the
stranded, tick and pr-state steps in loop-tools-gate.yml). Gate: PASS.

Local on the merge: loop-tools-tracked.sh, test_stranded_work_is_found_
without_writing, test_a_tick_resumes_from_what_it_reads, test_an_open_pr_is_
not_a_green_one, test_damage_repair_snapshot_required, test_tri_says_it_
could_not_run all pass; every scripts/tri_loop/*.py compiles.
test_a_page_is_measured_at_both_widths hit a 600 s local cap; harness.py and
that test are byte-identical to master, where #5828's CI ran them.

Refs #5786

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tri harness: a page measured at 375px and 1024px as one command

1 participant