Skip to content

default_kb override: agents ignore explicit KB destinations and capture to default_kb instead #800

Description

@williamthorsen

Problem

Since default_kb was added to the kb registry, agents repeatedly ignore explicit in-session instructions to capture an event into a specific named KB. capture-event's --store flag is optional, so when the agent omits it the helper silently resolves to default_kb and the record lands in the wrong store. The user then has to move the misfiled records by hand.

The cause is structural, not a logic error: The resolver behaves exactly as written. A setting that removes required-argument friction pulls the agent toward under-specifying the argument, and the silent success is the trap: The helper returns ok: true with the resolved store, the capture appears to work, and nothing prompts the agent to reconsider whether that store matches the request.

Context

Observed five times across four sessions in recent days, with no change in the pattern between occurrences. The strongest evidence is the fifth occurrence: The agent was composing an event body that explicitly argued "when the user names a KB, pass --store <name>", then invoked the helper without --store and landed the record in the wrong store. The rule was in working memory and lost to the silent fallback anyway, so prompting alone is insufficient.

Two factors reinforce the pull:

  • capture-event's SKILL.md models the failure. Its invocation example shows [--store <name>] as a bracketed optional and the docs state the flag "defaults to the registry's default_kb", so an agent copying the example correctly drops the bracketed flag.
  • default_kb is recent, deliberate work (the kb set-default command and the registry default). The fix keeps it and changes only how capture-event reaches it.

Related captured events: 01KV9Q4AXJ2ZZRG4TD6E9EWVEN and 01KV9Q8X1F2HFADB7VDK15XYAE record this bug, including a self-demonstration where the agent misrouted the very event describing it. 01KV9NG9Z75XPNX0MAZEJG5Z4Q records a separate same-family kb-add bug tracked elsewhere.

Proposed solution

Convert the silent fallback into a hard, self-documenting refusal, so a missing destination interrupts the agent instead of resolving for it.

  • Make capture-event's --store required. Omitting it fails with an error that lists the registered stores, marks which is the registry default, and points to the @default sentinel.
  • Add --store @default as a reserved sentinel that resolves to the registry's default_kb, preserving deliberate one-token access to the environment-level default without recalling its name. A readonly default is refused as it is today.
  • Interpret the sentinel in the capture resolver, alongside the existing default-resolution and readonly logic. --store <name> resolves by registry name as before, and a KB literally named default stays reachable as --store default, since only @default is reserved.
  • Rework the SKILL.md so it stops modeling the failure: --store is required in the arguments table, the invocation example is uniformly --store <name|@default> with no optional bracket, and the store-selection guidance reframes default_kb as rarely the right in-session target, chosen deliberately via @default.

Scope is capture-event only. kb-add's analogous default_kb fallback is a separate follow-up, because its .kb/ ancestor discovery is legitimate context resolution and needs its own design.

Acceptance criteria

Must have

  • capture-event refuses to capture when --store is omitted, failing with an error that names the registered stores, marks the registry default, and points to --store @default.
  • --store @default captures into the registry's default_kb, and a readonly default is refused.
  • --store <name> captures into the named store, and a store named default remains reachable via --store default.
  • capture-event's SKILL.md no longer models omission: --store is documented as required, the invocation example shows no optional bracket, and the store-selection guidance reframes default_kb as a deliberate @default choice.
  • New and modified behavior in this change is covered by tests.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions