WinterGram/docs/superpowers/plans/2026-04-26-postbox-wave-103-retry-account-manager-store-resource-data-drain.md
isaac 7ccb382f53 Postbox -> TelegramEngine waves 103-105 (squashed)
Wave 103 (original): ChatRecentActionsControllerNode.peer Peer ->
EnginePeer migration ABANDONED after pre-flight discovered a 75-site
ADD-bridge cascade through chatRecentActionsHistoryPreparedTransition
into Message.peers SimpleDictionary<PeerId, Peer> store sites.
Lessons captured in docs/superpowers/postbox-refactor-log.md "Wave 103
ABANDONED" section + ~/.claude/projects/-Users-isaac-build-telegram
-telegram-ios/memory/feedback_wave71_shadow_risk.md (4-layer pre-flight
checklist for stored-Peer-field migrations).

Wave 103 (retry, 92230b0691): drained 5 accountManager.mediaBox
.storeResourceData Shape-A sites against the wave-94 facade. 2 files /
3 Edit calls (1 single + 2 replace_all) / 1-iter / 29.5s build. Closes
the storeResourceData accountManager-side drain entirely.

Wave 104 (08fc3f721e): drained 3 of 8 accountManager.mediaBox.resourceData
Shape-A sites against the wave-32/wave-94 AccountManagerResources.data
(resource:) facade + 3 consumer-side .complete -> .isComplete renames
(EngineMediaResource.ResourceData field rename). 1 file / 6 Edit calls
/ 1-iter / 11.7s build. 5 of 8 candidates deferred behind Postbox-typed
-function-parameter barriers (fetchCachedScaled*Representation cascade,
combineLatest typed-tuple coupling). Established the "Postbox-typed
-function-parameter barrier registry" pattern.

Wave 105 (0c76724409): DeviceContactInfoSubject enum 3 case Peer?
payloads + 2 callback signatures + 1 computed property migrate to
EnginePeer?. 5 files / 17 edits / 1-iter / 203s build (foundational
AccountContext touch). Net wrap delta -8 (10 drops, 2 ADD bridges, 1
downcast->case-let). First wave-71-shadow-style migration after the
wave-103 abandonment forced a discipline reset; first-pass-clean via
thorough pre-flight inventory (~15 min).

Net session progress: -16 wraps across 4 wave attempts plus durable
scaffolding (feedback memory, barrier registry, 4-layer pre-flight
checklist).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 16:57:55 +04:00

9.7 KiB
Raw Blame History

Wave 103 (retry): accountManager.mediaBox.storeResourceData drain Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Drain 5 remaining accountManager.mediaBox.storeResourceData(...) Shape-A sites against the wave-94 AccountManagerResources.storeResourceData(id:data:synchronous:) facade. Wave 103 (retry) of the Postbox → TelegramEngine refactor, after the abandonment of the original wave-103 plan.

Architecture: Wave-shape-G drain. Pure call-site rewrite; no facade addition, no TelegramCore touch, no public-API change. 5 sites across 2 consumer files (ThemeUpdateManager.swift, WallpaperResources.swift) migrated via 3 Edit calls (1 single + 2 replace_all=true batches).

Tech Stack: Swift, Bazel via Make.py, no unit tests (per CLAUDE.md). Verification is the full-project debug-sim-arm64 build.

Iteration budget: 1 (target first-pass-clean given mechanical scope and validated facade).

Note on TDD: This project has no unit tests. Each task writes the edits, then verifies via Bazel build + residue grep.


File Structure

File Role Changes
submodules/TelegramUI/Sources/ThemeUpdateManager.swift Theme-update background sync 1 site migrated
submodules/WallpaperResources/Sources/WallpaperResources.swift Wallpaper resource pipeline 4 sites migrated via 2 replace_all=true batches

No public-API ripple — both files are leaf consumers of the wave-94 facade.


Task 1: ThemeUpdateManager.swift — single-site migration

