Opinionated multi-model delegation for very large repos.
Use to turn a big-repo change into a parallel execution plan: decomposes work into disjoint, dependency-layered lanes, each file-scoped with acceptance criteria and a verification command, ready for tk-execute.
Install: npx skills add thunderock/thunderkit -s tk-plan -g
The heart of the thunderkit thesis. tk-plan takes a change and produces a plan whose unit is the lane: a disjoint, file-scoped slice of work that can run *in parallel* with its siblings without collision, ordered into dependency layers. A plan that can't be split into lanes is not finished here — that's the opinion this skill enforces.
Preferred model: Opus 4.8 (planning is load-bearing — bad lanes cost the whole run). This is one of the choices tk-router should offer the user (Opus 4.8 / Opus 5). See ../references/model-roster.md. Read .thunderkit/MAP.md from tk-map first.
what makes parallel execution safe. If two slices need the same file, they belong in different *layers*, not the same layer.
intra-plan dependencies and start immediately.
tk-review runs to gate the lane. No command → the lane is blocked, not plannable.
.thunderkit/PLAN.md + .thunderkit/plan.jsonHuman-readable PLAN.md and a machine-readable plan.json that tk-execute consumes:
{
"goal": "one-line change description",
"layers": [
{
"layer": 0,
"lanes": [
{
"id": "L0-auth-token-refresh",
"files": ["src/auth/token.rs", "src/auth/token_test.rs"],
"depends_on": [],
"acceptance": "token refresh retries 3x with backoff; expired token triggers refresh",
"verify": "cargo test -p auth token::",
"model_hint": "critical-path"
}
]
}
]
}
tk-map.MAP.md so lanes fall on realmodule edges and file scopes genuinely don't overlap.
slice that needs another's output in a later layer.
A lane with no runnable verify is blocked — record why and what's needed to unblock it.
tk-router knows to ask the userwhich model implements them.
a command is aspirational (test doesn't exist yet), the lane's first task is to create it.
files. If not, re-layer.verify or is explicitly blocked.model_hint for the user-choice step.serial; reconsider the seams.
If a clean disjoint decomposition isn't possible (genuinely entangled code), say so explicitly: record the entanglement, propose the least-bad layering, and flag the lanes that must run serial. Don't flatten a real dependency into fake parallelism.