Blast Radius Assessment
Purpose
Know exactly what will break before changing shared code. Prevents "fixed one thing, broke three others."
When to Use
- •Changing a type definition
- •Modifying a function signature
- •Renaming a prop or field
- •Altering API response shape
- •Updating shared utility
- •Any change to exported symbols
Prerequisites
- •Change clearly defined (what's changing, how)
- •HelixDB indexed and connected
- •Repo Prompt connected
Included Files (Optional)
This skill can bundle extra files in its directory.
- •
scripts/read_file.py: quick file-read preview script (demo/testing)- •Run (from this skill folder):
python3 scripts/read_file.py path/to/file --max-bytes 4096 - •Run (absolute path, user-scope install):
python3 ~/.codex/skills/blast-radius/scripts/read_file.py path/to/file - •(Optional) If you use
uv:uv run python scripts/read_file.py path/to/file
- •Run (from this skill folder):
- •
scripts/run_uv.sh: convenience wrapper- •Runs with plain
python3by default - •If you add a
pyproject.tomlto this skill, it will create/use an isolated env at~/.Mx/skill-envs/blast-radius(override withMX_SKILL_ENVS_DIR) and run viauv - •Run:
bash ~/.codex/skills/blast-radius/scripts/run_uv.sh scripts/read_file.py README.md --max-bytes 200
- •Runs with plain
Protocol
Step 1: Define the Change
Document before starting:
| Property | Value |
|---|---|
| Target file | src/types/product.ts |
| Symbol | Product type |
| Change type | Add field / Remove field / Rename / Change type |
| Before | { sku: string } |
| After | { sku: string, skuSource: "auto" | "manual" } |
| Breaking | New required field |
Step 2: Find All Consumers (HelixDB)
For types:
code
helix: get_references("<TypeName>")
For functions:
code
helix: get_call_hierarchy("<functionName>")
For components:
code
helix: get_references("<ComponentName>")
For renamed fields:
code
helix: search_code("<oldFieldName>", limit: 50)
Step 3: Categorize Impact
For each consumer, read the usage:
code
read_file(path: "<consumer>", start_line: N, limit: 20)
Categorize by risk:
| Category | Definition | Action Required |
|---|---|---|
| Direct | Uses changed field/param directly | MUST update |
| Passthrough | Receives and passes without transforming | MAY need type annotation |
| Type-only | Only imports the type | Update if renamed |
| Test | Test asserting on old shape | MUST update fixtures |
| Indirect | Uses via intermediate | Check intermediate |
Step 4: Build Update Plan
Order by dependency (roots first):
- •Type definitions (the contract)
- •Producers (where data created)
- •Direct consumers
- •Passthroughs
- •Tests
Step 5: Load Impact Set (Repo Prompt)
code
manage_selection(op: "set", paths: [<all impacted files>], mode: "codemap_only") workspace_context(include: ["tokens", "selection"])
If over budget, prioritize:
- •Direct consumers → full
- •Tests → full
- •Passthroughs → codemap
Output Format
markdown
## Blast Radius: [Change Description] ### Change Definition | Property | Before | After | |----------|--------|-------| | File | src/types/product.ts | - | | Symbol | Product | - | | Field | - | skuSource: "auto" \| "manual" | | Breaking | - | Yes (new required field) | ### Impact Assessment #### By Category | Category | Count | Files | |----------|-------|-------| | Direct | 3 | Products.tsx, Catalog.tsx, QuoteBuilder.tsx | | Passthrough | 1 | ProductList.tsx | | Type-only | 2 | index.ts, types.ts | | Test | 2 | product.test.ts, catalog.test.ts | #### Detailed Impact | File | Category | Risk | Specific Change Needed | |------|----------|------|------------------------| | Products.tsx | Direct | HIGH | Add skuSource to form state | | Catalog.tsx | Direct | HIGH | Display skuSource indicator | | QuoteBuilder.tsx | Direct | MED | Handle missing skuSource | | ProductList.tsx | Passthrough | LOW | Type annotation only | | product.test.ts | Test | HIGH | Update all Product fixtures | | catalog.test.ts | Test | HIGH | Update assertions | ### Update Order | Order | File | Change | Depends On | |-------|------|--------|------------| | 1 | types/product.ts | Add skuSource field | - | | 2 | convex/products.ts | Populate skuSource in queries | Step 1 | | 3 | Products.tsx | Consume skuSource | Steps 1-2 | | 4 | Catalog.tsx | Display skuSource | Steps 1-2 | | 5 | QuoteBuilder.tsx | Handle skuSource | Steps 1-2 | | 6 | product.test.ts | Update fixtures | Steps 1-5 | ### Migration Checklist - [ ] All direct consumers identified - [ ] Update order determined - [ ] Tests identified for update - [ ] Rollback plan documented
Verification After Changes
Search for stragglers:
code
helix: search_code("<old_field_name>", limit: 20)
If results found → migration incomplete.
Limitations
- •Dynamic property access (
obj[key]) not detected - •String-based field access (
obj["field"]) may be missed - •Runtime-only consumers (config files, external systems) invisible
- •Transitive dependencies may need recursive queries
Risk Levels
| Change Type | Typical Risk | Mitigation |
|---|---|---|
| Add optional field | Low | Usually safe, verify defaults |
| Add required field | High | All consumers must update |
| Remove field | High | Must verify no usage remains |
| Rename field | High | Find-replace across all consumers |
| Change type | Medium-High | Verify coercion doesn't hide bugs |
| Change optionality | Medium | Required→optional safe; reverse risky |
Next Actions
- •Execute
coordinate-changeswith the update order - •After changes, run
verify-seams - •If pattern likely to recur,
extract-contract