Symptom
brain.feedback (and any verb resolving a profile) returns a hard NotFound for a profile that verifiably exists in the DB, when the call is served by a kkernel mcp process that started before the profile was created.
Root cause (verified in source)
kkernel mcp processes are long-lived per Claude Code session; a daemon bounce does not restart them.
ensure_loaded loads state.profiles once per namespace behind an is_loaded gate (crates/khive-pack-brain/src/persist.rs:450, with the gate fields around :100/:110). After the first load, the in-memory registry is never refreshed.
create_profile (crates/khive-pack-brain/src/handlers.rs:1440) inserts the new profile into the registry of the creating process only. Every other live process keeps its stale snapshot.
- On a registry miss,
feedback fails hard with NotFound (crates/khive-pack-brain/src/handlers.rs:905-911) instead of re-checking the store.
Net effect: profile creation in session A is invisible to sessions B, C, ... until those processes happen to restart. In a multi-session fleet this silently breaks the feedback loop for newly created or newly bound profiles.
Proposed fix
Reload-on-miss: when profile resolution misses the in-memory registry, re-run the load path (via ensure_loaded / the dispatch gate in crates/khive-pack-brain/src/pack.rs:56-61) before returning NotFound. A miss is rare, so the extra store read is off the hot path; a true miss still returns NotFound after one reload.
Regression shape: create a profile through one runtime handle, call brain.feedback targeting it through a second runtime handle constructed earlier (stale registry), assert it succeeds after reload-on-miss rather than NotFound. Isolated SQLite, never prod khive.db.
Provenance
Split out of the #391 recon (leg A of the 3-leg root cause; legs B/C were the resolve-path namespace bugs fixed in PR #393).
Symptom
brain.feedback(and any verb resolving a profile) returns a hard NotFound for a profile that verifiably exists in the DB, when the call is served by akkernel mcpprocess that started before the profile was created.Root cause (verified in source)
kkernel mcpprocesses are long-lived per Claude Code session; a daemon bounce does not restart them.ensure_loadedloadsstate.profilesonce per namespace behind anis_loadedgate (crates/khive-pack-brain/src/persist.rs:450, with the gate fields around:100/:110). After the first load, the in-memory registry is never refreshed.create_profile(crates/khive-pack-brain/src/handlers.rs:1440) inserts the new profile into the registry of the creating process only. Every other live process keeps its stale snapshot.feedbackfails hard with NotFound (crates/khive-pack-brain/src/handlers.rs:905-911) instead of re-checking the store.Net effect: profile creation in session A is invisible to sessions B, C, ... until those processes happen to restart. In a multi-session fleet this silently breaks the feedback loop for newly created or newly bound profiles.
Proposed fix
Reload-on-miss: when profile resolution misses the in-memory registry, re-run the load path (via
ensure_loaded/ the dispatch gate incrates/khive-pack-brain/src/pack.rs:56-61) before returning NotFound. A miss is rare, so the extra store read is off the hot path; a true miss still returns NotFound after one reload.Regression shape: create a profile through one runtime handle, call
brain.feedbacktargeting it through a second runtime handle constructed earlier (stale registry), assert it succeeds after reload-on-miss rather than NotFound. Isolated SQLite, never prod khive.db.Provenance
Split out of the #391 recon (leg A of the 3-leg root cause; legs B/C were the resolve-path namespace bugs fixed in PR #393).