AgentSkillsCN

blast-radius

在修改共享代码(如类型、API、实用工具)之前,务必先找出所有使用该代码的消费者。此举可有效避免部分迁移导致的集成中断。在对任何已导出的符号进行更改之前,应提前触发此检查。

SKILL.md
--- frontmatter
name: blast-radius
description: Before modifying shared code (types, APIs, utilities), find all consumers. Prevents partial migrations and broken integrations. Trigger before changing any exported symbol.

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
  • scripts/run_uv.sh: convenience wrapper
    • Runs with plain python3 by default
    • If you add a pyproject.toml to this skill, it will create/use an isolated env at ~/.Mx/skill-envs/blast-radius (override with MX_SKILL_ENVS_DIR) and run via uv
    • Run: bash ~/.codex/skills/blast-radius/scripts/run_uv.sh scripts/read_file.py README.md --max-bytes 200

Protocol

Step 1: Define the Change

Document before starting:

PropertyValue
Target filesrc/types/product.ts
SymbolProduct type
Change typeAdd field / Remove field / Rename / Change type
Before{ sku: string }
After{ sku: string, skuSource: "auto" | "manual" }
BreakingNew 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:

CategoryDefinitionAction Required
DirectUses changed field/param directlyMUST update
PassthroughReceives and passes without transformingMAY need type annotation
Type-onlyOnly imports the typeUpdate if renamed
TestTest asserting on old shapeMUST update fixtures
IndirectUses via intermediateCheck intermediate

Step 4: Build Update Plan

Order by dependency (roots first):

  1. Type definitions (the contract)
  2. Producers (where data created)
  3. Direct consumers
  4. Passthroughs
  5. 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:

  1. Direct consumers → full
  2. Tests → full
  3. 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 TypeTypical RiskMitigation
Add optional fieldLowUsually safe, verify defaults
Add required fieldHighAll consumers must update
Remove fieldHighMust verify no usage remains
Rename fieldHighFind-replace across all consumers
Change typeMedium-HighVerify coercion doesn't hide bugs
Change optionalityMediumRequired→optional safe; reverse risky

Next Actions

  1. Execute coordinate-changes with the update order
  2. After changes, run verify-seams
  3. If pattern likely to recur, extract-contract