| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Most of these failed on Windows for reasons that had nothing to do with the
code under test, which is how real Windows defects hid among them:
- Read and write files as UTF-8, and talk to Node in UTF-8. read_text(),
write_text() and subprocess text=True use the locale codepage, cp1252 on
Windows: "é", "—" and "→" arrived as "?" or crashed, some sixty tests.
Calls to PowerShell and schtasks are left alone -- they answer in the
console codepage.
- Import ESM harness modules by file URL (as_uri): a raw "C:\..." path is not
a module specifier.
- test_cli_golden: mask the tmp path in its JSON-escaped form, spell it the
POSIX way, record on Linux, mask the protocol version (the recording had
failed everywhere since the MNP 4.0 bump) and argparse's version-dependent
quoting; point USERPROFILE at the tmp home, or `member invite` and
`operator pair` wrote their codes into the developer's profile.
- test_disk_io_off_loop: expect what a free loop can reach on the platform's
timer, 15.6 ms on Windows, not an assumed 5 ms.
- test_root_paths_are_operator_only: expect the OS's spelling of the path.
- test_audio_meta_cache: find ffprobe with shutil.which.
Node suite on Windows: 1489 passed, none failed. Hub suite: 3 failures left,
all older than this change (two SQLite concurrency tests, one transfer resume).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
`ruff check .` had gone unrun long enough to report 568 errors, which is the
same as having no linter: the next real finding would have been invisible in the
noise. This is the 521 it fixes by itself, in 173 files, and nothing else — the
98 it cannot fix are the next commit.
What actually changed: import sorting (225), imports nobody used (87, none of
them a re-export — no `__init__.py` is touched, which was the one way this could
have broken an import elsewhere), `datetime.timezone.utc` to `datetime.UTC` (69)
and `asyncio.TimeoutError` to `TimeoutError` (18), both plain aliases on the 3.12
this project requires, `Optional[X]` to `X | None` (24), and f-strings with
nothing to interpolate (19).
Checked rather than assumed: every module in the three packages still imports,
and the suite is 2893 passed — the same count, test for test, as the merge
before it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Everything under static/ is served at /a/<hash>/ with a year's
`immutable`, but the hash was computed from a hand-kept list of 43
top-level modules. The ten catalogues and vendor/ were not on it, nor
was anything the guarding test could see: it globbed *.js at the top
level only. A change confined to the catalogues therefore kept the hash,
and a phone went on showing a heading that had been rewritten and
deployed - pull-to-refresh fetched the no-store shell, which was
current, and never refetched en.js at a URL that had not moved.
The fingerprint now hashes every file under static/, path and content,
so a change, a rename or a new file moves the version with nothing to
register. _ASSETS is gone, and CLAUDE.md, MESHBAY_DESIGN.md 9.4 step 6,
assets/brand/README.md and docs/playlists.md no longer ask for it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D9MCBBWSm9GhBESmqzJxNy
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Two defects found while closing out the Search merge, neither of them in
that feature.
The maintenance loop. create_app's lifespan starts cleanup_loop as an
asyncio task, so every test — each entering that lifespan — ran a purge
pass concurrently with its own requests. On SQLite :memory: that is not
merely noisy: the engine uses a StaticPool, one connection for the whole
process, so the request's session and the cleanup task's session
interleave transactions on the same connection. A registration could
commit and then be invisible to the login three lines later, surfacing
as 401 Invalid credentials for an account created moments before, in
roughly one run of test_node_ws_auth.py in four.
The purge itself is not at fault and this is not a production condition.
A passive SQL listener caught the DELETE removing 0 rows, and the INSERT
carrying status='active' — so neither the pending-account mechanism nor
the purge filter is involved, and PostgreSQL gives every session its own
connection. What the fixture removes is the second user of the shared
one. 60 runs of the previously flaky file, 0 failures; reproductions
before the fix landed on attempts 4, 6, 13 and 29 of separate loops, so
a clean run of 60 has about a 1% chance of being luck.
_ASSETS. source-merge.js shipped missing from webapp._ASSETS, the
cache-busting hash's input list — exactly the silent failure docs/apps.md
§4 step 5 warns about: the file changes, the asset URL does not, and a
browser holding the old page keeps the old copy. Harmless this time only
because search-page.js changed in the same commit and is listed, which is
the worst way for it to go unnoticed. Found by re-reading that checklist
for the doc pass, not by any test — so there is a test now, holding
_ASSETS to every .js in static/ (sw.js excepted, unversioned on purpose).
It was the only one missing.
Phase 9 of docs/refactoring-search.md also lands here: mediacenter.md
§10.6, musicbay.md §9b, photos.md §10b, apps.md §2b and step 5.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbwJDbNTkiRUh7HTWEoyss
|
|
|
`Cache-Control: no-cache` requires a browser to revalidate, but it only binds
one that asks. A browser that cached app.js before that header existed applies
heuristic freshness instead — a fraction of the file's age, which for a file
dated weeks ago is days — and never asks. It then runs an old player against a
new node.
That cost most of a session. A phone kept a player without the read-ahead bound
and filled the browser's buffer ceiling at 106 MB, the exact symptom the bound
had been written to remove, for an hour after the bounded player went live. A
fix that is written, tested, deployed and served, and still not what runs, is
indistinguishable from a fix that does not work.
The whole module graph now lives under `/a/<content-hash>/`. A path prefix
rather than a query string, because relative imports inherit it: `app.js`
reaching for `./i18n.js` gets the build it was written against, and never a
mixture of two — which does not render a stale page, it fails to link. The URL
changes with the content, so those may be cached hard.
`sw.js` stays at the root. Its scope is its own path, and under the prefix it
would no longer control the pages whose downloads it exists to intercept.
|