---
name: general-dev-workflow
description: Structured development workflow for any project. Guides you through Plan → Issue → Implement → Test → PR with checkpoints at each stage to ensure code quality, thorough testing, and well-documented PRs before merge. Use this whenever starting a new feature, bug fix, or change — regardless of tech stack or platform (GitHub, GitLab, Gitea, etc.). Works locally or with remote repositories.
compatibility: Git, GitHub/GitLab/Gitea (auto-detected)
---

# General Development Workflow

This skill guides you through a structured, repeatable development workflow that works across any tech stack and version control platform. The goal is to ensure consistent, high-quality code while reducing context-switching and providing clear checkpoints.

## The 5-Phase Workflow

### Phase 1: Plan
**Goal**: Define the change clearly before writing code.

Start by answering:
- **What** are you building/fixing? (Brief 1-2 sentence summary)
- **Why** does it matter? (Problem it solves, value it adds)
- **Scope**: What's included? What's NOT included? (Define boundaries early)
- **Success criteria**: How will you know it's done? (Tests pass, performance improves, etc.)
- **Dependencies**: Does this require changes elsewhere? Do other features depend on this?
- **Risks**: What could go wrong? (Breaking changes, performance issues, etc.)

**Output**: A clear plan document or issue description ready for the next phase.

**Checkpoint**: Does the plan make sense? Is scope realistic? Have you thought through edge cases?

---

### Phase 2: Create Issue (in your VCS)
**Goal**: Formally track the work — and the time spent on it — starting from the moment the plan is approved.

> ⚠️ **Create the issue only after the plan has been reviewed and approved.** The issue marks the official start of implementation, so its creation timestamp doubles as the implementation start time. Do not create it speculatively while the plan is still being discussed.

Steps:
1. **Detect your VCS platform**: GitHub, GitLab, Gitea, or local-only?
2. **Create the issue** with:
   - Title matching your plan summary
   - Description from Phase 1 (what, why, scope, success criteria)
   - A `## Time tracking` section at the bottom with `Started: <date/time>` — this lets you measure implementation duration later
   - Any relevant labels/tags (bug, feature, enhancement, etc.)
   - Assignment (if applicable)
3. **For local-only work**: Create a text file or branch-based tracking if you prefer

**Output**: Issue link (or local tracking document) that you'll reference in commits and in the PR.

**Checkpoint**: Can someone else understand the work from this issue? Would they know how to verify it's done?

> 🕐 **Do not close the issue here.** It stays open until the PR is merged (Phase 5).

---

### Phase 3: Implement
**Goal**: Write code that solves the problem defined in the plan.

**Before you start coding:**
- Create a branch (e.g., `feature/user-auth`, `fix/api-latency`) that references your issue
- Name the branch clearly so it's easy to track what you're working on

**While coding:**
- Break work into logical, reviewable commits (not one giant commit)
- Write commit messages that explain *why*, not just *what*
  - Bad: "fix bug"
  - Good: "fix race condition in event handler by adding mutex lock — prevents duplicate events when rapidly clicking"
- Follow the project's code style and conventions
- Write code you'd be comfortable having someone else maintain

**As you finish sections:**
- Test locally (Phase 4 will be formal testing, but catch obvious issues early)
- If you realize the scope has changed, update your Phase 1 plan and issue

**Output**: Commits on your branch that are ready for review.

**Checkpoint**: Does each commit stand alone? Would a reviewer understand why each change was made?

---

### Phase 4: Test
**Goal**: Verify the code works correctly and doesn't break existing functionality.

**Build verification (critical for compiled languages):**
- Run `dotnet build <solution>` (for .NET projects) or equivalent build command for your tech stack
- Fix any compilation errors before proceeding
- If your project has multiple build targets, test all of them (e.g., multiple Dockerfiles, web + API)
- **Docker projects**: Run `docker compose --build` to verify all Docker images build successfully
- Check build artifacts exist and are correct size (no suspiciously small binaries)

