feat(skills): Phase 3a skill activation runtime - #1498
Conversation
Design review (Phase 3a skill activation)Overall the architecture is right and matches design §6. The "activation never widens authority" invariant is real and tested (
Changes to make before ready-for-review (ranked)1. [blocking] Wake re-load persists unconditionally — self-inflicted write + bus event on every wake. 2. [blocking] 3. [should-fix] No runtime-level test coverage for the behavior this PR is actually about. 4. [minor] "Relevance re-check" oversells what the code does. Notes (no action required):
|
Skip no-op wake writes of activeSkills; drop LLM task_id from skill-activate; tighten relevance filtering; add runtime coverage. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Joseph Fung <josephfung@users.noreply.github.com>
|
Addressed in ee0c076:
Also noted the |
Unified toolSearch returns kind:skill bundles; skill-activate loads member tools + SKILL.md instructions mid-turn; Tier-1 active set persists in tasks.progress.activeSkills and reloads on wake with relevance re-check. Activation never widens allowed_callers / action_risk. Closes #1495 Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Joseph Fung <josephfung@users.noreply.github.com>
Skip no-op wake writes of activeSkills; drop LLM task_id from skill-activate; tighten relevance filtering; add runtime coverage. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Joseph Fung <josephfung@users.noreply.github.com>
ee0c076 to
3f40a52
Compare
|
@coderabbitai review |
✅ Action performedReview finished.
|
📝 WalkthroughWalkthroughThis PR adds unified tool and skill discovery with typed Possibly related issues
Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 Checkov (3.3.8)config/registry-defaults.yamlTraceback (most recent call last): skills/skill-activate/tool.jsonTraceback (most recent call last): skills/tool-registry/tool.jsonTraceback (most recent call last): Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
src/skills/skill-activation.ts (1)
89-90: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTwo copies of "may this agent call this tool" logic — pick one and be done with it.
unifiedToolSearchreimplements the exactallowed_callerscheck thatagentMayCallToolalready performs a few lines below. Two implementations of the same rule is exactly the sort of thing that quietly diverges after the next edit, and nobody notices until production. Riveting.♻️ Proposed dedup
- const allowed = tool.manifest.allowed_callers; - if (allowed && allowed.length > 0 && !allowed.includes(agentId)) continue; + if (!agentMayCallTool(toolRegistry, name, agentId)) continue;Also applies to: 112-122
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/skills/skill-activation.ts` around lines 89 - 90, Remove the inline allowed_callers filtering from unifiedToolSearch and reuse agentMayCallTool as the single authorization check for each candidate tool. Ensure both the primary and alternate search paths apply agentMayCallTool consistently, preserving the existing behavior for permitted and denied agents.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@skills/skill-activate/tool.json`:
- Line 4: Update the version field in the new skill manifest from 0.1.1 to
0.1.0, preserving the rest of the manifest unchanged.
In `@src/db/active-skills-progress.ts`:
- Around line 67-74: Update activeSkillNameSetsEqual to perform true set
equality without relying on callers to deduplicate: compare the unique values
represented by both arrays, ensuring duplicate entries cannot make different
sets appear equal. Preserve the boolean result for identical sets and the
existing function signature.
In `@src/skills/execution.test.ts`:
- Line 2182: Remove the duplicate const searchResults declaration within the
same it() test block in execution.test.ts, leaving one declaration with its
existing type and behavior unchanged.
In `@src/skills/types.ts`:
- Around line 228-236: Remove the obsolete duplicate doc comment above the
toolSearch field, leaving a single accurate documentation block for toolSearch
and preserving the field definition and its type unchanged.
---
Nitpick comments:
In `@src/skills/skill-activation.ts`:
- Around line 89-90: Remove the inline allowed_callers filtering from
unifiedToolSearch and reuse agentMayCallTool as the single authorization check
for each candidate tool. Ensure both the primary and alternate search paths
apply agentMayCallTool consistently, preserving the existing behavior for
permitted and denied agents.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: ca464a21-b9d3-4317-9935-12c354bd53ca
📒 Files selected for processing (21)
CHANGELOG.mdconfig/registry-defaults.yamldocs/specs/03-tools-and-execution.mddocs/specs/19-tasks-and-backlog.mdskills/skill-activate/handler.test.tsskills/skill-activate/handler.tsskills/skill-activate/tool.jsonskills/tool-registry/handler.tsskills/tool-registry/tool.jsonsrc/agents/runtime.tssrc/db/active-skills-progress.tssrc/db/task-repo.tssrc/index.tssrc/skills/execution.test.tssrc/skills/execution.tssrc/skills/loader.tssrc/skills/skill-activation.tssrc/skills/types.tstests/unit/agents/runtime.test.tstests/unit/skills/active-skills-progress.test.tstests/unit/skills/skill-activation.test.ts
- skill-activate version back to 0.1.0 (new tool; one bump per release, not per commit) - activeSkillNameSetsEqual: compare unique membership, not array length, so duplicates can't mask a real set difference (e.g. ['x','x'] vs ['x','y']) - drop stale duplicate toolSearch doc comment in ToolContext - unifiedToolSearch reuses agentMayCallTool as the single allowed_callers check CodeRabbit's duplicate-const finding in execution.test.ts is a false positive: the two searchResults declarations live in separate it() scopes. Signed-off-by: Joseph Fung <joseph@josephfung.ca>
Skip no-op wake writes of activeSkills; drop LLM task_id from skill-activate; tighten relevance filtering; add runtime coverage. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Joseph Fung <josephfung@users.noreply.github.com>
Summary
Closes #1495 (Phase 3a of epic #1436). Builds on Phase 2 (#1489) by shipping the deferred activation runtime from design §6.
toolSearchreturnskind:"skill"for non-synthetic bundles and promotes member-atom matches to their owning skill (sotask-createsurfaces astasks, not a bare tool without instructions).skill-activatetool — discovery-enabled agents get it alongsidetool-registry; activation expands member tools into the working toolkit and injects the SKILL.md body mid-turn.progress.activeSkills(wake re-load with relevance filter + cap 5; no-op writes skipped) → Tier 2 discovery whenallow_discovery.allowed_callers/action_risk; disallowed members land inskippedTools. Persistence uses bound task only (no LLMtask_id).CHANGELOG[Unreleased].Design review follow-ups (ee0c076)
activeSkillswrite when name set unchanged; preserveactivatedAttask_idfromskill-activateTest plan
pnpm run typecheck(+ console typecheck)pnpm run lintpnpm testwithDATABASE_URLon initial implementation (5579 passed)