Addresses R2 CHANGES_REQUESTED from Miga + Rames on PR #2529:
1. Sibling-surface gap (blocker): `hyperframes cloudrun render{,-batch}`,
`hyperframes lambda render{,-batch}` all advertised the same tier-only
aliases (`1080p` / `hd` / `4k` / `uhd`) but normalized them to `landscape`
and never set `outputResolutionAspectAgnostic`. The distributed plumbing
PR #2529 added received `undefined` from those callers, so portrait `1080p`
still hit the original aspect-mismatch on Cloud Run / Lambda.
Fix: introduce `resolveResolutionFlagPair` in `@hyperframes/parsers` (the
single source of truth for the two-step normalize + aspect-agnostic
detect) and route every distributed entrypoint through a shared
`parseOutputResolutionFlag` CLI util so the alias signal now reaches
`SerializableDistributedRenderConfig`. Studio Server keeps its
canonical-only HTTP contract; that intent is now pinned in tests.
2. Preflight recompute (hardening): the earlier "downgrade aspect-mismatch"
preflight cleared un-remapped mismatches, so IG 4:5 (non-preset aspect,
no sibling) and portrait-4K comp + `--resolution 1080p` (remap +
downsample) both slipped through to fail late in `resolveDeviceScaleFactor`.
Now `checkRenderResolutionPreflight` computes the effective preset via
`suggestMatchingPreset` (mirroring the compile stage's
`adaptAspectAgnosticResolution`) and re-checks against that — only
genuinely-fixable mismatches clear early. New tests pin both regressed
input classes.
3. Docker forwarding boundary test (Miga's important #2): pinned
`1080p` survives verbatim as `--resolution 1080p` in the Docker args
so the in-container CLI can re-run `isAspectAgnosticResolutionAlias`.
4. Doc-nit (Miga): parsers/src/types.ts no longer references the
nonexistent `resolveResolutionForComposition` — points at the actual
remap helpers.
Fallow: cloudrun.ts / lambda.ts share 390 lines of pre-existing structural
symmetry (parallel AWS + GCP dispatchers), and lambda/render.ts +
render-batch.ts declare parallel RenderArgs interfaces. Both re-flagged
after threading the aspect-agnostic field through each surface; ignored
with justification in .fallowrc.jsonc. lambda.ts's `run` and
lambda/render.ts's `waitForCompletion` are pre-existing CRAP-score
hotspots untouched by this PR — added under health.ignore.
Co-Authored-By: Claude <noreply@anthropic.com>
— Via