22 call sites across 16 consumer modules migrated to the wave-19 facade:
context.account.postbox.mediaBox.shortLivedResourceCachePathPrefix(resource.id)
->
context.engine.resources.shortLivedResourceCachePathPrefix(id: EngineMediaResource.Id(resource.id))
ItemListStickerPackItem additionally drops the wave-18 `let rawResource` intermediate.
Skipped: MediaEditorComposerEntity.swift:245 (uses local `postbox:` init-param,
not `context.account.postbox`; needs its own wave). No modules become Postbox-free
this wave — each still has other Postbox usage.
Drop direct `import Postbox` from four leaf consumer submodules, routing
data access through TelegramEngine/TelegramCore. Behavior-preserving.
Consumers migrated:
- ChatInterfaceState
- ChatSendMessageActionUI
- ContactListUI
- DrawingUI
TelegramCore additions (typealiases + one EngineData item):
- EngineMemoryBuffer, EnginePostboxDecoder, EnginePostboxEncoder,
EngineAdaptedPostboxDecoder (narrow utility aliases for coding support)
- EngineData.Item.Configuration.ContactsSettings
Six planned modules were abandoned in wave 1 with reasons recorded in
the plan: ActionSheetPeerItem, ChatListSearchRecentPeersNode,
DirectMediaImageCache, FetchManagerImpl, GalleryData, ICloudResources.
Each either has a public API that leaks `Postbox`/`Account`/`MediaBox`
(banned umbrella-type aliases) or cascades into out-of-wave modules.
CLAUDE.md now records the wave rules, typealias cheat sheet, and the
wave-selection guidance learned from this pass.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>