3 Commits
Author SHA1 Message Date
Jake WriterandClaude Opus 5.5 73f81b2543 fix(pythonlib): write downloaded files beside their destination, not via mkdtemp (#829)
The fpgen model was staged in tempfile.mkdtemp() and os.replace'd into
fpgen's data directory, and an extracted GeoIP database was unpacked in
tempfile.TemporaryDirectory() and shutil.move'd into the cache. Since
Python 3.13, mkdtemp() on Windows creates an owner-only directory, and a
file moved out of it on the same volume keeps that ACL. So a model or
database installed from an elevated shell (or over SSH, which is elevated)
could not be read by the same user unelevated, or by any other account:
the launch failed with "fpgen's model directory is not writable by this
user", though the failure was a read. Found on Windows 11 with
camoufox 0.5.7b5 under Python 3.14.

Add pkgman.write_atomic(): write a temporary file beside the destination,
so it takes the directory's permissions, then os.replace it into place.
The model's members are all verified before any is written, as before.
The permission error now names the file and says how to recover from a
model another account installed.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 00:00:23 +00:00
Jake WriterandClaude Opus 5.5 8823d399b8 fix(fpgen): keep a values.dat the TypeScript launcher decompressed from the pin
CAMOUFOX_FPGEN_DATA may point the TS launcher at pythonlib's fpgen data/,
and it decompresses values.dat there. ensure_fpgen_model() refused to run
whenever values.dat existed, so sharing the directory broke every Python
launch. The pin now carries values.dat's sha256 (all three twins): a
matching values.dat is kept, any other is removed, since fpgen reads it in
preference to the verified archive. The files `fpgen decompress` leaves
still fail loudly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 20:09:03 +00:00
coffeegrind123 7f0e52e792 Install the pinned fpgen model before fpgen is imported
pythonlib left the model to fpgen, whose first import downloads the
first release the GitHub API lists: model-4/2025, whose WebGL records
have no vendor or renderer. Every generated launch on a fresh install
failed with KeyError: 'vendor'. scripts/pin-fpgen-model.py pinned the
model for CI only, and fpgen's five-week refresh replaced even that
pin, under a stamp the script's --check still trusted.

fpgen is now imported only through fpgen_model.load_fpgen(), which
installs the release named by the pin, checks the archive and each
file against their sha256, and dates the files past fpgen's refresh.
It writes the layout and stamp the script and the TypeScript launcher
use, verifies an install by hashing it, and leaves FPGEN_MODEL_URL to
fpgen. `camoufox fetch` installs the model as well. The pin gains each
file's sha256; the package carries a copy of it, and the script now
calls the module.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit f043de3598)
2026-09-27 20:09:03 +00:00