$npx -y skills add DSB-117/brainblast --skill brainblast-scoutSends an agent on a scouting mission to find real-world coding traps (footguns in popular SDKs/protocols), synthesize the finding into a proven brainblast rule pack, and submit it to the pack registry. Staking $BRAIN on the pack is an optional, opt-in bond (Phase 5) — never requi
| 1 | # Brainblast Scout |
| 2 | |
| 3 | End-to-end pipeline for an agent to go find a new "silent footgun" in some |
| 4 | external SDK/protocol, turn it into a proven brainblast knowledge pack, and |
| 5 | submit it — the same workflow used to produce |
| 6 | `packs/jupiter-quote-zero-slippage` and `packs/spl-transfer-not-checked-in-payout`. |
| 7 | |
| 8 | **Default scope is Phases 1–4 — they are entirely no-spend** (research → prove → |
| 9 | package → submit). They are all you need to *produce and sell* the data: a pack |
| 10 | that lands in `packs/` flows straight into the corpus and the storefront via |
| 11 | `npm run intake` (`gen:vti → pack:dataset → corpus → catalog`), no `$BRAIN` |
| 12 | required. **Phase 5 (stake) is OPTIONAL and opt-in** — a quality bond layered on |
| 13 | top, run only when the operator has set up the capped ops-wallet + caps. This is |
| 14 | a core marketplace invariant (`ROADMAP.md`, Lane 4): data intake never blocks on spend. |
| 15 | |
| 16 | Each phase fails closed: if a phase doesn't produce a clean result, stop and |
| 17 | surface a draft for human review rather than forcing it through. |
| 18 | |
| 19 | > **Stop after Phase 4 by default.** Only proceed to Phase 5 if the user has |
| 20 | > explicitly asked to stake AND the ops-wallet env (`AGENT_OPS_WALLET_SECRET` + |
| 21 | > caps) is configured. Producing the data does not require it. |
| 22 | |
| 23 | ## Fleet mode (the fast path — prefer this) |
| 24 | |
| 25 | The **fleet** (`fleet/`, `npm run fleet`) automates prove → promote → intake → |
| 26 | score, so a scout run is just: **pick a work-order, drop a candidate, run the |
| 27 | fleet.** |
| 28 | |
| 29 | 1. **Target a work-order.** Run `npm run fleet -- --dry-run` (or read |
| 30 | `datasets/COVERAGE.md`) and pick an **uncovered class** or **thin cell** from |
| 31 | the scoreboard — that's where a new trap is worth most. |
| 32 | 2. **Write a candidate** `fleet/candidates/<id>.json` (a Finding — see |
| 33 | `fleet/README.md` for the template). Prefer the vetted |
| 34 | `object-arg-property-forbidden-literal` checker (flags an options-object |
| 35 | property set to a forbidden string/number/**boolean** literal — the shape of |
| 36 | most insecure-default footguns); no new checker code needed. |
| 37 | 3. **Run the fleet.** `npm run fleet` proves every candidate RED→GREEN, |
| 38 | auto-promotes the proven ones to `packs/`, regenerates the corpus + storefront, |
| 39 | and prints what landed + the next work-orders. A candidate that doesn't |
| 40 | reproduce is reported DRAFT and never lands. |
| 41 | |
| 42 | That's the whole no-spend loop. The detailed Phases below are the reference for |
| 43 | *how* a Finding is shaped and what the gate checks; **for routine sourcing, use |
| 44 | fleet mode.** (Phases 2b/3 — manual synth + `cp` into `packs/` — are what the |
| 45 | fleet now does for you.) |
| 46 | |
| 47 | ## Phase 1 — Scout |
| 48 | |
| 49 | Research one external SDK/protocol (Solana programs, payment SDKs, etc.) for |
| 50 | a pattern where the *happy path compiles and runs* but silently does the |
| 51 | wrong thing — wrong constant, missing check, unchecked return value, |
| 52 | misordered calls. Good sources: official docs changelog, GitHub issues |
| 53 | tagged "footgun"/"gotcha", postmortems, audit reports. |
| 54 | |
| 55 | Use `/browse` for any web research (per the user's global gstack |
| 56 | instructions — never drive Chrome directly). |
| 57 | |
| 58 | Output: a candidate description in plain English — the SDK, the call/shape |
| 59 | that's wrong, why it's wrong, and what the fixed version looks like. This is |
| 60 | NOT yet a Finding JSON; it's the raw idea. |
| 61 | |
| 62 | ## Phase 2 — Synthesize into a Finding |
| 63 | |
| 64 | Turn the candidate into a `Finding` (see |
| 65 | `packages/core/src/synth/types.ts`) and write it to |
| 66 | `packages/core/findings/<id>.json`. Required: |
| 67 | |
| 68 | - `binding.check.kind` MUST be one of `checkerKinds` in |
| 69 | `packages/core/src/checkers/index.ts` — if your pattern needs a *new* |
| 70 | checker kind, that's a separate, larger task (see how |
| 71 | `literal-multiplier-wrong-constant` and `fee-allocation-shape` were added |
| 72 | historically); don't invent an unvetted kind here. |
| 73 | - `binding.test.kind` similarly must be in `testKinds`. |
| 74 | - `fixtures.vulnerable` / `fixtures.fixed` are full file contents — write |
| 75 | real, minimal, compilable-looking code demonstrating the trap and its fix. |
| 76 | |
| 77 | Then run, from `packages/core/`: |
| 78 | |
| 79 | ```bash |
| 80 | npm run synth -- findings/<id>.json |
| 81 | ``` |
| 82 | |
| 83 | - **exit 0 (PROVEN)**: rule + fixtures staged in `.synth/`, ready to promote. |
| 84 | Continue to Phase 3. |
| 85 | - **exit 2 (DRAFT)**: written to `packages/core/drafts/<id>/` for human |
| 86 | review. STOP here — do not proceed to packaging or staking on a draft. |
| 87 | - **exit 1**: bad input, fix the Finding JSON and retry. |
| 88 | |
| 89 | ## Phase 3 — Package as a pack |
| 90 | |
| 91 | Create the standalone pack directory: |
| 92 | |
| 93 | ```bash |
| 94 | npx brainblast pack init packs/<pack-id> --id <pack-id> --name "<name>" \ |