34fef55d25
#ensureDir checked #initialized then set it across an await #scanExistingIds() gap, so two concurrent first-use save/allocatePath callers both re-seeded #nextId=maxId+1 and allocateId() handed both the same id — silently overwriting the first artifact (same toolType) or making artifact:// resolution ambiguous (different toolTypes). Memoize the initial scan as a single in-flight #initPromise so all concurrent callers share one initialization and receive distinct ids. Fixes #4091