Source-level audit while investigating #457 found two pre-existing lifetime risks in Program.updateSource (packages/ts_program/src/ts_program.zig, currently around lines 317-336). It destroys cached compilation before allocating, duplicates the new source, removes/frees the old source-map key/value, then allocates a replacement key and reinserts. Failure after removal can leave File.source referring to freed bytes and leak the new duplicate. Also, addRedirectFile borrows target.source, but successful replacement of the canonical source does not refresh redirect source slices. This is an audit finding, not yet a dedicated failing-allocator/runtime reproduction.
Acceptance: add precise allocation-failure/recovery/leak regressions for source replacement; publish the new source/map/compilation state atomically; verify canonical and redirected-file ownership/lifetimes after successful updates; cover direct and redirected updates and preserve package-id semantics. Keep source snapshot invalidation consistent. The current performance work uses transient per-collection facts and continues excluding redirected files; it does not claim to fix these underlying update semantics. Track under #416.