Not yet generally available. Blast Radius ships in Shipmoor CLI 0.9.0, which is still in the release process. This page describes shipped behavior on the release candidate; the command is not on the stable channel yet.
This walks the shortest honest path: an ungoverned repo, one authored link, and a suspect you caused on purpose. Ten minutes, and no Claim Check run is required to follow it.
Before you start
You need the shipmoor CLI and an active IC subscription (blast_radius is a paid entitlement). Confirm both:
shipmoor version
shipmoor capabilities
capabilities lists what your license actually grants. If blast_radius is absent, the command will show you the upgrade guidance rather than running.
You also need a repo with a frozen acceptance set at .shipmoor/acceptance.json. That file is what gives an obligation a stable content identity, so Blast Radius can tell whether an obligation moved. If you have authored .shipmoor/acceptance.yaml but never frozen it:
shipmoor claim-check freeze .
Commit both files. Without the pin, every realizes link resolves to missing acceptance file and nothing can classify.
1. Run it on a repo with no graph
shipmoor blast
On a repo that has authored no links, the run prints one honest line naming where links come from, and exits 0. It does not create a store. An engine-created store would be an approval nobody made.
2. See what nothing covers
shipmoor blast --gaps
Gaps 4 lists · honest buckets disclosed
changed code with no links 1
- config/limits.py
obligations with no check 1
- AC-01
obligations with no realizes 0
documented surface unmatched not checked (this list arrives with docs verification)
not checkable: 0
This is the first-run product on a bare repo: here is what nothing covers. Every list prints its count including zero, because an omitted list and an empty one are indistinguishable to a reader. See Gaps.
3. Author your first link
Create .shipmoor/links.yaml. You write the endpoints; the run writes the pins, so leave the pin fields out entirely:
# shipmoor links.v1 store. Committed means approved; edits are reviewed in the PR.
links:
- id: ac-01.realizes.login
kind: realizes
item: AC-01
code:
- app/login.py
provenance: authored
Use an item id that exists in your frozen acceptance set and a code path that exists in the repo. If either is wrong, the run discloses it rather than dropping the entry — see Troubleshooting.
4. Let the run pin it
shipmoor blast
The run resolves both endpoints and writes the content pins back into the store, disclosed as a first pinning rather than a re-pin. Nothing drifted; the endpoints simply had no recorded identity yet, so the entry gains no re-pin history.
Look at the diff and commit it:
git diff .shipmoor/links.yaml
git add .shipmoor/links.yaml && git commit -m "govern AC-01 with a realizes link"
Committing is the approval. The store is repo state, reviewed in pull requests like everything else.
5. Cause a suspect on purpose
Edit app/login.py — any real edit, even a comment. Then:
shipmoor blast
Blast radius working tree vs HEAD · 1 file changed
suspect 1 · rerun advised 0 · ungoverned 0 · in sync 0 · silent 0
suspect ac-01.realizes.login · AC-01 realizes app/login.py · code moved, obligation unchanged · authored
exit 0 · suspects at warn (set blast.suspect_threshold: fail to gate) · report .shipmoor/blast.v1.json
The code endpoint moved and the obligation endpoint did not, so the link is suspect with the stale side named. The run still exits 0: suspects are advisory by default.
Note that a comment-only edit suspects too. Identity is content, not meaning. That is not a rough edge; it is the guarantee that nothing here is guessing. The relief valve is an explicit re-pin, never a smarter comparator.
6. Resolve it
You have two honest options.
The change really did alter the promise. Update the obligation as well. Both endpoints then move in the same change, which reads in sync and re-pins automatically.
The change did not alter the promise — a pure refactor, say. Accept that in writing:
shipmoor blast --repin ac-01.realizes.login
re-pinned ac-01.realizes.login · code app/login.py sha256:41c7… (was sha256:12b2…)
recorded in .shipmoor/links.yaml
The re-pin edits the committed store and appends a re-pin event to the entry’s history, so the judgment “this refactor did not change the promise” is itself reviewed in the pull request. Commit it with the change.
Not sure yet? --no-write makes it a dry run: the intended change is computed and disclosed, and the file on disk is untouched.
shipmoor blast --repin ac-01.realizes.login --no-write
7. Ignore the report, commit the store
A reporting run writes .shipmoor/blast.v1.json beside the store. Unlike the store, the report is generated, not authored — no human reviews it and every run overwrites it wholesale. Ignore it:
.shipmoor/blast.v1.json
Keep the entry targeted. A broad .shipmoor/ entry would also ignore .shipmoor/links.yaml, and an ignored link store breaks the approval mechanic the whole feature rests on.
Next
- Gate a pull request on suspects with the opt-in ratchet: Configuration and exit semantics.
- Let Claim Check mint links for you as obligations graduate, instead of authoring every one: The link model.
- Understand what the classifier can and cannot see: Classification and re-pinning.