Skip to content

Alpha 5: native macOS host and native BGFX client — scope and tracking #327

Description

@bobtista

Proposal

Alpha 5 delivers first-class macOS support and launches the community's native BGFX Zero Hour client against the user's retail data — no Wine. It lands the four-phase feat/macos-hostfeat/native-launch stack plus the hardening items from its external review.

Blocker for public macOS distribution: notarization (#322). An unsigned distributed GenHub quarantines every file it writes, and Gatekeeper then blocks the game binary. Until that lands, native launch works only on a developer machine.

Scope

Definition of done: the three PRs land and #322 notarization passes — at that
point there is a distributable macOS build. Priority order; "PR" is which stack PR
closes it (see The mac stack below).

# Issue Closed by
1 #314 — Reject multi-variant manifests at ingestion PR A
2 #315 — Validate retail archive roots before launch PR C
3 #316 — Materialize workspace executables atomically PR A
4 #317 — Remove DYLD_LIBRARY_PATH / LD_LIBRARY_PATH PR C
5 #318 — Fix stderr capture EOF race PR C
6 #319 — macOS detector must distinguish TCC denial from "none found" PR B
7 #320ValidateScopes shrink-only ratchet own PR
8 #322 — Playwright exclusion, inside-out signing, notarization own PR
9 #323 — Launch receipt + cheap revalidation own PR
10 #324 — Engine-only launch smoke on macos-15 CI own PR
11 #325 — Magic-byte executable classification own PR

#314#319 are review findings on code that has not shipped. Their fixes are
folded into the owning branch before the PR opens, so each will close without a
visible "fixes #NNN" diff — the code reads as originally written. Each issue
carries a comment saying which PR closes it. They are kept as issues rather than PR
checklist items because they describe user-visible behaviour worth finding later.

Moved out of this milestone:

Dependencies worth knowing

The mac stack

Restructured from four sequential PRs into two independent PRs plus one dependent
one
, and rebased onto development @ 8e07339. Local only so far — no remote
branches, no PRs open.

PR Branch Commits Base Depends on
A feat/cross-platform-fixes 7 development
B feat/macos-host 4 development
C feat/native-launch 16 (B + A + 4 + wiring) A and B both

A and B are independent and can be reviewed in parallel. C opens once they land.

Why this beats the original four-deep chain

The original plan chained macos-hostplatform-neutral-model
unix-filesystemnative-launch. Measured against this repo's rules, that chain
is expensive: squash-merging a parent orphans its child (it keeps the parent's
unsquashed commits and goes CONFLICTING, needing a manual retarget and rebase),
and dismiss_stale_reviews_on_push: true means every such rebase drops the
approvals. A four-deep stack pays that three times. We hit exactly this with
#305/#309 during the Alpha 4 blockers.

The two middle phases fix real Linux and Windows bugs — silent hard-link copy,
Windows paths on Linux, updater installing the wrong platform, symlink reachability
— and are not macOS work. Checking the actual coupling: of 43 files they touch,
only two tie them to the macOS layer, and the types they introduce
(MacOSGamePathProvider, UnixFileOperationsService, UnixSymlinkCapabilityProvider)
all live in the shared project, not GenHub.MacOS. The only genuinely
macOS-dependent parts are three DI registration lines plus two entries in a shared
test-assertion helper that the macOS branch creates.

Those five lines moved into a single wiring commit at the head of C, which is the
first point where both the types and the module exist. That makes A fully
standalone: 7 commits, zero GenHub.MacOS files, 1384 tests green directly on
development
. C's tree is byte-identical to the original four-deep stack, so
nothing was lost or gained — 1395 tests green.

The practical win: the cross-platform bug fixes stop being hostage to macOS review,
and two of the three PRs can be reviewed at the same time.

Landing notes

  1. The stack must be rebased once more after chore: alpha 4 release #229 merges. main requires
    linear history, so chore: alpha 4 release #229 lands as a squash or rebase — both mint new SHAs, and
    8e07339 will not be an ancestor of main. The rebase already done resolved
    both collisions against current code, so the second pass should be mechanical.

    Two collisions were found and are already resolved in the branches:

  2. Fold the review fixes into the owning branch before opening PRs
    (Reject multi-variant manifests at ingestion until .Files consumers are migrated #314macOS installation detector must distinguish TCC denial from no installations found #319 map to PRs as noted in the priority table above).

  3. Open A and B together; open C after both land.

Say in A's description that it fixes Linux and Windows bugs and stands on its own
merits — it is not macOS-only work.

Engine-repo track

Tracked separately in the engine repository (bobtista/GeneralsGameCode, topic/trunk, upstream TheSuperHackers):

  • CNC_ZH_USERDATAPATH for per-profile Options.ini
  • Normalize install-path roots in GlobalData.cpp to always append the separator
  • Machine-readable failure (exit code or sentinel log line) when required archives fail to mount

The third is the engine-side half of #315 and would simplify every GenHub-side mitigation.

Status

Alpha 5 opens once Alpha 4 ships. Alpha 4 readiness is tracked in #307.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions