Change Review
SkillProductivityValidate CRM/PM changes before PR
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Change Review skill
What this skill tells your AI
The instructions your AI receives, as published by aaaaqwq/agi-super-team in skills/change-review/SKILL.md and read by ahel’s review.
Review of CRM and PM data changes before PR -- a data equivalent of code-review
Public repository: https://github.com/your-org/claude-change-review-skill
When to use
- Before a PR with CRM changes
- Before a PR with PM changes (tasks, projects)
- "check my CRM changes"
- "change review"
- "data review"
Paths
| What | Path |
|---|---|
| CRM | $CRM_PATH/ |
| CRM Schema | $CRM_PATH/schema.yaml |
| PM | $PM_PATH/ |
How to execute
Step 1: Read schema.yaml
# ALWAYS read the schema first -- it contains all the rules
cat $CRM_PATH/schema.yaml
Schema contains:
primary_key-- unique identifierrequired-- required fieldsunique-- unique fieldsforeign_keys-- relationships between tablescomposite_unique-- composite unique keysenums-- allowed valuesid_format-- regex for ID formatrules-- business rules
Step 2: Get the diff
git diff HEAD -- sales/crm/
Step 3: Load data
import pandas as pd
import yaml
# Read schema
with open('$CRM_PATH/schema.yaml') as f:
schema = yaml.safe_load(f)
# Load all tables
base_path = '$CRM_PATH/'
tables = {}
for table_name, table_def in schema['tables'].items():
tables[table_name] = pd.read_csv(base_path + table_def['file'])
Step 4: Validate against schema
import re
def validate_table(name, df, table_schema, all_tables):
issues = []
# 1. Primary key uniqueness
pk = table_schema['primary_key']
if df[pk].duplicated().any():
dups = df[df[pk].duplicated()][pk].tolist()
issues.append(('critical', f'Duplicate {pk}: {dups}'))
# 2. Required fields
for field in table_schema.get('required', []):
missing = df[df[field].isna()]
if len(missing) > 0:
issues.append(('critical', f'Missing required {field}: {len(missing)} rows'))
# 3. Unique fields
for field in table_schema.get('unique', []):
if field == pk:
continue
dups = df[df[field].notna() & df[field].duplicated()]
if len(dups) > 0:
issues.append(('high', f'Duplicate {field}: {dups[field].tolist()}'))
# 4. Foreign keys
for fk_field, ref in table_schema.get('foreign_keys', {}).items():
ref_table, ref_field = ref.split('.')
valid_values = all_tables[ref_table][ref_field]
invalid = df[df[fk_field].notna() & ~df[fk_field].isin(valid_values)]
if len(invalid) > 0:
issues.append(('critical', f'Invalid {fk_field} references: {invalid[fk_field].tolist()}'))
# 5. Composite unique
for fields in table_schema.get('composite_unique', []):
dups = df[df.duplicated(subset=fields, keep=False)]
if len(dups) > 0:
issues.append(('critical', f'Duplicate {"+".join(fields)} combination'))
# 6. Enum values
for field, valid_values in table_schema.get('enums', {}).items():
invalid = df[df[field].notna() & ~df[field].isin(valid_values)]
if len(invalid) > 0:
issues.append(('high', f'Invalid {field} values: {invalid[field].unique().tolist()}'))
# 7. ID format
if 'id_format' in table_schema:
pattern = table_schema['id_format']
invalid = df[~df[pk].str.match(pattern, na=False)]
if len(invalid) > 0:
issues.append(('low', f'Invalid ID format: {invalid[pk].tolist()}'))
return issues
# Validate all tables
for name, table_schema in schema['tables'].items():
if name in tables:
issues = validate_table(name, tables[name], table_schema, tables)
for severity, msg in issues:
print(f'[{severity.upper()}] {name}: {msg}')
Step 5: Business rules (from schema.rules)
# Example: won_lead_has_client
if 'leads' in tables and 'clients' in tables:
won_leads = tables['leads'][tables['leads']['stage'] == 'won']
for _, lead in won_leads.iterrows():
client_exists = (
(tables['clients']['company_id'] == lead['company_id']) &
(tables['clients']['product_id'] == lead['product_id'])
).any()
if not client_exists:
print(f"[HIGH] Won lead without client: {lead['lead_id']}")
Step 6: Output
## Change Review Summary
**Schema version:** 1.0
**Files reviewed:** [list]
**Risk Level:** Critical / High / Medium / Low
### Critical Issues (must fix)
- [table:field] Description
### High Priority
- [table:field] Description
### Validation by Schema
- [x] Primary keys unique
- [x] Required fields present
- [x] Foreign keys valid
- [x] Enum values valid
- [x] Business rules passed
Severity Levels
| Level | Schema Rule | Examples |
|---|---|---|
| Critical | primary_key, required, foreign_keys, composite_unique | Duplicate ID, broken FK |
| High | unique, enums, rules | Duplicate email, invalid status |
| Medium | (manual check) | Missing optional fields |
| Low | id_format | Wrong ID pattern |
Troubleshooting
| Problem | Solution |
|---|---|
| Broken FK | Add parent record or fix ID |
| Duplicate PK | Change ID or remove duplicate |
| Invalid enum | Use values from schema.yaml |
| Wrong ID format | See id_format in schema.yaml |
Related skills
add-lead-- adding records (also reads schema.yaml)update-lead-- updating recordscode-review-- for code (not data)
Signals
- GitHub stars
- 92
- Forks
- 23
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
change-review- Source
- github.com/aaaaqwq/agi-super-team