feat: complete native execution and Steam discovery

This commit is contained in:
2026-07-18 20:11:52 -04:00
parent 514f87dacb
commit bc0090c63d
42 changed files with 6403 additions and 97 deletions
+21
View File
@@ -0,0 +1,21 @@
# Phase 2 native vertical-slice evidence
- Date: 2026-07-18
- Requirement IDs: R-006, R-009, R-012, R-016, R-018, R-024, R-029
- Phase/gate: phase 2 / native discovery through execution
- Scope: bounded opt-in manifests, approved Desktop Entry parsing, normalization,
durable identity, search, dry-run plans, global user configuration, owned child
execution, bounded redacted logs, and failures
- Exclusions: arbitrary application scanning, real graphical games, wrappers, Steam,
daemon or IPC, cache, installation management, and public stability
- Commands: `cargo test --workspace --all-targets --locked`; `make check`;
isolated CLI list/search/info/scan/dry-run/launch integration test
- Expected result: hostile metadata fails closed; arguments remain discrete; exact IDs
and unique names resolve deterministically; ambiguity is structured; child output is
logged privately with sensitive output and home paths redacted; unsuccessful launches
return structured errors; concurrent configuration edits fail closed
- Observed result: 56 workspace tests and strict repository gates passed; the isolated
native process executed through the production CLI path and produced a bounded mode-0600
log; configuration CLI edits reached native launch-plan runtime, session, environment,
and provenance fields
- Result: pass
+51
View File
@@ -0,0 +1,51 @@
# Native game manifests
Native discovery is opt-in. Place one schema-versioned TOML file per game under
`${XDG_CONFIG_HOME:-$HOME/.config}/kiln/native/`. Discovery is authoritative and
read-only; it does not scan arbitrary system applications.
## Direct executable
```toml
schema_version = 1
id = "openmw"
name = "OpenMW"
install_path = "/games/openmw"
executable = "/games/openmw/openmw"
arguments = ["--replace"]
```
`id` becomes `native:<id>`. `install_path` and `executable` must be absolute,
normalized UTF-8 paths. Arguments are passed directly and are never evaluated by a
shell.
## Approved Desktop Entry
```toml
schema_version = 1
id = "supertuxkart"
name = "SuperTuxKart"
install_path = "/usr/bin"
desktop_entry = "/usr/share/applications/supertuxkart.desktop"
```
The explicit path is the approval boundary. The adapter accepts Application entries,
parses `Exec=` without a shell, expands `%%`, `%c`, `%i`, and `%k`, and omits file/URL
codes because no files or URLs are supplied. Unknown field codes, malformed quoting,
symlinks, invalid UTF-8, files over 64 KiB, and mixed executable/Desktop Entry sources
fail closed.
## Commands and state
```text
kiln list [--json]
kiln search <query> [--json]
kiln info <id-or-name> [--json]
kiln scan [--provider native] [--no-cache] [--json]
kiln launch <id-or-name> --dry-run [--json]
kiln launch <id-or-name> [--json]
```
Installation identity remains in the Phase 1 XDG state registry. Native stdout and
stderr append to `${XDG_STATE_HOME:-$HOME/.local/state}/kiln/logs/native.log` with mode
`0600`. A non-zero child exit returns a structured `launch-failed` error.
+19
View File
@@ -0,0 +1,19 @@
# Phase 2 status
Phase 2 is complete.
| Exit condition | Evidence | Status |
|---|---|---|
| Explicit native discovery | Manifest and approved Desktop Entry tests | Passed |
| Normalization and durable identity | Game-record and move-preservation tests | Passed |
| Search and ambiguity handling | Native adapter and CLI integration tests | Passed |
| Dry-run planning | Typed launch-plan CLI test | Passed |
| Launch execution | Owned `/usr/bin/printf` isolated integration test | Passed |
| Logging | Private-mode, bounded, redacted stdout/stderr log tests | Passed |
| Configuration | Defaults, validate, explain, safe edits, provenance, and launch-plan integration tests | Passed |
| Failure handling | Malformed/non-UTF-8 input, traversal, symlinks, missing install, spawn, and non-zero exit tests | Passed |
| Repository gates | `make check` | Passed |
Real graphical-game execution is not required for this provider-independent native slice
and would interrupt the active desktop session. The isolated process test exercises the
same execution path without opening a window.