Files:

  • Modify: submodules/TelegramUI/Sources/ThemeUpdateManager.swift

Edits in this task: 1.

  • Step 1: Migrate the storeResourceData call at line 112

Find:

                                        accountManager.mediaBox.storeResourceData(file.file.resource.id, data: fullSizeData, synchronous: true)

Replace with:

                                        accountManager.resources.storeResourceData(id: EngineMediaResource.Id(file.file.resource.id), data: fullSizeData, synchronous: true)

accountManager here is closure-captured from presentationThemeSettingsUpdated(_:) scope, typed AccountManager<TelegramAccountManagerTypes>. The facade is exposed via public extension AccountManager { var resources: AccountManagerResources }.


Task 2: WallpaperResources.swift — two batched migrations

Files:

  • Modify: submodules/WallpaperResources/Sources/WallpaperResources.swift

Edits in this task: 2 (each replace_all=true, covering 2 sites apiece).

  • Step 1: Migrate the reference.resource.id pattern (lines 973, 1214)

Use Edit with replace_all=true:

Find:

accountManager.mediaBox.storeResourceData(reference.resource.id, data: data)

Replace with:

accountManager.resources.storeResourceData(id: EngineMediaResource.Id(reference.resource.id), data: data)

Both sites share identical text (verified by pre-flight grep). replace_all=true handles both atomically.

  • Step 2: Migrate the file.file.resource.id pattern (lines 1260, 1523)

Use Edit with replace_all=true:

Find:

accountManager.mediaBox.storeResourceData(file.file.resource.id, data: fullSizeData)

Replace with:

accountManager.resources.storeResourceData(id: EngineMediaResource.Id(file.file.resource.id), data: fullSizeData)

Both sites share identical text. replace_all=true handles both atomically.


Task 3: Full-project Bazel build

Files: none (verification only).

  • Step 1: Run the build
source ~/.zshrc 2>/dev/null; python3 build-system/Make/Make.py --overrideXcodeVersion \
 --cacheDir ~/telegram-bazel-cache \
 build \
 --configurationPath build-system/appstore-configuration.json \
 --gitCodesigningRepository git@gitlab.com:peter-iakovlev/fastlanematch.git \
 --gitCodesigningType development --gitCodesigningUseCurrent \
 --buildNumber=1 --configuration=debug_sim_arm64

Expected: clean build (bazel build complete / INFO: Build completed successfully). No --continueOnError because the small scope makes the first error informative.

Build cost projection: WallpaperResources is foundational with wide rebuild fan-out; expect ~30-90s.

  • Step 2: If build fails, triage iteration

Common failure modes:

  • EngineMediaResource.Id not in scope — verify import TelegramCore is at the top of the failing file (it should be — pre-flight inventoried both files have it). If absent, add it.
  • Type mismatch on id: parameter — would suggest an unexpected MediaResourceId subtype. STOP and re-read; the migration assumed MediaResource.id: MediaResourceId for both reference.resource and file.file.resource. Both should resolve to MediaResourceId per Postbox protocol.
  • accountManager.resources not in scope — the public extension AccountManager exists in TelegramCore (wave 94). If unreachable, the consumer's BUILD might be missing a TelegramCore dep — but both files already use TelegramCore types, so this should not happen. STOP if it does.

If errors land outside those 2 files: STOP and report BLOCKED. The wave is supposed to be self-contained.

Fix in place and re-run step 1. Budget: 2 iterations.


Task 4: Post-edit residue grep

Files: none (verification only).

  • Step 1: Verify zero remaining accountManager.mediaBox.storeResourceData in the 2 touched files

Run:

grep -rn "accountManager\.mediaBox\.storeResourceData" \
  submodules/TelegramUI/Sources/ThemeUpdateManager.swift \
  submodules/WallpaperResources/Sources/WallpaperResources.swift

Expected: empty output.


Task 5: Commit the wave

Files: none (git only).

  • Step 1: Stage the 2 modified files
