Follow dev-updater's own config to RON
The same move, for the same reason: this file is written and read by hand, and JSON has no comments to say why a host is configured the way it is. Both house rules come across with it, in config.rs's `format` module and nowhere else -- a file is the *body* of the config, so no outer parentheses and nothing indented for them, and `Some` is implicit, which is what makes `skip_serializing_if` on every optional field load-bearing rather than tidiness. The switch is outright: there is no reader for the old format. That is invisible everywhere except here, because this file holds the enrolled token hashes -- starting empty leaves the phone unable to talk to the server and looks, from the phone, like the config having been lost. So a config.json left beside the new file is named in the log and left alone, rather than read or deleted. One wart, documented at DriverKind: the kebab-case spelling is the string the phone compares against, so it stays, and the file pays for it with `kind: r#claude-cli` -- a hyphen is not a RON identifier. Renaming the variant would change what an already-installed build is talking to. Verified: cargo test, cargo clippy --all-targets, and a real start against a scratch state directory -- a hand-typed config with comments and a bare `port: 2222` loads, and what the server writes back sits at column 0 with no Some(...) in it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017xn8nHw1tw1R6PtiY1eEtw
This commit is contained in:
1 parent
effefdeb03
commit
19de699bfa
13 files changed
+167
-30
No files matched your search
@@ -76,7 +76,7 @@ backend (Rust/Axum, desktop)
|
||||
│ decided per session by the host it names
|
||||
├─ LlamaServerManager (llama-server lifecycle, local + SSH)
|
||||
├─ UsageMonitor (Anthropic OAuth usage endpoint)
|
||||
└─ config.json + per-session transcript files
|
||||
└─ config.ron + per-session transcript files
|
||||
```
|
||||
|
||||
### Backend layout (`server/`)
|
||||
@@ -196,7 +196,7 @@ turn. Claude's dialect: a `user` message on stdin mid-stream; pi's: `steer`.
|
||||
|
||||
### llama-server management
|
||||
|
||||
`config.json` lists **models** (name → GGUF path or llama-server args, per
|
||||
`config.ron` lists **models** (name → GGUF path or llama-server args, per
|
||||
host) and **hosts**. The manager runs at most one llama-server per
|
||||
`(host, model)`, spawned on demand when a session needs it:
|
||||
|
||||
@@ -215,7 +215,7 @@ host) and **hosts**. The manager runs at most one llama-server per
|
||||
|
||||
### SSH
|
||||
|
||||
- Host entries in `config.json`: name, `user@host`, optional ssh options,
|
||||
- Host entries in `config.ron`: name, `user@host`, optional ssh options,
|
||||
which capabilities it has (claude / pi / llama-server, with paths if not on
|
||||
PATH). Key-based auth only, using the system `ssh` client via
|
||||
`tokio::process` — no Rust SSH library; this inherits `~/.ssh/config`,
|
||||
@@ -267,7 +267,7 @@ GET /usage cached usage windows
|
||||
GET/PUT /hosts, /models config editing from the phone
|
||||
```
|
||||
|
||||
Sessions live in `config.json` (`$XDG_CONFIG_HOME/ai-app/`) + a per-session
|
||||
Sessions live in `config.ron` (`$XDG_CONFIG_HOME/ai-app/`) + a per-session
|
||||
directory under `$XDG_DATA_HOME/ai-app/sessions/` (transcript.jsonl,
|
||||
attachments, produced images), owner-only. Deleting a session is the
|
||||
complete path out of everything spawning one created.
|
||||
@@ -300,7 +300,7 @@ complete path out of everything spawning one created.
|
||||
attacker-writable. Two consequences:
|
||||
- **Nothing secret lives in the repo.** Certificates are generated on
|
||||
the machine that serves them and written to
|
||||
`$XDG_CONFIG_HOME/ai-app/certs` (0700, keys 0600); `config.json` and
|
||||
`$XDG_CONFIG_HOME/ai-app/certs` (0700, keys 0600); `config.ron` and
|
||||
session transcripts go to the XDG config and data directories, per
|
||||
machine. A CA private key the VM could read would let it mint a leaf
|
||||
the pinned app accepts, which is precisely the attack pinning exists
|
||||
@@ -344,7 +344,7 @@ complete path out of everything spawning one created.
|
||||
scanner Activity reached through the AndroidX Activity Result API,
|
||||
fully offline, no Play Services/ML Kit model download) and feeds the
|
||||
decoded URI to the same `parseEnrollmentUri` (2026-08-25).
|
||||
- **Storage**: server keeps only the SHA-256 in `config.json` (plain hash
|
||||
- **Storage**: server keeps only the SHA-256 in `config.ron` (plain hash
|
||||
is enough for high-entropy random input; buys that a leaked config
|
||||
doesn't leak the credential). No "show token again" — lost means rotate.
|
||||
Phone side: sealed with an Android Keystore AES-GCM key (a small
|
||||
@@ -475,7 +475,7 @@ window just fills.
|
||||
|
||||
1. **Skeleton** — *done 2026-08-24.* Repo layout, cert script, TLS + token
|
||||
auth, wg0-bound listener (fail closed if the interface is missing),
|
||||
config.json, session registry with a fake `EchoDriver`, session list +
|
||||
config.ron, session registry with a fake `EchoDriver`, session list +
|
||||
session screen in the app end-to-end over SSE. Proves the whole pipe
|
||||
before any AI is involved. Verified: 10 server tests + clippy clean;
|
||||
curl end-to-end over pinned TLS (auth rejection, spawn, SSE
|
||||
|
||||
Reference in new issue
Block a user