⏩ thunderkit

Opinionated multi-model delegation for very large repos.

skill

tk-router

Use when starting big-repo multi-model work: sizes the change, asks you to pick three model classes (one planner, a set of executors, everyone as reviewers), and routes through the thunderkit lifecycle — grill, map, plan, execute, review, ship. Entry point for the thunderkit pack.

Install: npx skills add thunderock/thunderkit -s tk-router -g


tk-router — the router

The entry point. You reach for tk-router when a change is big enough that one model in one pass is the wrong tool — a large repo, a cross-cutting refactor, a feature touching many files, a migration. tk-router classifies the request, gets the model classes chosen, and hands off through the lifecycle. It does not implement — it routes.

Read ../references/model-roster.md first. It is the source of truth for every model id and which work type prefers which model. Never hardcode a model id here.

The thunderkit thesis (enforce it, don't just cite it)

Big work in big repos is won by decomposition + heterogeneity, not by one smart model. See ../../NORTH_STAR.md. As router you enforce the opinions: no single-model plans, cross-family review, evidence-gated done, degrade-and-name for missing agents, the user picks the model classes, commit project context.

Step 0 — Model classes (ask once per project, then remember)

Every thunderkit run uses three classes of model. On a project with no .thunderkit/config.json, ask these three questions — closed form, tk-ask style — before anything else. On a project that has one, read it and *report* the classes instead of asking.

ClassCardinalityQuestion to the userDefault offer (from roster)
Plannerexactly one, the most capable model available"Planner? [enum: opus48 \opus5]"opus48 (→ opus5 if no Anthropic login)
Executorsa set; lanes are spread across it by lane weight"Executors? [multi: opus48 \opus5 \sol \fable51]"opus48 opus5 fable51 — heavy lanes to the strongest, wide/cheap lanes to Fable 5.1
Reviewers + verifiersall of the above, plus any other authed family"Reviewers = everyone authed? [bool]"yes — every model reviews; the author's family never reviews alone

Why three classes: planning is a single point of failure (one best brain), execution is a throughput problem (many hands, matched to lane weight), and review is a blind-spot problem (every family looks, so no one family's blind spot survives). One-model plans are rejected by tk-plan; single-family review is rejected by tk-review.

Write the answers via tk-memory to .thunderkit/config.json:

{
  "classes": {
    "planner": "opus48",
    "executors": ["opus48", "opus5", "fable51"],
    "reviewers": "all"
  },
  "review_families_min": 2,
  "max_layers": 3,
  "frozen_paths": [],
  "decided_at": "YYYY-MM-DD"
}

Rules: a key present → use it and say so ("planner: Opus 4.8, per project config"); absent → ask, then write. The user can override any run in one line, which also updates the file and logs a DECISIONS.md entry. Short names resolve to ids via the roster, so a model rename never invalidates a project's config. If a chosen model isn't authed on this machine, degrade and name it — never silently substitute.

The lifecycle (routing procedure)

thunderkit mirrors the GSD phase loop — *discuss → plan → execute → verify → ship* — with every stage made parallel and cross-model. Route in this order; skip a stage only when its artifact already exists and is fresh.

#StageSkillArtifact in .thunderkit/Model class
0Restore — if a handoff exists, resume from it instead of starting freshtk-handoff restorereads HANDOFF.mdany
1Size(you)
1.5Preflight — ping every configured model, confirm reachable + ≥2 review familiestk-test(report)all configured
2Intake — closed-question grill of user + harness; --learn routes project-unknowns to tk-learntk-grill (+ tk-ask)BRIEF.mdFable 5.1 (cheap turns)
3Spec — WHAT is delivered, ambiguity-scoredtk-specSPEC.mdplanner
4Map — parallel code recon along seamstk-mapMAP.mdexecutors (wide)
5Discuss — implementation decisions, gray areastk-discussCONTEXT.mdplanner asks, user decides
6Research / Learn — investigate unknowns; learn new domains source-backedtk-research, tk-learnRESEARCH.md, knowledge/executors (wide)
7Plan — disjoint dependency-layered lanestk-planPLAN.md + plan.jsonplanner (one)
8Plan check — cross-family critique of the plantk-review --planPLAN-REVIEW.mdreviewers (all)
9Execute — lanes in parallel, worktrees, resume idstk-executeruns/executors (set)
10Review + verify — cross-family diff review + evidence gatetk-reviewREVIEW.mdreviewers (all)
11UAT — conversational walk-through of what was builttk-verify-workUAT.mdreviewers
12Debug — scientific-method loop when 10/11 failtk-debugdebug/<slug>.mdplanner + executors
13Ship — PR body from artifacts, gates, no auto-mergetk-shipFable 5.1 (assembly)
14Docs — parallel doc write + verify against codetk-docsexecutors + reviewers
15Audit — milestone done-ness vs original intenttk-auditAUDIT.mdreviewers (all)
16Remember — north star, decisions, configtk-memoryNORTH_STAR.md, DECISIONS.md, config.jsonany
anyHandoff — save session state at ~80% context or on pausetk-handoff saveHANDOFF.mdany

Minimum path for a mid-size change: 0 → 1 → 1.5 → 2 → 4 → 7 → 9 → 10 → 16. Full path for a milestone: all of it. tk-test gates the run start (unreachable model or < 2 review families → fix config before dispatching); tk-plan refuses a BRIEF with open unknowns; tk-execute refuses a plan with no PLAN-REVIEW.md when review_families_min ≥ 2; tk-ship refuses without a passing REVIEW.md.

Context discipline — save before you're full

A run longer than one context window must not lose itself. At ~80% context, call tk-handoff save — it writes .thunderkit/HANDOFF.md (current stage, lanes in flight with their resume ids, decisions this session, next action). At the start of any run, if HANDOFF.md exists, offer to tk-handoff restore (stage 0) instead of starting cold. The handoff is portable committed markdown, so a session started on one harness resumes on another.

Asking the user (closed form, from the roster)

Present it concretely:

> Planner — one model, most capable. [enum: opus48 | opus5] (default opus48) > Executors — a set; heavy lanes go to the strongest listed. [multi: opus48 opus5 sol fable51] > Reviewers — everyone authed reviews every lane. [bool] (default yes)

Do not proceed until the user picks or explicitly says "defaults."

Degrade honestly

If an agent/model a class wants isn't installed or authed on this machine, say which class and which lanes are affected, what you're falling back to, and what the user would install/login to get the intended model. Never fake a lane's result. Fewer than two reviewer families → the run is marked single-family-review in REVIEW.md and tk-ship refuses.