Skip to content

Architecture and Source Ownership

Nick Hamze edited this page Jul 21, 2026 · 10 revisions

Architecture and Source Ownership

SwanSong is one experience built from several deliberately separate products, repositories, and trust lanes. Those boundaries keep a Mac app update from becoming permission to install a game, and keep a Core release from becoming permission to change the Mac app.

Repository boundaries

Product or input Canonical source Ownership boundary
Story Forge novel framework RegionallyFamous/swansong-story-forge Schema-v3 narrative policy, starter, reports, catalog audits, ImageGen review contract, and publication tooling. Desktop provides the typed local UI and does not fork those rules.
SwanSong Desktop for macOS RegionallyFamous/SwanSong-Desktop SwiftUI/AppKit app, library, translation workbench, C ABI, release tooling, and macOS tests.
SwanSong for Analogue Pocket RegionallyFamous/swansong-core FPGA source, Pocket packaging, hardware qualification, and Pocket releases. Desktop can install only a verified, authorized release from this lane onto a user-selected card.
Yokoi hardware utilities Yokoi Boot and Yokoi Cart Service at the immutable source revision recorded in SOURCE_PROVENANCE.md Separately executable GPLv3 WonderSwan programs used by Cartridge Tools. Their payloads, license, notice, and corresponding-source location are verified independently from the GPLv2 Mac executable.
First-party Homebrew Catalog RegionallyFamous/swansong-catalog Signed catalog bytes, publisher/right attestations, immutable provenance, and source-file evidence. Catalog content is fetched only after explicit consent and is not bundled into Desktop.
First-party homebrew releases Identified immutable source repositories, including RegionallyFamous/swansong-story-forge Licensed ROM source and exact-tag release assets referenced by the signed catalog. A catalog entry cannot replace the source repository's own license and provenance.
WonderSwan software engine Upstream ares pinned by Dependencies/ares.lock.json Exact upstream revision prepared locally, patched only by the tracked integration patch, and included as sanitized corresponding source in official releases.
SwanSong Studio SDK SwanSong SDK 0.5.0 pinned by Dependencies/swansong-sdk.lock.json Exact tagged runtime, schema, recipes, Python package, license, and tool entry point are embedded in the signed app with a per-file content manifest. External checkouts are explicit development overrides.
SwanSong Desktop updater updates/appcast.xml plus this repository's GitHub Releases Sparkle updates the signed macOS app only. It does not publish homebrew or invoke the Pocket installer.
Native updater framework Sparkle at the exact version and commit in Package.swift, Package.resolved, and Dependencies/sparkle.lock.json Third-party embedded framework. Official corresponding-source archives include its locked source and license; SwanSong's integration, feed, policy, release tooling, and tests remain here.

The repositories and release authorizations are intentionally independent. Installing SwanSong Desktop does not touch a card. A user may separately invoke Desktop's Analogue Pocket tool, which trusts only an immutable authorized swansong-core stable release and scopes its merge to that package's managed Core/platform files. Installing or updating the Pocket core does not modify the Mac app. The full card eligibility, package trust, transaction, and rollback contract is documented in Analogue Pocket SD Setup.

The app-update and Homebrew trust paths are also independent. Sparkle verifies SwanSong app enclosures with the public update key in the signed app. The Homebrew Catalog uses a different public key, signed schema, consent, cache, anti-rollback state, and ROM validator. Compromise or activation of one path must not authorize content in the other.

macOS runtime architecture

The main execution path is:

  1. SwiftUI and AppKit present the library, player, settings, legal/support, native update, and Translation Lab interfaces.
  2. SwanSongKit owns import validation, private storage, persistence, state, controller mapping, compatibility evidence, Open IPL identity, and Translation Lab policy.
  3. CSwanEngine is the backend-neutral C ABI between Swift and the engine.
  4. The live release backend links the pinned ares WonderSwan engine.