**Docker container startup verification (required for Docker projects):**
- After successful build, run `docker compose up -d` to start all containers
- **Wait 10-15 seconds** for services to initialize (database migrations, seeding, etc.)
- Run `docker compose ps` and verify all containers have status **Up** (not Restarting or Exited)
- Run `docker logs <service>` for each container and verify:
  - No errors or fatal exceptions in startup logs
  - Services logged successful initialization (e.g., "startup complete", "listening for requests")
  - Database migrations completed successfully (if applicable)
  - Configuration loaded without errors
- **This is not optional for Docker changes** — a container that restarts means the change is incomplete
- If any container fails to start, the build is not successful until fixed

**Why build AND startup verification matters:**
- Catches missing dependencies, import errors, and configuration issues early
- Docker builds catch missing project references and file copies, but don't catch runtime config problems
- Missing appsettings files, invalid environment variables, or database connection issues only show up at runtime
- A failed startup blocks entire services in production — this must be caught before code review
- A failed build blocks reviewers and CI/CD pipelines; a failed startup blocks production deployments

**Write tests for your changes:**
- Unit tests for individual functions/methods
- Integration tests if your code touches multiple systems
- Edge case tests (null inputs, boundary conditions, etc.)
- Regression tests to ensure you didn't break something else

**Run existing tests:**
- Do all tests pass? Fix failures in Phase 3 code
- Check code coverage. Did you test your changes?

**Manual testing:**
- Does the feature work as described in the plan?
- Did you test the success criteria from Phase 1?
- Test on different inputs/environments if relevant

**Test results document** (save for Phase 5 PR):
- Which tests were added?
- What's the coverage? (old → new)
- Any manual testing notes
- Known limitations or edge cases not yet tested

**Output**: Passing tests, code coverage report, test summary, successful build, containers running successfully (for Docker projects).

**Checkpoint**: Does the code compile without errors? Do all Docker containers start and stay running (status: Up)? No errors in container logs? Can you confidently say the code works? Are there any untested paths you're worried about?

---

### Phase 5: Create Pull Request
**Goal**: Get code reviewed and merged into `main`, and automatically close the tracking issue on merge.

