Repository navigation
Conversation
tests/test_app.py read public/site.css 17 times and runner.js, editor.js, syntax-highlight.js and search.js repeatedly, asserting literal text such as "transform: scale(0.96)" and "execution: 'execute'". Those tests broke on harmless refactors and passed when the rendered page regressed. scripts/check_browser_layout.mjs, which already drives a real Worker and Chrome in CI, now checks the same intentions on the page: - computed transforms under a forced :active for Run, Copy link, the copy button and home cards; - 40px touch targets for runner buttons and nav links, underlined nav links, balanced headings, antialiased text, tabular execution time, no "transition: all"; - the reader's browser font size (Page.setFontSizes), the skip link appearing on focus, the share button sitting at the toolbar end, the copy button anchored to its cell; - light/dark page, body-text, Run-button and terminal contrast, and marginalia figures staying on light paper in dark mode; - header fallbacks under emulated prefers-reduced-transparency and prefers-contrast: more, and the nav visible on landing; - long output wrapping and tall output growing the panel, and the fallback textarea not overflowing; - behaviour: network errors end a run with a message, unedited Copy link copies the plain URL, copy falls back to execCommand, arrow keys ignore modifiers and buttons and walk back to a no-op at the first example, search exposes combobox/listbox/option state, and the Turnstile widget renders in execute mode and is removed afterwards; - About-page design tokens all resolve. Arrow-key guards now count attempted navigations with the Navigation API instead of checking the pathname 50ms later, which could not see a navigation that had started but not committed. The source-text assertions and the 19 tests made only of them are removed; HTML rendering assertions stay. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012eisRQmQvg4TphwztxhQGJ
make deploy stopped after `pywrangler deploy`; the documented scripts/smoke_deployment.py ran only if someone remembered. It now ends with a post-deploy-smoke step against DEPLOY_URL (default https://www.pythonbyexample.dev) and exits non-zero, saying the new version is live and how to roll back, if any GET or POST check fails. SMOKE_ARGS passes extra smoke flags explicitly. The hello-world quality waiver expires on 2026-12-01, after which CI would fail every pull request with no earlier signal. check_quality_scores.py now warns when a waiver has 30 days or fewer left, and --fail-within-days N turns that window into an error. A new weekly Scheduled quality workflow runs `make quality-checks` and `make check-waiver-expiry` (--fail-within-days 30), so the expiry turns a scheduled run red a month early instead of breaking unrelated PRs. --as-of makes the date explicit for tests and manual checks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012eisRQmQvg4TphwztxhQGJ
docs/lessons-learned.md said "54 tests today cover 9 contract families"; tests/test_marginalia_geometry.py has 31 tests in 13 contract classes. The sentence now points at the classes instead of quoting a number that drifts. It also said the golden fixture is "refreshed explicitly by scripts/refresh_golden_fixture.py"; the script and fixture were deleted in 0929c25, so it now names what catches loader and parser regressions today. tests/test_markdown_migration_prereqs.py checked that the finished migration's spec contained particular phrases, including "Red", "Green" and "Refactor" in that order, which proves nothing about the process. Those tests are dropped; the README and CI command contract stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012eisRQmQvg4TphwztxhQGJ
…anual check The owner's verification-cost standard allows no new CI workflows or schedules. The 30-day warning already prints in every make verify run, and make check-waiver-expiry stays runnable by hand. README, CONTRIBUTING, the Makefile comment and the script docstring now say so. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UpksNcNFYPn6dR3UscZj4Z
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.
Summary
This PR implements the pythonbyexample recommendations from the September 2026 verification audit (https://github.com/adewale/testing-best-practices/blob/claude/github-testing-practices-review-n5749j/research/PORTFOLIO_VERIFICATION_AUDIT_2026-09.md, pythonbyexample row). There are three implementation commits, plus a merge of
mainand a pruning commit.1. P1: rendered-style contracts replace CSS/JS source-text tests.
tests/test_app.pyreadpublic/site.css17 times and read the JS sources repeatedly. It asserted literal text such as"transform: scale(0.96)","text-wrap: balance"or"execution: 'execute'".docs/lessons-learned.mdrecords these tests breaking on the harmlesshas-figurechange, and they still pass when the rendered page regresses.scripts/check_browser_layout.mjsalready drives a real Worker and Chrome in CI. It now measures the same intentions on the page::active(viaCSS.forcePseudoState) for Run, Copy link and the copy button (0.96), and for home cards (0.99).h1, antialiased body text, tabular execution time, and no element withtransition: all.Page.setFontSizesat 20px).prefers-reduced-transparencyandprefers-contrast: more, and nav links get the full text colour under more contrast. The nav is visible on landing.Run failed: ….execCommand('copy')without the Clipboard API. Its status is an off-screen polite live region, and its mask glyph changes.execution: 'execute'and nosize, and is removed and hidden afterwards.2. P1:
make deploysmoke-tests the deployed origin. Deploy now ends with apost-deploy-smokestep. It runsscripts/smoke_deployment.pyagainstDEPLOY_URL(defaulthttps://www.pythonbyexample.dev). If any GET or POST check fails, it exits non-zero with "the new version is already live: investigate now, or roll back".SMOKE_ARGSpasses extra flags explicitly. This runs only inside the manualmake deploy, never in CI.2 (continued). P2: waiver expiry warns 30 days ahead, with a manual fail-early check.
check_quality_scores.pywarns when a waiver has 30 days or fewer left.--fail-within-days Nturns that window into an error, and--as-offixes the date.make check-waiver-expiryruns--fail-within-days 30. It is a manual command, not run in CI. (An earlier revision added a weeklyScheduled qualityworkflow; it was removed when the PR was pruned to the owner's verification-cost standard.)hello-worldwaiver expires 2026-12-01. Before this change, its first signal would have been a failure on every PR from that day. Now every CI run prints a warning from 2026-11-01, andmake check-waiver-expiryfails from that day.3. P2/P3: stale docs and phrase-order tests.
docs/lessons-learned.mdsaid "54 tests today cover 9 contract families".tests/test_marginalia_geometry.pyhas 31 tests in 13 contract classes. The sentence now points at the classes instead of giving a number.scripts/refresh_golden_fixture.py, which was deleted in 0929c25. It now names what catches loader and parser regressions today.tests/test_markdown_migration_prereqs.pyloses its spec-wording tests, including the "Red" < "Green" < "Refactor" order check. The README/CI command-contract test stays.Cost and limits
Pruned to the owner's verification-cost standard on 2026-10-09.
What CI runs for this PR. Only the existing
verifyjob inverify.yml. This PR adds no workflows, jobs, matrix entries or schedules.make verifyalready runs:browser-layout-test(against the localpywrangler devWorker, never a deployed origin) and the unit tests.origin/main's script. Both runs stopped on the same environment-only failure described below. The 2 new expiry unit tests add well under a second.verifypassed in 57 s total on the pre-prune head 1d5cd26.waitForbudget (300 × 100 ms) is unchanged frommain.Moved to manual.
Scheduled qualityworkflow (.github/workflows/scheduled-quality.yml, cron23 6 * * 1plusworkflow_dispatch) is deleted. Its two steps, run by hand:make quality-checks: already part ofmake verify, so every PR runs it.make check-waiver-expiry: exits 1 while any quality waiver has 30 days or fewer left. Run it monthly or before a release. It is documented in README.md, CONTRIBUTING.md and the Makefile.check_quality_scores.pyprintsWARNING: quality waiver …during the final 30 days and fails once a waiver has expired.make post-deploy-smoke, which runs only inside the manualmake deploy. No CI step or schedule calls production.PBT and fuzz budgets. This PR adds or changes no property-based or fuzz tests.
tests/test_parser_properties.py(Hypothesis) is unchanged and keeps the project's existing settings. No mutation testing is added anywhere.What is not verified.
make check-waiver-expiry. Thehello-worldwaiver expires on 2026-12-01, so the warning window opens on 2026-11-01.--no-sandbox), the browser test failsSearch focus indicator is too weakandCodeMirror focus indicator is too weak. Those checks already exist onmain, andmain's script fails them identically here. All the checks this PR adds passed. CI usesgoogle-chrome, where they pass.make deployand the deploy smoke against production were not run.main(chore: patch Wrangler tooling security dependencies #27, Wrangler dependency patches), somainwas merged in with a normal merge commit (68c7387). There was no conflict.Checks on the pruned head (59ec97f), with
CHROME_PATHpointing at a scratch wrapper for/opt/pw-browsers/chromium:npm audit --audit-level=high: pass.git diff --exit-code -- pylock.toml: pass, afterpywrangler dev.make verify, run target by target:make build test seo-cache-lint verify-examples quality-checks: pass, 227 tests OK.browser-layout-test: fail, on the environment-only focus checks above.search-ranking-test,lint,check-generated: pass.scripts/format_examples.py --check: pass.make verify-python-version VERSION=3.13: pass.git diff --check: pass.make check-waiver-expiry: pass.Verification (original, pre-prune head 1d5cd26)
make verify. I ran each target against a localpywrangler devon port 9796 (to avoid clashing with other local servers) with Chrome for Testing 154:make build test seo-cache-lint verify-examples quality-checks search-ranking-test lint check-generatedexited 0, with 227 tests OK.node scripts/check_browser_layout.mjs http://127.0.0.1:9796/examples/valuesexited 0.scripts/format_examples.py --check: exit 0.make verify-python-version VERSION=3.13: exit 0, "Verified 109 example(s)".git diff --checkis clean,npm audit --audit-level=highexits 0, andgit diff --exit-code -- pylock.tomlshows no change.make post-deploy-smoke DEPLOY_URL=http://127.0.0.1:9796against the local Worker printed "Deployment smoke OK (9 GETs, 5 POSTs)". The first attempt hit a local-devProxyWorker … Network connection lostonPOST /examples/subprocesses. Retried by itself, that POST returned 200 three times, and the rerun passed.Red, then green.
Browser contracts. I applied 11 mutations at once, ran
make build, and ran the browser test:site.css:fontset to16px/1.6;.share-button { margin-left: auto; },.button:active,.skip-link:focus, the dark figure-paper rule, the reduced-transparencybackdrop-filter: none, and.cell-source { position: relative; };white-space: pre.runner.js:size: 'invisible'instead ofexecution: 'execute', and themetaKeyguard dropped.syntax-highlight.js: theexecCommandresult forced tofalse.It exited 1 and named all 11:
After restoring and rerunning
make build, the test exited 0 andgit statuswas clean.The first drafts of two checks missed their mutations: the modifier-key check (pathname after 50 ms) and the wrapping check (
scrollWidth). I rewrote them, using the Navigation API and a text range measured against the panel edge, until they failed on the mutation.Waiver expiry.
origin/main's script, becauseexpiry_warningandwaiver_expiry_findingsdo not exist there.check_expiry_date('2026-12-01', today=2026-11-05)returnsNone, so it stays silent.--as-of 2026-11-05WARNING: quality waiver hello-world: expires on 2026-12-01 (26 days left)…--as-of 2026-11-05 --fail-within-days 30--as-of 2026-12-01--fail-within-days 30(today)Deploy smoke.
make -n deployshowspywrangler deployfollowed bypost-deploy-smoke.make post-deploy-smoke DEPLOY_URL=http://127.0.0.1:9exited 2 withDeployment smoke FAILED … The new version is already live.Test counts. 249 on
origin/main, 227 now: 19 source-text-only tests and 5 spec-wording tests removed, 2 expiry tests added. Each intermediate commit also passes on its own (230 and 232 tests).Workflows. This PR no longer adds or changes any workflow.
verify.ymlis untouched.Not in this PR
src/main.py, the git hooks,Makefileand workflows (test_turnstile_verification_is_session_gated_in_worker,test_worker_entrypoint_uses_fastapi_asgi_bridge,test_dynamic_worker_execution_uses_hash_keyed_get_cache,test_generated_drift_is_blocked_before_commit_and_merge). The recommendation targeted the CSS/JS tests, and 466f616 already added behavioural coverage for most of themain.pypaths.#FF4801,#F5F1EB,#521000,#EBD5C1,.runner-grid,--space-6andbox-shadow:were dropped rather than converted, because they pinned text, not behaviour. Legibility is covered by the contrast checks instead.make deploy. It touches production.Notes
PBE_SMOKE_BYPASS_SECRETexported, as the script's docstring already says. Without it,make deploywill now fail loudly after deploying.SMOKE_ARGS=--skip-postis available only as a deliberate choice.DOM/CSSdomains,Emulation.setFocusEmulationEnabled,Page.setFontSizesand media-feature emulation, all of which currentgoogle-chromeonubuntu-latestsupports.--no-sandbox. It also needed to trust this session's egress-proxy CA, which I did with--ignore-certificate-errors-spki-listfor the proxy CA keys only. Both lived in a localCHROME_PATHwrapper; the committed script is unchanged in that respect.🤖 Generated with Claude Code
https://claude.ai/code/session_012eisRQmQvg4TphwztxhQGJ
https://claude.ai/code/session_01UpksNcNFYPn6dR3UscZj4Z