| name | copilotforge-plan-executor |
| description | Autonomous plan execution — reads IMPLEMENTATION_PLAN.md, picks the next task, implements it, validates, commits, and repeats |
| domain | execution |
| confidence | high |
| source | manual — Plan Executor skill |
| triggers | ["run the plan","execute the plan","work through tasks","start building","continue the plan","pick up where I left off","what's next in the plan","implement the next task","keep building"] |
CopilotForge Plan Executor
This skill teaches you how to autonomously execute an IMPLEMENTATION_PLAN.md file — reading tasks, implementing them one by one, validating each result, committing, and moving on. It is the "execute" phase of the Describe → Generate → Execute workflow.
What This Does
When a user says "run the plan" (or any trigger above), you become an autonomous builder. You read the plan, pick the next pending task, write real working code for it, validate it compiles and passes tests, mark it done, commit, and repeat until every task is finished or attempted.
This skill assumes:
- An
IMPLEMENTATION_PLAN.md file already exists at the project root (generated by the CopilotForge planner wizard, or created manually)
- The project may have a
FORGE.md, forge-memory/ files, and package.json / requirements.txt / go.mod or similar config files
- Git is initialized in the project
This skill produces:
- Real, working code for each task in the plan
- Updated
IMPLEMENTATION_PLAN.md with tasks marked [x] (done) or [!] (failed)
- One git commit per completed task
- A summary logged to
forge-memory/decisions.md (if the forge-memory directory exists)
Capture Decisions (forge remember)
If the user says "forge remember: [anything]" at any point in this conversation,
immediately acknowledge it ("Got it — logging that.") and append a new entry to
forge-memory/decisions.md in this format:
## [YYYY-MM-DD] [brief label]
[the user's exact words]
Then continue the conversation without interruption. Do not ask for confirmation.
Instructions
When this skill is triggered, follow every step below in order. Do not skip steps. Do not ask the user for permission between tasks — the whole point is autonomous execution. If the user sends a message, answer briefly and immediately resume. Never stop the plan unless you see an explicit stop command. If something goes wrong with a task, handle it (see Failure Handling below) and keep going.
Step 1 — Find the Plan
Look for IMPLEMENTATION_PLAN.md in the project root directory.
If the file does not exist:
Say exactly this:
No plan found. Say "set up my project" to create one, or create IMPLEMENTATION_PLAN.md manually.
A plan file uses this format — one task per line:
- [ ] task-id — Task title
Then stop. Do not proceed further.
If the file exists but is empty or contains no parseable tasks:
Say:
Your plan is empty. Add tasks like:
- [ ] setup-project — Initialize project structure
- [ ] add-api — Create the main API endpoint
Then stop.
If all tasks are already marked [x] (done) or [!] (failed):
Say:
All tasks are already complete! Nothing left to do. If you want to retry failed tasks, change [!] back to [ ] in IMPLEMENTATION_PLAN.md and say "run the plan" again.
Then stop.
If the file exists and has pending [ ] tasks: Continue to Step 2.
Step 2 — Gather Context
Before implementing anything, read the following files to understand the project. If a file doesn't exist, skip it — never crash or abort because a context file is missing.
IMPLEMENTATION_PLAN.md — Parse all tasks (see parsing rules in Step 3)
FORGE.md — Read the project description, stack, and settings
forge-memory/decisions.md — Read past decisions to avoid contradicting them
forge-memory/patterns.md — Read coding conventions to follow them in generated code
- Dependency files — Read whichever exists:
package.json, requirements.txt, pyproject.toml, go.mod, Cargo.toml, *.csproj, pom.xml, build.gradle, Gemfile, composer.json
- Source scan — List the existing source files and directories to understand the project layout. Pay attention to folder structure, naming conventions, and existing code style.
Use this context for every task you implement. Generated code should match the project's stack, conventions, and existing patterns.
Step 3 — The Execution Loop
This is the core of the skill. Repeat this loop until no pending tasks remain.
3a. Parse the Plan
Read IMPLEMENTATION_PLAN.md and identify every task line. A task line matches one of these patterns:
| Pattern | Meaning |
|---|
- [ ] task-id — Title | Pending — needs to be implemented |
- [x] task-id — Title | Done — already completed |
- [!] task-id — Title | Failed — attempted but something went wrong |
Parsing rules:
- The task ID is the first word after the checkbox (kebab-case, e.g.,
init-project)
- The title is everything after the em-dash (
—)
- Lines starting with
# are comments — preserve them, don't treat them as tasks
- Be lenient with spacing.
- [ ], -[ ], - [ ] should all be recognized as pending
- Be lenient with dash style. Both em-dash (
—) and regular hyphen/double-hyphen (-, --) separating ID from title should work
- Ignore blank lines and any lines that don't match the task pattern
3b. Show Progress
Before starting work, display:
📋 Plan: {done}/{total} tasks complete. Starting with: {task-id} — {title}
Where {done} is the count of [x] tasks, {total} is the count of all tasks (pending + done + failed), and {task-id} / {title} come from the first pending task.
3c. Pick the Next Task
Select the first task in the file that has a [ ] (pending) checkbox. Tasks are executed in file order — the planner generates them in dependency order, so file order is correct.
3d. Implement the Task
This is where you write real code. Using the task title, the project context from Step 2, and common sense:
-
Determine what files to create or modify. Use the task title, project stack, and existing file structure as guides. For example:
- "Initialize TypeScript project" → create
tsconfig.json, update package.json
- "Create Express server" → create
src/index.ts or src/server.ts
- "Add Prisma models" → create or update
prisma/schema.prisma
-
Write working code. The code must:
- Follow patterns from
forge-memory/patterns.md if available
- Match the project's existing code style (indentation, naming, imports)
- Include necessary imports and exports
- Handle basic error cases
- Be complete enough to pass validation (no placeholder
// TODO blocks that would break compilation)
-
Install dependencies if needed. If the task requires a new package:
- For Node.js:
npm install {package} or npm install -D {package}
- For Python:
pip install {package} (or add to requirements.txt and run pip install -r requirements.txt)
- For Go:
go get {package}
- For other stacks: use the appropriate package manager
-
Create directories if needed. If you're creating a file in a directory that doesn't exist yet, create the directory first.
3e. Validate the Task
After implementing, verify the code actually works. Use the project's test/build tools:
Primary validation — run the project's test command if one exists:
- Check
package.json for a test script → run npm test
- Check for
pytest.ini, setup.cfg, pyproject.toml → run pytest
- Check for
go.mod → run go test ./...
- Check for
Cargo.toml → run cargo test
- Check for
*.csproj → run dotnet test
- Check for
pom.xml → run mvn test
- Check for
build.gradle → run gradle test
Fallback validation — if no test command exists or tests aren't set up yet:
- For TypeScript/JavaScript:
npx tsc --noEmit (type-check without emitting)
- For Python:
python -c "import {module}" (verify the module loads)
- For Go:
go build ./... (verify it compiles)
- For Rust:
cargo check
- For C#:
dotnet build
- For Java:
mvn compile or gradle compileJava
- For any stack: verify the files were created/modified and check for obvious syntax errors
If validation succeeds: Continue to Step 3f.
If validation fails: Jump to Failure Handling (below).
3f. Update the Plan
Open IMPLEMENTATION_PLAN.md and change the current task's checkbox from [ ] to [x]:
Before: - [ ] setup-express — Create Express server with health check endpoint
After: - [x] setup-express — Create Express server with health check endpoint
Write the updated content back to the file. Do not modify any other lines.
3g. Commit
Stage only the files you created or modified for this task, plus the updated plan file. Follow the Git Safety Protocol below — never use git add -A or git add ..
git add src/server.ts src/server.test.ts IMPLEMENTATION_PLAN.md
git commit -m "feat(setup-express): Create Express server with health check endpoint
Task: setup-express — \"Create Express server with health check endpoint\""
Run the Pre-Commit Checklist (see Git Safety Protocol) before every commit. If git is not initialized or the commit fails, skip the commit and note it in the task report. Don't let a git error stop the whole plan.
3h. Report
After each task, display:
✅ {task-id} done ({done}/{total}). Next: {next-task-id} — {next-title}
If there are no more pending tasks, skip the "Next:" part.
3i. Repeat
Go back to Step 3c and pick the next pending task. Continue until no [ ] tasks remain.
Handling User Questions Mid-Plan
If the user sends any message during plan execution, do NOT stop. Treat it as a question. Handle it inline, then IMMEDIATELY resume without asking for permission.
Protocol:
- Answer the question in 1–3 sentences (direct and brief — don't elaborate)
- On the very next line, show resume banner:
▶️ Resuming plan ({done}/{total} done) — next: **{task-id}** — {title}
- Immediately continue executing the next task — no pause, no "shall I continue?"
What counts as an interruption (handle inline, then resume):
- Questions about the plan ("what does task X do?", "how long will this take?")
- Requests for clarification ("what file are you editing?")
- Comments or context ("I changed the API endpoint to /v2")
- General conversation ("looks good so far")
What counts as a STOP command (stop the plan, wait for user):
- "stop", "pause", "cancel", "hold on", "wait"
- "change the plan" — stop, help the user edit IMPLEMENTATION_PLAN.md, then ask if they want to resume
- Rejection of current task result — stop, address the rejection, ask how to proceed
Inline context capture: If the user provides new information ("I changed the API endpoint to /v2"), capture it:
- Note it in your working context for remaining tasks
- If it affects upcoming tasks, say: "📌 Noted — I'll use /v2 for the remaining API tasks. Resuming..."
- Do NOT stop to ask follow-up questions about it
Example of correct behavior:
User: "what is ralph loop?"
Response: "Ralph Loop is the autonomous task execution engine — it reads IMPLEMENTATION_PLAN.md and executes tasks one by one. ▶️ Resuming plan (3/8 done) — next: add-auth — Add JWT authentication middleware"
[immediately starts add-auth task]
Git Safety Protocol
These rules are mandatory. Violating them can delete user code.
Staging Rules
- ❌ NEVER use
git add . or git add -A — these stage unintended files and deletions
- ❌ NEVER use
git commit -a — same risk
- ✅ ALWAYS stage specific files you created or modified:
git add src/auth.ts src/auth.test.ts
- ✅ ALWAYS stage the updated
IMPLEMENTATION_PLAN.md (you mark tasks done)
Pre-Commit Checklist
Before every commit, run these checks:
- Verify file count:
git diff --cached --stat — expect ≤10 files for most tasks
- Check for deletions:
git diff --cached --diff-filter=D --name-only — should be empty unless you intentionally removed a file
- Review staged files:
git diff --cached --name-only — every file should relate to the current task
If any check fails, unstage everything (git reset HEAD) and re-stage only the correct files.
Commit Message Format
Use this format for every task commit:
feat(task-id): brief description
Task: task-id — "Task title from plan"
Example:
feat(add-auth): implement JWT authentication
Task: add-auth — "Add JWT authentication to API routes"
Red Flags — STOP
If you encounter any of these, stop autonomous execution and report to the user:
- 🚩 More than 20 files in your
git diff --cached --stat
- 🚩 Any file deletions you did not explicitly intend
- 🚩 Changes to files outside the scope of the current task
- 🚩 Changes to
.env, .gitignore, package-lock.json, or other sensitive files you didn't plan to modify
- 🚩 The staged diff is larger than what one task should produce
Rollback Protocol
If validation fails for a task:
- Discard all uncommitted changes:
git checkout -- .
- Remove any untracked files created for this task:
git clean -fd (only in the directories you were working in)
- Mark the task as
[!] (failed) in IMPLEMENTATION_PLAN.md
- Commit ONLY the plan update:
git add IMPLEMENTATION_PLAN.md && git commit -m "mark task-id as failed"
- Move to the next task
Max Files Per Commit
- Normal: 1–10 files per task commit
- Warning: 11–20 files — log a note but proceed
- Stop: >20 files — something is wrong, stop and report
Failure Handling
If validation fails for a task:
-
Mark the task as failed. Change [ ] to [!] in IMPLEMENTATION_PLAN.md:
Before: - [ ] add-auth — Add JWT authentication middleware
After: - [!] add-auth — Add JWT authentication middleware
-
Report what went wrong in plain English. Include:
- What you tried to implement
- What the validation error was (compile error, test failure, missing dependency, etc.)
- A brief suggestion for how to fix it manually
-
Commit the partial work (if any files were created/modified) — stage only the specific files you touched:
git add src/auth.ts IMPLEMENTATION_PLAN.md
git commit -m "wip(add-auth): Add JWT authentication middleware (failed: type errors)
Task: add-auth — \"Add JWT authentication middleware\""
-
Continue to the next task. Do not stop the whole plan because one task failed. Other tasks may not depend on the failed one.
-
At the end of the plan, if any tasks failed, display:
⚠️ {N} tasks failed. Review the [!] items in IMPLEMENTATION_PLAN.md. To retry a failed task, change [!] back to [ ] and say "run the plan" again.
Step 4 — Completion
When no pending [ ] tasks remain (all are either [x] or [!]), display:
🏁 Plan complete! {done} succeeded, {failed} failed out of {total}.
Where:
{done} = count of [x] tasks
{failed} = count of [!] tasks
{total} = count of all tasks
If forge-memory/decisions.md exists, append a summary entry:
### {today's date} — Plan Execution Summary
Executed IMPLEMENTATION_PLAN.md: {done}/{total} tasks succeeded, {failed} failed.
**Completed:**
- {task-id} — {title}
- {task-id} — {title}
...
**Failed:**
- {task-id} — {title} (reason: {brief error description})
...
Resume Support
If the user says "continue the plan" or "pick up where I left off":
- Read
IMPLEMENTATION_PLAN.md
- Count how many tasks are
[x] (done), [!] (failed), and [ ] (pending)
- If no pending tasks remain, say: "All tasks are already complete! Nothing left to do."
- If pending tasks exist, display progress and start the execution loop from the first
[ ] task:
📋 Resuming plan: {done}/{total} tasks already complete. Picking up at: {task-id} — {title}
Previously completed [x] tasks are always skipped. Failed [!] tasks are also skipped — the user must manually change [!] back to [ ] in the plan file to retry them.
Auto-resume after interruption: After answering any user question, always show the resume banner and continue. The only exception is an explicit stop command or a task rejection.
Single-Task Mode
"What's next in the plan?"
If the user asks what the next task is (without asking to execute it):
- Read
IMPLEMENTATION_PLAN.md
- Find the first
[ ] task
- Display it without executing:
📋 Next up: {task-id} — {title}
({done}/{total} tasks complete so far)
Say "run the plan" to start executing, or "implement {task-id}" to do just this one task.
"Implement {task-id}"
If the user names a specific task ID:
- Read
IMPLEMENTATION_PLAN.md
- Find the task with that ID, regardless of its position in the file
- If the task is
[x] (done): "That task is already complete."
- If the task is
[!] (failed): "That task previously failed. I'll retry it now." Then change [!] to [ ] and execute it.
- If the task is
[ ] (pending): Execute it using the same implement → validate → update → commit flow from Step 3
- After completing the single task, stop. Don't continue to other tasks.
Important Reminders
- Be autonomous. Don't ask "should I proceed?" between tasks. The user said "run the plan" — that means run all of it.
- Write real code. Every task should produce actual, working files. No stubs, no
// TODO: implement this, no placeholder functions that throw "not implemented" errors.
- Follow the project's conventions. If
forge-memory/patterns.md says "use 2-space indentation" or "use single quotes", follow that. If the existing code uses a specific folder structure, match it.
- One commit per task. This creates a clean git history where each commit maps to one plan task. It also makes it easy to revert a single task if needed.
- Don't modify the plan format. When updating checkboxes, only change
[ ] to [x] or [!]. Don't reformat the file, don't change task IDs, don't reorder tasks.
- Handle missing context gracefully. If
FORGE.md doesn't exist, you can still run the plan. If forge-memory/ doesn't exist, skip the decision logging. Never fail because an optional file is missing.
Memory Feedback Loop
During autonomous execution, write significant decisions back to memory:
-
After each completed task, append a one-liner to forge-memory/decisions.md:
### {date}: Completed {task-id}
**What:** {brief description of what was built}
**Stack choices:** {any libraries or patterns chosen during implementation}
-
If you establish a new pattern (e.g., chose a specific error handling approach), add it to forge-memory/patterns.md
-
If the user says "remember that..." or "forge remember: ...", immediately write it to forge-memory/decisions.md
This ensures the memory system improves with every task, not just during wizard runs.