plan-milestone
Skill2 starsChanged 30 days agoMITView on GitHub
Defines the next milestone (goal, exit criteria, size) and writes M###-CONTEXT.md and M###-ROADMAP.md. Use after init-project or adopt-brownfield, after a milestone closed, or when the user says plan the next milestone, new milestone, define the milestone. Not for slicing (slice-milestone) and not for unvalidated greenfield ideas (office-hours first).
6 other projects use a version of this.
Adopted by
Most recently taken up by
- adrian-wulf/vorarbeiter-gamedevtheir own version, first seen Oct 17, 2026
- thaitype/sandcontainertheir own version, first seen Oct 13, 2026
- mattolson/agent-sandboxtheir own version, first seen Oct 8, 2026
- kohj1018/agentic-dev-harnesstheir own version, first seen Sep 29, 2026
- adrian-wulf/vorarbeiter-codetheir own version, first seen Sep 27, 2026
- jasoncrawford/claude-skillstheir own version, first seen Apr 25, 2026
Other versions6 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 6
- mattolson/agent-sandbox★ 212same name
- adrian-wulf/vorarbeiter-code★ 2same name
- kohj1018/agentic-dev-harness★ 2same name
- jasoncrawford/claude-skills★ 1same name
- adrian-wulf/vorarbeiter-gamedev★ 0same name
- thaitype/sandcontainer★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository32 other files it gives its agents.
- AGENTS.mdAGENTS.md
- check-consistencySkill
- adopt-brownfieldSkill
- atomic-designSkill
- code-reviewSkill
- deutschland-stack-apiSkill
- document-releaseSkill
- european-alternatives-apiSkill
- finish-branchSkill
- grillSkill
- handoff-sessionSkill
- init-projectSkill
- minimal-codeSkill
- office-hoursSkill
- oss-projectSkill
- plan-ceo-reviewSkill
- plan-eng-reviewSkill
- plan-taskSkill
- quick-taskSkill
- reassess-roadmapSkill
- reconcileSkill
- resume-sessionSkill
- retroSkill
- shipSkill
- slice-milestoneSkill
- software-craftsmanshipSkill
- spawn-milestone-teamSkill
- summarize-taskSkill
- systematic-debuggingSkill
- test-driven-developmentSkill
- using-ytstackSkill
- verification-before-completionSkill
The file
We split this skill into the rules it gives an agent
7 rules. 0 are common, 1 is distinctive, and 6 are very specific to this project.
0
Common
Most of the 4 edited versions we read keep these.
1
Distinctive
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 129
If HAS_YTSTACK is no:
- Distinctive: line 133
STOP. Do not invoke any other skill automatically.
- Very specific: line 137
If YTSTACK_NON_INTERACTIVE is true, parse goal from prompt context.
- Very specific: line 166
If YTSTACK_NON_INTERACTIVE is true, auto-pick M (medium) and log.
- Very specific: line 184
Use Write tool. Path: {YT_DIR}/{NEXT_MILESTONE}-CONTEXT.md.
- Very specific: line 274
Use Edit tool on {YT_DIR}/STATE.md.
- Very specific: line 310
Do NOT invoke ytstack:slice-milestone, ytstack:plan-task, or any other downstream skill automatically.
“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
plan-milestone
Define the next milestone for a ytstack project: goal, exit criteria, rough size. Produces a milestone roadmap skeleton; slice-level detail comes from the next skill (slice-milestone).
Anti-Pattern: "This feature is too small for a milestone"
Every feature goes through this. A CSS tweak, a single bugfix, a config change -- all of them. "Small" features are where unexamined assumptions cause the most wasted work. The milestone can be minimal (one slice, two tasks), but you MUST define its goal, exit criteria, and rough shape before planning slices.
Checklist
You MUST create a TodoWrite task for each of these items and complete them in order:
- Run preamble -- detect ytstack state + next milestone number
- HARD-GATE: check ytstack initialized -- abort if
HAS_YTSTACK=no - Ask goal -- one-sentence outcome the milestone delivers
- Ask exit criteria -- how we know it's done (concrete signals)
- Ask rough size -- S / M / L (cascading from task-count estimate)
- Write
M###-CONTEXT.md-- Q/A transcript locked as the milestone's source-of-truth - Write
M###-ROADMAP.md-- skeleton with placeholder slices based on size - Update STATE.md -- new
current_milestone, next action points to slice-milestone - Report + return -- suggest running
ytstack:slice-milestonenext
Process Flow
digraph plan_milestone {
"Run preamble" [shape=box];
"HAS_YTSTACK?" [shape=diamond];
"Abort: run init-project first" [shape=doublecircle];
"Ask goal" [shape=box];
"Ask exit criteria" [shape=box];
"Ask size" [shape=box];
"Write CONTEXT + ROADMAP" [shape=box];
"Update STATE.md" [shape=box];
"Report + return" [shape=doublecircle];
"Run preamble" -> "HAS_YTSTACK?";
"HAS_YTSTACK?" -> "Abort: run init-project first" [label="no"];
"HAS_YTSTACK?" -> "Ask goal" [label="yes"];
"Ask goal" -> "Ask exit criteria";
"Ask exit criteria" -> "Ask size";
"Ask size" -> "Write CONTEXT + ROADMAP";
"Write CONTEXT + ROADMAP" -> "Update STATE.md";
"Update STATE.md" -> "Report + return";
}Preamble
# ytstack resolver (M016): checkout = where this shell runs, via the shared lib.
_LIB="${CLAUDE_SKILL_DIR}/../../hooks/lib/git-ctx.sh"
if [ -f "$_LIB" ]; then
. "$_LIB"; yt_git_ctx "$PWD"; yt_resolve_yt_dir >/dev/null
_PROJECT_DIR="$YT_TOPLEVEL"; _YT_DIR="$YT_DIR"; _YT_SCOPE="$YT_SCOPE"; _IS_GIT="$YT_IS_GIT"; _PROJECT_KEY="$YT_REPO_KEY"
else
# Host did not substitute CLAUDE_SKILL_DIR (e.g. Codex adapter): project scope only.
_IS_GIT=$([ "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = true ] && echo yes || echo no)
_PROJECT_DIR=$(git rev-parse --show-toplevel 2>/dev/null || pwd -P)
_YT_DIR=""; _YT_SCOPE=none; _PROJECT_KEY=""
[ -d "$_PROJECT_DIR/.ytstack" ] && { _YT_DIR="$_PROJECT_DIR/.ytstack"; _YT_SCOPE=project; }
fi
cd "$_PROJECT_DIR" 2>/dev/null || true
_PROJECT_SLUG=$(basename "$_PROJECT_DIR")
_BRANCH=$(git branch --show-current 2>/dev/null || echo unknown)
_HAS_YTSTACK=$([ -n "$_YT_DIR" ] && echo yes || echo no)
# Next milestone number
_NEXT_MILESTONE="M001"
if [ -n "$_YT_DIR" ]; then
_MAX=$(ls "$_YT_DIR"/M[0-9][0-9][0-9]-*.md 2>/dev/null | sed -E 's/.*M([0-9]{3})-.*/\1/' | sort -u | tail -1)
if [ -n "$_MAX" ]; then
_NEXT_MILESTONE=$(printf "M%03d" $((10#$_MAX + 1)))
fi
fi
# Project-level frontmatter
_PROJECT_NAME=""
if [ -f "$_YT_DIR/PROJECT.md" ]; then
_PROJECT_NAME=$(sed -n 's/^name: *//p' "$_YT_DIR/PROJECT.md" | head -1)
fi
# External issue tracker (STATE.md `tracker:`; none | linear | github-projects | paperclip | jira)
_TRACKER=none
if [ -f "$_YT_DIR/STATE.md" ]; then
_TRACKER=$(sed -n 's/^tracker: *//p' "$_YT_DIR/STATE.md" | head -1)
_TRACKER=${_TRACKER:-none}
fi
_NON_INTERACTIVE=false
if [ -n "$YTSTACK_NON_INTERACTIVE" ] || [ -n "$OPENCLAW_SESSION" ] || [ -n "$CLAUDE_AGENT_TEAM_MEMBER" ]; then
_NON_INTERACTIVE=true
fi
echo "BRANCH: $_BRANCH"
echo "PROJECT_SLUG: $_PROJECT_SLUG"
echo "PROJECT_NAME: $_PROJECT_NAME"
echo "YT_DIR: $_YT_DIR"
echo "YT_SCOPE: $_YT_SCOPE"
echo "HAS_YTSTACK: $_HAS_YTSTACK"
echo "NEXT_MILESTONE: $_NEXT_MILESTONE"
echo "TRACKER: $_TRACKER"
echo "YTSTACK_NON_INTERACTIVE: $_NON_INTERACTIVE"Procedure
Step 2: HARD-GATE
If HAS_YTSTACK is no:
"ytstack isn't initialized in this project yet. Run
/ytstack:init-projectfirst, then return here to plan the first milestone."
STOP. Do not invoke any other skill automatically.
Step 3: Ask goal
If YTSTACK_NON_INTERACTIVE is true, parse goal from prompt context. Otherwise use AskUserQuestion (open-ended):
Planning milestone {NEXT_MILESTONE} for project {PROJECT_NAME} on branch
{BRANCH}.What's the goal of this milestone? One sentence describing the outcome it delivers. Not the tasks -- the result.
{Only if
TRACKERis notnone:} Day-to-day issues and bugfixes are tracked in {TRACKER} and do not need a milestone; name a discrete initiative here, not the BAU queue.Good examples:
- "Users can sign up with email and get a verification link."
- "Deploy a staging environment that mirrors prod config."
- "Ship a CLI subcommand that imports CSV exports."
Remember as _GOAL.
Step 4: Ask exit criteria
Use AskUserQuestion (open-ended):
How will we know this milestone is done? List the concrete signals.
Concrete > abstract. "Signup form posts to /api/signup and returns 201" beats "signup works".
Give 2-4 checkable items, one per line.
Remember as _EXIT_CRITERIA (preserve line breaks).
Step 5: Ask rough size
If YTSTACK_NON_INTERACTIVE is true, auto-pick M (medium) and log. Otherwise use AskUserQuestion:
Rough size of this milestone? Use your gut -- we'll refine in slice-milestone.
Size drives the initial slice skeleton. You can always add slices later.
RECOMMENDATION: Choose M for most milestones. S is for near-trivial features. L signals you should probably split into two milestones; review after slicing.
A) S -- small. 1 slice, 2-4 tasks total. (Completeness: 10/10 for truly small work, risk: 8/10 if the scope is actually larger than it feels) B) M -- medium. 2-3 slices, 5-10 tasks total. (Completeness: 10/10, recommended for most milestones) C) L -- large. 4-5 slices, 11-20 tasks total. (Completeness: 10/10, risk: consider splitting into two milestones)
(to change later: edit
size:in{NEXT_MILESTONE}-CONTEXT.mdand{NEXT_MILESTONE}-ROADMAP.md)
Remember as _SIZE (value: S, M, or L).
Step 6: Write M###-CONTEXT.md
Use Write tool. Path: {YT_DIR}/{NEXT_MILESTONE}-CONTEXT.md.
---
milestone: {NEXT_MILESTONE}
project: {PROJECT_NAME}
created: {ISO_TIMESTAMP}
size: {SIZE}
---
# {NEXT_MILESTONE} -- Context
## Goal
{GOAL}
## Exit criteria
{EXIT_CRITERIA}
## Size
{SIZE} -- see `{NEXT_MILESTONE}-ROADMAP.md` for slice breakdown.
## Decisions locked in discuss phase
(Append decisions here as they're made during slicing + execution. Format: "YYYY-MM-DD: decided X because Y.")
## Open questions
(Items to resolve before or during slicing. Close as decisions land in the list above.)Step 7: Write M###-ROADMAP.md
Use Write tool. Path: {YT_DIR}/{NEXT_MILESTONE}-ROADMAP.md.
Slice-count based on size: S=1, M=2-3, L=4-5. For v0.1, always seed the lower bound (S=1, M=2, L=4). User can add more during slice-milestone.
Template (substitute slice placeholders based on size):
---
milestone: {NEXT_MILESTONE}
project: {PROJECT_NAME}
size: {SIZE}
created: {ISO_TIMESTAMP}
status: planned
total_slices: {SLICE_COUNT}
completed_slices: 0
---
# {NEXT_MILESTONE} Roadmap
**Goal:** {GOAL}
**Exit criteria:**
{EXIT_CRITERIA}
## Slices
Slice detail lives in per-slice `{NEXT_MILESTONE}-S##-PLAN.md` files, created by `ytstack:slice-milestone`.
- [ ] S01 -- (to be planned)
{#if SIZE == "M" or SIZE == "L"}
- [ ] S02 -- (to be planned)
- [ ] S03 -- (to be planned)
{/if}
{#if SIZE == "L"}
- [ ] S04 -- (to be planned)
{/if}
## Run order
Slices execute sequentially. After each slice, `ytstack:reassess-roadmap` checks if the plan still fits reality.
## How to update this file
- Flip slice checkbox `[ ]` → `[x]` when its tasks are all `summarize-task`-confirmed
- Update `completed_slices` count
- On milestone completion, flip `status: planned` → `status: done` and update global ROADMAP.mdReplace the {#if ...} blocks with actual lines based on _SIZE:
- S → keep only S01
- M → S01, S02, S03
- L → S01, S02, S03, S04
Step 8: Update STATE.md
Use Edit tool on {YT_DIR}/STATE.md. Change:
current_milestone: <old value>→current_milestone: {NEXT_MILESTONE}active_slice: <old>→active_slice: noneactive_task: <old>→active_task: nonelast_updated: <old>→last_updated: {ISO_TIMESTAMP}
Also update the # State body:
- Status line →
**Status:** {NEXT_MILESTONE} planned ({SIZE}). Ready to slice. - Next action →
Run \ytstack:slice-milestone` to break {NEXT_MILESTONE} into concrete slices and tasks.`
Step 9: Report + return
Report:
Milestone {NEXT_MILESTONE} planned ({SIZE}):
- Goal: {GOAL}
- Exit criteria: {EXIT_CRITERIA_FIRST_LINE} ...
- Slices: {SLICE_COUNT} placeholder(s) in
{NEXT_MILESTONE}-ROADMAP.mdFiles created:
{YT_DIR}/{NEXT_MILESTONE}-CONTEXT.md-- Q/A locked{YT_DIR}/{NEXT_MILESTONE}-ROADMAP.md-- slice skeletonSTATE.md updated:
current_milestone= {NEXT_MILESTONE}.Next step: run
/ytstack:slice-milestoneto define the slices in detail.
Terminal State
The terminal state is one of:
- Returning control after writing M###-CONTEXT.md + M###-ROADMAP.md + updating STATE.md
- Aborting if HAS_YTSTACK=no (with clear message to run init-project first)
Do NOT invoke ytstack:slice-milestone, ytstack:plan-task, or any other downstream skill automatically. The ONLY valid next actions are:
- User reviews the generated files
- User runs
/ytstack:slice-milestonethemselves when ready
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
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.

