home / skills / tkersey / dotfiles / tk

tk skill

/codex/skills/tk

This skill applies the TK software surgery protocol to produce a minimal, correct patch by contract, invariants, and a focused incision.

npx playbooks add skill tkersey/dotfiles --skill tk

Review the files below or copy the command above to add this skill to your agents.

Files (3)
SKILL.md
18.7 KB
---
name: tk
description: "Software surgery protocol for proof-backed, minimal-diff implementation: Contract to Invariants to Creative Frame to inevitable incision to Proof. Use when users say \"run $tk\", \"patch-first\", \"keep the diff small\", \"state contract + invariants\", \"one clear incision\", \"fix it with a validation signal\", or orchestration cues like \"workers use $tk\" / \"internally use $tk\"."
---

# TK (Surgeon's Principle)

## Platonic Ideal
Software surgery as inevitability: find the stable boundary, refine to valid states, derive behavior from composable operations, and integrate with minimal collateral—leaving code whose purpose is self-evident.

## Intent
TK is a task-to-incision protocol for writing the *fundamental expression* of a change:
- The contract and invariants determine the code.
- The patch is as small as correctness allows, and obviously correct.
- Cleverness is allowed only when it reduces risk and branching.
- Creativity is deliberate: once seams are named, use reframing + techniques to explore cuts before choosing the incision.

TK optimizes for:
- Correctness: illegal states are unrepresentable (or rejected at the boundary).
- Cohesion: one clear place where the rule lives.
- Reviewability: a diff you can trust without heroics.
- Durability: the next change becomes cheaper (within the blast radius).

## Double Diamond fit
TK is the converge-heavy half of Double Diamond:
- Discover: establish the proof signal and read for the cut.
- Define: write Contract + Invariants (hard gate).
- Develop: widen the cut-space via Creative Frame + (internal) tiered options.
- Deliver: cut the incision and run Proof.

If the work is still in Discover/Define uncertainty (needs options/tradeoffs, stakeholder alignment, or competing constraints), invoke `creative-problem-solver` first, then return to TK with a chosen tier and success criteria.

## What TK Outputs (and only this)
TK has two modes.

Output order is fixed. Do not lead with a Summary.
If you must summarize, place it inside **Incision** as the change summary.

Output-contract precedence (required):
- If a higher-priority instruction requires strict artifact output (for example one fenced `diff` block, one `NO_DIFF:` line, or strict JSON), follow that outer contract.
- In strict-output contexts, run TK internally (Contract, Invariants, Creative Frame, Why This Solution) and emit only the required external artifact.
- Do not treat invocation text alone (`$tk` inside prompts/wrappers) as proof that TK output format was executed.

Advice mode (no code change requested):
- Output exactly: Contract, Invariants, Creative Frame, Why This Solution.

Implementation mode (code change requested):
- Output: Contract, Invariants, Creative Frame, Why This Solution, Incision, Proof.
- Incision is the code change you made: minimal diff, meaningful changes, no churn.
  - Report it as an excellent change summary (not a diff):
    - Lead with the meaningful changes (behavior/invariants/API/tests), not a file inventory.
    - Include file paths and key identifiers only as anchors when they improve reviewability.
    - Use a file-by-file list only if the change is sprawling or the reader needs a map.
    - Include tiny excerpts only when they clarify something non-obvious (signatures or <= ~15 lines), fenced with a language tag.
  - You may use `git diff --stat` / `git diff --name-only` to build the summary. Do not paste diff output unless explicitly required by system/user instructions; if required, add a **Patch** section after **Proof**.
- Proof includes at least one executed signal (test/typecheck/build/run).
  - If execution is impossible: give exact commands and define "pass".
- If blocked on requirements: output Contract, Invariants, Creative Frame, Why This Solution, Question (no Incision/Proof yet).

Template compliance (order is mandatory):
- Contract → Invariants → Creative Frame → Why This Solution → Incision → Proof (default mode).
- Strict-output override: follow the required external artifact format and keep TK sections internal.
- If blocked: Contract → Invariants → Creative Frame → Why This Solution → Question.