**Before opening the PR:**
- Rebase onto the latest `main`/`master` (avoid merge commits if possible)
- Verify all tests still pass
- Check for merge conflicts
- The PR **must target `main`** (or the project's primary branch) — never merge directly without a PR

**PR Description** (use this template):
```
## What
Brief summary of the change (one sentence)

## Why
Problem it solves / value it adds (2-3 sentences)

## Changes
- Major code change 1
- Major code change 2
- (Be specific—help reviewers understand scope)

## Testing
- Tests added: [list test files or test count]
- Coverage change: [old % → new %]
- Manual testing: [describe what was tested]

## Risk Assessment
- Breaking changes? [yes/no, if yes: explain migration path]
- Performance impact? [none/minor/significant]
- Closes #<issue-number>

## Checklist
- [ ] All tests passing
- [ ] Code review ready
- [ ] Documentation updated (if needed)
- [ ] No merge conflicts
```

> 🔗 **Always include `Closes #<issue-number>`** in the PR body. On GitHub and Gitea this auto-closes the issue the moment the PR is merged into the target branch — no manual close needed.

**During review:**
- Respond to feedback promptly
- If changes are requested, make them and push again (don't force-push)
- Ask for clarification if feedback is unclear

**Merge criteria** (before merging):
- ✅ All tests pass
- ✅ Approved by at least one reviewer (adapt to your team's policy)
- ✅ No unresolved discussions
- ✅ No merge conflicts

**After the PR is merged:**
- Verify the issue was automatically closed by the `Closes #N` keyword
- If the platform did not auto-close it, close it now and add a comment with the merge commit SHA and the elapsed time (issue `Created` timestamp → merge timestamp)
- **Never close the issue before the PR is merged** — an open issue means work is still in progress

**Output**: Merged PR with clear history and review comments; issue automatically closed.

**Checkpoint**: Is the code in `main`? Is the issue closed? Did you record the implementation duration in the issue?

---

## Workflow Summary (Quick Reference)

| Phase | Input | Output | Checkpoint |
|-------|-------|--------|-----------|
| 1. Plan | Problem description | Approved plan document | Scope and success criteria defined? Plan reviewed and approved? |
| 2. Issue | **Approved** plan | Issue/ticket link + start timestamp | Is it understandable to others? Issue open (not closed)? |
| 3. Implement | Issue/ticket | Commits on feature branch | Are commits logical and well-messaged? |
| 4. Test | Code on branch | Passing tests + coverage report | Are edge cases covered? |
| 5. PR | Tests passing | PR merged into `main`; issue auto-closed via `Closes #N` | Is `main` updated? Is the issue closed? Duration recorded? |

---

## Tips for Success

**Keep phases focused.** Don't mix planning with implementation. Don't test in Phase 2. This separation helps catch problems early.

**Verify builds AND container startup before review.** Always run a full build (`dotnet build` or `docker compose --build`) in Phase 4 before opening the PR. **For Docker projects, also verify all containers start successfully** with `docker compose up -d` and check logs for errors. Build errors block reviewers; startup failures block deployments. Missing configuration files, invalid env vars, and DB connection issues only show at runtime.

**Commit frequently.** Small commits are easier to review, easier to revert if needed, and easier to understand. Aim for 50-200 lines per commit.

**Write for your future self.** Six months from now, you'll read your own commits and PRs. Make them clear.

**Catch blocking issues early.** If Phase 1 reveals something complex or risky, discuss it with your team *before* you code.

**Adapt to your team.** If your team requires code owners approval, or has a specific PR template, use those instead of the defaults here. The phases stay the same; the details adapt.

---

## For Different Platforms

**GitHub**: Issues are native. Use GitHub's PR template and auto-linking (`Closes #123`).

**GitLab**: Merge Requests (MRs) replace PRs. Pipeline status is built-in. Use GitLab's merge request template.

**Gitea**: Similar to GitHub. Use Gitea's PR templates and linking.

**Local/No Platform**: Create a `.github` folder locally with your own issue and PR templates. Track work via commit messages and branch names.

---

## Common Questions

**Q: Can I skip Phase 2 (create issue)?**
A: If you're working solo on a small fix, maybe. But issues are useful for: remembering *why* you made a change, helping others understand work in progress, tracking what's been done, and measuring how long implementation actually takes. Recommended even for solo developers.

**Q: When exactly should I create the issue?**
A: Only after the plan (Phase 1) has been reviewed and approved. The issue creation timestamp marks the official start of implementation and serves as the start of your time-tracking window. Creating it during planning inflates the recorded duration.

**Q: When should I close the issue?**
A: Never close it manually before the PR is merged. Use `Closes #N` in the PR body — the platform (GitHub/Gitea) will close it automatically when the PR merges into the target branch. If auto-close doesn't trigger, close it immediately after merge and note the elapsed time.

**Q: How do I track implementation time?**
A: The issue creation time is your start. The issue close time (= PR merge time) is your end. To make this explicit, add a `## Time tracking` section to the issue body with `Started: <date/time>` when you create it. After merge, update or comment with `Completed: <date/time> — Duration: X hours/days`.

**Q: What if my plan changes mid-implementation?**
A: Update your issue/plan (Phase 1) to reflect the new scope. Let your team know if scope grew significantly.

**Q: How big should commits be?**
A: Aim for "one logical change per commit." If you're changing authentication and fixing a typo, those are two commits. A good rule: can you describe the commit in one clear sentence without "and"?

**Q: Do I need tests for everything?**
A: Write tests for anything that could break. UI color changes? Maybe not. API endpoint behavior? Definitely. If you're unsure, write the test.
