Claude-skill-registry debug-knowledge

Debug the Copilot Knowledge service - investigate sync failures, schema mismatches, and data issues between tenants.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/debug-knowledge" ~/.claude/skills/majiayu000-claude-skill-registry-debug-knowledge && rm -rf "$T"
manifest: skills/data/debug-knowledge/SKILL.md
source content

Debug Knowledge Service

You are debugging the Copilot Knowledge service, which exports models from one tenant's WrenAI instance and syncs them to other tenants.

Architecture Overview

┌─────────────────┐    Export     ┌──────────────────┐     Sync      ┌─────────────────┐
│  Source Tenant  │ ───────────► │  KnowledgeItem   │ ────────────► │  Target Tenant  │
│  (WrenAI + DB)  │              │  (hub-backend)   │               │  (WrenAI + DB)  │
└─────────────────┘              └──────────────────┘               └─────────────────┘

Key services location:

hub-backend/app/services/hub/chord_ai/knowledge/

Debugging Setup

Always start by setting up your test environment. Use

mise
for correct Ruby version:

# Run with: eval "$(mise activate bash)" && bin/rails runner "<code>"

tenant_1 = Hub::Tenant.first
store_1 = tenant_1.stores.first

tenant_2 = Hub::Tenant.second
store_2 = tenant_2.stores.first

user = Hub::User.last
environment = 'staging'  # or 'production'

Key Services Reference

1. List Models in WrenAI

See what models exist in a tenant's WrenAI instance:

result = Hub::ChordAI::Knowledge::Models::List.call(
  tenant: tenant, store: store, user: user, environment: 'staging'
)
models = result.success? ? result.data : []
models.each { |m| puts "#{m['referenceName']} (#{m['fields']&.count} fields)" }

2. Get Single Model Details

Get full details including fields, calculated fields:

result = Hub::ChordAI::Knowledge::Models::Get.call(
  tenant: tenant, store: store, user: user, id: model_id, environment: 'staging'
)
model = result.data
model['fields'].each { |f| puts "#{f['sourceColumnName']} -> #{f['type']}" }

3. List Data Source Tables (Snowflake)

See what tables/columns exist in the actual database:

result = Hub::ChordAI::Knowledge::DataSourceTables.call(
  tenant: tenant, store: store, user: user, environment: 'staging'
)
tables = result.data
table = tables.find { |t| t['name'].include?('TABLE_NAME') }
table['columns'].each { |c| puts c['name'] }

4. Check Knowledge Items (Exported Models)

Hub::ChordAI::KnowledgeItem.all.each do |item|
  puts "#{item.reference_name} - #{item.item_type} (#{item.assignments.count} assignments)"
end

5. Check Assignments and Sync Status

item = Hub::ChordAI::KnowledgeItem.find(id)
item.assignments.each do |a|
  puts "Tenant: #{a.hub_tenant.name}, Status: #{a.sync_status}, Error: #{a.last_error}"
end

Common Debugging Scenarios

Scenario 1: GraphQL Schema Mismatch

Symptom: Error like

String cannot represent a non string value
or
Field "X" is not defined

Investigation:

  1. Identify which service is failing from the error path (e.g.,
    data.fields[0]
    )
  2. Find the GraphQL mutation in the service file
  3. Use the wrenai agent to check the actual schema:
Use Task tool with subagent_type=wrenai to find the GraphQL input type definition
in wren-ui/src/apollo/server/schema.ts
  1. Compare what hub-backend sends vs what schema expects

Common fixes:

  • Array of objects → Array of strings (fields: [String!]!)
  • Missing required field (id: Int!)
  • Extra field not in schema

Scenario 2: Column Not Found in Data Source

Symptom: Error like

Column "X" not found in table "Y" in the data Source

Investigation:

  1. Check if column exists in source tenant's data source:
# Get data source tables
result = Hub::ChordAI::Knowledge::DataSourceTables.call(...)
table = result.data.find { |t| t['name'] == 'TABLE_NAME' }
cols = table['columns'].map { |c| c['name'] }
puts cols.include?('COLUMN_NAME')  # Should be true
  1. Check if model has phantom columns (model fields > data source columns):
# Compare model fields vs data source columns
model_fields = model['fields'].map { |f| f['sourceColumnName'] }
db_columns = table['columns'].map { |c| c['name'] }

phantom = model_fields - db_columns
puts "Phantom columns: #{phantom}"  # These exist in model but not DB
  1. If phantom columns exist, the source model is corrupted/stale

Scenario 3: Model Exists in One Tenant But Not Another

Symptom: Sync fails because model doesn't exist in target

Investigation:

# Compare models between tenants
result_1 = Hub::ChordAI::Knowledge::Models::List.call(tenant: tenant_1, ...)
result_2 = Hub::ChordAI::Knowledge::Models::List.call(tenant: tenant_2, ...)

names_1 = result_1.data.map { |m| m['referenceName'] }
names_2 = result_2.data.map { |m| m['referenceName'] }

only_in_1 = names_1 - names_2
only_in_2 = names_2 - names_1

puts "Only in tenant 1: #{only_in_1}"
puts "Only in tenant 2: #{only_in_2}"

Scenario 4: Field Count Mismatch Between Tenants

Symptom: Same model name but different field counts

Investigation:

model_1 = result_1.data.find { |m| m['referenceName'] == 'MODEL_NAME' }
model_2 = result_2.data.find { |m| m['referenceName'] == 'MODEL_NAME' }

fields_1 = model_1['fields'].map { |f| f['sourceColumnName'] }.sort
fields_2 = model_2['fields'].map { |f| f['sourceColumnName'] }.sort

only_in_1 = fields_1 - fields_2
only_in_2 = fields_2 - fields_1

puts "Fields only in tenant 1: #{only_in_1}"
puts "Fields only in tenant 2: #{only_in_2}"

When to Use WrenAI Agent

Spawn the wrenai agent (via Task tool with

subagent_type=wrenai
) when you need to:

  1. Validate GraphQL schema - Find input type definitions in
    wren-ui/src/apollo/server/schema.ts
  2. Understand WrenAI internals - How models, fields, relations are stored
  3. Check GraphQL resolvers - What mutations actually do on the WrenAI side
  4. Investigate WrenAI-specific errors - Errors originating from WrenAI's validation

Example prompt for wrenai agent:

Find the GraphQL schema definition for UpdateModelMetadataInput and
UpdateColumnMetadataInput in wren-ui/src/apollo/server/schema.ts.
List all fields and their types.

Quick Diagnostic Checklist

When investigating a Knowledge sync failure:

  • What's the exact error message?
  • Which service is failing? (check stack trace)
  • Is it a GraphQL schema issue or data issue?
  • Does the model exist in source tenant's WrenAI?
  • Does the table exist in target's data source?
  • Do all model fields exist in the data source?
  • Are there phantom columns in the source model?
  • Is this a new model creation or update to existing?

File Locations

ComponentLocation
Knowledge services
hub-backend/app/services/hub/chord_ai/knowledge/
Models services
hub-backend/app/services/hub/chord_ai/knowledge/models/
Sync logic
hub-backend/app/services/hub/chord_ai/knowledge/sync_model.rb
Export logic
hub-backend/app/services/hub/chord_ai/knowledge/export.rb
WrenAI GraphQL schema
wrenai/wren-ui/src/apollo/server/schema.ts
Project documentation
projects/copilot-knowledge/
Learning notes
learn/hub-backend/wrenai-graphql-integration.md
debug-knowledge — OpenSkillIndex