Summary
hallways._save_hallways() publishes the palace-scoped hallways.json through an adjacent tempfile.mkstemp() file followed by os.replace().
PR #2420 demonstrated that, on affected Python/Windows behavior, repeated PermissionError results during temporary-name allocation can be interpreted as candidate collisions and cause an extremely large retry loop before eventually surfacing an unrelated-looking EEXIST.
The hallway writer retains the same unbounded standard-library allocation shape.
Current path
_save_hallways() currently:
- creates the destination directory
- calls
tempfile.mkstemp()besidehallways.json - writes the complete payload
- applies restrictive permissions
- publishes it with
os.replace()
Temporary-file allocation occurs before the existing cleanup try block.
Impact
When the destination directory refuses every adjacent temporary name, hallway persistence can hang for an impractical amount of time or fail only after exhausting the standard-library retry budget.
This can affect hallway recomputation and hallway deletion.
The previous hallways.json remains valuable state and must not be truncated merely because an adjacent temporary file cannot be created.
Desired behavior
- place a deterministic upper bound on temporary-name allocation
- retain exclusive creation and cryptographically strong random names
- preserve the atomic
os.replace()publication model - preserve restrictive file permissions
- propagate a prompt, actionable filesystem error when the directory cannot accept a temporary file
- do not fall back to truncating the existing
hallways.jsonin place - do not leave a temporary file behind after write, chmod, or replace failures
- avoid copying a config-private helper into this module; use a shared internal atomic-file utility where practical
Regression coverage
Add tests proving that:
- repeated
EPERMorEACCESreaches the caller after a bounded number of opens - the previous
hallways.jsonremains byte-for-byte unchanged - no temporary file remains after failure
- a genuine first-name collision is retried successfully
- a successful save still publishes complete JSON atomically
- restrictive permissions remain applied where supported
Relationship
Follow-up to #2420 and the review observation identifying the remaining hallways.py allocation path.
This is intentionally separate from #2392 because config persistence has an explicit in-place fallback, while hallway persistence should preserve the existing sidecar rather than abandon atomic publication.
Activity
0No activity yet.