You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
kb-add resolves its writable knowledge base via a precedence chain: explicit --kb <name>, then .kb/ ancestor discovery, then the registry's default_kb. When --kb is omitted and no .kb/ is discoverable, it silently writes to default_kb. This is the same "succeeds-too-easily" failure family as #800: removing destination friction pulls the agent toward under-specifying where a note lands, so a note can end up in the default store when a specific KB was intended.
Footprint: the fix lives in the shared writable-KB resolver, whose other consumers are kb-curate and kb-edit. The new precedence therefore applies uniformly across all three tools — refusing a silent default_kb fall-through and reaching the registry default only via --kb @default are not kb-add-specific. This entails routing the tightened resolver outcomes through the kb-curate and kb-edit CLIs and bringing kb-curate's documentation in line with the new precedence alongside kb-add's.
Out of scope: the separate kb-add bug in which --folder paths are written to the KB root instead of the content/ subdirectory, captured in event 01KV9NG9Z75XPNX0MAZEJG5Z4Q.
Proposed solution
Refuse the bare fall-through to default_kb, and reach the registry default only through an explicit @default sentinel that mirrors #800, while keeping .kb/ discovery as the in-context default.
The resulting precedence is: an explicit --kb @default (the only path to the registry default), then a concrete --kb <name>, then .kb/ discovery, then a refusal when no --kb is given and no .kb/ is found. The shared writable-KB resolver gains distinct failure outcomes for "no destination could be determined" and "@default requested but no default configured," so the skill can route each to its own recovery. The refusal that fires when a destination cannot be determined is self-documenting: it names the registered knowledge bases and points to --kb @default. The @default sentinel value is shared with capture-event as a single cross-tool constant so the two tools cannot drift.
Acceptance criteria
Must have
When --kb is omitted and no .kb/ is discoverable, kb-add refuses to write rather than falling back to default_kb.
The registry default_kb is reachable only via an explicit --kb @default sentinel, which overrides .kb/ discovery like a concrete --kb <name>.
.kb/ discovery remains the default destination when --kb is omitted and a .kb/ is found.
--kb default still resolves a knowledge base literally named "default"; only @default triggers the sentinel.
--kb @default with no configured default_kb fails with a distinct, clearly worded error.
The refusal for an undeterminable destination names the registered knowledge bases and points to --kb @default.
The @default sentinel value is defined once and shared between kb-add and capture-event.
The skill's documentation (the --kb argument, the KB-selection description, and the result-handling guidance) reflects the new precedence and drops the "falls back to default_kb" behavior.
Problem
kb-addresolves its writable knowledge base via a precedence chain: explicit--kb <name>, then.kb/ancestor discovery, then the registry'sdefault_kb. When--kbis omitted and no.kb/is discoverable, it silently writes todefault_kb. This is the same "succeeds-too-easily" failure family as #800: removing destination friction pulls the agent toward under-specifying where a note lands, so a note can end up in the default store when a specific KB was intended.Context
.kb/ancestor discovery is legitimate context resolution (it finds the KB you are physically working in) and must be preserved. This is why the fix cannot be a copy of default_kb override: agents ignore explicit KB destinations and capture to default_kb instead #800.capture-eventby making--storealways required, with--store @defaultas the deliberate sentinel for the registry default.capture-eventhas no discovery tier, so its "always require a name" approach does not transfer directly.kb-curateandkb-edit. The new precedence therefore applies uniformly across all three tools — refusing a silentdefault_kbfall-through and reaching the registry default only via--kb @defaultare notkb-add-specific. This entails routing the tightened resolver outcomes through thekb-curateandkb-editCLIs and bringingkb-curate's documentation in line with the new precedence alongsidekb-add's.kb-addbug in which--folderpaths are written to the KB root instead of thecontent/subdirectory, captured in event01KV9NG9Z75XPNX0MAZEJG5Z4Q.Proposed solution
Refuse the bare fall-through to
default_kb, and reach the registry default only through an explicit@defaultsentinel that mirrors #800, while keeping.kb/discovery as the in-context default.The resulting precedence is: an explicit
--kb @default(the only path to the registry default), then a concrete--kb <name>, then.kb/discovery, then a refusal when no--kbis given and no.kb/is found. The shared writable-KB resolver gains distinct failure outcomes for "no destination could be determined" and "@defaultrequested but no default configured," so the skill can route each to its own recovery. The refusal that fires when a destination cannot be determined is self-documenting: it names the registered knowledge bases and points to--kb @default. The@defaultsentinel value is shared withcapture-eventas a single cross-tool constant so the two tools cannot drift.Acceptance criteria
Must have
--kbis omitted and no.kb/is discoverable,kb-addrefuses to write rather than falling back todefault_kb.default_kbis reachable only via an explicit--kb @defaultsentinel, which overrides.kb/discovery like a concrete--kb <name>..kb/discovery remains the default destination when--kbis omitted and a.kb/is found.--kb defaultstill resolves a knowledge base literally named "default"; only@defaulttriggers the sentinel.--kb @defaultwith no configureddefault_kbfails with a distinct, clearly worded error.--kb @default.@defaultsentinel value is defined once and shared betweenkb-addandcapture-event.--kbargument, the KB-selection description, and the result-handling guidance) reflects the new precedence and drops the "falls back to default_kb" behavior.