Skip to content

fix(images): export light/dark pairs together with granular cache - #84

Merged
alexey1312 merged 1 commit into
mainfrom
fix/images-granular-cache-pairing
Jul 30, 2026
Merged

fix(images): export light/dark pairs together with granular cache#84
alexey1312 merged 1 commit into
mainfrom
fix/images-granular-cache-pairing

Conversation

@alexey1312

Copy link
Copy Markdown
Collaborator

Problem

ImagesLoader.loadFromSingleFileWithGranularCache filtered to changed nodes without pairing light/dark variants. A designer edit touching only the dark variant produced an orphan dark asset, and ImagesProcessor then rejected the whole config:

Error: Asset count mismatch: light=0, dark=1
Missing assets in Light: safety-sos-button-color

f124526 added pairing to IconsLoader only — ImagesLoader was never updated, and both of its branches were affected (the PNG branch had no pairing-aware helper at all). This broke 03_daily_assets_update in Oymyakon-Atoms-iOS on every day the illustrations file changed (4 runs in July).

Changes

  • loadPNGImagesWithGranularCache takes darkModeSuffix: String? = nil and routes to fetchImageComponentsWithGranularCacheAndPairing when set
  • single-file PNG branch passes darkSuffix; SVG branch switches to loadVectorImagesWithGranularCacheAndPairing
  • loadFromLightAndDarkFileWithGranularCache keeps nil on purpose — light and dark live in separate files and are filtered independently

Also fixed (found during the same investigation)

  • batch returned exit code 0 while reporting failures, so CI treated a broken export as green — now throws ExitCode.failure when failureCount > 0
  • the failure table truncates both config name and error, making CI logs useless for diagnosis — full errors are now printed underneath it
  • 5 tests in SubcommandFaultTolerancePrecedenceTests crashed on ParsableArguments.init(), which leaves every @Option undecoded so the first read traps. Switched to try FaultToleranceOptions.parse([]), the pattern already used throughout FaultToleranceOptionsTests. Under --parallel this surfaced as a non-zero exit with no XCTAssert failure line, which is why it read as a green suite.

Tests

New ImagesLoaderGranularCachePairingTests covers both branches:

  • testOnlyDarkChanged_vectorBranch_includesBothVersions
  • testOnlyDarkChanged_pngBranch_includesBothVersions

Full suite: 1996 XCTest + 211 swift-testing, exit 0 (swift test --parallel, Swift 6.3).

Docs

Updated .claude/rules/cache-granular.md, gotchas.md, and modification-checklists.md so the pairing requirement is recorded next to the granular-cache rules it belongs to.

`ImagesLoader.loadFromSingleFileWithGranularCache` filtered to changed nodes
without pairing, so a designer edit to only the dark variant produced an orphan
dark asset and `ImagesProcessor` rejected the whole config:

    Error: Asset count mismatch: light=0, dark=1
    Missing assets in Light: safety-sos-button-color

f124526 added pairing to `IconsLoader` only. `ImagesLoader` was never updated,
and both of its branches were affected — the PNG branch had no pairing-aware
helper at all. This broke `03_daily_assets_update` in Oymyakon-Atoms-iOS on
every day the illustrations file changed (4 runs in July).

- `loadPNGImagesWithGranularCache` takes `darkModeSuffix: String? = nil` and
  routes to `fetchImageComponentsWithGranularCacheAndPairing` when set
- single-file PNG branch passes `darkSuffix`; SVG branch switches to
  `loadVectorImagesWithGranularCacheAndPairing`
- `loadFromLightAndDarkFileWithGranularCache` keeps `nil` on purpose: light and
  dark live in separate files and are filtered independently

Also fixed, found during the same investigation:

- `batch` returned exit code 0 while reporting failures, so CI treated a broken
  export as green — now throws `ExitCode.failure` when `failureCount > 0`
- the failure table truncates both config name and error, making CI logs
  useless for diagnosis — full errors are now printed underneath it
- 5 tests in `SubcommandFaultTolerancePrecedenceTests` crashed on
  `ParsableArguments.init()`, which leaves every `@Option` undecoded so the
  first read traps. Switched to `try FaultToleranceOptions.parse([])`, the
  pattern already used throughout `FaultToleranceOptionsTests`. Under
  `--parallel` this surfaced as a non-zero exit with no `XCTAssert` failure
  line, which is why it read as a green suite.

Full suite now green: 1996 XCTest + 211 swift-testing, exit 0.
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@alexey1312
alexey1312 merged commit 055de73 into main Jul 30, 2026
4 checks passed
@alexey1312
alexey1312 deleted the fix/images-granular-cache-pairing branch July 30, 2026 06:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant