Files
cleveragents-core/features/tool_registry.feature
T
CoreRasurae 798db9088e
CI / lint (pull_request) Successful in 15s
CI / typecheck (pull_request) Successful in 36s
CI / security (pull_request) Successful in 25s
CI / quality (pull_request) Successful in 19s
CI / build (pull_request) Successful in 23s
CI / integration_tests (pull_request) Successful in 6m49s
CI / coverage (pull_request) Successful in 12m1s
CI / unit_tests (pull_request) Successful in 16m28s
CI / docker (pull_request) Successful in 51s
feat(tool): add tool registry persistence
2026-02-17 20:28:20 +00:00

258 lines
13 KiB
Gherkin

@phase1 @domain @repository @tool_registry
Feature: Tool Registry Persistence
As a system operator managing tools and validations
I want the tool registry to reliably persist, retrieve, and filter tools
So that the execution layer can discover and invoke tools at runtime
Background:
Given a clean in-memory database with the tool registry schema
And a tool registry repository backed by the database
And a validation attachment repository backed by the database
# ---------------------------------------------------------------------------
# Registering tools
# ---------------------------------------------------------------------------
@tool_reg_create
Scenario: A new builtin tool is registered and retrievable
Given a valid tool dict named "core/read-file" with source "builtin"
When the tool is registered through the tool registry repository
Then the tool registry repository should not raise an error
And the persisted tool should have the registry name "core/read-file"
@tool_reg_create
Scenario: A custom tool with inline code is registered
Given a valid tool dict named "local/custom-lint" with source "custom"
And the tool dict includes inline code "return {'passed': True}"
When the tool is registered through the tool registry repository
Then the persisted tool should have the registry name "local/custom-lint"
And the persisted tool should have source "custom"
@tool_reg_create
Scenario: An MCP tool is registered with server fields
Given a valid tool dict named "mcp/github-search" with source "mcp"
And the tool dict includes mcp_server "github" and mcp_tool_name "search"
When the tool is registered through the tool registry repository
Then the persisted tool should have the registry name "mcp/github-search"
@tool_reg_create
Scenario: A validation tool is registered with mode
Given a valid tool dict named "core/schema-check" with source "builtin"
And the tool dict has tool_type "validation" and mode "required"
When the tool is registered through the tool registry repository
Then the persisted tool should have tool_type "validation"
@tool_reg_create
Scenario: A tool is registered with resource bindings
Given a valid tool dict named "core/git-commit" with source "builtin"
And the tool dict includes a resource binding for slot "repo"
When the tool is registered through the tool registry repository
Then the persisted tool should have 1 resource binding
@tool_reg_create @error_handling
Scenario: Registering a tool with a duplicate name is rejected
Given a valid tool dict named "core/read-file" with source "builtin"
And the tool has already been registered once in the tool registry
When a second tool with the same registry name "core/read-file" is registered
Then a DuplicateToolError should be raised mentioning "core/read-file"
# ---------------------------------------------------------------------------
# Retrieving tools by name
# ---------------------------------------------------------------------------
@tool_reg_read
Scenario: A tool is retrieved by its namespaced name
Given a valid tool dict named "core/write-file" with source "builtin"
And the tool has been registered through the tool registry repository
When the tool is looked up by registry name "core/write-file"
Then the returned tool should have the registry name "core/write-file"
@tool_reg_read
Scenario: Looking up a non-existent tool name returns nothing
When the tool is looked up by registry name "core/does-not-exist"
Then no tool should be returned from the registry
# ---------------------------------------------------------------------------
# Listing tools with filters
# ---------------------------------------------------------------------------
@tool_reg_list
Scenario: All tools are listed without filters
Given the following tools have been registered:
| name | source | tool_type |
| core/read-file | builtin | tool |
| core/write-file | builtin | tool |
| local/custom-lint | custom | validation |
When all tools are listed from the tool registry
Then 3 tools should be returned from the registry
@tool_reg_list
Scenario: Tools are filtered by namespace
Given the following tools have been registered:
| name | source | tool_type |
| core/read-file | builtin | tool |
| local/custom-lint | custom | validation |
When tools in the "core" namespace are listed from the registry
Then 1 tools should be returned from the registry
And the returned tool names from the registry should include "core/read-file"
@tool_reg_list
Scenario: Tools are filtered by tool_type
Given the following tools have been registered:
| name | source | tool_type |
| core/read-file | builtin | tool |
| core/schema-check | builtin | validation |
When tools of type "validation" are listed from the registry
Then 1 tools should be returned from the registry
@tool_reg_list
Scenario: Tools are filtered by source
Given the following tools have been registered:
| name | source | tool_type |
| core/read-file | builtin | tool |
| local/custom-lint | custom | tool |
When tools with source "custom" are listed from the registry
Then 1 tools should be returned from the registry
# ---------------------------------------------------------------------------
# Updating tools
# ---------------------------------------------------------------------------
@tool_reg_update
Scenario: A tool description is updated
Given a valid tool dict named "core/read-file" with source "builtin"
And the tool has been registered through the tool registry repository
When the tool description is updated to "Updated description"
Then the persisted tool should have description "Updated description"
@tool_reg_update
Scenario: Tool resource bindings are replaced on update
Given a valid tool dict named "core/git-commit" with source "builtin"
And the tool dict includes a resource binding for slot "repo"
And the tool has been registered through the tool registry repository
When the tool is updated with a new resource binding for slot "workspace"
Then the persisted tool should have 1 resource binding
And the persisted tool binding slot should be "workspace"
# ---------------------------------------------------------------------------
# Deleting tools
# ---------------------------------------------------------------------------
@tool_reg_delete
Scenario: A tool is removed from the registry
Given a valid tool dict named "core/read-file" with source "builtin"
And the tool has been registered through the tool registry repository
When the tool "core/read-file" is removed from the registry
Then the removal should return true from the registry
And the tool should no longer exist in the registry
@tool_reg_delete
Scenario: Removing a non-existent tool returns false
When the tool "core/nonexistent" is removed from the registry
Then the removal should return false from the registry
@tool_reg_delete @error_handling
Scenario: Deleting a tool with active attachments is rejected
Given a valid tool dict named "core/schema-check" with source "builtin"
And the tool dict has tool_type "validation" and mode "required"
And the tool has been registered through the tool registry repository
And an unscoped validation attachment for "core/schema-check" on resource "res-001"
When the tool "core/schema-check" is removed from the registry
Then a ToolInUseError should be raised mentioning "core/schema-check"
# ---------------------------------------------------------------------------
# Validation attachment lifecycle
# ---------------------------------------------------------------------------
@tool_reg_attach
Scenario: A validation is attached to a resource
Given a valid tool dict named "core/schema-check" with source "builtin"
And the tool dict has tool_type "validation" and mode "required"
And the tool has been registered through the tool registry repository
When the validation "core/schema-check" is attached to resource "res-001"
Then the attachment should have a valid ULID identifier
And the attachment should reference resource "res-001"
@tool_reg_attach
Scenario: A validation is detached from a resource
Given a valid tool dict named "core/schema-check" with source "builtin"
And the tool dict has tool_type "validation" and mode "required"
And the tool has been registered through the tool registry repository
And an unscoped validation attachment for "core/schema-check" on resource "res-001"
When the validation attachment is detached by its identifier
Then the detachment should return true
@tool_reg_attach
Scenario: Detaching a non-existent attachment returns false
When the validation attachment "01ZZZZZZZZZZZZZZZZZZZZZZZZ" is detached
Then the non-existent detachment should return false
@tool_reg_attach
Scenario: Attachments are listed for a resource
Given a valid tool dict named "core/schema-check" with source "builtin"
And the tool dict has tool_type "validation" and mode "required"
And the tool has been registered through the tool registry repository
And an unscoped validation attachment for "core/schema-check" on resource "res-001"
When all attachments for resource "res-001" are listed
Then 1 attachment should be returned
@tool_reg_attach
Scenario: Attachments are scoped by project name
Given a valid tool dict named "core/schema-check" with source "builtin"
And the tool dict has tool_type "validation" and mode "required"
And the tool has been registered through the tool registry repository
And a project-scoped validation attachment for "core/schema-check" on resource "res-001" in project "my-project"
And a project-scoped validation attachment for "core/schema-check" on resource "res-001" in project "other-project"
When project-filtered attachments for resource "res-001" in project "my-project" are listed
Then 1 attachment should be returned
@tool_reg_attach
Scenario: Attachments are scoped by plan identifier
Given a valid tool dict named "core/schema-check" with source "builtin"
And the tool dict has tool_type "validation" and mode "required"
And the tool has been registered through the tool registry repository
And a plan-scoped validation attachment for "core/schema-check" on resource "res-001" in plan "01PLAN00000000000000000001"
When plan-filtered attachments for resource "res-001" with plan "01PLAN00000000000000000001" are listed
Then 1 attachment should be returned
@tool_reg_attach
Scenario: An attachment is retrieved by its identifier
Given a valid tool dict named "core/schema-check" with source "builtin"
And the tool dict has tool_type "validation" and mode "required"
And the tool has been registered through the tool registry repository
And an unscoped validation attachment for "core/schema-check" on resource "res-001"
When the attachment is retrieved by its stored identifier
Then the retrieved attachment should reference validation "core/schema-check"
# ---------------------------------------------------------------------------
# Service layer integration
# ---------------------------------------------------------------------------
@tool_reg_service
Scenario: The service registers and retrieves a tool
Given a tool registry service backed by the repositories
And a valid tool dict named "svc/echo" with source "builtin"
When the tool is registered through the service
And the tool is retrieved from the service by name "svc/echo"
Then the service-returned tool should have the registry name "svc/echo"
@tool_reg_service
Scenario: The service attaches and detaches a validation
Given a tool registry service backed by the repositories
And a valid tool dict named "svc/val-check" with source "builtin"
And the tool dict has tool_type "validation" and mode "required"
And the tool has been registered through the service
When the service attaches validation "svc/val-check" to resource "svc-res-001"
And the service detaches the validation attachment
Then the service detachment should return true
@tool_reg_service
Scenario: The service lists validations for a resource
Given a tool registry service backed by the repositories
And a valid tool dict named "svc/val-check" with source "builtin"
And the tool dict has tool_type "validation" and mode "required"
And the tool has been registered through the service
And the service has attached validation "svc/val-check" to resource "svc-res-002"
When the service lists validations for resource "svc-res-002"
Then the service should return 1 validation attachment