chore(openspec): archive skill-catalog-subscription

Change is complete (24/24 tasks) per its declared scope (read-only local
catalog + MCP tools + sync client contract). Management UI and the
upstream Subscription Platform were explicitly out of scope. Deltas
synced into three new main specs: skill-catalog, skill-mcp-tools,
skill-subscription-sync.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-15 00:09:24 +08:00
co-authored by Claude Opus 4.6
parent 56f3f96363
commit e5a12f9b74
10 changed files with 164 additions and 0 deletions
+56
View File
@@ -0,0 +1,56 @@
# skill-catalog Specification
## Purpose
Provides a local, read-only catalog of Skills (knowledge and flow-template) synced from the Subscription Platform, queryable by list, search, and id without per-query network round-trips.
## Requirements
### Requirement: Unified Skill data model
The system SHALL represent every Skill with shared metadata (id, name, description, version, tags, source/subscription id, updated_at) and a `kind` discriminator of either `knowledge` or `flow_template`, so both kinds can be listed and searched through one catalog.
#### Scenario: Knowledge skill has content
- **WHEN** a Skill with `kind = knowledge` is stored
- **THEN** it includes a `content` field (structured instructional text/markdown) in addition to the shared metadata
#### Scenario: Flow-template skill has steps and parameters
- **WHEN** a Skill with `kind = flow_template` is stored
- **THEN** it includes an ordered `steps` list (each referencing a tool name and an args template that may contain `{param}` placeholders) and a `parameters` schema (name, type, required, description) in addition to the shared metadata
### Requirement: Local skill storage
The system SHALL persist the synced Skill Catalog locally so that skills can be listed and fetched without a live round-trip to the Subscription Platform for every query.
#### Scenario: Skill readable after sync
- **WHEN** a skill has been synced from the Subscription Platform into the local catalog
- **THEN** subsequent list/search/get operations return that skill without requiring a new network call to the Subscription Platform
#### Scenario: Local catalog is not independently authored
- **WHEN** a caller attempts to create or edit a skill directly in the local catalog (outside of a sync operation)
- **THEN** the system SHALL reject or ignore the write, since the Subscription Platform is the sole source of truth for skill content
### Requirement: Skill search and query
The system SHALL provide functions to list all currently visible skills, search skills by name/tag/description text, and fetch a single skill by id.
#### Scenario: List returns only visible skills
- **WHEN** the catalog is queried for the list of skills visible to the current caller
- **THEN** it returns only skills whose subscription is currently active for that caller, sorted in a stable order (e.g. by name)
#### Scenario: Search matches on name, tags, or description
- **WHEN** a search query string matches a skill's name, a tag, or its description
- **THEN** that skill is included in the search results
#### Scenario: Get by id returns full content
- **WHEN** a caller fetches a skill by its id
- **THEN** the system returns the full skill record, including `content` for knowledge skills or `steps`/`parameters` for flow-template skills
#### Scenario: Get by id for unknown or invisible skill
- **WHEN** a caller fetches a skill id that does not exist, or exists but is not currently visible to them (subscription inactive)
- **THEN** the system returns a clear "not found" result rather than leaking the skill's existence or content
### Requirement: Flow-template tool reference validation
The system SHALL validate that a flow-template skill's referenced tool names correspond to currently registered device-capability tools, and SHALL mark a flow-template skill as invalid/unavailable rather than allowing it to be fetched successfully if a referenced tool does not exist.
#### Scenario: Valid flow template
- **WHEN** every step in a flow-template skill references a tool name that is currently registered
- **THEN** the skill is fetchable and returned normally
#### Scenario: Flow template references an unknown tool
- **WHEN** a flow-template skill's steps reference a tool name that is not currently registered (e.g. renamed or removed)
- **THEN** fetching that skill returns a clear "skill unavailable/invalid" result instead of a step list containing a dangling tool reference
+44
View File
@@ -0,0 +1,44 @@
# skill-mcp-tools Specification
## Purpose
Exposes Skill Catalog discovery, retrieval, and flow-template parameter resolution as MCP tools on the same surface used for device capabilities, so an LLM client can discover and use Skills through the existing tool-calling mechanism.
## 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, so an LLM client can discover and fetch Skill content using the same tool-calling mechanism it already uses for device actions.
#### Scenario: LLM lists available skills
- **WHEN** an MCP client calls `list_skills`
- **THEN** it receives the set of skills currently visible to it (per subscription visibility), each with id, name, description, kind, and tags, without any Subscription Platform-specific fields or identifiers
#### Scenario: LLM searches for a relevant skill
- **WHEN** an MCP client calls `search_skills` with a query string
- **THEN** it receives matching skills ranked/filtered by relevance to the query, using the same visibility rules as `list_skills`
#### Scenario: LLM fetches a specific skill's content
- **WHEN** an MCP client calls `get_skill` with a skill id
- **THEN** it receives the full skill content appropriate to its kind: `content` text for a `knowledge` skill, or `steps`/`parameters` for a `flow_template` skill
### Requirement: Flow-template parameter resolution helper
The system SHALL provide an MCP-facing helper that, given a flow-template skill id and a set of proposed parameter values, validates the values against the skill's declared `parameters` schema and returns the fully resolved step sequence (placeholders substituted) for the LLM to then execute step-by-step via the existing device-capability tools.
#### Scenario: Valid parameters resolve the template
- **WHEN** the LLM provides values for all required parameters of a flow-template skill
- **THEN** the system returns the ordered steps with all `{param}` placeholders substituted by the provided values
#### Scenario: Missing required parameter
- **WHEN** the LLM omits a required parameter when resolving a flow-template skill
- **THEN** the system returns a clear validation error identifying the missing parameter(s) instead of returning a partially-substituted step list
### Requirement: No server-side flow execution tool
The system SHALL NOT expose an MCP tool that executes a flow-template skill's full step sequence server-side on the LLM's behalf; the LLM SHALL issue each resulting device-capability tool call itself so every step remains subject to the existing Agent Runtime's Observe-Think-Act loop and Executor retry/wait handling.
#### Scenario: No batch-execute tool is available
- **WHEN** the MCP tool list is inspected
- **THEN** it contains skill discovery/retrieval/resolution tools but no tool that both resolves and executes a flow-template skill's steps in a single call
### Requirement: Skill MCP errors are semantic
The system SHALL translate catalog-level errors (skill not found, skill not visible/entitled, invalid/unavailable flow template) into clear, semantic MCP tool error responses, consistent in style with the device-capability tool error handling.
#### Scenario: Requesting a non-visible skill
- **WHEN** `get_skill` is called with a skill id that exists but is not visible to the caller's current subscriptions
- **THEN** the tool returns a semantic "not found" error rather than a raw database or internal exception
@@ -0,0 +1,64 @@
# skill-subscription-sync Specification
## Purpose
Keeps the local Skill Catalog aligned with the external Subscription Platform via periodic pull sync (and optional push-triggered sync), enforcing subscription-based visibility and degrading gracefully on sync failures.
## Requirements
### Requirement: Pull-based sync from the Subscription Platform
The system SHALL periodically fetch, from the external Subscription Platform, the set of skills the current deployment (tenant/device/agent) is entitled to, and SHALL apply creates/updates/removals to the local Skill Catalog to match that entitled set.
#### Scenario: New skill appears after sync
- **WHEN** the Subscription Platform reports a new entitled skill that does not yet exist locally
- **THEN** the next sync cycle creates it in the local Skill Catalog
#### Scenario: Updated skill content is refreshed
- **WHEN** the Subscription Platform reports a newer version of a skill already present locally
- **THEN** the next sync cycle updates the local copy to the newer version
#### Scenario: Revoked entitlement removes local visibility
- **WHEN** the Subscription Platform no longer includes a previously-entitled skill in the current entitled set
- **THEN** the next sync cycle removes or marks that skill as no longer visible in the local Skill Catalog
#### Scenario: Sync interval is configurable
- **WHEN** the deployment is configured with a sync poll interval
- **THEN** the system performs pull sync on approximately that interval without requiring a restart to take effect on the next cycle
### Requirement: Optional push-triggered sync
The system MAY support receiving a change notification (e.g. webhook) from the Subscription Platform, and WHEN it does, SHALL trigger an immediate out-of-cycle pull sync rather than waiting for the next poll interval; correctness of the catalog SHALL NOT depend on push notifications being delivered.
#### Scenario: Push notification triggers immediate sync
- **WHEN** a change notification is received from the Subscription Platform
- **THEN** the system performs a pull sync immediately, independent of the regular poll schedule
#### Scenario: No push configured still stays eventually consistent
- **WHEN** push notifications are not configured or not received
- **THEN** the local Skill Catalog still reflects the Subscription Platform's entitled set within one poll interval via the baseline pull sync
### Requirement: Subscription-based visibility enforcement
The system SHALL enforce, at both sync time and query time, that only skills belonging to the caller's currently active subscription(s) are stored as visible or returned by catalog queries.
#### Scenario: Query-time re-check catches stale entitlement
- **WHEN** a skill's entitlement has been revoked but the local cache has not yet completed its next sync cycle
- **AND** a catalog query for that skill is made using already-known revocation information
- **THEN** the system does not return that skill as visible, even though its record may still exist locally pending cleanup
#### Scenario: Multiple subscriptions compose visibility
- **WHEN** a deployment holds more than one active subscription, each entitling a different set of skills
- **THEN** catalog queries return the union of skills entitled across all of that deployment's active subscriptions
### Requirement: Sync client contract is transport-replaceable
The system SHALL define the Subscription Platform integration (fetch entitled skills, optional change notification receipt) behind a single internal interface, so the concrete HTTP client/auth mechanism can be adjusted to match the real Subscription Platform API without changes to the Skill Catalog or MCP tool layers.
#### Scenario: Sync client swap does not affect catalog/tools
- **WHEN** the concrete Subscription Platform client implementation is replaced (e.g. different auth scheme or request/response shape)
- **THEN** `skill-catalog` and `skill-mcp-tools` behavior and their own specs remain unaffected, as long as the new client still satisfies the sync interface
### Requirement: Sync failure handling
The system SHALL treat a failed sync attempt (network error, auth failure, malformed response) as non-fatal to already-cached skills: the local catalog SHALL continue serving its last-known-good state, and the failure SHALL be recorded/observable rather than silently discarded.
#### Scenario: Sync failure preserves last-known catalog
- **WHEN** a sync attempt fails due to a network or platform error
- **THEN** the local Skill Catalog is left unchanged (not cleared or partially corrupted) and remains queryable using its last successfully synced state
#### Scenario: Sync failure is observable
- **WHEN** a sync attempt fails
- **THEN** the system records the failure (e.g. last-error timestamp/reason) so it can be surfaced to operators rather than failing silently forever