Skip to content

fix: don't let active-skill continuity mask an out-of-scope tool request - #186

Merged
imaustink merged 1 commit into
mainfrom
fix/skill-fit-capability-mismatch
Aug 1, 2026
Merged

fix: don't let active-skill continuity mask an out-of-scope tool request#186
imaustink merged 1 commit into
mainfrom
fix/skill-fit-capability-mismatch

Conversation

@imaustink

Copy link
Copy Markdown
Owner

Summary

  • checkActiveSkill's fit-checker only judges topic continuity ("is this still the same task?"), not whether the request names a capability outside the active skill's own toolIds. In production, a user mid-debug on a failed web-fetch call asked "use your kubectl access to debug it" — the fit-check said "still fits" (same debugging task), so the turn stayed locked in skill-web-search (which explicitly forbids any other tool) instead of ever reaching selectFallbackTool's full-catalog search. The model then flatly denied having kubectl access, even though a kubectl-readonly Tool CR exists and is enabled in production.
  • Adds hasOutOfScopeToolMatch in graph.ts, reusing the existing toolFitChecker (already used by the fallback-tool path) against vector-store candidates NOT already in the active skill's toolIds. A confirmed out-of-scope match now forces fallthrough to full retrieval + selection instead of trusting the topic-continuity fit-check alone.

Test plan

  • npx vitest run src/agent/graph.test.ts — 137/137 passing, including two new cases: falls through on an out-of-scope tool match (kubectl example), and still reuses the active skill when candidates are already in-scope.
  • Full apps/agent-orchestrator suite run; the 3 pre-existing NATS-channel test failures were confirmed present on main before this change (unrelated flake/build issue) via git stash.
  • tsc --noEmit pre-existing errors in nats-agent-channel.ts/nats-job-receiver.ts confirmed present on main (stale @controller-agent/messaging build), unrelated to this change.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JGyJx3E5PHapvYvwK7YyFd

checkActiveSkill's fit-checker only judges topic continuity ("is this
still the same task?"), so a mid-task request naming a different
capability (e.g. "use your kubectl access to debug this" while still
inside skill-web-search) passed the fit-check and got silently absorbed
into the active skill -- producing a flat "I can't do that" from the
model instead of ever reaching selectFallbackTool's full-catalog search.

Add hasOutOfScopeToolMatch, reusing the existing toolFitChecker against
candidates outside the active skill's toolIds; a hit now forces
fallthrough to full retrieval instead of trusting the fit-check alone.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JGyJx3E5PHapvYvwK7YyFd
@imaustink
imaustink merged commit f64daf9 into main Aug 1, 2026
4 checks passed
@imaustink
imaustink deleted the fix/skill-fit-capability-mismatch branch August 1, 2026 17:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant