Why this matters
The bug. Python evaluates default arguments once, when the function is defined — not on each call. The single shared [] accumulates events from every caller, leaking memory and bleeding state across requests.
The fix. Sentinel pattern: default to None, create a fresh list inside the body if needed. (You'll also need log = log if log is not None else [] — the puzzle accepts the signature change as the canonical fix.)
Why this puzzle is `memory_leak`. It's a slow leak in a long-running process. Adjacent categories like unsafe_mutation are also valid — the adjacency graph awards yellow.
Review heuristic
Every long-lived collection (cache, registry, event bus, observer list) needs an eviction or unsubscribe path that fires deterministically. "It'll get GC'd" is true for the value but not for the reference holding it.
External reference: CWE-401: Missing Release of Memory after Effective Lifetime.