ABI 6 introduced the narrow final-writer display-provenance capability. ABI 7 added bounded upstream CPU dataflow from those final display bytes to exact half-open cartridge ranges, with explicit unknown/overflow completeness flags and private outside-consumer records. ABI 8 adds component-selective seeds and private executed-read context (caller, exact operand segment/offset, mapper window/bank, and resolved cartridge operand); outside-consumer discovery remains component-complete. ABI 9 adds sprite-attribute ownership: the private owner sample records its OAM range and final writer, and upstream probing can select spriteAttribute separately. Conservative dataflow now retains the first private reason and V30 origin while continuing to withhold exact lineage. ABI 10 binds exact lineage to sealed consumed-prefetch contexts. Static-analysis seed-v2 keeps those contexts and fetched cartridge bytes inside the private project for the required decoder check; public automation sees only counts and hashes. During a clean replay the renderer can describe the final owner of a bounded native rectangle—layer, map/tile/raster/palette or sprite/OAM source, and last CPU writer—without exposing a general trace API. Writer history is intentionally not serialized in save states, so a restored session cannot claim provenance and must replay from boot.

Private source-probe artifacts share a 64 MiB evidence bound and may normalize as many as 256 disjoint selected cartridge ranges. Those are storage and aggregation bounds, not permission to weaken lineage: a true per-byte range-set overflow, unknown dependency, conservative origin, or incomplete outside- consumer scope still blocks promotion and static-seed export.

A stub backend exists for UI-only contributor work. It is not evidence that a game boots, that audio/video timing is healthy, or that a release is valid. Compatibility and release claims require the live ares backend.

Build and source storage

The prepared ares checkout and build products live under ignored .engine/ and .build/ directories. They are reproducible inputs or outputs, not canonical source. Official release packaging recreates the pinned ares tree, removes upstream convenience firmware binaries, applies the tracked integration patch, and includes that exact sanitized tree in the corresponding-source archive. It also materializes the exact Sparkle commit from the tracked lock without Git metadata and includes its complete license under Dependencies/sparkle-source. Before signing, the app records the Git source commit and whether its checkout was dirty. Release packaging requires clean metadata matching the current checkout and embedded ares lock, then binds the source, ares, and Sparkle commits into the release manifest, source archive's generated provenance marker, and archived dependency locks.

User ROMs, original firmware, saves, states, captures, and Translation Lab evidence are ignored private material and must never be committed or attached to public issues.

Cartridge Lab keeps the same narrow ownership rule. The Mac app owns serial transport, bounded transfer policy, local destinations, and the visible confirmation flow. Yokoi Boot and Yokoi Cart Service run separately on the user's WonderSwan Color or SwanCrystal. See Cartridge Lab for the hardware, backup, restore, and bootstrap boundaries.

App icon source

The editable icon master, shipped raster/ICNS outputs, provenance record, and deterministic regeneration script all live in this repository:

Generated icon outputs are reviewed and committed so release builds do not depend on an untracked design file or an external asset service.

Local MCP boundary

SwanSongMCP is a separate local STDIO executable with a small JSON-RPC adapter for the MCP methods SwanSong exposes. It has no inbound network listener. Live-app requests cross a token-authenticated Distributed Notification Center bridge and are handled on SwanSong's main actor through a fixed method allowlist.

The bridge returns coarse app state and accepts only navigation or playback of the already selected game. Translation automation bypasses the UI bridge and calls SwanSongKit proof/evidence primitives directly, but restricts every input to the selected project and requires an explicit project-write confirmation. See Local MCP and Automation.

Story Forge follows the same narrow ownership rule. A user explicitly selects the framework repository, catalog, and novel manifest. Desktop verifies the complete schema-v3 tool surface and invokes only fixed operations; it does not offer an arbitrary command field. The coarse app bridge can reveal only whether a novel project is open and navigate to Story Forge. Novel titles, paths, manuscript text, reports, art, music, editions, diagnostics, and approval records remain local.

Clone this wiki locally