git add \
  submodules/TelegramUI/Sources/ThemeUpdateManager.swift \
  submodules/WallpaperResources/Sources/WallpaperResources.swift
  • Step 2: Confirm staging is clean
git status --short | grep -v "^??"

Expected output: only the 2 staged files (lines starting with M ). The line m build-system/bazel-rules/sourcekit-bazel-bsp is pre-existing WIP and should NOT appear in the staged list.

  • Step 3: Commit
git commit -m "$(cat <<'EOF'
Postbox -> TelegramEngine wave 103 (retry)

Drain 5 accountManager.mediaBox.storeResourceData(...) Shape-A sites
that the wave-94/95-99 sweep missed. All 5 migrated to
accountManager.resources.storeResourceData(id: EngineMediaResource.Id(...))
against the existing wave-94 facade.

Sites: ThemeUpdateManager:112 (with synchronous: true),
WallpaperResources:973, 1214 (reference.resource.id pattern, replace_all),
WallpaperResources:1260, 1523 (file.file.resource.id pattern, replace_all).

5 sites / 2 files / 3 Edit calls. Consumer-only build.

Wave-103 retry after the abandonment of ChatRecentActionsControllerNode
peer migration; see postbox-refactor-log "Wave 103 outcome" for the
forensics.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"
  • Step 4: Verify commit
git log --oneline -1

Expected: shows the wave 103 (retry) commit as HEAD.


Task 6: Update outcome log + memory

Files:

  • Modify: docs/superpowers/postbox-refactor-log.md

  • Modify: ~/.claude/projects/-Users-isaac-build-telegram-telegram-ios/memory/project_postbox_refactor_next_wave.md

  • Modify: ~/.claude/projects/-Users-isaac-build-telegram-telegram-ios/memory/MEMORY.md

  • Step 1: Append wave 103 (retry) outcome to refactor log

Append a "Wave 103 (retry) outcome" entry to docs/superpowers/postbox-refactor-log.md. Include:

  • Commit hash (from Task 5 step 4).

  • Iteration count (1 if first-pass-clean; 2 if Task 3 step 2 fired).

  • Bazel build duration.

  • Net-delta accounting: 5 raw mediaBox.X accesses, +5 facade calls, +5 EngineMediaResource.Id(...) wraps (canonical engine-side, not Postbox bridges).

  • Wave-shape note: G drain, validates the wave-94 facade across an additional 2-module footprint.

  • Step 2: Update next-wave memory

Edit project_postbox_refactor_next_wave.md:

  • Add wave 103 (retry) outcome line into the recent-waves section.

  • Mark the 5 sites as drained; remove from candidate inventories (the file currently lists "Wave 95+ candidates" with stale storeResourceData entries — clean those up).

  • Update the top frontmatter description to reflect wave 103 (retry) landed.

  • Promote next candidate. Options: 7-site resourceData(...) drain (would need a new facade method or use existing data(resource:)), DirectMediaImageCache Shape-C/D, or pivot to a foundational wave.

  • Step 3: Update MEMORY.md index

Edit ~/.claude/projects/-Users-isaac-build-telegram-telegram-ios/memory/MEMORY.md:

  • Update the [Postbox refactor next wave] line to mention wave 103 (retry) landed.

  • Step 4: Commit the doc update

git add docs/superpowers/postbox-refactor-log.md
git commit -m "$(cat <<'EOF'
docs: log wave 103 (retry) outcome

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EOF
)"

(Memory file updates are not committed — they live outside the repo.)


Net delta projection

Category Count Sites
Raw mediaBox.X access drops 5 TUM:112 + WR:973, 1214, 1260, 1523
Facade calls added +5 same sites, migrated form
EngineMediaResource.Id(...) wraps +5 canonical engine-side constructs (not Postbox bridges)
import Postbox drops 0 both files retain Postbox import for unrelated symbols
Postbox-free module count 0 no module dropped from the import list

Total commit footprint: 5 line edits (3 Edit calls) across 2 files, plus a docs commit for the outcome log.