Verified at b4543b4 (clean tree, matches origin/main).
The defect
The documented user-tier config path and the path the code actually reads are different directories. A user who follows the README gets no config at all, with no error and no warning.
Code — crates/synapse-module/src/lib.rs:13575-13580, inside load_module_config():
let user_path = env::var_os("HOME").map(|home| {
PathBuf::from(home)
.join(".config")
.join("cortexkit") // <- cortexkit/
.join("synapse.jsonc")
});
Docs — four sites all say ~/.config/synapse/synapse.jsonc:
README.md:28 — "Example user-tier ~/.config/synapse/synapse.jsonc"
docs/design-remote-gateway.md:233
docs/design-synapse-module.md:253
docs/design-synapse-module.md:257
There is no fallback to ~/.config/synapse/. The only paths consulted are SYNAPSE_CONFIG_PATH (env override), $HOME/.config/cortexkit/synapse.jsonc (user), and ./.cortexkit/synapse.jsonc (project).
Why the code is right and the docs are wrong
The e2e test independently agrees with the code — crates/synapse-module/tests/skeleton_e2e.rs:432:
let operator_config_dir = operator_home.join(".config").join("cortexkit");
So cortexkit/ is the intended path in both implementation and test. The four doc references are the outlier.
Failure mode: silent, not loud
load_module_config() ends with:
Ok(ModuleConfig::default())
A missing user config is not an error — it falls through to defaults. So a user who places a file exactly where the README tells them gets a module that starts fine, reports healthy, and silently ignores every setting they wrote: knob, cache_max_bytes, decode_chain_k, grammar_enabled, alias_admin_enabled, worker.load_timeout_ms, and the whole inline / jobs / probe blocks.
cache_max_bytes is the one that bites hardest — a user capping the model cache below the 32 GiB default would silently keep the default and fill the disk.
There is no diagnostic that would lead them to the cause: no log line names the path that was searched.
Suggested fix
Docs are the cheap half — correct the four references to ~/.config/cortexkit/synapse.jsonc.
Worth considering alongside it, since the silence is what makes this expensive to diagnose: log the resolved config source at startup (path + tier, or "defaults, no config file found"). That turns every future instance of this class into a one-line answer instead of a bisect.
Happy to send a PR for the doc correction if useful; say the word on whether you want the startup log line in the same change or kept separate.
Verified at
b4543b4(clean tree, matchesorigin/main).The defect
The documented user-tier config path and the path the code actually reads are different directories. A user who follows the README gets no config at all, with no error and no warning.
Code —
crates/synapse-module/src/lib.rs:13575-13580, insideload_module_config():Docs — four sites all say
~/.config/synapse/synapse.jsonc:README.md:28— "Example user-tier~/.config/synapse/synapse.jsonc"docs/design-remote-gateway.md:233docs/design-synapse-module.md:253docs/design-synapse-module.md:257There is no fallback to
~/.config/synapse/. The only paths consulted areSYNAPSE_CONFIG_PATH(env override),$HOME/.config/cortexkit/synapse.jsonc(user), and./.cortexkit/synapse.jsonc(project).Why the code is right and the docs are wrong
The e2e test independently agrees with the code —
crates/synapse-module/tests/skeleton_e2e.rs:432:So
cortexkit/is the intended path in both implementation and test. The four doc references are the outlier.Failure mode: silent, not loud
load_module_config()ends with:A missing user config is not an error — it falls through to defaults. So a user who places a file exactly where the README tells them gets a module that starts fine, reports healthy, and silently ignores every setting they wrote:
knob,cache_max_bytes,decode_chain_k,grammar_enabled,alias_admin_enabled,worker.load_timeout_ms, and the wholeinline/jobs/probeblocks.cache_max_bytesis the one that bites hardest — a user capping the model cache below the 32 GiB default would silently keep the default and fill the disk.There is no diagnostic that would lead them to the cause: no log line names the path that was searched.
Suggested fix
Docs are the cheap half — correct the four references to
~/.config/cortexkit/synapse.jsonc.Worth considering alongside it, since the silence is what makes this expensive to diagnose: log the resolved config source at startup (path + tier, or "defaults, no config file found"). That turns every future instance of this class into a one-line answer instead of a bisect.
Happy to send a PR for the doc correction if useful; say the word on whether you want the startup log line in the same change or kept separate.