smoke-test
Run a smoke test of all gnapsis MCP tools to verify the system works end-to-end.
SKILL.md
| Name | smoke-test |
| Description | Run a smoke test of all gnapsis MCP tools to verify the system works end-to-end. |
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:
# Force local database — overrides global ~/.config/gnapsis/config.toml
[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 graphgnapsis_smoke_testinstead ofgnapsis_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_versionandgraph_version applied_db_migrationsis non-emptyapplied_graph_migrationsis non-emptywas_initializedis false (fresh graph)
1.3 Run init_project again (force: false) and verify:
was_initializedis trueapplied_db_migrationsis empty (no new migrations)applied_graph_migrationsis empty
Phase 2: Project Overview (Empty State)
2.1 Run project_overview with no optional params and verify:
categoriescontains 17 categories across 5 scopes (Domain, Feature, Namespace, Component, Unit)stats.domainsis 0stats.featuresis 0stats.namespacesis 0stats.componentsis 0stats.unitsis 0stats.referencesis 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
untrackedlist 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 tosrc/config.rs, lsp_symbol "Config", source_id "default"]- Verify: entity created with ID (save as
DOMAIN_ID),has_embeddingis true - Verify:
executedcontains the Add command result with reference ID (save asDOMAIN_REF_ID) - Verify:
failedis null,skippedis 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 tosrc/config.rs, lsp_symbol "ProjectConfig", source_id "default"]- Verify: entity created with ID (save as
FEATURE_ID), parent relationship established - Verify:
executedcontains Add result with reference ID (save asFEATURE_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 tosrc/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_IDdescription: "Updated smoke test feature description"- Verify:
embedding_updatedis true - Verify: description changed in response
4D.2 Update entity with Relate command:
entity_id:COMPONENT_IDcommands: [Relate toDOMAIN_IDwith note "smoke test relationship"]- Verify:
executedcontains the Relate result
4D.3 Update entity with Unrelate command:
entity_id:COMPONENT_IDcommands: [Unrelate fromDOMAIN_ID]- Verify: relationship removed
4D.4 Update entity name only:
entity_id:COMPONENT_IDname: "Renamed Smoke Component"- Verify: name changed,
embedding_updatedis false (description unchanged)
4D.5 Update entity categories (replace semantics):
entity_id:COMPONENT_IDcategory_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:
deletedis 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:
executedcontains Add with reference (save asVAULT_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:
referencesarray 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:
entitiesarray 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:
nodesarray contains the domain entity and connected entities - Verify:
edgesarray shows BELONGS_TO and HAS_REFERENCE relationships - Verify:
statsincludesestimated_tokensandnodes_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_IDsemantic_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_IDmax_tokens: 500- Verify:
stats.estimated_tokensis within budget
6B.6 Query with max_nodes limit:
entity_id:DOMAIN_IDmax_nodes: 2- Verify: at most 2 nodes returned
6B.7 Query with scoring_strategy "branch_penalty":
entity_id:DOMAIN_IDscoring_strategy: "branch_penalty"- Verify: response is valid (may differ from global strategy)
6B.8 Query with relationship_types filter:
entity_id:DOMAIN_IDrelationship_types: ["BELONGS_TO"]- Verify: edges only contain BELONGS_TO relationships
6B.9 Query with output_format "toon":
entity_id:DOMAIN_IDoutput_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: trueinclude_untracked: trueinclude_diffs: true- Verify:
trackedreferences appear (from Phase 4) - Verify:
untrackedsymbols are listed - Verify:
source_idis "default" in response - Verify:
document_typeis "code" - Verify:
summaryhas correct counts
7.2 Run analyze_document with only tracked references:
include_tracked: trueinclude_untracked: falseinclude_diffs: false- Verify:
untrackedis empty,diff_hunksis empty - Verify:
trackedis populated
7.3 Run analyze_document with only untracked symbols:
include_tracked: falseinclude_untracked: trueinclude_diffs: false- Verify:
trackedis empty - Verify:
untrackedis populated
7.4 Run analyze_document with explicit LSP symbols:
- Provide
lsp_symbolsarray 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_typeis "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_lineto a new value (e.g., 10) - Update
end_lineto 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
anchorto "# Updated Anchor" - Verify: anchor updated
8C: Alter References - Delete
8C.1 Attempt to delete a reference that is attached to an entity:
- Run
alter_referenceswith Delete onFEATURE_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_entitywith Unattach command to detach the reference - Run
alter_referenceswith 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_countshows how many references were refreshed - Verify:
updatedarray shows old and new line numbers for changed refs - Verify:
unmatched_countshows symbols with no matching reference
Phase 9: Graph Validation
9.1 Run validate_graph with all checks enabled:
check_orphans: truecheck_cycles: truecheck_scope_violations: truecheck_unclassified: truecheck_no_references: true- Verify:
validis true or only has expected issues from test data - Verify:
issue_countmatches the sum of all issue arrays
9.2 Run validate_graph with only orphan check:
check_orphans: truecheck_cycles: falsecheck_scope_violations: falsecheck_unclassified: falsecheck_no_references: false- Verify: only
orphansarray may have entries, all others are empty
9.3 Run validate_graph with only cycle check:
check_cycles: true, all others false- Verify:
cyclesis 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.domainsis 0stats.featuresis 0stats.componentsis 0stats.referencesis 0
10.3 Drop the smoke test graph to leave no residue:
# The graph gnapsis_smoke_test can be dropped via psql or left for next run
# init_project with force:true will recreate it anyway
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.tomlunder[[project.sources]] - All sources share the same graph:
gnapsis_<project_name> - References store
source_idto 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