Introduce graphCacheState, a wrapper around GraphCache that tracks its
population lifecycle (loading -> loaded) and buffers concurrent mutations
during the initial DB scan. Once population completes, buffered updates
are replayed and the cache begins serving reads.
Start() now launches populateCache in a background goroutine by default.
While the cache is loading, all graph reads fall back to the database.
The KV iterators (ForEachNodeCacheable, ForEachChannelCacheable) now
respect context cancellation so that Stop() can interrupt a long-running
population.
Tests cover: concurrent reads during population, concurrent write replay,
shutdown cancellation during load, population failure with DB fallback,
and KV iterator cancellation.