Repository navigation
self install writes config.d/<program>.yaml, which no program reads: an edit there changes nothing #1009
Description
self install writes a configuration file for each program that no program reads. Every program reads one file, ~/.config/devlore/config.yaml; the per-program files sit beside it in ~/.config/devlore/config.d/, and an edit there changes nothing. The owner, 2026-10-02: "config is centralized. if we discover the need to separate config, i'd be inclined to follow git's include model."
- Written.
initDevloreConfig(cmd/internal/cli/selfinstall.go:1088) createsconfig.d/(:1106), seedsconfig.yamlfromschema.SharedDefaultConfigwhen it is absent, and writesconfig.d/<program>.yamlfrom the program'sDefaultConfigwhen that is absent (:1119) -- for all four programs on the shared root: devlore-test, lore, star and writ.self uninstallremoves the file and then the directory once it is empty (removeDevloreConfig,:760). - Never read. The shared root calls
cli.InitViperwithUseSharedConfig: true(cmd/internal/cli/root.go:176-179), which searches~/.config/devlore/forconfig.yamland nothing else (cmd/internal/cli/viper.go:73). Everyconfigsubcommand reads or writescli.SharedConfigPath(), the same file. star's extension configuration readsstar/config.yamlat the repository root and~/.config/star/config.yaml(cmd/star/config/config.go:93-105). No code opensconfig.d. - Proved. In a sandbox configuration home,
writ: {verbose: true}inconfig.yamlmakes writ printUsing config: …; the same setting inconfig.d/writ.yamlalone has no effect. - What it costs. lore's file sets
lore.ai_providerandlore.sourcesuncommented, so it reads as lore's live configuration; lore never sees it. writ's carries the commentedwrit.scopesandwrit.segmentsexamples, so a user who uncomments one there is ignored. And on a machine with noconfig.yaml,config editseeds that file with the program's own defaults (cmd/internal/cli/config.go:247,:337), whose header namesconfig.d/<program>.yamlas the location. - Documented as read. The headers of
schema/defaults/{devlore-test,lore,star,writ}.yaml, the doc comments atschema/schema.go:22,:28and:39,docs/architecture/9-star-extensions.md:219(star's configuration), anddocs/architecture/configuration.md:863(star config getreads it) all nameconfig.d/<program>.yamlas the location. - A second per-program location, unreachable.
InitViper's other branch,UseSharedConfig: false, reads~/.config/<program>/config.yaml(viper.go:76), andBindFlagskeeps a matching unprefixed form. No caller passes false.
Found 2026-10-02 at 01634491, planning lane 7 of #916 (#926).
Resolution
Configuration is one file, ~/.config/devlore/config.yaml, read by every program; docs/architecture/configuration.md § One user configuration file is the reference. If a real need to separate it appears, the separation follows git's include model: an include the user writes in the file, never a directory scanned by convention and never a file a program writes for itself.
The fix stops self install writing config.d and self uninstall removing it, removes InitViper's per-program branch, and corrects the headers, the doc comments and the two design documents. Where each program's documented defaults go instead is the plan's open question, and #780's requirement that each program "generates its own default config" is read against the answer. No code retires the files already on machines: under the governing principle they are deleted by hand, after anything edited in them is moved into config.yaml.
Plan and design documents
| Kind | Document |
|---|---|
| Plan | docs/plans/fix/1009-config-d-retired.md, a draft on PR C's branch until it merges |
| Design | docs/architecture/configuration.md |
Activity
docs(config): configuration is one file, with git's include model if …
docs(plan): lane 22 takes the owner's ruling (d), no program writes t…