clone

an offline map explorer where each world, from a game map to a city's open data, ships as one .atlas file

main
atlas / docs / decisions / 0007-hostenv-portability.md
0007-hostenv-portability.md 2.0K rendered
1# 7. One pure handler, everything OS-shaped behind hostenv23- **Date:** 2026-08-024- **Status:** accepted5- **Where it is written down:** issue #5 §3.3, §10 decision 3;6 [app.md](../app.md) §178## Context910The application needs a desktop window, a headless server for the dev loop and11CI, and — eventually, maybe — a zero-install static distribution where Go12compiles to `js/wasm` and a Service Worker synthesizes the responses. Written13the ordinary way, the handler reaches for `os`, builds paths, and opens14dialogs, and each of those calls quietly picks one of those three futures.1516## Decision1718The application is **one pure `http.Handler`**. It touches no filesystem,19builds no path, opens no dialog and reads no environment. Everything OS-shaped20arrives through three small interfaces:2122```go23type Hostenv interface {24 Volumes() VolumeStore25 Sessions() SessionStore26 PickFile(ctx context.Context) (io.ReadCloser, string, error)27}28```2930`SessionStore` is bytes under a name, which is what lets a file, an OPFS31handle, and a test's map be the same store. `VolumeStore` hands over32descriptors; the fold that decides which build serves is pure and lives in33`format/bundle`. `PickFile` distinguishes three answers — a file,34`ErrNoSelection`, `ErrNotAvailable` — because an import that cannot happen and35an import nobody wanted are different things to say.3637The rule is mechanical, not cultural: `tools/depcheck`'s `hostenv` analyzer38fails any import of `os`, `os/exec`, `path/filepath`, `syscall` or a window39toolkit from `internal/app` outside `internal/app/hostenv`.4041## Consequences4243- The OS implementations sit in `internal/app/hostenv/oshost`, so a host that44 is not an operating system links none of them.45- The PWA host stays reachable at near-zero cost now. **No PWA work is46 scheduled**; the discipline is the whole investment.47- A pull request that leaks an OS call past `hostenv` fails a check rather than48 earning a review comment.49- Testing the application needs no temp directories: the stores are interfaces50 and the handler is a function.