Files
cleveragents-core/features/skill_registry_persistence.feature
freemo 7235d46ade
CI / quality (pull_request) Successful in 19s
CI / lint (pull_request) Successful in 21s
CI / benchmark-publish (pull_request) Has been skipped
CI / security (pull_request) Successful in 50s
CI / typecheck (pull_request) Successful in 58s
CI / build (pull_request) Successful in 29s
CI / integration_tests (pull_request) Successful in 4m16s
CI / unit_tests (pull_request) Successful in 12m18s
CI / docker (pull_request) Successful in 1m30s
CI / benchmark-regression (pull_request) Successful in 25m15s
CI / coverage (pull_request) Successful in 1h21m51s
CI / build (push) Successful in 15s
CI / quality (push) Successful in 17s
CI / lint (push) Successful in 21s
CI / security (push) Successful in 28s
CI / typecheck (push) Successful in 31s
CI / benchmark-regression (push) Has been skipped
CI / integration_tests (push) Successful in 2m47s
CI / unit_tests (push) Successful in 11m0s
CI / docker (push) Successful in 40s
CI / benchmark-publish (push) Successful in 12m22s
CI / coverage (push) Successful in 44m42s
feat(skill): persist flattened tool sets
Add Alembic migration m4_002_skill_flattened_tools to extend the skills
table with five new columns: flattened_tools_json, includes_json,
capability_summary_json, yaml_text, and flattening_hash (SHA-256).  A
defence-in-depth uniqueness constraint (uq_skills_name) is also added.

Update SkillModel with the new column definitions and extend
SkillRepository with update_flattened_tools(), get_flattened_tools(),
needs_refresh(), recompute_flattening_hash(), and
invalidate_cached_summaries() methods.  The existing update() method
now nulls all cached fields on mutation (hash-based invalidation).

All new repository methods follow the session-factory pattern with
@database_retry and flush-but-don-t-commit semantics.  Structured
logging via structlog records cache updates and invalidations.

Database schema docs updated with the new skills table columns and a
persistence-field-to-domain-model mapping table.

Tests:
- 6 Behave scenarios covering create, invalidation, hash staleness,
  refresh recomputation, uniqueness constraint, and namespace filtering
- 2 Robot Framework smoke tests (round-trip and invalidation)
- 3 ASV benchmarks (persist, refresh check, namespace list)

ISSUES CLOSED: #166
2026-02-27 20:09:26 +00:00

85 lines
4.2 KiB
Gherkin

@phase1 @domain @repository @skill_registry @m4_persist
Feature: Skill Registry Flattened Tool Persistence
As a system operator managing skills
I want flattened tool sets persisted alongside skill definitions
So that the execution layer can skip redundant resolution and detect stale caches
Background:
Given a clean in-memory database with the skill persistence schema
And a skill persistence repository
# ---------------------------------------------------------------------------
# Persisting flattened tools
# ---------------------------------------------------------------------------
@skill_persist_create
Scenario: Skill creation persists flattened tool set
Given a skill "local/code-tools" with description "Code helper tools"
When the skill is created via the persistence repository
And the flattened tools are updated with tools json '["tool-a","tool-b"]' and hash "abc123"
Then the stored flattened tools json should be '["tool-a","tool-b"]'
And the stored flattening hash should be "abc123"
# ---------------------------------------------------------------------------
# Update invalidation
# ---------------------------------------------------------------------------
@skill_persist_invalidate
Scenario: Skill update invalidates cached capability summary
Given a skill "local/editor" with description "Editor tools"
And the skill is created via the persistence repository
And the flattened tools are updated with tools json '["edit"]' and hash "hash1"
When the skill "local/editor" is updated with description "Updated editor"
Then the stored flattened tools json for "local/editor" should be null
And the stored capability summary json for "local/editor" should be null
And the stored flattening hash for "local/editor" should be null
# ---------------------------------------------------------------------------
# Hash-based staleness detection
# ---------------------------------------------------------------------------
@skill_persist_hash
Scenario: Flattening hash detects stale cached data
Given a skill "local/lint" with description "Lint tools"
And the skill is created via the persistence repository
And the flattened tools are updated with tools json '["lint"]' and hash "hash_v1"
Then the skill "local/lint" should not need refresh for hash "hash_v1"
And the skill "local/lint" should need refresh for hash "hash_v2"
# ---------------------------------------------------------------------------
# Refresh recomputation
# ---------------------------------------------------------------------------
@skill_persist_refresh
Scenario: Skill refresh recomputes flattened tools
Given a skill "local/refresh-me" with description "Refreshable"
And the skill is created via the persistence repository
When the flattening hash for "local/refresh-me" is recomputed from yaml "name: local/refresh-me"
Then the stored flattening hash for "local/refresh-me" should not be null
And the skill "local/refresh-me" should not need refresh for the recomputed hash
# ---------------------------------------------------------------------------
# Uniqueness constraint
# ---------------------------------------------------------------------------
@skill_persist_unique
Scenario: Uniqueness constraint prevents duplicate skill names
Given a skill "local/unique-test" with description "First"
And the skill is created via the persistence repository
When a second skill "local/unique-test" with description "Second" is created
Then the second creation should raise a duplicate error
# ---------------------------------------------------------------------------
# Namespace index
# ---------------------------------------------------------------------------
@skill_persist_namespace
Scenario: Namespace index supports filtered listing
Given a skill "local/tool-a" with description "Tool A"
And the skill is created via the persistence repository
And a skill "devops/deploy" with description "Deploy"
And the skill is created via the persistence repository
When skills are listed with namespace "local"
Then the listed skills should contain "local/tool-a"
And the listed skills should not contain "devops/deploy"