## Context The existing distribution pipeline already queues real `distribution.build` jobs and keeps raw component keys out of platform APIs. The weak point is the generated package shape: Run artifacts still contain `config.json`, which makes accidental token disclosure easy when a ZIP is shared or inspected. The operator expectation is also a single `run.exe` on Windows, not an archive. ## Goals / Non-Goals **Goals:** - Produce Windows Run downloads as `run-windows-amd64.exe` and Linux Run downloads as raw executable files such as `run-linux-amd64`. - Compile server identity and the current Run key into the Run binary using Go native `-ldflags -X`. - Keep `RUN_PLATFORM_URL` and other explicit environment overrides working for local development and diagnostics. - Support raw-executable Run self-update artifacts with checksum verification and the existing staging/rollback flow. - Make run-key reset reachable from the server list while preserving the compact action popover. - Immediately revoke an online Run control session after its key is reset. **Non-Goals:** - Do not add device authorization, enrollment binding, or a token exchange ceremony. - Do not claim compile-time embedded tokens are unrecoverable from the executable; possession of the executable remains a trust boundary. - Do not change Client Manager packaging or plugin-declared client-manager build semantics. - Do not modify billing, cloud host sales, AI provider, plugin marketplace, or unrelated server workflows. ## Decisions ### Decision 1: Compile-time Run identity is a build-input contract Platform extends authenticated distribution build input with the public Run platform URL and the existing identity fields. The trusted Run worker passes those values to `go build -ldflags -X browser.local/run/config.=`. Run config loading prefers explicit environment variables, then compile-time build values, then developer defaults. This uses the Go-native mechanism the user requested. It avoids `go:embed`, generated source files, temporary code rewrites, or sidecar config files for Run. The compile-time value is still recoverable by someone holding the binary, but it removes the casual ZIP/config leak. ### Decision 2: Raw executable is a Run-only package format Run distributions use a new `raw-executable` package format. The worker uploads the compiled binary bytes directly and does not call the archive writer for Run. Client-manager distributions keep the existing ZIP/tar.gz packaging and config injection because they are plugin-declared companion builds with their own lifecycle. ### Decision 3: Self-update treats raw executable as first-class Run update input may carry `raw-executable`. The self-update executor still downloads through the artifact channel, verifies the full artifact checksum, writes the staged executable under the transaction workspace, records its binary checksum, and uses the existing activation and rollback logic. ### Decision 4: Run keys get a dedicated generator The existing `randomToken()` remains 32 random bytes because it is also used for auth sessions, user ID suffixes, and job leases. Run component keys use a new 64-byte URL-safe generator, increasing key length only for Run authorization. ### Decision 5: Reset revokes the active Run session The reset service already revokes old distribution artifacts and increments key generation. This change also removes the active Run control session for that server endpoint when the Run component key is reset, forcing a freshly compiled binary to authenticate before more control/job traffic is accepted. ## Risks / Trade-offs - Embedded authorization can be extracted from a binary by a determined operator or attacker with file access. This is acceptable for the requested distribution model and is explicitly not a DRM or device-binding system. - Compile-time values can be visible to privileged users on the build worker. The build worker remains part of the trusted platform boundary. - Raw executables lose the convenience of multi-file package payloads, so any future service installer/systemd wrapper should be a separate explicit distribution profile rather than hidden in this change. ## Verification - `openspec validate secure-single-file-run-distribution --strict` - `cd run && go test ./...` - `cd platform && go test ./...` - `cd platform_web && npm test` - `cd platform_web && npm run typecheck` - `scripts/check-structure.sh`