agentleFS
mhyllemhylle/claude-skills-collection/skills/tt-create-plan/SKILL.md

tt-create-plan

Skill20 starsChanged 36 days agoMITView on GitHub

Tasktracker-native implementation planning. Turns a /brainstorm file from docs/brainstorms/ (or a clear requirement) into a phased plan persisted as tasktracker phase tasks — NOT as a docs/plans/*.md file. Creates requirements with formal acceptance criteria, registers architecture components, generates phases via createPhaseFromTemplate, links every task back to its requirement, and uses getProjectReadiness as the completion gate. Use whenever the user wants to plan, design, or scope an implementation AND the work is (or will be) tracked in tasktracker: "tt create plan", "plan this in tasktracker", "/tt-create-plan", or any plan-creation request inside a session that already has a tasktracker active task or project. Prefer this over the plain /create-plan skill whenever a tasktracker MCP is available — the resulting phase tasks integrate with /tt-implement-plan and /implement-phase, so picking the file-based variant in a tasktracker project just creates orphan markdown.

The file

Show its rules and text

We split this skill into the rules it gives an agent

20 rules. About 0 are common, 15 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈15

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    If the user is not using tasktracker, use /create-plan instead.

    line 65
  2. Distinctive:

    If the user passed a path, use that file.

    line 99
  3. Very specific:

    If the project already has a frozen TaskTracker brainstorm (tasktracker_listBrainstorms({projectId, status: "frozen"})), you may read it …

    line 101
  4. Very specific:

    Check its status: If the file says Status: Needs More Exploration, or its "Ready for Planning" section says No, tell the user what it lists …

    line 104
  5. Distinctive:

    Map it to the plan: Read the whole file, including Session History when the brainstorm was continued, then:

    line 106
  6. Distinctive:

    Update the requirements-lifecycle phase task to completed when satisfied, then activate the architecture-lifecycle phase task.

    line 158
  7. Distinctive:

    When done, complete the architecture-lifecycle phase and activate the plan-lifecycle phase task.

    line 192
  8. Distinctive:

    Don't skip this just because tasktracker is in the loop.

    line 196
  9. Distinctive:

    Wait for user approval before writing phases.

    line 211
  10. Distinctive:

    Prefer more small phases over fewer large ones.

    line 234
  11. Very specific:

    If none of the templates fit, use createTask({type: "phase"}) and add sub-tasks manually — but first ask whether the phase really doesn't …

    line 248
  12. Distinctive:

    Every phase's description (set at creation, never edited later — see "Locked phase body" below) MUST include:

    line 283
  13. Distinctive:

    ADR reference: if a design decision was recorded.

    line 290
  14. Distinctive:

    Tests before implementation: When seeding sub-tasks, put the test sub-task BEFORE the implementation sub-task.

    line 295
  15. Distinctive:

    If you ever find yourself wanting to update a phase body during implementation, that's the mistake the lock catches — pivot to a sub-task.

    line 308
  16. Very specific:

    All four rows should now read satisfied (the brainstorm row may carry an "optional" or "deliberately skipped" note, per the project's …

    line 316
  17. Distinctive:

    Every phase MUST have:

    line 330
  18. Distinctive:

    Thorough: read entire files, follow import chains.

    line 365
  19. Distinctive:

    Skeptical: when the user corrects you, verify through code investigation rather than accepting at face value.

    line 367
  20. Distinctive:

    Do not seed phases with "TBD" or open questions in their description.

    line 371

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

tt-create-plan

<!-- contents: generated by tests/skill_structure.py --write; edit headings, not this block -->

Contents

  • How this differs from /create-plan
  • Workflow
    • Step 0: Establish project + lifecycle context (MANDATORY)
    • Step 1: Ingest the brainstorm
    • Step 2: Requirements (with formal acceptance criteria)
    • Step 3: Architecture (register the structural pieces)
    • Step 4: Present design options (Phase 4 from /create-plan, kept)
    • Step 5: Document the decision (ADR)
    • Step 6: Propose phase structure (get approval before creating)
    • Step 7: Create the phases (and link to requirements)
    • Step 8: Embed verification approach in each phase
    • Step 9: Locked phase body (a hard rule)
    • Step 10: Verify readiness and hand off
  • Verification-first planning (kept from /create-plan)
  • Be thorough, interactive, skeptical (kept from /create-plan)
  • No unresolved questions
  • Anti-patterns to avoid
  • Quality checklist
  • Resources
    • references/
    • Related tasktracker skills

Reference files (open one when a step points to it):

  • references/exit-conditions.md: Exit Condition Templates by Project Type
  • references/lifecycle-cheatsheet.md: Tasktracker Lifecycle Cheatsheet
<!-- /contents -->

Tasktracker-native implementation planning. Walks the four lifecycle stages (brainstorm → requirements → architecture → plan) and lands the plan as phase tasks in tasktracker, with each task linked to the requirement it implements and architecture components registered for the structural pieces. No docs/plans/*.md file is written — the plan is the task tree.

How this differs from /create-plan

/create-plan/tt-create-plan (this skill)
Outputdocs/plans/YYYY-MM-DD-*.md file + TasksPhase tasks in tasktracker (no file)
RequirementsFree text under "Context"First-class Requirement rows with AcceptanceCriterion
ArchitectureImplicit, narrativeArchitectureComponent + ArchitectureRelationship rows
Phase scaffoldingHand-written checklistscreatePhaseFromTemplate with rituals embedded
Phase bodyEditable markdownLocked once children exist (immutable scope contract)
Progress gateTaskListgetProjectReadiness per lifecycle stage
Plan/spec separation"checkboxes in markdown"Spec on phase task, progress on sub-tasks

If the user is not using tasktracker, use /create-plan instead.

Workflow

Step 0: Establish project + lifecycle context (MANDATORY)

1. tasktracker_listProjects({search: "<topic-keywords>"})
   - Use the user's words. The most common failure mode is creating a
     duplicate project because you couldn't find the existing one.
   - If the brainstorm file names a project, use that one.

2. tasktracker_getProjectReadiness({projectId})
   - This 4-row table is the ground truth for "what stage are we in".
   - Note the `brainstorm` row; Step 1 settles it when it isn't
     satisfied. Don't paper over a missing brainstorm; the requirements
     end up shaky.

3. tasktracker_getPrinciples({projectId, includeGlobal: true})
   - Surface conflicts before design, not after.

4. Find the first non-satisfied lifecycle phase task and
   tasktracker_setActiveTask(<that-task-id>).
   That is the brainstorm-lifecycle phase when its row isn't satisfied,
   otherwise usually the requirements-lifecycle phase. setActiveTask
   folds principles + acceptance criteria + the hierarchical requirement
   link into the digest you'll work from.

Step 1: Ingest the brainstorm

The upstream is a /brainstorm file, docs/brainstorms/YYYY-MM-DD-<topic-slug>.md. Look for one even when the brainstorm row is already satisfied; it is where the requirements come from.

Find it.

  • If the user passed a path, use that file.
  • Otherwise list docs/brainstorms/ and take the most recent file whose title or slug matches the topic. If several match, pauseActiveTask and ask the user which one to plan from.
  • If the project already has a frozen TaskTracker brainstorm (tasktracker_listBrainstorms({projectId, status: "frozen"})), you may read it too with tasktracker_getBrainstorm({brainstormId, verbosity: "fat"}); treat its chosen decisions like Key Clarifications.
  • No brainstorm anywhere and the row isn't satisfied: stop and offer two ways on — run /brainstorm first, or, if the user confirms the requirement is already clear, plan from that requirement with the brainstorm stage marked as skipped (below). Don't pick for them; the requirements end up shaky without one.

Check its status. If the file says **Status**: Needs More Exploration, or its "Ready for Planning" section says No, tell the user what it lists as unsettled and suggest another /brainstorm <file> session first. Plan from it only if the user says to go ahead.

Map it to the plan. Read the whole file, including Session History when the brainstorm was continued, then:

Brainstorm sectionBecomes
Key Clarifications, Refined Understanding, Ready for Planning → Suggested Plan ScopeCandidate requirements (Step 2). What the scope leaves out stays out.
Risks & ConcernsAn acceptance criterion where the mitigation is testable; otherwise a risk note in the requirement's description
GapsQuestions to resolve before any phase is created (see "No unresolved questions")
Research Findings → Codebase ContextInput for architecture (Step 3) and design options (Step 4)
Parking LotOut of scope; no requirements

Get the brainstorm row satisfied. Readiness counts that row satisfied for a frozen or promoted TaskTracker brainstorm, or through the project's brainstormPolicy; a brainstorm file alone doesn't count. When the row isn't satisfied and you are planning from a file:

tasktracker_updateProject({projectId, brainstormPolicy: "optional"})
# "optional": a project with no TaskTracker brainstorm reads as satisfied.

tasktracker_updateTaskStatus({
  taskId: "<brainstorm-lifecycle phase id>",
  status: "completed",
  version: <version from tasktracker_getTask>,
  note: "Brainstorm: docs/brainstorms/<file>.md"
})

When the user chose to plan from a clear requirement with no brainstorm, use brainstormPolicy: "skipped-deliberately" instead and say why in the note. Re-run getProjectReadiness. If the row is still not satisfied, the project has a draft TaskTracker brainstorm; show it to the user and ask whether to freeze it or set skipped-deliberately. Then setActiveTask on the requirements-lifecycle phase task.

Step 2: Requirements (with formal acceptance criteria)

For each capability the user wants in scope:

tasktracker_createRequirement({
  projectId,
  title: "<short verb-phrase title>",
  description: "<who needs this and why; cite the brainstorm file
                and section where applicable>",
  priority: "low" | "medium" | "high" | "urgent"
})
# Capture the returned requirementId.

# Add acceptance criteria — at least one per requirement. Use
# Given/When/Then form. Each criterion is independently verifiable.
tasktracker_addAcceptanceCriterion({
  requirementId,
  statement: "Given <context>, when <action>, then <observable outcome>"
})

Lifecycle gate: the requirements row in readiness flips to satisfied only when at least one requirement has criteria AND is past draft. Status defaults to draft; usually leave it there and let the lifecycle trigger promote it on approval.

Prefer /user-story for non-trivial requirement decomposition. It generates an epic → feature → task hierarchy with Given/When/Then criteria already in formal shape, and writes through these same MCP calls.

Update the requirements-lifecycle phase task to completed when satisfied, then activate the architecture-lifecycle phase task.

Step 3: Architecture (register the structural pieces)

Implementation will touch things. Register them.

# One call per component (service, module, table, page, agent, etc.)
tasktracker_createArchitectureComponent({
  projectId,
  name: "<canonical name>",
  kind: "service" | "module" | "table" | "page" | "agent" | ...,
  description: "<what this component does>"
})

# One call per directed relationship (depends-on, calls, writes-to, etc.)
tasktracker_createArchitectureRelationship({
  projectId,
  sourceComponentId,
  targetComponentId,
  kind: "<edge type>",
  description: "<one-line>"
})

# Optional but recommended for non-trivial systems:
tasktracker_createArchitectureDiagram({
  projectId,
  name: "<title>",
  body: "<mermaid or plain text>"
})

Lifecycle gate: the architecture row flips to satisfied when at least one component exists. Don't over-register — pick the structural pieces the plan will actually create or modify.

When done, complete the architecture-lifecycle phase and activate the plan-lifecycle phase task.

Step 4: Present design options (Phase 4 from /create-plan, kept)

Don't skip this just because tasktracker is in the loop. The MCP doesn't substitute for design thinking.

Option A: [Approach Name]
- Description: [How it works]
- Pros: [Benefits]
- Cons: [Drawbacks]
- Fits pattern: [Reference to existing codebase patterns / components]

Option B: [Alternative Approach]
- ...

Recommendation: [Preferred option with rationale]

Wait for user approval before writing phases.

Step 5: Document the decision (ADR)

For any non-trivial design choice, invoke the /adr skill. ADRs live in docs/decisions/ (this is one of the few cases where file output is correct — ADRs are repository artifacts, not project lifecycle state). Cross-reference: add the ADR number into the chosen design option's record on the relevant architecture component or in the phase task description below.

Step 6: Propose phase structure (get approval before creating)

Present the proposed phases as plain text first. The user may want to add/remove/reorder.

Proposed Implementation Phases:

Phase 1: [Name] — [one-line objective] — template: backend-feature
Phase 2: [Name] — ... — template: schema-migration
Phase 3: [Name] — ... — template: ui-fix
...

Phase granularity:

  • One concern per phase. Touches two unrelated subsystems → split.
  • Think in layers: foundation → data → core → API → integration → polish.
  • Each phase must be demonstrably working when complete.
  • Prefer more small phases over fewer large ones.

Template selection — createPhaseFromTemplate saves the canonical sub-task triplet for common shapes. Pick the closest fit:

TemplateSub-tasks seededUse when
backend-featureDesign + decision, Implement, Tests, Deploy verifyAdding/modifying a backend capability
ui-fixReproduce, Fix, VerifyUI bug or UI tweak with a clear repro
refactorMap current shape, Refactor, Regression verifyCode shape change with no behaviour change
schema-migrationMigration, Wire-up, Tests, Deploy verifyDB schema change
bug-investigationReproduce, Root-cause, Fix, Verify + documentUnknown-cause bug
docs-onlyEdit, Verify-renders-and-commitPure documentation phase
data-housekeepingSurvey + snapshot, Operate via MCP (no raw SQL), Verify + log learningData migration, archive, merge

If none of the templates fit, use createTask({type: "phase"}) and add sub-tasks manually — but first ask whether the phase really doesn't fit a template, or whether it's actually two phases bundled together.

Get explicit approval before creating tasks.

Step 7: Create the phases (and link to requirements)

For each approved phase:

# Either: template-based (preferred when it fits)
tasktracker_createPhaseFromTemplate({
  projectId,
  templateKey: "backend-feature",
  phaseTitle: "Phase N — <short title>",
  contextNote: "<optional: paste the design rationale and ADR link>"
})
# Returns the new phase task. Sub-tasks are pre-created.

# Or: ad-hoc (when no template fits)
tasktracker_createTask({
  projectId, type: "phase",
  title: "Phase N — <short title>",
  description: "<objective + verification approach + ADR ref>",
  requirementIds: [<reqId1>, <reqId2>]   # ← link at the phase level
})
# Then sub-tasks via createTask({type: "task", parentId: <phase-id>})
# or batchCreateTasks for atomicity.

Linking requirements (Phase 73 contract). Pass requirementIds on the phase task. Sub-tasks under that phase inherit the link automatically — you don't need to repeat it on every leaf. If you create a task without a link and no ancestor has one, an advisory friction insight fires; resolve it by adding the link or by wontfix-ing if the task is genuinely link-less (infra plumbing, etc.).

linkRole — defaults to implements. Use verifies for the testing/verification sub-task explicitly when the template doesn't already encode this.

Step 8: Embed verification approach in each phase

Every phase's description (set at creation, never edited later — see "Locked phase body" below) MUST include:

  1. Verification approach — what will prove this phase works (test command, browser check, API call, etc.). Concrete, not "we'll test it".
  2. Exit conditions — all three categories:
    • Build (compile, lint, typecheck)
    • Runtime (starts, no errors, endpoint reachable)
    • Functional (tests pass, manual check passes)
  3. ADR reference if a design decision was recorded.
  4. Requirement IDs the phase implements.

See references/exit-conditions.md for per-language templates.

Tests before implementation. When seeding sub-tasks, put the test sub-task BEFORE the implementation sub-task. The default templates already do this in spirit (e.g., backend-feature has "Tests" as a distinct sub-task) but order the sequence so tests are written first.

Step 9: Locked phase body (a hard rule)

Once a phase task has any unarchived child, its description is immutable — the backend returns HTTP 422 on update. This is the immutable scope contract set at planning time, and it's deliberate.

NeedRight place
Original scope and verification approachPhase task description (write it correctly at creation; you cannot edit later)
Design rationale, decision logs, follow-up notes during implementationThe "Design + decision note" sub-task (templates seed this)
Title, priority, due date, metadata changesPhase task — these fields stay editable
Discovered scope gapNew sub-task under the phase, OR a follow-up phase

If you ever find yourself wanting to update a phase body during implementation, that's the mistake the lock catches — pivot to a sub-task.

Step 10: Verify readiness and hand off

tasktracker_getProjectReadiness({projectId})

All four rows should now read satisfied (the brainstorm row may carry an "optional" or "deliberately skipped" note, per the project's brainstormPolicy). The plan row is satisfied when concrete phases exist beyond the four lifecycle phases.

Complete the plan-lifecycle phase task. Do not auto-activate Phase 1 of the implementation — that's /tt-implement-plan's job. clearActiveTask.

Closing summary (in chat, not as a file):

  • Requirements created (count + titles).
  • Architecture components registered (count + names).
  • Phases created (count + titles + template used).
  • ADRs created.
  • Next step: /tt-implement-plan (with no path — it works from the task tree).

Verification-first planning (kept from /create-plan)

Every phase MUST have:

  1. Verification approach — clear statement of how success is measured.
  2. Tests before implementation — sub-task order shows tests first.
  3. Specific scenarios — not "write tests" but what scenarios.

Example phase description (paste at creation; cannot edit later):

Objective
- Implement password hashing + login endpoint.

Verification approach
- Unit tests: hash generation, hash comparison, invalid inputs.
- Integration test: POST /auth/login accepts valid creds, rejects invalid.
- Manual: hit endpoint with curl, confirm 200/401 contract.

Exit conditions
Build:
- npm run build succeeds
- npm run lint passes
- npm run typecheck passes
Runtime:
- npm run start starts cleanly
- POST /auth/login reachable
Functional:
- npm test -- auth passes
- Manual curl check passes

Requirements: REQ-0007 (user login), REQ-0008 (password storage)
ADR: ADR-0015 (chose bcrypt over argon2 for v1)

Be thorough, interactive, skeptical (kept from /create-plan)

  • Thorough: read entire files, follow import chains. The MCP doesn't replace reading code.
  • Interactive: get buy-in at each lifecycle boundary. The user can redirect.
  • Skeptical: when the user corrects you, verify through code investigation rather than accepting at face value.

No unresolved questions

Do not seed phases with "TBD" or open questions in their description. The phase body is locked once children exist — TBDs in there become permanent. Resolve ambiguity before phase creation:

  1. Stop. Investigate.
  2. Present options.
  3. Get resolution.
  4. Then create the phase.

Anti-patterns to avoid

  • ❌ Writing docs/plans/*.md. The plan lives in tasktracker phase tasks.
  • ❌ Creating phases before requirements exist (requirements lifecycle is upstream of plan lifecycle).
  • ❌ Linking requirements on every leaf instead of on the phase. Inheritance handles it.
  • ❌ Editing a phase description after sub-tasks exist (HTTP 422). Use a sub-task instead.
  • ❌ Skipping getProjectReadiness — it's the truth source for lifecycle state.
  • ❌ Bundling unrelated subsystems into one phase. Split.
  • ❌ Creating a new project when an existing one already covers the work. listProjects first.

Quality checklist

  • Existing project found (or /init-project was used).
  • Active task set before any tasktracker writes.
  • Principles read; conflicts flagged.
  • Brainstorm file read in full and its path noted on the brainstorm-lifecycle phase (or the brainstorm skipped, with the user's OK).
  • Each in-scope requirement has at least one Given/When/Then criterion.
  • Architecture components registered for what the plan will touch.
  • Design options presented; user picked one.
  • ADR recorded for non-trivial decisions.
  • Phase structure approved by user before creation.
  • Each phase uses the closest matching template (or is justified ad-hoc).
  • Each phase task is linked to ≥1 requirement (inheritance for sub-tasks).
  • Each phase description includes verification approach + 3 exit-condition categories + ADR ref.
  • Tests sub-tasks precede implementation sub-tasks.
  • getProjectReadiness shows all four rows satisfied.
  • No "TBD" anywhere in phase bodies.
  • clearActiveTask after the plan-lifecycle phase is marked complete.

Resources

references/

  • exit-conditions.md — Per-language exit-condition templates (Node, Python, Go, Rust, Java).
  • lifecycle-cheatsheet.md — Quick reference for which tasktracker tool maps to which lifecycle stage.

Related tasktracker skills

  • /init-project — Scaffold a tasktracker project if none exists.
  • /project-ready — Pretty-print readiness (4-row table). Use as a sanity check.
  • /brainstorm — Upstream: refines the idea into the docs/brainstorms/ file this skill plans from.
  • /user-story — Generate the hierarchical requirement tree (recommended for non-trivial scope).
  • /adr — Record significant design decisions in docs/decisions/.
  • /tt-implement-plan — Downstream: execute the plan you just seeded.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.