> For the complete documentation index, see [llms.txt](https://docs.kouch.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kouch.dev/docs/kod_platforms_plan.md).

# .kod on every platform: per-platform profiles, an online home, versions

Owner request, 2026-09-27: one `.kod` works on every platform Kouch supports (Windows and Linux/SteamOS now, macOS in a future update); it points somewhere online (GitHub / GitLab) so it has updates and a version history; Linux downloads work; Flatpak is an option; **nothing updates automatically** — updating is opt-in per emulator. This addendum does not replace `PLAN_V2.md` Phase 7/8 or `docs/PROFILE_AUTHORING.md`; it extends the profile format (schema v3) and the updater.

## Today (checked in the code, 2026-09-27)

* A profile has **one** `launch` (an `exe` path or a Flatpak) and **one** `source` (one asset glob, one `executable`). A `.kod` written on Windows downloads the Windows build on a Deck; a Flatpak profile does nothing on Windows.
* Sources: `github_release` (latest only), `json_feed` (a project's own "latest" feed), `direct_url`. No GitLab, no Flatpak, no list of versions.
* The updater unpacks zip / tar / tar.gz / 7z. A bare AppImage download fails with `UnsupportedArchive`; zip and 7z unpack without the executable bit on Linux.
* Updates are already opt-in per emulator: `update_check` (notify) and `auto_update` (install) default off and an imported profile can never set them (`source.auto_update` is only a suggestion). Keep that.
* Verified live: Windows import → download → config edits → launch → DSU → quit (four test profiles). Linux: import works (Game Mode too) and a user-installed Flatpak profile launches with DSU and the Quick Menu; Linux downloads were never tested.

## The format (profile schema v3)

Shared fields stay at the top (`id`, `name`, `systems`, `extensions`, `players`, `hotkeys`, `options`, `mods`, `netplay`, …). What differs per OS moves into `platforms`:

```json
{
  "version": 3,
  "id": "example-emu",
  "name": "Example Emulator",
  "origin": { "kind": "github", "repo": "someone/kouch-profiles", "path": "example-emu.kod" },
  "systems": [ … ],
  "extensions": [ … ],
  "platforms": {
    "windows": {
      "launch": { "kind": "exe", "path": "{install}/Emu.exe" },
      "source": { "kind": "github_release", "repo": "emu/emu", "asset": "*-windows-x64.zip", "executable": "Emu.exe" },
      "user_data": { "config_edits": [ … ] }
    },
    "linux": {
      "launch": { "kind": "exe", "path": "{install}/Emu.AppImage" },
      "source": { "kind": "gitlab_release", "host": "gitlab.com", "project": "emu/emu", "asset": "*-x86_64.AppImage" }
    }
  }
}
```

* **Platform keys:** `windows`, `linux` and `macos`. Kouch runs on Windows and Linux today; **macOS is a future update** (owner, 2026-09-27), but the schema accepts a `macos` section now, the validator checks it like the others, and it is stored and exported untouched, so profiles written today carry it when a Mac build ships. Launch kinds and sources a platform can't use are refused in that section (a `flatpak` launch or source outside `linux`, for instance). A macOS `.app` bundle is an `exe` whose path points inside it; the macOS updater details (`.dmg`, notarised bundles) are designed with the Mac port, not now.
* **A platform section** holds `launch` (required) and optionally `source`, `args`, `env`, `working_dir` and `user_data` (config files live in different places per OS). Anything it leaves out comes from the top level.
* **Choosing a section:** Kouch uses the section for its own OS (`windows` / `linux`; the Deck is `linux`). None for this OS → the import refuses in plain words: *"This emulator has no Linux version in this file. It has: Windows."* — before anything downloads. Since K7 that refusal covers the install only: the file's data still imports, into an emulator this system already has or finds.
* **Stored whole:** the saved profile keeps every section, so a backup, a LAN transfer or a re-export to another OS keeps working; the host's section is resolved when installing and launching.
* **v1/v2 profiles keep working:** a top-level `launch`/`source` is a single-platform profile — Windows when the launch is an `.exe` (or a `windows-*`-looking asset), Linux when it's a Flatpak or an AppImage, otherwise "any OS" exactly as today.
* **`origin`, the profile's online home** (GitHub or GitLab, optional host for self-hosted GitLab): where the `.kod` itself is published. Kouch can check it for a newer version of the profile and show its history (the repo's releases, or the commits touching `path`). Applying a newer profile keeps the user's own settings (toggles, option values, installed version), like today's re-import.

## Sources (where the emulator comes from)

| `kind`            | Updates + version history                    | Notes                                                                                                                                                 |
| ----------------- | -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `github_release`  | releases list (tags, dates, notes link)      | exists; add the list + install-a-version                                                                                                              |
| `gitlab_release`  | GitLab releases API (`gitlab.com` or `host`) | new                                                                                                                                                   |
| `json_feed`       | latest; a list only if the feed has one      | exists (the owner's reference emulator uses it)                                                                                                       |
| `flatpak` (Linux) | `flatpak remote-info` / `--log`              | new, optional: `flatpak install --user --noninteractive <remote> <app_id>` through the download queue; still only the emulator itself (ground rule 2) |
| `direct_url`      | none                                         | kept for local, hand-made profiles; a shared `.kod` should use one of the above (the validator warns, the import sheet says "no updates")             |

**Linux downloads:** a bare AppImage (ELF with the `AI\x02` magic) installs as the executable itself; unpacked zip/7z restore the zip's Unix modes and always mark the source's `executable` (and a top-level AppImage) executable; tar keeps its modes. Checksums and the `system`/`bios` exclusions are unchanged.

## Versions and updates (checks automatic, installs opt-in per emulator)

Owner, 2026-09-27 (revises the first draft, where checking was off by default too): *"make sure to auto check for emulator updates, but only show 'update available!' when auto update is disabled"*.

* **Checks are automatic, for every emulator with an updatable source** (github/gitlab release, a feed, Flatpak; a `direct_url` can't be checked): at start (after first paint, off the UI thread) and every few hours while Kouch runs, never during a game. No per-emulator "check" toggle; one global switch in Settings › Emulators, **Check for emulator updates automatically**, on by default, for people who want Kouch offline. The old per-profile `update_check` field is kept for compatibility and ignored.
* **Installing stays opt-in per emulator:** **Install updates automatically**, off by default; an imported profile can never turn it on (the import sheet shows the author's suggestion as text).
* **When a check finds a newer version:**
  * **auto-install off** → the emulator shows **"Update available!"** (its row in Settings › Emulators, its Versions sheet, Home's emulator-updates widget, once as a toast per new version), with **Update** to install it;
  * **auto-install on** → it installs by itself when that emulator isn't running (queued until the game quits), and "Update available!" is never shown for it; afterwards a short "Updated to 2.4.0" notice says what happened.
* **Versions:** installed version and the source's list (version, date, notes link; *Install this version*, *Roll back*); a manual *Check now*.
* **Steam Cloud sync is on by default** for every emulator, imported ones included (owner, 2026-09-27; ADR 0018). It can't sync until Kouch has its own app id, and the toggle says so.
* **Profile updates** (a profile with an `origin`): checked with the same automatic checks; a newer profile file shows "Profile update available" and is applied only by the user (never automatically), keeping their settings.

## K7 A file without this OS's section still imports its data (owner, 2026-09-27)

After the K6 report (*"a Windows-only file is refused"*), the owner: *"it should not be refused if the import is available in deck but did not have the data in the .kod file, but the user has installed it, so it can import saves and data etc if the user wants to"*.

* **The refusal stops the install, nothing else.** The file's saves, states, config, emulator settings, per-game settings, graphics values and mods still import when the user picks them (GAME\_MENU\_EXPORT\_PLAN G7's choices).
* **One emulator never blocks the others.** A multi-emulator file (all emulators at once) imports every emulator it can. Today one emulator with no section for this OS refuses the whole file (`refuse_other_os`); that goes.
* **Kouch looks for a copy of the emulator this OS can run, in this order:**
  1. **Already in Kouch:** this system has a profile with the same id and a section for this OS. The import keeps that install and launch, adds the file's other-OS sections to the profile (so the next export covers both), and restores the chosen data into it.
  2. **Installed outside Kouch:** the emulator's Flathub app is installed on this system (checked through the host, as the `flatpak` source does). The sheet offers "Use the installed one"; the profile gets a `flatpak` launch for this OS with no download.
  3. **The same project has a build for this OS:** the same GitHub/GitLab release has an asset for this OS, or Flathub has the app. This is the export fill-in (`emulators_platform_candidates`) run on import. The sheet offers "Install the Linux build from the same project"; nothing downloads until the user chooses it.
  4. **Installed by hand:** "Locate it": the user picks the program, and it becomes this OS's section with no source.
  5. **None of these, or the user skips:** the data imports alone. The emulator is listed as "Not installed on this system", with its data in place, and Settings › Emulators offers cases 2–4 later.
* **The sheet says which case applies, in plain words:**
  * *"This file has no Linux version of . It's already installed here: its saves and settings go into that copy."*
  * *"… Kouch can install the Linux build from the same project."*
  * *"… Import its data now and install it later."*
* A section added this way was filled in on this system (`origin_ref` untouched). It travels in the next export, where Windows and Linux are required anyway (ADR 0019).
* **Who:**
  * **B:** the inspection reports the case per emulator (with the candidates), `kod_import` accepts per-emulator `install: "existing" | "candidate" | "locate" | "skip"` next to latest/exported, merges sections, and refuses per emulator, not per file.
  * **A:** the import sheet's platform line becomes that choice.
  * **Central, live on the Deck:** the Windows-only test file with the emulator already in Kouch (its saves arrive in the Linux copy), with the Flathub app installed, and data-only; plus a two-emulator file where only one has a Linux section.

## Who does what

| Part                                                                                                                                                                                                                                                                                                                                                 | Owner             |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| K1 Schema v3 (`platforms`, `origin`), host-OS resolution, v1/v2 compatibility, validator, `kouch-lab gen-schemas`, `PROFILE_AUTHORING.md`                                                                                                                                                                                                            | B                 |
| K2 Updater: AppImage installs, exec bits, `gitlab_release`, release lists + install-a-version, `flatpak` source (install/update/list via the host, Deck-safe)                                                                                                                                                                                        | B                 |
| K3 Contract: import preview says which platforms a file has and refuses a missing one; `emulators_versions`, `emulators_install_version`, profile-origin check/history/apply; toggles                                                                                                                                                                | B (Rust) → A (UI) |
| K4 UI: the import sheet's platform line and refusal, Settings › Emulators versions and toggles, mock data for all of it                                                                                                                                                                                                                              | A                 |
| K5 Guide: creators' profile page (platforms, origin, sources), adding/managing emulators, updates are opt-in                                                                                                                                                                                                                                         | docs session      |
| K6 Live checks: one shared test `.kod` with a Windows and a Linux section — Windows download → setup → launch → quit on this PC; the Deck: AppImage download → exec → launch → quit, the refusal for a Windows-only file, versions + rollback on both. A Flatpak install on the Deck needs the owner's OK first (it installs outside `~/kouch-dev`). | central           |

## Status

| Part                                      | Status                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| K1 schema v3                              | done (B, 34122e3): platforms {windows, linux, macos}, origin, host resolution, the refusal, v1/v2 compatibility, validator, schema, PROFILE\_AUTHORING                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| K2 updater                                | done (B, `4d750fe`, `19e3cbb`; `current.json` `previous` fixed in `b6bf4b5`), verified live in K6 on Windows and the Deck; an already-installed Flathub app is adopted, never installed twice (`8dc20a6`)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| K3 contract                               | done (B, 96492e0; auto-check setting and events with K2)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| K4 UI                                     | done (A, `937c2ac`, `13755dd`, `6711a06`: checks automatic, installs opt-in, "Update available!" only while installs are manual; `f215e6a`: "Uses the installed Flathub app")                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| K5 guide                                  | done (docs session: `e79c913`, `13b397d`, `9480242`, `8cfba59`)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| K6 live checks                            | **done 2026-09-27** with one shared three-platform test file. Deck (Linux): a Windows-only file refused in the planned words; the real GitHub release resolved (v2.6, 61.4 MB AppImage, sha256 matches GitHub digest), installed under its stable name with the exec bit; 50 versions listed; install v2.5 keeps v2.6 for rollback; launched with `{user_data}` placeholders in `env` resolved (the emulator's XDG dirs inside Kouch's data; the owner's own emulator config folders unchanged); graceful quit. Windows: a Linux-only file refused; the Windows zip installed (program found inside the zip's subfolder); versions + rollback; export preview `missing: []`, the exported file carries all three sections + `exported_version`, no install state. Found: older Kouch builds rejected newer files with a raw error (fixed, abe2545: they read it or say "Update Kouch"). **Cross-system:** the file exported on Windows (v2.5 installed there) imported on the Deck with "install the exported version" installs the Linux v2.5 AppImage, executable, with no manual step. |
| K7 data imports without this OS's section | **done 2026-09-27** (B `09eb39c`, A `c979c36`), verified live on the Deck: a Windows-only file into the copy already installed there (sections merged, no download, its save replaced the old one); a two-emulator file where one has no Linux section (saved as not installed here with its data, the other not blocked); the Deck's own Flatpak of an emulator detected as installed, with a clear Flathub match (nothing installed or updated). Open nit: the merge drops a stored section the file lacks                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.kouch.dev/docs/kod_platforms_plan.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
