| name | smoke-test |
| description | Run a smoke test of all gnapsis MCP tools to verify the system works end-to-end. |
Gnapsis Smoke Test
Run through every gnapsis MCP tool to verify the system is functional. This skill
exercises the full feature set: project setup, taxonomy, entity CRUD, references,
search, subgraph queries, document analysis, validation, and multi-source support.
Prerequisites
- Database must be running:
just db-up
- gnapsis must be installed:
cargo install --path .
- MCP server must be connected:
/mcp
Test Procedure
Run each phase sequentially. If any step fails, jump to Phase 10 (Cleanup) to restore
the original config before reporting the failure.
Track entity IDs, reference IDs, and category IDs created during the test for cleanup.
Phase 0: Config Isolation
The smoke test uses a separate project name (gnapsis_smoke_test) so it gets its own
graph and does not interfere with the real project data.
0.1 Backup the real config:
cp .gnapsis.toml .gnapsis.toml.bak
0.2 Overwrite .gnapsis.toml with the smoke test config:
[postgres]
uri = "postgresql://postgres:postgres@localhost:5432/gnapsis_dev"
[embedding]
provider = "fastembed"
model = "BAAI/bge-small-en-v1.5"
dimensions = 384
[project]
name = "smoke_test"
[[project.sources]]
id = "default"
path = "<absolute path to this repo>"
[[project.sources]]
id = "vault"
path = "<absolute path to vault source from the backup>"
Copy the source paths from the backup file. The key differences are:
[postgres] and [embedding] force the local Docker database (overrides global config)
name = "smoke_test" creates graph gnapsis_smoke_test instead of gnapsis_gnapsis
0.3 Reconnect the MCP server so it picks up the new config: /mcp
Phase 1: Database Reset & Init
1.1 Drop the smoke test graph so init starts fresh:
just db-reset
just db-up
Wait for the database to be ready before proceeding.
1.2 Run init_project (force: true) and verify:
- Response includes
db_version and graph_version
applied_db_migrations is non-empty
applied_graph_migrations is non-empty
was_initialized is false (fresh graph)
1.3 Run init_project again (force: false) and verify:
was_initialized is true
applied_db_migrations is empty (no new migrations)
applied_graph_migrations is empty
Phase 2: Project Overview (Empty State)
2.1 Run project_overview with no optional params and verify:
categories contains 17 categories across 5 scopes (Domain, Feature, Namespace, Component, Unit)
stats.domains is 0
stats.features is 0
stats.namespaces is 0
stats.components is 0
stats.units is 0
stats.references is 0
2.2 Run project_overview with include_descriptions: true and verify:
- Response structure is the same
- Descriptions are not truncated
2.3 Run project_overview with output_format: "toon" and verify:
- Response is returned in TOON format
2.4 Note down the category IDs needed for entity creation:
- Find the "core" category at Domain scope -> save as
DOMAIN_CAT_ID
- Find the "functional" category at Feature scope -> save as
FEATURE_CAT_ID
- Find the "struct" category at Component scope -> save as
COMPONENT_CAT_ID
- Find the "function" category at Unit scope -> save as
UNIT_CAT_ID
Phase 3: Taxonomy
3.1 Run create_category with name "smoke-test", scope "Feature", description "Temporary category for smoke testing"
- Verify the category is created with an ID -> save as
SMOKE_CAT_ID
3.2 Run project_overview and verify:
- The "smoke-test" category appears in the Feature scope
- Total category count is now 18
Phase 4: Entity CRUD
4A: Analyze Document (discover symbols)
4A.1 Run analyze_document on src/config.rs with source_id: "default" to discover symbols
- Verify
untracked list contains symbols (e.g., "Config", "ProjectConfig", "Source")
- Save the untracked symbol names for use in entity creation
4B: Create Entity - Success Paths
4B.1 Create a Domain entity:
name: "Smoke Test Domain"
description: "Temporary domain for smoke testing gnapsis"
category_ids: [DOMAIN_CAT_ID]
commands: [Add code reference to src/config.rs, lsp_symbol "Config", source_id "default"]
- Verify: entity created with ID (save as
DOMAIN_ID), has_embedding is true
- Verify:
executed contains the Add command result with reference ID (save as DOMAIN_REF_ID)
- Verify:
failed is null, skipped is empty
4B.2 Create a Feature entity with parent:
name: "Smoke Test Feature"
description: "Temporary feature for smoke testing"
category_ids: [FEATURE_CAT_ID]
parent_ids: [DOMAIN_ID]
commands: [Add code reference to src/config.rs, lsp_symbol "ProjectConfig", source_id "default"]
- Verify: entity created with ID (save as
FEATURE_ID), parent relationship established
- Verify:
executed contains Add result with reference ID (save as FEATURE_REF_ID)
4B.3 Create a Component entity (child of Feature):
name: "Smoke Test Component"
description: "Temporary component for smoke testing"
category_ids: [COMPONENT_CAT_ID]
parent_ids: [FEATURE_ID]
commands: [Add code reference to src/config.rs, lsp_symbol "Source", source_id "default"]
- Verify: entity created with ID (save as
COMPONENT_ID)
4C: Create Entity - Error Paths
4C.1 Attempt to create entity with empty category_ids:
- Expect error about missing classification
4C.2 Attempt to create entity with a non-existent category ID:
- Expect error about invalid category
4C.3 Attempt to create entity with a non-existent parent ID:
- Expect error about invalid parent
4D: Update Entity - Success Paths
4D.1 Update the Feature entity description:
entity_id: FEATURE_ID
description: "Updated smoke test feature description"
- Verify:
embedding_updated is true
- Verify: description changed in response
4D.2 Update entity with Relate command:
entity_id: COMPONENT_ID
commands: [Relate to DOMAIN_ID with note "smoke test relationship"]
- Verify:
executed contains the Relate result
4D.3 Update entity with Unrelate command:
entity_id: COMPONENT_ID
commands: [Unrelate from DOMAIN_ID]
- Verify: relationship removed
4D.4 Update entity name only:
entity_id: COMPONENT_ID
name: "Renamed Smoke Component"
- Verify: name changed,
embedding_updated is false (description unchanged)
4D.5 Update entity categories (replace semantics):
entity_id: COMPONENT_ID
category_ids: [COMPONENT_CAT_ID] (same category, verifies replace works)
- Verify: categories replaced
4E: Get Entity
4E.1 Run get_entity on DOMAIN_ID:
- Verify: returns full entity details with classifications, references, and hierarchy
- Verify: references include the code reference from 4B.1
- Verify: entity has parent/child relationships as expected
4F: Delete Entity - Error Paths
4F.1 Attempt to delete Domain entity (has children):
entity_id: DOMAIN_ID
- Expect error: "has N children and cannot be deleted"
4G: Delete Entity - Success Path
4G.1 Delete the Component entity (leaf node):
entity_id: COMPONENT_ID
- Verify:
deleted is true
Phase 5: Multi-Source References
5.1 Create a Feature entity with a vault text reference:
name: "Smoke Vault Feature"
description: "Feature referencing vault documentation"
category_ids: [FEATURE_CAT_ID]
parent_ids: [DOMAIN_ID]
commands: [Add text reference: source_id "vault", document_path "designs/005-ontology-improvements.md", start_line 1, end_line 30, anchor "# DES-005: Ontology Improvements"]
- Verify: entity created (save as
VAULT_FEATURE_ID)
- Verify:
executed contains Add with reference (save as VAULT_REF_ID)
5.2 Run get_entity on VAULT_FEATURE_ID:
- Verify: reference details include
source_id: "vault"
- Verify: reference type is "text"
- Verify: document_path, start_line, end_line, anchor are correct
5.3 Create another entity with a code reference using default source_id:
commands: [Add code reference without specifying source_id, document_path "src/config.rs", lsp_symbol "default_source_id"]
- Verify: reference created with source_id "default" (the default)
Phase 6: Search & Query
6A: Unified Search
6A.1 Search with target "entities":
query: "smoke test domain"
target: "entities"
- Verify: results contain entity matches
- Verify:
references array is empty (target is entities-only)
6A.2 Search with target "references":
query: "configuration"
target: "references"
- Verify: results contain reference matches with document paths
- Verify:
entities array is empty (target is references-only)
6A.3 Search with target "all" (default):
query: "smoke testing"
- Verify: results may contain both entities and references
6A.4 Search with scope filter:
query: "smoke"
scope: "Domain"
- Verify: only Domain-scope entities returned
6A.5 Search with min_score filter:
query: "smoke"
min_score: 0.9
- Verify: only high-similarity results returned (may be empty)
6A.6 Search with limit:
query: "smoke"
limit: 1
- Verify: at most 1 result returned
6A.7 Search with output_format "toon":
query: "smoke"
output_format: "toon"
- Verify: response is in TOON format
6B: Semantic Subgraph Query
6B.1 Query with entity_id:
entity_id: DOMAIN_ID
- Verify:
nodes array contains the domain entity and connected entities
- Verify:
edges array shows BELONGS_TO and HAS_REFERENCE relationships
- Verify:
stats includes estimated_tokens and nodes_pruned
6B.2 Query with semantic_query only:
semantic_query: "smoke test configuration"
- Verify: returns a subgraph relevant to the query
6B.3 Query with both entity_id and semantic_query:
entity_id: DOMAIN_ID
semantic_query: "configuration management"
- Verify: subgraph extracted with semantic relevance scoring
6B.4 Query with neither entity_id nor semantic_query:
- Expect error: "Either entity_id or semantic_query must be provided"
6B.5 Query with max_tokens limit:
entity_id: DOMAIN_ID
max_tokens: 500
- Verify:
stats.estimated_tokens is within budget
6B.6 Query with max_nodes limit:
entity_id: DOMAIN_ID
max_nodes: 2
- Verify: at most 2 nodes returned
6B.7 Query with scoring_strategy "branch_penalty":
entity_id: DOMAIN_ID
scoring_strategy: "branch_penalty"
- Verify: response is valid (may differ from global strategy)
6B.8 Query with relationship_types filter:
entity_id: DOMAIN_ID
relationship_types: ["BELONGS_TO"]
- Verify: edges only contain BELONGS_TO relationships
6B.9 Query with output_format "toon":
entity_id: DOMAIN_ID
output_format: "toon"
- Verify: response is in TOON format
6C: Find Entities
6C.1 Find by scope:
scope: "Domain"
- Verify: the smoke test domain entity appears in results
6C.2 Find by category:
category: "core"
- Verify: domain entity appears
6C.3 Find by parent_id:
parent_id: DOMAIN_ID
- Verify: the Feature and Vault Feature entities appear
6C.4 Find with limit:
scope: "Feature"
limit: 1
- Verify: at most 1 result
6C.5 Find with no filters:
- No scope, category, or parent_id
- Verify: returns all entities (up to default limit of 50)
6D: Get Document Entities
6D.1 Get entities for "src/config.rs" with source_id "default":
- Verify: entities with references to config.rs are listed
- Verify: reference details are included
6D.2 Get entities for a vault document:
document_path: "designs/005-ontology-improvements.md"
source_id: "vault"
- Verify: vault feature entity appears
Phase 7: Document Analysis
7.1 Run analyze_document on src/config.rs with source_id "default", all options enabled:
include_tracked: true
include_untracked: true
include_diffs: true
- Verify:
tracked references appear (from Phase 4)
- Verify:
untracked symbols are listed
- Verify:
source_id is "default" in response
- Verify:
document_type is "code"
- Verify:
summary has correct counts
7.2 Run analyze_document with only tracked references:
include_tracked: true
include_untracked: false
include_diffs: false
- Verify:
untracked is empty, diff_hunks is empty
- Verify:
tracked is populated
7.3 Run analyze_document with only untracked symbols:
include_tracked: false
include_untracked: true
include_diffs: false
- Verify:
tracked is empty
- Verify:
untracked is populated
7.4 Run analyze_document with explicit LSP symbols:
- Provide
lsp_symbols array with at least one symbol (e.g., name "Config", kind 23, start_line and end_line from Phase 4A)
- Verify: untracked detection uses provided symbols
7.5 Run analyze_document with output_format "toon":
- Verify: response is in TOON format
7.6 Run analyze_document on a vault document:
document_path: "designs/005-ontology-improvements.md"
source_id: "vault"
- Verify: responds without error
- Verify:
document_type is "text"
- Verify: tracked references from Phase 5 appear (if any)
Phase 8: Reference Management
8A: Get Changed Files
8A.1 Run get_changed_files with no params:
- Verify: returns a list of changed files with change types
- Verify: response includes file paths
8A.2 Run get_changed_files with from_sha and to_sha (use HEAD~1 and HEAD):
- First get HEAD SHA via git
- Verify: returns files changed in the last commit
8B: Alter References - Update
8B.1 Run alter_references with an Update command on FEATURE_REF_ID:
- Update
start_line to a new value (e.g., 10)
- Update
end_line to a new value (e.g., 50)
- Verify: update succeeds
- Verify: response shows the updated reference
8B.2 Run alter_references with Update on text reference VAULT_REF_ID:
- Update
anchor to "# Updated Anchor"
- Verify: anchor updated
8C: Alter References - Delete
8C.1 Attempt to delete a reference that is attached to an entity:
- Run
alter_references with Delete on FEATURE_REF_ID
- Expect error: reference is attached to an entity
8C.2 To test delete success: first create a standalone reference, detach it, then delete:
- Create a temporary entity with a reference
- Use
update_entity with Unattach command to detach the reference
- Run
alter_references with Delete on the detached reference
- Verify: deletion succeeds
- Clean up the temporary entity
8D: LSP Refresh
8D.1 Run lsp_refresh on src/config.rs with source_id "default":
- Provide LSP symbols from analyze_document (Phase 7.1) untracked list
- Include at least the symbols that have existing references (e.g., "Config", "ProjectConfig")
- Verify:
updated_count shows how many references were refreshed
- Verify:
updated array shows old and new line numbers for changed refs
- Verify:
unmatched_count shows symbols with no matching reference
Phase 9: Graph Validation
9.1 Run validate_graph with all checks enabled:
check_orphans: true
check_cycles: true
check_scope_violations: true
check_unclassified: true
check_no_references: true
- Verify:
valid is true or only has expected issues from test data
- Verify:
issue_count matches the sum of all issue arrays
9.2 Run validate_graph with only orphan check:
check_orphans: true
check_cycles: false
check_scope_violations: false
check_unclassified: false
check_no_references: false
- Verify: only
orphans array may have entries, all others are empty
9.3 Run validate_graph with only cycle check:
check_cycles: true, all others false
- Verify:
cycles is empty (no cycles in test data)
9.4 Run validate_graph with only scope violations check:
check_scope_violations: true, all others false
- Verify: no scope violations in test data
Phase 10: Cleanup
This phase MUST run even if a previous phase failed — it restores the original config.
10.1 Delete entities in reverse dependency order:
- Delete
VAULT_FEATURE_ID (and any temp entities from Phase 8C)
- Delete
FEATURE_ID
- Delete
DOMAIN_ID
- Verify: each deletion succeeds
10.2 Run project_overview and verify:
stats.domains is 0
stats.features is 0
stats.components is 0
stats.references is 0
10.3 Drop the smoke test graph to leave no residue:
10.4 Restore the original config:
mv .gnapsis.toml.bak .gnapsis.toml
10.5 Reconnect the MCP server to restore the real project config: /mcp
10.6 Report: "Smoke test PASSED - all 10 phases completed successfully"
Failure Reporting
If any phase fails:
- Always run Phase 10.4 and 10.5 first to restore the original config
- Then report:
- Phase number and subtest that failed (e.g., "Phase 4, Test 4C.1")
- Tool name and parameters used
- Error message received
- "Smoke test FAILED at Phase N, Test N.X"
Notes
- The vault source path is configured in
.gnapsis.toml under [[project.sources]]
- All sources share the same graph:
gnapsis_<project_name>
- References store
source_id to track which source they belong to
- If vault source is not configured, skip Phase 5 and vault-related steps in Phases 6-7
- Entity IDs, reference IDs, and category IDs should be tracked throughout the test for assertions and cleanup
- Error path tests (e.g., 4C, 6B.4, 8C.1) expect specific errors - verify the error message matches