[v0.1/Config Review] Windows/macOS の config 探索パス二重化は 1.0 で正規化すべき #137
Labels
No labels
priority/P0
priority/P1
priority/P2
release/v0.1.0
status/blocked
status/planned
type/bug
type/design
type/test-gap
type/tracker
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
natsukium/felis#137
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
背景
config.tomlの探索パスはdirectories::ProjectDirsに委譲され、1.0 で凍結すると破壊的変更が不可能になる。$XDG_CONFIG_HOME/felis/config.toml(~/.config/felis/config.toml) — 妥当。~/Library/Application Support/felis/config.toml固定で~/.config/felis/は無視 — CLI ツールとしてはXDG_CONFIG_HOMEを優先するのが一般的(flake.nixの devShell も XDG を置く)。現行はdocs/how-to/fix-terminfo-problems.mdで混乱が報告されている。%APPDATA%\felis\config\config.toml—ProjectDirs::config_dir()が返す%APPDATA%\felis\config\にconfig.tomlを足した結果、configセグメントが二重。期待される%APPDATA%\felis\config.tomlではない。以後ユーザが手で作ったファイルはconfig\config.tomlに固定される。Home Manager の symlink 管理 (config.toml -> /nix/store/...) でも mtime ではなく resolved path の変化で reload する特殊分岐が入っている。felis configの E2E テストが Windows でcfg(unix)に限定されているのも、--config <path>/FELIS_CONFIGの override が無いため実 profile を置換せずテストできないことが直接原因。これらは filesystem 上の「どこに置くか」という契約で、1.0 で frozen label を貼った後は移行コストが高い(既存ファイルを移動する migration / deprecation warn が必要)。互換性を無視できる今しか直せない。
問い
1.0 で以下を決める:
%APPDATA%\felis\config.tomlに変更し、二重config\を解消する。ProjectDirsをやめてdirs/ 手書き解決に置き換えるか、ProjectDirsの結果から末尾configを strip するか。~/Library/Application Support/felis/config.tomlを第一候補、$XDG_CONFIG_HOME/felis/config.toml→~/.config/felis/config.tomlを第二候補として両方読む、または XDG を優先する。reference/config.mdの Platform 表を「どちらが選ばれるか」で一意に決める。--configの解決ベースを freeze するか — 現行はfelis起動時の cwd に対して絶対化し frontend に転送する(resolve_config_source)。FELIS_CONFIGenv を持たない理由(spawning env への漏洩)はexplanation/architecture/control-surfaces.mdにあるが、Windows の drive-relativeC:foo.tomlを拒否する分岐は 1.0 で公開契約として残すか。提案
%APPDATA%\felis\config.tomlに一本化(breaking だが今しかできない)。explanation/architecture/control-surfaces.mdに「なぜ ProjectDirs のデフォルトを上書きしたか」を記録し、--configの存在を移行手段として明記。XDG_CONFIG_HOMEが設定されていればそれを優先、なければ~/Library/Application Support/felis/config.toml、さらにフォールバックとして~/.config/felis/config.tomlを読む順序で凍結。felis config pathが実際に読む候補を列挙して返すようにし、テストは--configで代替できていることを担保。reference/config.md「Platform file locations」表に frozen として刻み、just schemaとnix/hm-module.nixの expected path を同時に更新。CHANGELOG.mdUnreleased に migration note。判定基準
felis config pathの出力だけで「どこに何を書けばいいか」迷わないこと。config\config.tomlを置いたユーザが 1.0 で黙ってデフォルトに戻らないこと(migration warn か両パスを読む猶予を 1 minor 置くか、いずれかを docs に明記)。cfg(unix)限定でなく--config経由で通ること。reference/config.md/explanation/architecture/control-surfaces.md/how-to/install/nix/hm-module.nix/skills/felisが同一 path を示すこと(doc-cascadeの grep sweep)。対象ファイル
crates/felis-client-core/src/config.rs(config_path,ConfigSource::resolve)crates/felis-client-core/felis-config.schema.json/nix/hm-module.nixdocs/reference/config.md「Platform file locations」docs/explanation/architecture/control-surfaces.md「Lenient config / Platform」docs/how-to/*/flake.nix(devShell の XDG)Parent: #12 および #11 / #4, #27 (本 issue は #4 の「探索パスと platform 差」の破壊的決定を具体化、
--config自体は #27)Triage (2026-09-05)
Verdict: accept with narrowing, P1. P1 only because
reference/config.mddocuments the paths and that table freezes; v0.1.0 advertises x86_64-linux only, so the platforms themselves are ungated.%APPDATA%\felis\config.toml. The doubledconfig\is aProjectDirsartifact that the docs currently reproduce as if intended. No migration shim: nothing has been released.~/Library/Application Support/felis/config.toml. An XDG fallback introduces a precedence rule and aconfig pathoutput with two candidates for a platform v0.1.0 does not gate;--configalready covers the "I keep dotfiles in XDG" case explicitly. Record the rejection and a Revisit trigger inexplanation/architecture/control-surfaces.md.--configresolution is #27's recorded decision; out of scope here.Cascade:
reference/config.mdPlatform table,nix/hm-module.nix,skills/felis,CHANGELOG.md.directories::ProjectDirsに従う、で良いと思うTriage plan (2026-09-05)
Source-grounded triage against
mainat07a77ae4, reviewed through six rounds of an independent reviewer (piluna then sol); every finding was verified against the source and folded in, and the design decisions below were settled with the maintainer on 2026-09-05. The order that supersedes the tracker's is posted on #12: this issue lands before #29 (schemas, goldens, and reference tables freeze there).Config discovery paths: keep
directories::ProjectDirs, freeze the tableClaim check
crates/felis-client-core/src/config/document.rs:408-417: the path isProjectDirs::from("", "", "felis").config_dir().join("config.toml"),which yields
%APPDATA%\felis\config\config.tomlon Windows and~/Library/Application Support/felis/config.tomlon macOS. Thereference table (
docs/reference/config.md:15-22),nix/hm-module.nix:107-108,192-203,and the how-to already state these paths consistently.
cfg(unix)test-gating argument is moot since #27:--configexists precisely so the Windows config and doctor suites can isolate a
temp profile (
docs/explanation/architecture/control-surfaces.md:222-229).Verdict
accept, docs-only. Maintainer decision on the issue (2026-09-05):
follow
directories::ProjectDirsas-is. No path changes on any platform.Approach
docs/explanation/architecture/control-surfaces.md"Lenient config /Platform": record the decision inline. Rationale: one resolver owned by
a maintained crate instead of a felis-owned per-platform table; the
doubled
config\on Windows and the non-XDG macOS location are thatcrate's conventions, and
--configis the escape hatch for a user whokeeps dotfiles elsewhere. Rejected: flattening Windows (a felis-specific
override of the resolver that every future ProjectDirs consumer in felis
would have to mirror), XDG fallback on macOS (a two-candidate
config pathoutput and a precedence rule for a platform v0.1.0 does not gate).Revisit if: ProjectDirs changes its layout, or macOS becomes a gated
platform and users report the location as a support load.
docs/reference/config.mdPlatform table: mark frozen for 1.0; keep theexisting two sentences of guidance.
#[cfg(unix)]tests incrates/felis-cli/tests/cli_config.rseach have their own reason, so handle them one by one:
default_discovery_is_untouched_when_the_flag_is_absent(:72) testsdiscovery itself and stays Unix (on Windows
ProjectDirsreads theknown-folder API, not
APPDATA, so a child cannot be redirected — thetest's own comment); it gains a Windows-only twin that runs
config path --format jsonwithout reading the file and asserts the reportedpath ends in
felis\config\config.tomland starts with the roamingapp-data folder — the executable form of the frozen table row;
an_unreadable_selected_file_reports_io(
:127) usesPermissionsExt, so make it portable by selecting adirectory as the config path instead; the relative-path test (
:175)needs Windows path spelling in its assertion, then un-gates.
cli_version.rs/cli_daemon.rsare whole-file#![cfg(unix)]forsocket reasons and stay.
nix/hm-module.nix,skills/felis,docs/how-to/*forthe three paths (they agree today; the sweep is the proof).
Dependencies / risk / labels
None. S. Keep labels. Not a
CHANGELOG.mdentry (nothing changes).