Skip to content
Back to skills

Tranche

ASecurity

Take ONE target from the plan and land it without changing behaviour: guard it on the untouched code, move it verbatim, prove the equivalence by running both, mutation-sweep the tests, pass every gate, open a PR and merge it on green CI — or decline it with the cost written down.

  • 234 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 28, 2026
ai-agentsrustgobashgitdocumentation

Works with

  • cli

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned October 2, 2026

npx -y skills add receptron/mulmoterminal --skill tranche --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Tranche?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Tranche
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/receptron-tranche/badge)](https://www.skillsdirectory.com/skills/receptron-tranche)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: blueprint-refactor-tranche
description: "Take ONE target from the plan and land it without changing behaviour: guard it on the untouched code, move it verbatim, prove the equivalence by running both, mutation-sweep the tests, pass every gate, open a PR and merge it on green CI — or decline it with the cost written down."
---

# One target, one change

This step repeats. Each round does **one** target from `.blueprint/targets.json` — the first whose status
is `todo` — and nothing else. The whole claim of the change is **"this behaves the same"**, and that is
not provable by reading. What follows is how it is proved instead.

Read `.blueprint/spec.md` (the plan the person approved), `.blueprint/gates.json` (the gates) and
`.blueprint/answers.json` (`merge`: whether to merge on green CI).

## 0. The approved plan wins

The person may have changed the plan by talking to it at the review gate, which rewrites `spec.md` but not
`targets.json`. If the two disagree — a target added, dropped, reordered or reworded — bring
`targets.json` in line with `spec.md` first. Keep finished targets as they are.

## A `ci` target

Close the gaps in `.blueprint/ci.json` with the smallest change: prefer adding a step to the workflow that
already installs dependencies over a new workflow, and use the install command from `gates.json`. Every
workflow gets a top-level `permissions:` block (default `contents: read`; a job gets more only if it needs
it) and `actions/checkout` gets `persist-credentials: false`. Then continue from step 8 — the pull request's
own checks are the proof that the new CI runs and passes.

## 1. Start clean, and check nobody else is in the file

- On the default branch, `git pull --ff-only`. Branch: `blueprint/<target id>`.
- `gh pr list --state open` and `git log origin/<default> --oneline -20 -- <files>`. A pull request merged an
  hour ago is in neither your tree nor the open list. If someone else is changing these lines, mark the
  target `skipped` with that as the note, and stop the round.
- Confirm the target is still reachable: grep for its caller or renderer, not its import.

## 2. Find the guards before touching anything

```bash
grep -rln "<file basename>" test/ tests/ src/ --include='*.test.*' --include='*.spec.*'
grep -rn "'<identifier>'\|\"<identifier>\"" test/ tests/ src/
```

Sort the hits: **behavioural** tests call the code and break loudly. **Source-text** guards (a test that
reads a file and looks for a string, a census, an AST scan) **fail open**: when the text moves they go
vacuously green, still running and checking nothing. Each of those has to be re-pointed by what it
protected (step 5), and a guard should derive its population rather than carry a list written down.

## 3. Write the missing guard against the UNMODIFIED code

If the behaviour you are about to move — above all an ordering or a shared answer that holds only because
the code is adjacent — has no test, write one **now**, on the untouched code, where it passes. Then
**break-verify it on the untouched code**: insert exactly the defect the move could introduce and watch it
go red. A guard written after the move pins the new shape and proves nothing about the old one.

Commit the guard on its own (`test:` prefix) before the move. For a `test`-kind target this is the whole
change: tests for untested, high-value logic, each one mutation-verified (step 7).

## 4. Move the text verbatim

- The moved body is the original text with mechanical renames only. No "while I'm here" tidying — a
  cleanup mixed into a move destroys the only cheap proof you have.
- Pick the move from what the **call site** does on each path. Does this path already `await`?
  - An `async` helper suspends its caller even on a path that reaches no `await`: one more microtask before
    everything after it. Write the helper synchronous first; keep the `await` at the call site.
  - A write to shared state (a module singleton, `process.env`, a registry) and the call that reads it must
    stay in one continuation. If the region does I/O and then writes, split it: the async half returns a
    plan, a synchronous half applies it at the call site.
  - `let x;` filled by the block below it → `const x = f(…)`: the canonical, checkable move.
- Prove only the control flow changed: a multiset of the file's code lines against the default branch,
  comments stripped, should show only the inversion.
  ```bash
  strip() { grep -vE '^\s*(//|\*|/\*)' "$1" | sed 's/[[:space:]]//g' | grep -v '^$' | sort; }
  diff <(git show origin/<default>:<file> | strip /dev/stdin) <(strip <file>)
  ```

## 5. Re-point every source-text guard by what it protected

Never by where it sat. For each moved anchor: what defect was this there to catch, and where can that
defect now appear? Sometimes that is two places — inside the helper **and** around its call. Break-verify
each re-pointing.

## 6. Prove the equivalence — run both, do not reason

In order of preference:

1. **Replica differential.** Copy the OLD code verbatim into a throwaway harness and run it beside the new
   code over **generated** inputs — not inputs you chose; the ones you would think of are the ones you
   already believe are equal. Compare the whole result (`JSON.stringify` both sides), and treat a throw as
   an outcome (`ok:<value>` vs `threw:<message>`). Generate deliberately: missing keys, `null` elements,
   falsy-but-not-nullish (`0`, `''`, `false`), both alternatives of a `??`/`||` chain present at once, the
   same value at two positions, keys every object has (`constructor`, `__proto__`).
2. **Drive it** through the seam the codebase already has (an injected clock, client, or `realpath`).
3. Verbatim body plus the guards — and say out loud that this is all it rests on.

**Mutation-verify the harness** before trusting its zero: change one edited line in the new code and the
harness must report differences. A zero it cannot move off is not a measurement.

Before deleting the harness, **harvest what outlives it**: the generator (which inputs matter) and the
property (what must hold) become a permanent test.

## 7. Mutation sweep of the tests you wrote

A test that cannot fail is documentation with a green tick. For each decision you touched:

1. Hash the file. Confirm the anchor matches **exactly once**.
2. Apply the mutation, re-read the file, confirm the old text is **gone** (it landed) and that it runs
   (a duplicate object key or a compile error is not a behaviour mutation).
3. Run the tests; read the **exit code** and the thrown assertion.
4. Restore; compare the hash back.

Worth running: the helper suspends before its first statement; each guard dropped; each branch's answer
swapped; a value handed on as a copy instead of the live object. **Record mutations that stay green**
rather than silently dropping them — each is either a hole to close or a sentence saying why no input can
tell the two apart.

## 8. Gates, by exit code

Run the install and every gate from `.blueprint/gates.json`, and read `$?` — never the last line of output.
The typecheck is its own gate; a test runner that only transpiles runs code with type errors happily.

## 9. Pull request, CI, merge

- Commit with `refactor:` (or `test:` / `fix:` for what it is), adding files one by one — never `git add .`.
- Push the branch. Open a PR whose body says: what the region was, which invariant was at risk, how
  behaviour was proved (and over what inputs), which mutations went red, and **what was not proved**. Say
  what moved and how, not by how much — no line counts.
- **Cross-review with Codex, when it is available** — follow `cross-review.md` beside this file. Dispatch
  the first round as soon as the pull request is pushed; it runs alongside CI, not after it.
- `gh pr checks <n> --watch`. Read a red check and fix it; never retry blindly, never merge while pending.
  Merge only when CI is green **and** the Codex review ended clean (or could not run, and the pull request
  says why).
- If `merge` is `CI が緑なら自動でマージする`: `gh pr merge <n> --merge --delete-branch`. Otherwise leave it open.
- Back to the default branch, `git pull --ff-only`, and confirm the gates are still green there.

## 10. Record the round

In `.blueprint/targets.json`, set this target's `status` to `done` with `"pr": "<url>"` and
`"review": "codex: clean after <n> rounds"` (or why there was no Codex review). In `.blueprint/spec.md`
add one line under the target saying how it went.

**Then stop — end your turn here**, even when there are targets left and even when an answer you just got
reads like "carry on". The executor checks this round and starts the next one in a fresh session; a second
target done in this session skips that check and the next round's fresh context.

## When to decline instead

Declining with the cost written down is a real result and beats a move whose behaviour is only argued.
Set `status` to `skipped` and write `note` — what it would buy, what the risk is, and what would have to be
established first — then delete your branch (`git branch -D`, only the one you made) and return to the
default branch. Decline when:

- you cannot prove the move preserves behaviour;
- the extracted piece is itself over the bound (the finding moved rather than cleared);
- nothing reaches the code — say so and do not delete it on your own authority;
- someone else is changing the same lines.

Ask the person (and stop) only when a decision is theirs: a gate red for reasons outside this change, a fix
that would change behaviour, or a target the plan did not foresee.

Make it a pick, not an essay. Put the evidence in the question — the lines, the caller that reaches them,
what you measured — and offer the options as `CHOICES`, each with what it costs and risks, and `RECOMMEND`
the one you would take. The decisions this work stops for, and their usual options:

| decision | options |
|---|---|
| a declared type is narrower or wider than what arrives | fix the type / narrow the code to it / leave it |
| something looks like a bug | file an issue / leave it |
| a fix would change behaviour | change it / keep today's behaviour |
| a costed no | accept it / do it anyway |

Done when the check passes: every finished target's PR is merged (or open, if the person merges), the clone
is back on a clean, up-to-date default branch, every gate is green, and one more target is finished than
before this round.

## Always

- One target per round. Do not start the next one — the executor starts the next round. An answer from
  the person (say, that they merged the pull request) finishes THIS target; it is not a go-ahead for the next.
- Never force-push, rebase or squash. Never push to the default branch. Never delete a branch you did not create.
- Never silence a lint or type error to get green (`eslint-disable`, `@ts-ignore`, `as`): fix the cause or decline.
- When you need a decision, ask it through the blueprint question tool and stop. Do not guess.
- Say you are done by stopping; the executor runs the check. Do not claim success yourself.

Files in this skill

  • SKILL.md10.3 KB
  • cross-review.md4.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.