config: validate only this client's overlay in the JSON schema #155

Merged
natsukium merged 2 commits from fix/client-overlay-schema-140 into main 2026-09-06 04:03:03 +09:00
Owner

Fixes #140.

The runtime carries every [client.<name>] section as raw TOML and never
validates a foreign one, but the published JSON schema described the map as
BTreeMap<String, EffectiveConfig> — so an editor validated every client's
section against felis' own vocabulary. The schema now names the felis
overlay explicitly and leaves the rest of the map open, reproducing the
runtime split the file is published to describe. The root object and the
config sections stay open, for the same reason the loader warns instead of
rejecting an unknown key; the schema's $comment carries that reason where a
reader of the published file finds it.

Doc cascade: docs/reference/config.md now states that a malformed foreign
section is ignored too — the property a third-party frontend depends on and
the one a 1.0 freeze has to name — and what the published schema validates.
docs/explanation/architecture/control-surfaces.md gains the trigger that
would reopen the one-document decision: a second first-party client whose
top-level vocabulary diverges from the GUI's, where config.d/<client>.toml
drop-ins buy back strict per-file validation with nothing left to drift.
CHANGELOG.md records the user-visible schema change.

Verified: just check green (fmt, clippy, nextest, deny, proto-compat);
reviewed by pi luna + pi sol; docs proofread by Gemini gemini-3.8-flash-high

Deferred

  • just check's skill-check step cannot run in this harness shell (yq: command not found). Environment gap only: flake.nix already provides yq-go for the dev shell and the script passes when YQ points at it. Pre-existing and unrelated to #140.
Fixes #140. The runtime carries every `[client.<name>]` section as raw TOML and never validates a foreign one, but the published JSON schema described the map as `BTreeMap<String, EffectiveConfig>` — so an editor validated every client's section against felis' own vocabulary. The schema now names the `felis` overlay explicitly and leaves the rest of the map open, reproducing the runtime split the file is published to describe. The root object and the config sections stay open, for the same reason the loader warns instead of rejecting an unknown key; the schema's `$comment` carries that reason where a reader of the published file finds it. Doc cascade: `docs/reference/config.md` now states that a malformed foreign section is ignored too — the property a third-party frontend depends on and the one a 1.0 freeze has to name — and what the published schema validates. `docs/explanation/architecture/control-surfaces.md` gains the trigger that would reopen the one-document decision: a second first-party client whose top-level vocabulary diverges from the GUI's, where `config.d/<client>.toml` drop-ins buy back strict per-file validation with nothing left to drift. `CHANGELOG.md` records the user-visible schema change. Verified: just check green (fmt, clippy, nextest, deny, proto-compat); reviewed by pi luna + pi sol; docs proofread by Gemini gemini-3.8-flash-high ## Deferred - `just check`'s skill-check step cannot run in this harness shell (`yq: command not found`). Environment gap only: flake.nix already provides yq-go for the dev shell and the script passes when `YQ` points at it. Pre-existing and unrelated to #140.
The runtime carries every `[client.<name>]` section as raw TOML and
never validates a foreign one, but the schema described the map as
`BTreeMap<String, EffectiveConfig>`, so an editor validated every
client's section against felis' vocabulary. Naming the `felis` overlay
explicitly and leaving the map open reproduces the runtime split, which
is what the file is published for.

The root object and the config sections stay open. Closing them would
turn a key another consumer of the shared document writes into a
validation error, which is the same reason the loader warns instead of
rejecting; the schema's `$comment` now carries that reason where a
reader of the published file finds it.

Refs #140
docs: freeze the inert foreign client section for 1.0
All checks were successful
bench / Criterion full-suite snapshot (pull_request) Has been skipped
fuzz / cargo fuzz nightly long-run (pull_request) Has been skipped
darwin / build felis (aarch64-darwin) (pull_request) Successful in 49s
bench / Criterion regression gate (pull_request) Successful in 2m2s
fuzz / cargo fuzz smoke (per target) (pull_request) Successful in 1m21s
pr / nix flake check (pull_request) Successful in 27s
pr / cargo build / clippy / test / deny (pull_request) Successful in 1m33s
pr / wire schema is compatible with the base (pull_request) Successful in 8s
pr / frontend smoke (x86_64-linux) (pull_request) Successful in 52s
pr / publish felis (x86_64-linux) (pull_request) Has been skipped
windows / cargo clippy (Windows cross) (pull_request) Successful in 14s
windows / cargo nextest (Windows) (pull_request) Successful in 5m59s
windows / frontend smoke (Windows) (pull_request) Successful in 2m0s
windows / package felis (x86_64-pc-windows-msvc) (pull_request) Has been skipped
7c76610b81
The reference stated that other clients' sections are ignored without
saying that a malformed one is ignored too, which is the property a
third-party frontend depends on and the one a 1.0 freeze has to name.
It also has to say what the published schema validates, now that the
schema draws the same line as the loader.

The one-document decision gains the trigger that would reopen it: a
second first-party client whose top-level vocabulary diverges from the
GUI's, where `config.d/<client>.toml` drop-ins buy back strict
per-file validation with nothing left to drift.

Refs #140
natsukium deleted branch fix/client-overlay-schema-140 2026-09-06 04:03:03 +09:00
Sign in to join this conversation.
No description provided.