| name | bluespec.plan |
| description | Turn what detect found into the defense plan, with a fix for each finding, its priority, and the charter principle it upholds. Reads the detect map and the charter, then plans every finding, just the files or directories you name, or a specific concern you describe. |
| argument-hint | Optionally name files/dirs or a concern, or leave empty to plan every finding |
| user-invocable | true |
User Input
$ARGUMENTS
The User Input above decides how this command runs. Read it before proceeding.
Outline
You are producing a defense plan at .bluespec/memory/plan.md: a prioritized set of fixes for what detect found, each one pointing at a detect finding, given a priority, paired with the charter principle it upholds, and the control to apply. This phase continues from detect. Detect already detected what the system does and recorded the risk each thing carries, so the plan does not restate the risk: it decides what to do about it. Every fix must point at something detect actually detected, never a generic checklist. The fixes are the WHAT to do. Applying them is the next phase, harden, not this one.
The detect map is the primary input: the fixes follow from what detect found. The charter is the governing context: it tells you which fixes matter most for this project and gives each fix a principle to uphold.
Step 1: Decide the scope from the input
This phase is built entirely on the detect map. It never reads the code directly: it only knows the system through what detect already detected. Every fix it plans must point at a finding that is really in the detect map. The User Input above selects one of three modes, and each one is answered from the detect map, never from the code:
- No input (the User Input is empty): plan the fixes for every finding in the detect map. This is the full defense plan across the detected context.
- Files or directories given (the input names one or more paths in the project): plan the fixes for the detect findings whose evidence points at those paths. Match paths to findings through the tracking map (
.bluespec/tracking.json), which records each finding's paths, do not open the files yourself. Leave the rest of the plan untouched.
- A concern described (the input describes a worry, for example "where sensitive data could leak"): plan the fixes for that specific concern, drawing on the detect findings that relate to it. The plan covers what the user asked about, not the whole context.
If the input is ambiguous between a path and a described concern, prefer the most literal reading (an existing path is a path), and state which mode you chose before continuing.
When the scope points somewhere detect has not mapped, follow the coverage rules in Step 2 rather than reading the code to fill the gap.
Step 2: Load context
- Load the detect map at
.bluespec/memory/detect.md. This is the required primary input.
- If it does not exist, stop and tell the user to run
/bluespec.detect first. The defense plan is built from detected findings, so there is nothing to plan without it. Do not invent findings to work around a missing detect map.
- If it exists, read its findings. Each finding's name and recorded risk is what a fix points at, and the tracking map holds the paths that finding lives at. Fixes only ever point at findings that are really in the map.
- Check that the scope is covered by detect before planning:
- If nothing in the scope you chose is in the detect map (the named paths match no finding's tracked paths, or no finding relates to the described concern), stop and tell the user to run
/bluespec.detect on that scope first, then run the plan phase again. Do not read the code to fill the gap.
- If the scope is partly covered (some findings are in the map, but the paths or concern also reach things detect has not mapped), plan the fixes for what is covered, and record each uncovered part under Open questions (naming the uncovered path and noting the detect map does not cover it yet). Do not stop, and do not read the code for the uncovered part.
- Load the defense plan at
.bluespec/memory/plan.md.
- If it does not exist, initialize it from the template at
.bluespec/templates/plan-template.md first, and identify every placeholder token of the form [ALL_CAPS_IDENTIFIER].
- If it already exists, read the fixes already in it. You will reconcile them in Step 3 before adding anything new. Each fix's identity is the finding it points at plus the fix itself.
- Load the charter at
.bluespec/memory/charter.md for the governing principles, if it exists. Use it to judge which fixes matter most for this project and to give each fix the principle it upholds. The charter guides priority, it does not box you in: plan a real fix even if no principle names it, and let the user rescope. If the charter does not exist, plan the fixes from the findings alone, set each Upholds to None directly, and take each priority from the risk detect recorded for the finding.
Step 3: Reconcile the existing plan
This plan is reconciled, never append-only. If the plan was empty or freshly initialized, skip this step. Otherwise, before planning anything new, re-check each existing fix against the current detect map:
- Still needed: the finding it points at is still in the detect map and still unfixed. Keep it, and update its priority, principle, or fix if the details changed.
- Done or gone: the finding it points at is no longer in the detect map, or the detect map now shows it resolved. Remove it from the plan. Do not keep finished fixes for history. The plan reflects the work still to do, not the past.
- Only re-check fixes that fall within the current scope. A fix outside the scope you are running stays untouched.
A fix whose finding verify already proved closed was stood down out of the whole chain, so it is simply absent here. That absence is expected, not a broken chain, and is no reason to run repair.
If reconciling reveals the chain is inconsistent (for example the tracking map points a finding at a file that was renamed or moved, so the path on record no longer exists), run /bluespec.repair and then continue. Repair fixes Blue Spec's internal tracking across every phase at once, so the chain stays coherent. Do not try to repair the tracking yourself: this phase reconciles its own plan in prose, repair owns the tracking.
Step 4: Plan the fixes
For each in-scope detect finding, read the risk detect already recorded for it (do not restate that risk in the plan), then decide the fix that answers it. For each finding you plan:
- Title the block with the detect finding's name, verbatim, so it is the same item. Do not rename it or add an action prefix, and do not copy its file path into the plan: the path lives in the tracking map.
- Set the priority from the risk detect recorded for that finding (see Step 5). The more serious and exposed the recorded risk, the higher the priority.
- Name the charter principle the fix upholds, if the charter names one. If the fix supports more than one principle, name them all, separated by commas. If no principle fits, write
None directly and keep the fix.
- Describe the control to apply: the WHAT to do, not the application. Applying is harden's job.
One finding is one item. When a finding needs more than one fix, write them as more than one paragraph under its single block, never a second block. Plan what the findings support, nothing speculative.
Step 5: Fill the template
- Replace every placeholder with concrete text. Leave no bracket tokens behind.
- Set
Scope to reflect the mode you ran: all findings, the named files or directories, or the described concern.
- Merge, do not overwrite. The plan now holds the reconciled fixes from Step 3 plus what you planned in Step 4. Add a new block only for a finding genuinely new, not already represented. Do not duplicate a finding that is already there under a different wording.
- Write one block per finding, titled with the finding's name (verbatim from detect, no action prefix). Each block MUST carry these parts:
- Priority: one of
Critical, High, Medium, or Low, by the scale below.
- Upholds: the charter principle the fix supports, or several separated by commas if it supports more than one. If no charter is loaded or none fits, write
None directly and keep the fix.
- Fix: the control to apply in harden, described not applied.
- Use a simple priority scale, plain enough for any reader, taken from the risk detect recorded for the finding:
- Critical: the recorded risk is severe and can be reached and exploited right now (for example data already exposed to anyone, an account anyone can take over, a way to run code or commands on the system). Drop everything and fix it first.
- High: the recorded risk is serious and exposed, but not trivially exploitable this moment (it needs a condition to line up, some access, or a step to chain). Fix next, before normal work.
- Medium: the recorded risk is real but less likely or harder to reach. Fix soon.
- Low: the recorded risk is limited or unlikely in practice. Fix when convenient.
When in doubt between two levels, judge by the seriousness of the recorded risk first, then by how exposed it is. Choose the higher level if the harm would be severe. Reserve
Critical for risk that is both severe and reachable right now, so the label keeps its meaning.
- The template ships with three starter fixes. This is a starting point, not a limit. Add or remove fixes so the plan matches what the findings actually need.
- If part of the scope was not covered by the detect map, record it under Open questions. Do not invent a finding to fill the gap. Remove that section if there are none.
- Set
Planned to today's date in ISO format YYYY-MM-DD.
Step 6: Validate before writing
- No bracket tokens remain.
- Every block is titled with a finding name that really exists in the detect map, and carries Priority, Upholds, and Fix.
- No fix for a finding that Step 3 found resolved is still in the plan, and no finding is duplicated.
- Every
Priority is one of Critical, High, Medium, or Low.
- The
Scope line matches the mode you actually ran.
- The date is ISO
YYYY-MM-DD.
Step 7: Write and summarize
- Write the reconciled plan to
.bluespec/memory/plan.md.
- Register the items you planned so the tracking map keeps each one current. This is registration, not reconciliation: hand the track hook only the findings this run planned, as the
entries list of {name, paths}, named by the finding's name (your section title, the same name detect used). The hook finds that same item by name and updates its paths. It does not create a second entry: one finding is one item. name is the finding's name, and paths holds the file paths the fix touches. The path lives here, in tracking, never in the prose. Run it from the project root, passing the payload as the single argument:
node ./.bluespec/hooks/track.mjs '{"entries":[{"name":"<FINDING NAME>","paths":["<PATH>"]}]}'
Do not edit .bluespec/tracking.json yourself, and do not reconcile here. Track only advances what this phase planned. Repairing the map across the conveyor stays with /bluespec.repair.
- Output a short summary to the user:
- The scope you ran (all findings, named files or directories, or concern).
- The fixes planned, each with its priority and one-line fix, highest priority first.
- What changed since the last run: fixes added, fixes removed because they are now done, and fixes updated.
- Anything left under Open questions, including any part of the scope the detect map did not cover.
- A suggested commit message, for example
docs: update defense plan.
- Next step: point the user to
/bluespec.harden, the phase that applies these fixes to the code, safely and one at a time, highest priority first. Frame it as the recommended next step. If anything is left under Open questions, point them instead to /bluespec.detect on that uncovered scope first, so the plan can cover it before harden runs.
Keep the plan in plain language throughout. A non-developer should understand what each fix does and why it is prioritized, while the finding name in each title stays precise enough for harden to act on.