Opens the skill-management-console openspec change (cloud/local skill split with local override) with proposal, design (D1-D11), four delta specs, and tasks. Implements the agent-side persistent local skill store (storage/local_skills.py): authored local skills + cloud-skill overrides in a physically separate SQLite file, with fork-on-revocation. 10 tests pass. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
47 lines
3.9 KiB
Markdown
47 lines
3.9 KiB
Markdown
## MODIFIED Requirements
|
|
|
|
### Requirement: MCP tools for skill discovery and retrieval
|
|
The system SHALL expose `list_skills`, `search_skills`, and `get_skill` as MCP tools on the same MCP server surface used for device capabilities. The tools SHALL present a unified catalog merged from cloud-synced skills and local skills (delegating to the `local-skill-management` read-merge surface), and SHALL return each skill with an `origin` of `"cloud"` or `"local"` and a `locally_overridden` flag when a local override shadows a cloud skill. The responses SHALL NOT expose any entitlement, subscription, or cloud-management-internal fields to the LLM.
|
|
|
|
#### Scenario: LLM lists available skills across both origins
|
|
- **WHEN** an MCP client calls `list_skills`
|
|
- **THEN** it receives the merged set of cloud-synced and local skills visible to it, each with id, name, description, kind, tags, `origin`, and `locally_overridden`
|
|
|
|
#### Scenario: LLM searches across both origins
|
|
- **WHEN** an MCP client calls `search_skills` with a query string
|
|
- **THEN** it receives matching skills from both origins ranked by relevance, each tagged with `origin`
|
|
|
|
#### Scenario: LLM fetches a skill, observing any active override
|
|
- **WHEN** an MCP client calls `get_skill` with a skill id that has an active local override
|
|
- **THEN** it receives the override's content, tagged `origin = "cloud"` and `locally_overridden = true`
|
|
|
|
### Requirement: Skill MCP errors are semantic
|
|
The system SHALL translate skill-level errors (skill not found, skill not visible/entitled, invalid/unavailable flow template, and authoring errors such as attempting to delete a cloud skill with no override) into clear, semantic MCP tool error responses, consistent in style with the device-capability tool error handling. A request for a cloud skill that is unknown or not visible to the caller SHALL produce an indistinguishable not-found error (no existence leak).
|
|
|
|
#### Scenario: Requesting a non-visible cloud skill
|
|
- **WHEN** `get_skill` is called with a cloud skill id that exists but is not visible to the caller's host and has no override
|
|
- **THEN** the tool returns a semantic "not found" error rather than a raw database or internal exception
|
|
|
|
#### Scenario: Deleting a cloud skill that has no override
|
|
- **WHEN** `delete_skill` is called with a cloud skill id that has no local override
|
|
- **THEN** the tool returns a semantic error indicating there is no local override to remove, without revoking any cloud entitlement
|
|
|
|
## ADDED Requirements
|
|
|
|
### Requirement: Authoring MCP tools dispatch by origin
|
|
The system SHALL expose `create_skill`, `update_skill`, and `delete_skill` as MCP tools on the agent's MCP server, always registered (no enable/disable gate). Their behaviour SHALL dispatch by the target skill's origin: `create_skill` creates a new local skill; `update_skill` edits a local skill or creates/updates a local override for a cloud skill; `delete_skill` deletes a local skill or removes a local override for a cloud skill. None of these tools SHALL ever write to the synced store or mutate a cloud skill directly; override semantics are governed by the `local-skill-management` capability.
|
|
|
|
#### Scenario: Create a new local skill
|
|
- **WHEN** the LLM calls `create_skill` with content for a new skill
|
|
- **THEN** a new local skill is created with `origin = "local"` and is thereafter discoverable via the read tools
|
|
|
|
#### Scenario: Update dispatches by origin
|
|
- **WHEN** the LLM calls `update_skill` with a local skill id
|
|
- **THEN** the local skill is edited; and **WHEN** called with a cloud skill id
|
|
- **THEN** a local override for that cloud id is created or updated (the cloud/synced store is untouched)
|
|
|
|
#### Scenario: Delete dispatches by origin
|
|
- **WHEN** the LLM calls `delete_skill` with a local skill id
|
|
- **THEN** the local skill is deleted; and **WHEN** called with a cloud skill id that has an override
|
|
- **THEN** the override is removed and the cloud skill resurfaces on the next read
|