Summary
mempalace/migrate.py contains two temporary-allocation paths that remain outside #2420:
- a temporary directory used to construct a replacement palace
- an adjacent temporary file used to publish the rewritten
known_entities.jsonduring wing-name migration
These paths need bounded failure behavior and migration-specific atomicity tests rather than being folded into the config fix.
Current paths
Full-palace migration
migrate() creates a staging palace through tempfile.mkdtemp() before importing drawers and swapping the replacement palace into position.
This path should be audited separately from mkstemp(), because the exact standard-library exception handling may differ, but it must still fail promptly and leave the original palace untouched when staging allocation cannot succeed.
Wing-name migration
migrate_wing_names() currently applies:
- drawer metadata updates
- closet metadata updates
- the
topics_by_wingrewrite inknown_entities.json
The registry rewrite allocates an adjacent temporary file through tempfile.mkstemp() and publishes it with os.replace().
If that allocation or publication fails after the collection updates, the migration can leave drawer/closet metadata normalized while topics_by_wing remains under the old keys.
Impact
Potential outcomes include:
- excessive temporary-name retries on affected Windows/Python behavior
- an apparently hung migration
- a failed full-palace migration before staging begins
- a partially applied wing-name migration across drawers, closets, and
known_entities.json - mismatched search metadata and topic-registry keys
Desired behavior
Shared allocation behavior
- use a bounded secure temporary allocator
- retain exclusive creation
- distinguish genuine collisions from access failures
- clean up all temporary paths after failure
- avoid duplicating the private helper introduced in #2420
Full-palace staging
- fail before changing the original palace when staging allocation is unavailable
- leave the original palace and its backup state intact
- emit an actionable error naming the failed staging location
- verify cleanup when construction fails after staging succeeds
Wing-name migration
The operation should not leave collections and the registry in different naming states.
A complete solution should either:
- prepare and validate the registry replacement before mutating collection metadata, then publish it as part of a rollback-capable sequence; or
- snapshot the affected collection metadata and restore it if registry publication fails.
Simply replacing tempfile.mkstemp() without addressing the partial-update order would be insufficient.
Regression coverage
Add tests proving that:
- denied staging allocation leaves the original palace untouched
- denied registry temporary allocation leaves drawers, closets, and
topics_by_wingmutually consistent - an
os.replace()failure does not leave a partially applied wing-name migration - the prior
known_entities.jsonremains byte-for-byte intact after failure - no staging directory or temporary registry file is leaked
- a genuine temporary-name collision is retried successfully
- the normal successful migration remains idempotent
Relationship
Follow-up to #2420 and the review observation identifying the remaining migration allocation paths.
Related to #2358 because both involve known_entities.json, but this issue concerns temporary allocation and cross-store migration atomicity. #2358 concerns unreadable or malformed registry input.
Activity
0No activity yet.