Found while building /todo triage (PR #17): I wrote saveRegistry(setProjectMaxOpen(loadRegistry(), name, max)) assuming the return value was the updated registry. It's the entry — so I persisted an entry-shaped object as the registry, and the next loadRegistry failed its shape check and silently returned empty (config-load-style recovery, so no error).
Two cheap hardsenings, either suffices:
- rename/reshape:
setMaxOpen(name, max) that loads + saves internally (like renameProject does), or
- keep the primitive but return the registry, and add
getProjectEntry for the entry case.
Also: the corrupt-registry recovery path (loadRegistry catch → emptyRegistry) is silent for exactly this shape-corruption case — a one-line warn-to-stderr would have saved me a debug loop.
Found while building
/todo triage(PR #17): I wrotesaveRegistry(setProjectMaxOpen(loadRegistry(), name, max))assuming the return value was the updated registry. It's the entry — so I persisted an entry-shaped object as the registry, and the nextloadRegistryfailed its shape check and silently returned empty (config-load-style recovery, so no error).Two cheap hardsenings, either suffices:
setMaxOpen(name, max)that loads + saves internally (likerenameProjectdoes), orgetProjectEntryfor the entry case.Also: the corrupt-registry recovery path (
loadRegistrycatch → emptyRegistry) is silent for exactly this shape-corruption case — a one-line warn-to-stderr would have saved me a debug loop.