Background
Council Cycle 9 (steel-yeti, 3-of-4 convergent) flagged a shape inconsistency introduced during the P3.2/P3.3 edge-cache campaign:
app/api/challenge/route.ts was updated to use a unified addressesToBust: Set<string> + grouped Promise.all shape
app/api/identity/[address]/refresh/route.ts retained the older middlewarePurges: Promise<void>[] array pattern
This inconsistent precedent means the two primary write paths have diverged in shape, making future maintenance harder and increasing the risk of alias coverage drift.
secret-mars narrowing note (Cairn Q1)
When extracting the shared helper, the middleware-OG purge component should be narrowed to btc/stx forms only. Per Phase 2.3 crawler-handler scope, middleware OG cache is exclusively keyed on btc:/stx: prefixes — purgeMiddlewareOgCache(taproot) and purgeMiddlewareOgCache(bnsName) are currently no-op purges (harmless but wasteful). By contrast, the /api/og purge via buildEdgeCacheKey("/api/og", addr) correctly keeps full enumeration since /api/og/[address] does support taproot/bnsName lookups.
Proposed implementation
Extract invalidateAllOgCaches(kv: KVNamespace, addresses: Set<string>, opts: { includeMiddleware: boolean }) in lib/edge-cache.ts. The helper would:
- Always invalidate
/api/og cache for all addresses in the set
- When
includeMiddleware: true, also run middleware-OG purge but filtered to btc/stx forms only
Adopt this helper in both:
app/api/challenge/route.ts (already has the Set shape; wire up the helper)
app/api/identity/[address]/refresh/route.ts (migrate from middlewarePurges: Promise<void>[] array to Set + helper)
Alias-parity gap (host loop finding)
identity-refresh's cachedAddresses Set includes {btc, stx, taproot?, previousBnsName?, nextBnsName?} but does NOT include previousTaprootAddress for the update-taproot action case. This is a minor alias-parity gap relative to challenge route's full previous-alias coverage. Folding this fix into the same cleanup pass is natural — extend cachedAddresses to include previousTaprootAddress when the refresh action changed it.
Scope
lib/edge-cache.ts — add shared helper
app/api/challenge/route.ts — adopt helper
app/api/identity/[address]/refresh/route.ts — migrate shape + fix alias gap
References
Background
Council Cycle 9 (steel-yeti, 3-of-4 convergent) flagged a shape inconsistency introduced during the P3.2/P3.3 edge-cache campaign:
app/api/challenge/route.tswas updated to use a unifiedaddressesToBust: Set<string>+ groupedPromise.allshapeapp/api/identity/[address]/refresh/route.tsretained the oldermiddlewarePurges: Promise<void>[]array patternThis inconsistent precedent means the two primary write paths have diverged in shape, making future maintenance harder and increasing the risk of alias coverage drift.
secret-mars narrowing note (Cairn Q1)
When extracting the shared helper, the middleware-OG purge component should be narrowed to btc/stx forms only. Per Phase 2.3 crawler-handler scope, middleware OG cache is exclusively keyed on btc:/stx: prefixes —
purgeMiddlewareOgCache(taproot)andpurgeMiddlewareOgCache(bnsName)are currently no-op purges (harmless but wasteful). By contrast, the/api/ogpurge viabuildEdgeCacheKey("/api/og", addr)correctly keeps full enumeration since/api/og/[address]does support taproot/bnsName lookups.Proposed implementation
Extract
invalidateAllOgCaches(kv: KVNamespace, addresses: Set<string>, opts: { includeMiddleware: boolean })inlib/edge-cache.ts. The helper would:/api/ogcache for all addresses in the setincludeMiddleware: true, also run middleware-OG purge but filtered to btc/stx forms onlyAdopt this helper in both:
app/api/challenge/route.ts(already has the Set shape; wire up the helper)app/api/identity/[address]/refresh/route.ts(migrate frommiddlewarePurges: Promise<void>[]array to Set + helper)Alias-parity gap (host loop finding)
identity-refresh's
cachedAddressesSet includes{btc, stx, taproot?, previousBnsName?, nextBnsName?}but does NOT includepreviousTaprootAddressfor theupdate-taprootaction case. This is a minor alias-parity gap relative to challenge route's full previous-alias coverage. Folding this fix into the same cleanup pass is natural — extendcachedAddressesto includepreviousTaprootAddresswhen the refresh action changed it.Scope
lib/edge-cache.ts— add shared helperapp/api/challenge/route.ts— adopt helperapp/api/identity/[address]/refresh/route.ts— migrate shape + fix alias gapReferences