**Contract**
- One sentence: what “working” means (include success criteria / proof target when possible).

**Invariants**
- What must remain true; what becomes impossible.

**Creative Frame**
- Reframe: <Inversion / Analogy transfer / Constraint extremes / First principles>
- Technique: <one named technique (e.g., Lotus blossom / SCAMPER / TRIZ)>
- Representation shift: <one sentence (or “N/A: no shift needed”)>

**Why This Solution**
- Argue inevitability: name the stable boundary, rule out at least one smaller and one larger tier, and state the proof signal.

Everything else (full portfolio, scorecards, scope fence, refactors) happens internally unless the user asks for options/tradeoffs (or you're blocked and must surface the portfolio).

## Brownfield defaults (legacy / gnarly)
These biases keep TK effective in brownfield codebases.

- Minimize surface area: no formatting churn; no renames unless required; touch the fewest files that can enforce the invariant.
- Seams before surgery: if the knot is hard to test, cut a seam (adapter/extract function/interface) and move the change there.
- Characterization over speculation: if behavior is unclear, add a characterization test/script; let it leash the change.
- Prefer adapters: refine at the boundary (parse/normalize); keep the core small and boring.
- Complexity first aid: flatten -> rename -> extract (then change behavior).
- Observability when uncertain: add the smallest temporary signal (assert/log); delete once proof exists.

## Greenfield defaults (new code)
These biases keep TK effective when you control the shape.

- Start with the boundary: define inputs/outputs; enforce invariants at construction (types/smart constructors) or parse/normalize at the edge.
- Compose a small core: keep effects at the boundary; keep the core pure/total when reasonable.
- Prefer a normal form: pick one canonical representation early; collapse cases to delete branching.
- Defer abstraction until it earns itself: prefer small duplication over a wrong framework.
- Bake in a proof signal: add the smallest fast test/check that makes the contract executable.

## Execution (required in Implementation mode)
- Gate: no code until Contract + Invariants are written.
- Choose the fastest credible proof signal you can actually run (existing unit test > typecheck > targeted script > integration test).
- Cut the incision at the stable boundary; avoid scattering checks through callers.
- Close the loop: run the proof signal; iterate until it passes; report the result.
- In wave-oriented execution paired with `$fix`, a wave is done only after `$tk -> $fix -> validation` and immediate delivery:
  - `commit_first`: run `$commit` for that wave.
  - `patch_first`: run `$patch` for that wave (no in-wave commit).
- If blocked on requirements: ask one targeted question with a recommended default; do not cut the incision yet.
- If still blocked: reveal the 5-tier portfolio (signal + escape hatch per tier) and ask the user to pick a tier.

Implementation non-negotiables:
- No pretend proofs: never claim PASS without an executed signal; if you can't run it, say so.
- No dependency adds without an explicit ask.
- No shotgun edits: if the diff starts spreading, cut an adapter/seam instead.
- Do not finalize a wave artifact (`$commit`/`$patch`) before `$fix` closes the wave with a passing signal.
- If a patch/diff is required by instructions, include it under **Patch** after **Proof** in default mode.
- In strict-output worker mode, keep TK sections internal and emit only the required external artifact contract.

## The TK Loop (how inevitability is produced)
TK is not a style; it’s a reduction process:
1. **Establish a proof signal**: pick the fastest credible local check (typecheck/test/log/law/diagram) you can run.
2. **Read for the cut**: locate where the meaning lives; name the seams.
3. **State the contract**: make “working” testable in principle.
4. **Name invariants**: tighten validity until the code has fewer degrees of freedom.
5. **Reframe + run a technique (Lotus blossom default, internal)**: generate a 5-tier portfolio (proof signals + escape hatches).
6. **Select the most ambitious safe tier**: bias toward Transformative/Moonshot, stay pragmatic.
7. **Cut the incision**: minimal diff at the stable boundary.
8. **Close the loop**: run the proof signal.

Double Diamond mapping:
- Discover: 1-2
- Define: 3-4
- Develop: 5-6
- Deliver: 7-8

## Doctrine (the few rules that do most of the work)

### 1) Contract first
- Restate “working” in one sentence.
- Prefer an executable contract (test/assert/log), but don’t force new harnesses.
- If the contract is product-sensitive or ambiguous: stop and ask.

### 2) Invariants first
- Say what must always hold after the change.
- Prefer stronger protection in this order:
  1. compile-time/construction-time (types, smart constructors)
  2. boundary parsing/refinement (parse, don’t validate)
  3. tests/assertions
  4. diagnostic logs as a last resort
- If the invariant is only in a comment, it isn’t real yet.

### 3) Structure over branching
- Don’t add a branch when a type can encode the distinction.
- Don’t scatter validation when one boundary parse can refine the value.
- Don’t add flags/conditionals when a normal form collapses cases.

A good sign you’re near the inevitable solution:
- the “impossible” branches disappear,
- and the remaining code reads like a direct statement of the rule.

### 4) Composition beats control-flow sprawl
Use the math, not the sermon:
- Make transformations small and composable.
- Push effects (IO, async, globals) to the boundary.
- Treat refactors as behavior-preserving structure changes; prove with existing tests.

### 5) Minimal incision
- Prefer the smallest change that could be correct.
- If uncertainty is high, cut **observability** first (a tight repro/test/log), then behavior.

## Guardrails (internal, required)
These rules keep “inevitability” from becoming scope creep.

- **Scope fence (YAGNI)**: list explicit non-goals; avoid roaming refactors; ask before widening scope.
- **Dialect fit**: follow the repo’s conventions for naming, errors, tests, and architecture; don’t import a framework to prove a point.
- **Proof signal**: run at least one credible local check; don’t declare done without it.
- **Total depravity (defensive constraints)**: assume human/agent attention fails; prefer tool-checked constraints over doc-only contracts; keep proofs with values (refined/validated types) instead of separate booleans.
- **No in-band signaling**: avoid sentinel values (`-1`, `null`, `""`, `NaN`); return explicit option/result/enum states that force handling.
- **Semantic tags for domains**: distinguish IDs, units, and environments with dedicated types/wrappers; never mix same-primitive values.
- **Raw vs validated separation**: keep untrusted inputs and validated data as different types; parse/normalize at boundaries; never mix.
- **Resource lifetime**: use scoped/RAII/with-style APIs to guarantee cleanup on all paths.
- **Evidence before abstraction**: require 3+ concrete instances; capture variance points (mini evidence table); prefer duplication to a wrong abstraction.
- **Seam test for abstractions**: callers stay ignorant of variants; one-sentence behavioral name; new instance fits without flags—otherwise shrink it.
- **Seams before rewrites**: if the right fix requires cutting a hard-to-test knot, add a seam and move the change to the seam.
- **Legibility (TRACE)**: guard clauses over nesting; flatten → rename → extract; delete incidental complexity.
- **Footgun defusal (API changes)**: identify likely misuses; make misuse hard via names/types/ordering; lock with a regression check.
- **Break-glass scenario (abstraction escape hatch)**: name the next likely change that would make it harmful; if it happens, inline into callers, delete dead branches, then re-extract the core.

## “Big refactor” vs “stay close” (pragmatic ambition)
TK always wants the Transformative/Moonshot answer, but earns it.

Default bias:
- **Transformative in shape, conservative in blast radius**.
  - Example: create a small algebraic island / refined domain type,
  - integrate through existing seams,
  - avoid repo-wide rewrites.

Escalate from a small patch to a transformative cut when a small patch would:
- scatter checks for the same rule across multiple sites,
- add another boolean/flag branch to an already-branchy flow,
- require shotgun edits (the boundary is wrong),
- fix a symptom but keep the bug-class alive,
- or make the “why” unexplainable without hand-waving.

Moonshot is permitted when it is:
- incremental (strangler-style),
- reversible (feature flag, adapter, fallback),
- and provable (an equivalence check, a law check, or a deterministic characterization test).

If moonshot is inevitable, proceed autonomously *only* via incremental cuts.

## Internal 5-tier portfolio (required, not displayed)
Always generate these five options before choosing an incision. Keep them internal unless asked for options/tradeoffs.

If entering from `creative-problem-solver`, treat its five-tier portfolio as this internal portfolio; regenerate only if new facts/constraints appear.

After you’ve named the stable boundary/seams and written the contract/invariants, force a creative search across the cut-space.

Creative frame (required):
- Reframe used: Inversion / Analogy transfer / Constraint extremes / First principles.
- Technique used: pick one technique (see references/creative-techniques.md) to generate non-obvious options.
- Representation shift: one sentence describing the model/representation change (or “N/A: no shift needed”) that makes the choice feel forced.
  - If still unclear: pick a different reframe + technique, then regenerate the portfolio.

Tier details, technique picker, and Lotus blossom expansion: references/creative-techniques.md.
Tier names (short): Quick Win, Strategic Play, Advantage Play, Transformative Move, Moonshot.

## Algebra (quietly)
Only use algebraic framing when it reduces branching or makes proofs cheaper.

Minimal guide (jargon allowed only when it buys precision):
- Variants/alternatives → a tagged union / sum type.
- Independent fields → a record / product type.
- Combine/merge with identity → a monoid (or “combine + neutral element”).
- Canonicalization → a normal form + idempotence check.

If you introduce a combine/normalize/map operation, add one executable behavioral check:
- round-trip, idempotence, identity, associativity, or a commuting diagram check.

## Examples
Canonical examples + full exemplars: references/tk-exemplars.md.

## Be like mike (behavioral bar)
TK is calm execution under constraints.

### Practice
- Work in small vertical slices you can exercise end-to-end.
- Prefer fast feedback loops (focused test/typecheck/log) over speculation.

### Composure
- Say the invariant out loud before cutting.
- When requirements are unclear: stop and ask, don’t guess.

### Finish
- Close the loop: run at least one credible proof signal.
- Leave a clean diff: no debug scaffolding, no incidental edits.

### Excellence
- Prefer types + laws over branching + comments.
- Aim for code legible in 30 seconds and durable for 2 years.

## Micro-glossary
- **Contract**: the promised behavior, stated succinctly.
- **Invariant**: what must always hold; enforced by types/tests/boundaries.
- **Incision**: the smallest correct patch.
- **Boundary (stable boundary)**: the interface where validity/effects enter; prefer enforcing the rule once here.
- **Seam**: an enabling point to substitute/redirect behavior safely.
- **Creative Frame**: the reframe + technique + representation shift used to widen the cut-space after seams are named.
- **Lotus blossom**: breadth-first ideation: center the boundary/contract, expand 8 TK-native petals, then turn petals into candidate incisions.
- **Proof signal**: the concrete check that makes the change trustworthy (test/typecheck/log/law/diagram).
- **Normal form**: a canonical representation used to simplify rules and comparisons.
- **Algebraic island**: a small compositional core (refined types + operations + one law/diagram check) integrated via adapters.
- **Representation shift**: a one-line model/representation change (or explicit N/A) that makes the incision feel forced.

## Deliverable format (chat)
Advice mode (no code changes): output exactly:

**Contract**
- <one sentence>

**Invariants**
- <bullet list>

**Creative Frame**
- Reframe: <Inversion / Analogy transfer / Constraint extremes / First principles>
- Technique: <one named technique (e.g., Lotus blossom / SCAMPER / TRIZ)>
- Representation shift: <one sentence (or “N/A: no shift needed”)>

**Why This Solution**
- Stable boundary: <where the rule belongs and why>
- Not smaller: <why at least one smaller-tier cut fails invariants>
- Not larger: <why at least one larger-tier cut is unnecessary or unsafe today>
- Proof signal: <what test/typecheck/log/law/diagram check makes this trustworthy>
- (Optional) Reversibility: <escape hatch / rollback lever>
- (Optional) Residual risk: <what you still don’t know>

Implementation mode (code changes): output exactly:

**Contract**
- <one sentence>

**Invariants**
- <bullet list>

**Creative Frame**
- Reframe: <Inversion / Analogy transfer / Constraint extremes / First principles>
- Technique: <one named technique (e.g., Lotus blossom / SCAMPER / TRIZ)>
- Representation shift: <one sentence (or “N/A: no shift needed”)>

**Why This Solution**
- Stable boundary: <where the rule belongs and why>
- Not smaller: <why at least one smaller-tier cut fails invariants>
- Not larger: <why at least one larger-tier cut is unnecessary or unsafe today>
- Proof signal: <what test/typecheck/build/run/law check makes this trustworthy>
- (Optional) Reversibility: <escape hatch / rollback lever>
- (Optional) Residual risk: <what you still don’t know>

**Incision**
- <meaningful change summary (behavior/invariants/API/tests); include file/identifier anchors only when helpful; no diffs>

**Proof**
- <commands run + one-line result (pass/fail + key line)>

**Patch** (only if required by system/user instructions)
- <unified diff or patch>

Strict-output mode (only when mandated by higher-priority instructions):
- Keep TK sections internal.
- Emit exactly the required external artifact shape (for example one fenced `diff` block, one `NO_DIFF:` line, or strict JSON).
- If the external contract disallows prose, do not add wrapper text.

If blocked (must ask before cutting):

**Question**
- <one targeted question; include a recommended default>

## Activation cues
- "tk" / "surgeon" / "minimal incision"
- "invariants" / "parse don’t validate"
- "migration" / "equivalence" / "commute"
- "workers use $tk" / "internally use $tk" / "PATCH-FIRST"

Overview

This skill codifies a surgical protocol for making minimal, proof-backed code changes: Contract → Invariants → Creative Frame → Incision → Proof. It guides you to state what “working” means, tighten valid states, explore a small portfolio of approaches, apply one clear incision, and close the loop with an executable proof signal. Use it to keep diffs tiny, reviewable, and durable in both greenfield and brownfield code.

How this skill works

When invoked, the skill walks you through a fixed sequence: define a one-sentence Contract, enumerate the Invariants that must hold, apply a Creative Frame to explore candidate cuts, and recommend the inevitable incision. In implementation mode it also produces a minimal-change patch and a Proof (a test/typecheck/run) that can be executed. It enforces no code until contract and invariants are stated and biases toward smallest effective surface area.

When to use it

  • You want the smallest correct patch that’s easy to review and reason about.
  • You need to make illegal states impossible or rejected at the boundary.
  • You must ship a change with a concrete, executable proof signal.
  • You face a legacy knot and want to add a seam before changing behavior.
  • You want to avoid shotgun edits, sprawling diffs, or hidden branchiness.

Best practices

  • State the Contract in one sentence before any code changes.
  • Protect invariants as early as possible (types/smart constructors → boundary parsing → tests).
  • Touch the fewest files required; prefer adapters/seams over repo-wide rewrites.
  • Pick the fastest credible proof signal you can actually run and iterate until it passes.
  • If uncertain, add a tight characterization test or temporary observability signal first.

Example use cases

  • Normalize a parsed ID at the API boundary so downstream code never sees invalid IDs.
  • Introduce a small refined type to encode mutually exclusive cases and remove branching checks.
  • Patch a bug by adding a single validation and a unit test that captures the invariant.
  • Extract an adapter around an untestable module, then change behavior inside the adapter.
  • Convert brittle sentinel-value logic into explicit enums with a short migration test.

FAQ

What counts as a valid Proof?

Any executed signal that demonstrates the Contract: an existing unit test passing with the change, a typecheck, a focused script run, or a small integration check. If it cannot be executed, explicit commands and a clear pass criterion must be provided.

How big can the incision be?

Prefer the minimal diff that enforces the invariant. Escalate only when a small patch would scatter checks, add branchiness, or leave the bug class alive; even then, make the cut incremental and reversible.

Do I need to surface all creative options?

The skill generates a five-tier internal portfolio but reports only the chosen Creative Frame and rationale unless you ask for options/tradeoffs.