> 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/adr/0020-user-provided-system-files.md).

# ADR 0020: Kouch places system files the user drops onto it

## Status

Accepted on 2026-09-27 (owner overrule of part of ground rule 2): *"can we do auto import from drag and dropping into the program? for keys at least for specific emulators/systems"*, then *"i mean if the user is providing it it should be fine"*. This is the one exception to "the `system` folder is the one folder Kouch never lists, reads, syncs, sends, receives or packs". Everything else in ground rule 2 stands:

* Kouch never ships, downloads, transfers or bundles ROMs, BIOS, firmware or keys;
* it never syncs, sends, packs or receives them from another machine (Steam Cloud, LAN, `.kod`);
* it never says where to get them.

## Context

* Emulators need the user's own BIOS, firmware or keys. Until now the user had to find each emulator's system folder and copy the files by hand (Settings › Emulators › Open system folder). The owner wants a dropped file to land in the right place by itself.
* The risks:
  1. **Store policy:** an emulator was pulled from Steam over key material. A Steam app that visibly handles keys invites scrutiny, even when the files are the user's own.
  2. **Scope creep:** a file-placing path is one step from a file-moving path, which ground rule 2 forbids (a `.kod`, LAN, Cloud).
  3. **Wrong placement:** a misnamed or wrong-region file placed silently is worse than a clear manual step.

## Decision

* **One path only: a local drop, or the file picker behind the same sheet.** The user drops files onto Kouch's window. Kouch matches each by **file name**, plus size where the profile lists one, against the system files the installed emulators' profiles declare (`user_data.system_files`).
* **The sheet:** *"Place 2 system files for : prod.keys, title.keys → its system folder"*, with one confirm. Kouch then copies (never moves) each file into that emulator's `system` folder, or the sub-path the profile names. On a name clash it asks: Replace / Keep mine.
* **Matching:**
  * Several emulators matching → the user picks.
  * No match → the file is ignored, with *"Not a file any of your emulators uses"*.
  * Kouch never guesses from contents.
* **Firmware packages** that the emulator installs with its own installer (a system update file, a firmware archive): Kouch runs the emulator's own install command when the profile declares one, or opens the emulator with its install dialog. It never unpacks firmware itself.
* **Everything else in ground rule 2 is unchanged.** Every other write and read path keeps its refusal of `system` / `bios`: `kod.rs`, the LAN manifest and receiver, `cloud.rs`, exports, reports, the screenshot watcher. The new path is a separate command with its own tests, and it can't be reached from a `.kod`, a link or the network.
* **Wording:** neutral, "system files". Kouch never explains how to obtain them, never names sources, and never logs file contents (names and sizes only).
* **A switch:** `settings.system_files.drop_import` (default on, per the owner), so a store build can turn the feature off in one place if review requires it.

## Consequences

* Setting up an emulator that needs keys or a BIOS becomes one drop. The launch check ("system files missing") clears afterwards.
* Profiles gain `user_data.system_files`: names, optional sizes, and an optional sub-path and install command. That data lives in profiles (the private test profiles and community profiles), never in Kouch's own code or assets, which stay brand-free.
* The store-policy risk is recorded here; the switch is the mitigation if it's ever needed.

## Follow-up: emulators that read system files from config or saves (2026-09-27, before any code)

Some emulators read their keys or boot ROM from folders that also hold data Kouch exports and syncs. One reads its key files from its portable root, next to its settings (Kouch's `config`). Another reads its boot ROM from a region folder next to its memory cards (`saves`). Placing the file there permanently would put system files into a `.kod` export, Steam Cloud or a LAN transfer. So these emulators get no drop placement until both parts below exist:

* **(a) Session-only placement.**
  * The file stays in the emulator's `system` folder. A profile entry names where the emulator reads it (`read_at`: a folder key and sub-path, e.g. `config:.` or `saves:GC/{region}`).
  * Just before launch Kouch places a *copy* there (never a link, so no walker can follow a link back into `system`), and removes it after the emulator quits.
  * Every copy is recorded in a crash-safe manifest before it's made, the same way mods are. A leftover is reverted at the next start, before anything touches user data (cloud sync, export, LAN).
  * A copy is removed only if its size and time still match what Kouch placed. One the emulator rewrote is left in place with a warning, and (b) still keeps it from leaving the PC.
* **(b) A hard exclusion through the existing private-path machinery.**
  * Every `read_at` location plus the declared names becomes an implicit `user_data.private` rule for that profile. It's computed, never stored.
  * `private` is already refused by `.kod` export and import, the LAN manifest and receiver, Steam Cloud and storage moves, so no path needs a new guard.
  * It also covers a file the user put there by hand before Kouch existed.

Tests to come with it:

* placement and removal around a session;
* the crash revert at startup, before any sync;
* export, Cloud and LAN each refusing a declared name in `config`/`saves` even when (a) never ran;
* a rewritten copy left alone.


---

# 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/adr/0020-user-provided-system-files.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.
