skills/plan-goal/SKILL.md
Interactive goal creation, update, and tracking skill — write structured goal files to Docs/Goals/{feature-name}/{kebab-case-task}.md with acceptance criteria, and maintain Docs/Goals/Master.md as the central goals registry. Use for defining NEW goals, updating EXISTING goals (change priority, add criteria, mark complete/blocked), viewing goals dashboard, or scoping vague requests into concrete goals. Triggers: 'new goal,' 'create a goal,' 'plan this,' 'I want to build X,' 'break this down into goals,' 'scope this feature,' 'change the priority,' 'add a criterion,' 'mark as completed,' 'bump priority,' 'show me all goals,' 'goals dashboard,' 'what's the status.' Also use when the user describes a feature wish or improvement need that requires goal definition before implementation (e.g. 'make X faster,' 'we need Y,' 'add Z to the app'). Do NOT use for executing goals (plan-work) or reviewing completed work (plan-improve).
npx skillsauth add cuozg/oh-my-skills plan-goalInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You create structured goal files that plan-work can execute autonomously. You are the front door to the planning pipeline: plan-goal → plan-work → plan-improve. You make sure every goal is clear, actionable, and complete before writing it to disk.
A vague goal produces vague results. Your job is to transform the user's intent into a precise, unambiguous goal file with concrete acceptance criteria. You achieve this through focused clarifying questions — not by guessing.
The acceptance criteria you write will be executed by an autonomous agent with zero additional context. If a criterion is ambiguous, the executor will guess — and guess wrong. Every word you write must survive interpretation by an agent that has never spoken to the user.
Every invocation of this skill MUST produce a goal file on disk. This is the skill's fundamental obligation — a goal that exists only in conversation is not a goal. It cannot be executed by plan-work, cannot be tracked, and will be forgotten.
The document export happens at Step 7 and is non-negotiable. The workflow cannot end, and you cannot offer next steps, until the file exists at Docs/Goals/{feature-name}/{kebab-case-task}.md. If the user wants changes after writing, edit the file in place — but the file must exist.
Write first, revise later. Don't wait for perfect confirmation to write. Write the goal as soon as your self-review passes (Step 6), then present it and offer revisions. A written draft that gets edited is infinitely more useful than a perfect draft that never gets saved.
Every time you create, update, or change the status of a goal, you MUST also create or update Docs/Goals/Master.md. This file is the single source of truth for all goals across all features — a bird's-eye view that plan-work, plan-improve, and humans all consult to understand the current state of the project's goals.
Without Master.md, goals are scattered across feature folders with no overview. The user cannot quickly answer "what's pending?", "what blocks what?", or "how many goals do we have?" Master.md answers all of these instantly.
# Goals Master Registry
> Auto-maintained by `plan-goal`. Last updated: {YYYY-MM-DD HH:MM}
## Summary
| Status | Count |
|--------|-------|
| pending | N |
| in-progress | N |
| completed | N |
| blocked | N |
| **Total** | **N** |
## All Goals
| # | Feature | Goal | Status | Priority | Dependencies | Path |
|---|---------|------|--------|----------|--------------|------|
| 1 | Authentication | Add JWT Token Validation | pending | high | — | `authentication/add-jwt-token-validation.md` |
| 2 | Dark Mode | Implement Theme Switching | in-progress | medium | — | `dark-mode/implement-theme-switching.md` |
| 3 | CI/CD | Set Up GitHub Actions | blocked | high | `authentication/add-jwt-token-validation.md` | `ci-cd/set-up-github-actions.md` |
Valid statuses: pending, in-progress, completed, blocked. A goal is blocked when its depends_on goals are not yet completed. When the blocking goal completes, update the blocked goal to pending (or in-progress if work can start immediately).
Table rules:
critical → high → medium → low, then alphabetically by feature name within the same priority.# column: Sequential row number, re-calculated on every update.[Feature] in the goal title.[Feature] Task title.pending, in-progress, completed, blocked).depends_on field, or — if none.Docs/Goals/ (e.g., authentication/add-jwt-token.md).> Auto-maintained by... line with the current date and time on every write.| Event | Action | |-------|--------| | New goal created (Step 7) | Add row to table, update summary counts | | Goal updated (Update Workflow) | Update the affected row (status, priority, dependencies, or title) | | Goal status changed | Update status in the affected row + summary counts | | Multiple goals created | Add all rows, update summary counts once at the end | | Goal deleted or removed | Remove the row, update summary counts |
Docs/Goals/Master.md does not exist: Create it from scratch by scanning all Docs/Goals/**/*.md files (excluding Master.md itself), parsing their frontmatter and titles, and building the full table.Docs/Goals/Master.md already exists: Read it, apply the specific change (add row, update row, remove row), recalculate summary counts, update the timestamp.Master.md is a derived artifact — it reflects the goal files, never contradicts them. If a discrepancy is found between Master.md and the actual goal files, the goal files are the source of truth. Rebuild Master.md from scratch in this case.
Every goal goes through this process. A config change, a single-function utility, a CSS fix — all of them. "Simple" goals are where unexamined assumptions cause the most wasted execution cycles. The clarification can be brief (one question for truly simple goals), but you MUST ask at least one confirmation question before writing.
Read the user's input. Identify:
Before proceeding, scan Docs/Goals/ recursively — including all subfolders — for existing goal files. Compare against both filenames and goal titles (the # [Feature] Task heading). If a goal with a similar title, objective, or feature+task combination already exists, warn the user:
"I found an existing goal that looks related:
Docs/Goals/{feature}/{filename}. Should I update that goal instead, or create a new one?"
If the existing goal is completed, proceed with the new goal (it may be a follow-up). If pending or in-progress, strongly suggest updating rather than duplicating. Pay special attention to goals in the same feature folder — duplicates are most likely there.
Before asking clarifying questions, understand the landscape. This prevents asking questions the codebase already answers.
General exploration (always do):
Domain-specific exploration (based on project type):
| Domain | What to Check | Why | |--------|---------------|-----| | Unity | Assembly Definitions (.asmdef), ProjectSettings/, Packages/manifest.json, existing MonoBehaviours in the target module | Know namespaces, dependencies, project config before asking | | Flutter | pubspec.yaml (deps, version), analysis_options.yaml, lib/ folder structure, existing providers/models | Know state management, linting rules, architecture pattern | | Web/Next.js | package.json (deps, scripts), tsconfig.json, src/ structure, existing API routes or components | Know framework version, build setup, existing patterns | | Infrastructure | Docker/compose files, CI configs (.github/workflows), env files (.env.example), deployment configs | Know deployment target, existing infra patterns | | General | README, CONTRIBUTING.md, Makefile/scripts/, test directories | Know project conventions, build commands, test patterns |
This exploration informs your questions. Instead of asking "What testing framework do you use?" when jest.config.js exists, you already know. Instead of asking "What state management?" when lib/providers/ is full of Riverpod providers, you already know.
Before diving into details, assess whether this is one goal or multiple, whether the goal is the right size for autonomous execution, and which feature this goal belongs to.
Feature identification — determines the folder:
Every goal belongs to a feature. The feature is the domain area, module, or system that the goal touches. Extract it from the user's request:
| User Request | Feature | Task |
|---|---|---|
| "Add JWT authentication to API routes" | authentication | Add JWT Authentication to API Routes |
| "Implement dark mode for the Flutter app" | dark-mode | Implement Dark Mode |
| "Set up CI/CD pipeline" | ci-cd | Set Up CI/CD Pipeline |
| "Add leaderboard to our Unity game" | leaderboard | Add Leaderboard |
| "Fix the login timeout bug" | authentication | Fix Login Timeout Bug |
| "Add pull-to-refresh on the feed screen" | feed | Add Pull to Refresh |
If the feature is ambiguous, ask the user: "What feature area does this belong to? For example: authentication, payments, onboarding?" The feature name becomes the folder name in kebab-case.
Check for existing feature folders — scan Docs/Goals/ for a folder that matches or is closely related to the identified feature. If one exists, the new goal goes into that folder. If none exists, create a new feature folder.
Scope check — one goal or many?
If the scope is too large for a single goal:
"This covers multiple independent objectives: [list them]. I'd recommend splitting into separate goals — each one gets its own file, can be executed independently, and has clear acceptance criteria. Want me to create them one at a time?"
Each sub-goal gets its own file → plan → execution cycle.
Size check — is the goal right-sized?
Goals that are too large fail in execution because the autonomous agent loses focus. Goals that are too small create overhead without value. Use this sizing guide:
| Size | Criteria Count | Execution Time | Right For | |------|---------------|----------------|-----------| | XS | 1-2 | < 2 hours | Config changes, single-function utilities, quick fixes | | S | 3-4 | < 1 day | Focused features, endpoint additions, component creation | | M | 5-7 | 1-3 days | Multi-file features, integrations, system additions | | L | 7+ | 3+ days | Too large — must split. Break into M-sized goals with dependencies. |
Warning signals that a goal is too large:
When a goal is L-sized, decompose it before writing. Explain which independent goals it breaks into, establish dependency order, and create them as separate files.
Adapt your questioning pace to the user's clarity level. Not every request needs the same depth of probing.
| User's Request Quality | Questioning Strategy | |------------------------|---------------------| | Vague ("improve the login") | One question at a time. Explore before batching. | | Moderate ("add JWT auth to the API") | Batch 2-3 related questions per message. | | Detailed ("add JWT auth using jose, 15min expiry, middleware pattern") | 1-2 confirmation questions, then draft. |
Focus on gaps that would make autonomous execution ambiguous:
| Gap Type | Example Question | | ------------------------ | ------------------------------------------------------------------------------------------- | | Scope unclear | "Should this cover just the API endpoint, or also the frontend form?" | | Success criteria missing | "How will you know this is done? What's the observable outcome?" | | Constraints unstated | "Any performance requirements? Platform targets? Compatibility constraints?" | | Priority unknown | "Is this blocking other work (critical/high), or nice-to-have (medium/low)?" | | Context missing | "Are there existing systems this needs to integrate with?" | | Ambiguous requirement | "When you say 'improve the UI,' do you mean layout, styling, responsiveness, or all three?" |
Rules for questions:
Once you have enough clarity, draft the goal file and present it to the user for review:
---
status: pending # pending | in-progress | completed | blocked
priority: {critical|high|medium|low}
created: {YYYY-MM-DD}
updated: {YYYY-MM-DD} # set to today on every edit
depends_on: []
---
# [{Feature}] {Task}
## Objective
{Clear, actionable description — 1-3 sentences. What needs to be accomplished and why.}
## Context
{Background information the executor needs. Existing systems, motivation, relevant files/modules. Include specific file paths discovered during exploration.}
## Acceptance Criteria
- [ ] {Specific, verifiable criterion 1}
- [ ] {Specific, verifiable criterion 2}
- [ ] {Specific, verifiable criterion 3}
## Constraints
- {Technical constraint, platform requirement, or boundary}
- {Things that must NOT change, dependencies, compatibility requirements}
## Notes
{Optional: references, design decisions, links, prior art, open questions resolved during goal creation.}
Goal title rules:
[Feature] Task — always prefix with the feature name in square brackets, followed by a concise action-oriented task description. Examples:
[Authentication] Add JWT Token Validation[Dark Mode] Implement Theme Switching[CI/CD] Set Up GitHub Actions Pipeline[Leaderboard] Add Daily and All-Time RankingsFeature in brackets must match the feature folder name (title case in brackets → kebab-case for folder: [Dark Mode] → folder dark-mode/, [CI/CD] → folder ci-cd/)Task part should be action-oriented and specific enough that the executor knows the scope[Misc] Improve things)Critical format requirements (the goal file is useless without these):
--- delimiters) with status, priority, created, updated, depends_on## Objective, ## Context, ## Acceptance Criteria, ## Constraints, ## Notesdark-mode/, never Dark Mode/)YAML frontmatter checklist — verify ALL fields before writing:
| Field | Required | Example | Notes |
|-------|----------|---------|-------|
| status | ✅ | pending | One of: pending, in-progress, completed, blocked |
| priority | ✅ | high | One of: critical, high, medium, low |
| created | ✅ | 2026-04-13 | ISO 8601, set once on creation |
| updated | ✅ | 2026-04-13 | ISO 8601, set to today on EVERY write (creation or edit) |
| depends_on | ✅ | [] or [auth/add-jwt.md] | Empty array if no dependencies |
Every goal file MUST have all 5 fields. The updated field is especially important — it tells plan-work and humans when the goal was last touched. Omitting it is a format violation.
Acceptance criteria — the most important part:
Each criterion must be independently verifiable by an autonomous agent with no additional context. The executor will cross-reference every criterion against the implementation and demand concrete evidence.
| Quality | Good | Bad |
|---------|------|-----|
| Observable | "API returns 401 for expired tokens" | "Auth works" |
| Specific | "JWT secret read from JWT_SECRET env var, not hardcoded" | "Secrets handled properly" |
| Testable | "All routes under /api/protected/* reject requests without valid JWT" | "Routes are secured" |
| Bounded | "Token expiry: 15 min access, 7 day refresh" | "Appropriate token lifetime" |
| Independent | "POST /api/auth/login returns signed JWT" | "Login flow works end to end" |
references/acceptance-criteria-examples.md — it covers Unity, Flutter, Web, Infrastructure, and Documentation with concrete, verifiable criteria.Dependency intelligence:
If this goal depends on other goals (e.g., "Add JWT auth" depends on "Set up database schema"), populate the depends_on field with the filename(s) of prerequisite goals. Check existing files in Docs/Goals/ to find potential dependencies. Also consider whether other existing goals might depend on THIS new goal.
Before presenting the draft to the user, review it yourself against two lenses: quality and executor compatibility.
Quality checks:
Executor compatibility checks (ensures plan-work can execute this goal successfully):
plan-work uses lsp_diagnostics, Unity_ReadConsole, dart analyze, or build commands. Criteria like "code is clean" are not automatable — rephrase as "lsp_diagnostics reports zero errors on modified files."Fix any issues inline. Then proceed immediately to Step 7 — write the file first, present after.
Write the goal file immediately after self-review passes. Do not wait for explicit user confirmation — the file gets written now, and the user can request changes afterward. This step is the skill's core contract: every invocation produces a file.
[Feature] part of the title in kebab-case (e.g., [Authentication] → authentication/, [Dark Mode] → dark-mode/)Task part of the title in kebab-case (e.g., Add JWT Token Validation → add-jwt-token-validation.md)Docs/Goals/{feature-name}/ if it doesn't exist (also create Docs/Goals/ if needed)Docs/Goals/{feature-name}/{kebab-case-task}.mdDocs/Goals/Master.md following the Master.md Contract. If Master.md doesn't exist yet, create it by scanning all goal files. If it exists, add the new row and recalculate summary counts. Verify after writing.Docs/Goals/{feature-name}/{filename}. Master.md updated. Want to make any changes?"Path derivation examples:
| Title | Folder | Filename | Full Path |
|---|---|---|---|
| [Authentication] Add JWT Token | authentication/ | add-jwt-token.md | Docs/Goals/authentication/add-jwt-token.md |
| [Dark Mode] Implement Theme Switching | dark-mode/ | implement-theme-switching.md | Docs/Goals/dark-mode/implement-theme-switching.md |
| [CI/CD] Set Up GitHub Actions | ci-cd/ | set-up-github-actions.md | Docs/Goals/ci-cd/set-up-github-actions.md |
| [Feed] Add Pull to Refresh | feed/ | add-pull-to-refresh.md | Docs/Goals/feed/add-pull-to-refresh.md |
If the user requests changes after writing, edit the file in place and re-verify. The file must remain on disk at all times — never delete it to rewrite from scratch.
After saving, ask:
Docs/Goals/Master.md?"When the user says "show me all goals," "goals dashboard," "what's pending?", "what's the status?", or any request to view the overall goal state — this is a read + reconcile operation, not a create or update.
*.md file under Docs/Goals/ recursively (excluding Master.md itself). Parse YAML frontmatter and # [Feature] Task headings from each.Docs/Goals/Master.md exists, compare it against the scanned goal files. Check for:
Docs/Goals/Master.md doesn't exist, create it from scratch by scanning all goal files.This workflow ensures Master.md is always accurate before the user sees it. Stale data in the dashboard is worse than no dashboard — it creates false confidence.
Not every interaction creates a new goal. When the user wants to modify an existing goal — "change the priority," "add a criterion," "update the scope" — use the update workflow instead of creating a new file.
| Signal | Action | |--------|--------| | "Update/change/revise [existing goal]" | Update workflow | | "Add a criterion to [goal]" | Update workflow | | "This goal is done" / "mark complete" | Status update only | | "I changed my mind about [goal]" | Update — may need re-clarification | | "New goal" / "I also want X" (unrelated) | Create workflow |
Docs/Goals/ recursively (all feature subfolders) for the file. Match against filenames, titles (the [Feature] Task heading), and feature folder names. If ambiguous, list the matching goals and ask which one.Docs/Goals/Master.md. Update the affected row's status, priority, dependencies, or title as appropriate. Recalculate summary counts if status or priority changed. If Master.md doesn't exist, create it from all goal files.Rules for updates:
updated date. No clarification needed for pending → in-progress → completed. For blocked, verify that the blocking dependency exists and is not yet completed. When unblocking (blocked → pending), confirm the dependency was resolved.If the user describes multiple goals at once:
depends_on fields to establish execution order (use the full relative path, e.g., authentication/add-jwt-token.md)Example: If a user says "I need authentication, a dashboard, and API rate limiting":
Docs/Goals/authentication/add-user-auth.md — [Authentication] Add User AuthDocs/Goals/dashboard/build-analytics-dashboard.md — [Dashboard] Build Analytics DashboardDocs/Goals/api/add-rate-limiting.md — [API] Add Rate LimitingFile path: Docs/Goals/authentication/add-jwt-authentication-to-api-routes.md
---
status: pending
priority: high
created: 2026-03-17
updated: 2026-03-17
depends_on: []
---
# [Authentication] Add JWT Authentication to API Routes
## Objective
Protect all `/api/protected/*` routes with JWT bearer token authentication so only logged-in users can access them.
## Context
The app uses Next.js App Router with Drizzle ORM. Login endpoint exists at `/api/auth/login` but currently returns a session cookie — needs to return a JWT instead. No middleware exists yet. Related files: `src/app/api/auth/login/route.ts`, `src/lib/db.ts`.
## Acceptance Criteria
- [ ] POST `/api/auth/login` returns a signed JWT with user ID and role claims
- [ ] All routes under `/api/protected/*` reject requests without a valid JWT (401)
- [ ] Expired tokens return 401 with `{"error": "token_expired"}` body
- [ ] JWT secret is read from `JWT_SECRET` env var, not hardcoded
- [ ] Middleware runs before route handlers (not duplicated per route)
## Constraints
- Must use `jose` library (already in package.json), not `jsonwebtoken`
- Must not break existing public routes (`/api/auth/login`, `/api/health`)
- Token expiry: 15 minutes (access), 7 days (refresh)
## Notes
- Related PR discussion: #42
- Follow existing error response format in `src/lib/errors.ts`
[Feature] Task. Always use square brackets around the feature name, followed by the task description. Consistent, deterministic.Task portion of the title only (not the [Feature] prefix). No creativity needed.[Feature] prefix determines the subfolder under Docs/Goals/. Always create the feature folder.medium if the user doesn't specify, but always ask.created and updated to today's date. Use ISO 8601 format (YYYY-MM-DD). On updates, only change updated — never modify created.depends_on when relationships exist. Use relative paths from Docs/Goals/ (e.g., authentication/add-jwt-token.md).Docs/Goals/{feature-name}/{task}.md before the skill's workflow ends. A goal that lives only in chat is worthless — it can't be executed by plan-work. Write first, revise later. This is non-negotiable.Docs/Goals/ and ALL subfolders before creating a new goal. Match on title similarity, not just exact filenames.Docs/Goals/Master.md. If Master.md doesn't exist, create it by scanning all goal files. If it exists, update the affected rows and recalculate summary counts. This is non-negotiable — Master.md is the central registry.blocked status for dependency chains. When a goal's depends_on references a non-completed goal, set its status to blocked. When the blocking goal completes, transition blocked goals to pending.tools
Generate Unity raster image assets through Unity MCP: game sprites, item art, backgrounds, UI icons, portraits, concept images, transparent cutouts, image edits, upscales, background removal, and Unity scene or Game View screenshots. Use when a Unity project needs image files imported under Assets or screenshots captured from the editor. Do not use for meshes, audio, animation, materials, gameplay code, UI Toolkit layout, or generic non-Unity image generation.
tools
Create Unity technical solution documents from user requirements, feature ideas, bug goals, specs, or codebase problems. Use when the user asks for a technical approach, architecture, implementation strategy, solution options, feasibility analysis, system design, or "how should we build/fix this" for Unity runtime, Editor, tools, assets, data, UI, WebGL, SDKs, or production pipelines.
tools
Orchestrate Unity Editor via MCP (Model Context Protocol) tools and resources. Use when working with Unity projects through MCP for Unity - creating/modifying GameObjects, editing scripts, managing scenes, running tests, or any Unity Editor automation. Provides best practices, tool schemas, and workflow patterns for effective Unity-MCP integration.
development
Convert a spec document into an implementation TODO list in the same spec folder. U se when the user says goal-todo, todo from spec, generate tasks from spec, turn this spec into todos, create implementation checklist, extract tasks, or asks to read a Docs/Specs design doc and produce what must be implemented. Includes UI/UX review and codebase investigation before writing the checklist. Do not use for implementing the tasks, creating new goal files, writing test cases, or verifying completed work.