diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-11 17:12:49 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-11 17:12:49 -0500 |
| commit | a9ef07d9ac9bf07b8c686030320a9c9991d10b26 (patch) | |
| tree | bad752a690bac185d9746e55e9326f311e8564fc | |
| parent | 072db415485ee49a8d2a3ca2b34556d2d9daf393 (diff) | |
| download | rulesets-a9ef07d9ac9bf07b8c686030320a9c9991d10b26.tar.gz rulesets-a9ef07d9ac9bf07b8c686030320a9c9991d10b26.zip | |
docs(start-work): add Phase 0 pre-work (reconcile + source check)
Phase 0 was a single eligibility gate. Two gaps: the skill cut new branches from whatever HEAD happened to be, and trusted the ticket's premise without checking the tree.
Two new sub-sections fix both before any state change. 0.2 fetches and fast-forwards the base branch, surfacing dirty or diverged state instead of auto-resolving. 0.3 reads the source, not git log, to confirm the problem the ticket describes still exists, with three dispositions for "the problem isn't there" findings: close, dig harder, or proceed with reduced confidence flagged at the Justify gate.
Two matching anti-patterns added: skipping the reconcile, and taking the ticket's word for it.
| -rw-r--r-- | .claude/commands/start-work.md | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/.claude/commands/start-work.md b/.claude/commands/start-work.md index 2224490..b9e87c8 100644 --- a/.claude/commands/start-work.md +++ b/.claude/commands/start-work.md @@ -1,5 +1,5 @@ --- -description: Pick up a task (Linear ticket, GitHub issue, todo.org task, or a described scope) and take it through Claim, Justify, Approach, Implement, Verify, and Hand-off. Three user-approval gates separate the phases. The Justify gate covers benefits, costs, engineer/user impact, urgency, effort, alternatives, and a ticket-quality check. The Approach gate covers root cause, risk, refactor prerequisites, test strategy (unit, integration, e2e, pairwise, characterization), migration and backwards-compat, feature-flag question, commit decomposition, and branch name. Implementation uses TDD (red, green, edge cases, refactor audit of every touched file). The audit walks the whole of each touched file against a language-agnostic checklist; every finding is either fixed on this branch or filed as a ticket — nothing is silently dropped. A verify phase exercises the feature end-to-end in the local environment (Playwright against localhost for web projects, scripted manual test otherwise) before the final gate confirms readiness and hands off to the Review-and-Publish flow in commits.md. Use when starting work on a specific task where both "should we" and "how exactly" are worth deliberating. Do NOT use for open-ended bug investigation without a clear target (use debug first), for architectural paradigm exploration (use arch-design), for architectural decision recording (use arch-decide), when the task is trivial and obvious (just do it), or when requirements are still being shaped (use brainstorm). +description: Pick up a task (Linear ticket, GitHub issue, todo.org task, or a described scope) and take it through Pre-work, Claim, Justify, Approach, Implement, Verify, and Hand-off. Three user-approval gates separate the phases. Pre-work covers eligibility, a fetch-and-reconcile against the base branch, and a source-code check that the problem the ticket describes still exists in the tree. The Justify gate covers benefits, costs, engineer/user impact, urgency, effort, alternatives, and a ticket-quality check. The Approach gate covers root cause, risk, refactor prerequisites, test strategy (unit, integration, e2e, pairwise, characterization), migration and backwards-compat, feature-flag question, commit decomposition, and branch name. Implementation uses TDD (red, green, edge cases, refactor audit of every touched file). The audit walks the whole of each touched file against a language-agnostic checklist; every finding is either fixed on this branch or filed as a ticket — nothing is silently dropped. A verify phase exercises the feature end-to-end in the local environment (Playwright against localhost for web projects, scripted manual test otherwise) before the final gate confirms readiness and hands off to the Review-and-Publish flow in commits.md. Use when starting work on a specific task where both "should we" and "how exactly" are worth deliberating. Do NOT use for open-ended bug investigation without a clear target (use debug first), for architectural paradigm exploration (use arch-design), for architectural decision recording (use arch-decide), when the task is trivial and obvious (just do it), or when requirements are still being shaped (use brainstorm). disable-model-invocation: true --- @@ -7,6 +7,7 @@ disable-model-invocation: true Three review gates separate the phases. The user can redirect or kill the work at each one. +0. **Pre-work.** Eligibility check, fetch-and-reconcile against the base branch, source-code check that the problem still exists. 1. **Claim.** Mark in-progress, assign, label, verify project. 2. **Justify (gate 1).** Benefits, costs, impact, urgency, effort, alternatives, ticket quality. Stop for approval. 3. **Approach (gate 2).** Root cause, risk, tests, migration, flag, commit decomposition. Stop for approval. @@ -30,7 +31,11 @@ Three review gates separate the phases. The user can redirect or kill the work a If the reference is ambiguous, ask the user to clarify before proceeding. -## Phase 0: eligibility +## Phase 0: pre-work + +Three checks before claiming the task. All run before any state change — no assignee added, no label written, no status moved. If any of them disqualify the task, the rollback is free. + +### 0.1 Eligibility Skip with a short note and stop if any apply: @@ -39,6 +44,48 @@ Skip with a short note and stop if any apply: - Task is an obvious duplicate of something in-progress. - Task description is so vague that even the Justify gate cannot engage. Route to `/brainstorm`. +### 0.2 Pre-flight reconcile + +The branch this task will be cut from must reflect the remote — otherwise the work happens on a stale base and Phase 4 starts from a phantom HEAD. Same shape as `commits.md` Step 0. + +1. `git fetch --all --prune`. +2. Identify the base branch the working branch will be cut from. Usually `main`, but `develop` or `release/*` for projects that use them. Ask the user if it isn't obvious from `git log` or project docs. +3. Check the base against its upstream: + + git rev-list --left-right --count @{u}...<base> + + Decide based on the pair: + + - **0 behind** — no-op. Continue. + - **Behind only, clean tree, on the base branch** — fast-forward: `git merge --ff-only @{u}`. + - **Behind only, non-checkout base** — `git fetch . origin/<base>:<base>` advances the ref without touching the working tree. + - **Behind only, dirty tree on the base** — surface to the user. Don't auto-stash or auto-merge. Offer to commit, stash, or skip the reconcile and proceed knowing the new branch will be cut from a stale base. + - **Diverged (behind AND ahead)** — surface to the user. Ask whether to rebase, merge, or skip. Don't auto-resolve. + +4. If the current branch is *not* the base branch (e.g. left over from a prior task), surface and ask whether to switch before continuing. Don't auto-switch — the user may want to finish or stash WIP first. + +### 0.3 Existence check (validate the problem is real) + +The ticket may describe a problem the code no longer has — fixed independently of the ticket, made obsolete by another change, or never present in the first place. Read the source to confirm the problem exists in the tree as the ticket describes, before justifying or planning the fix. + +The check is on the **source code**, not on commit messages. A `git log --grep` catches the obvious "someone shipped this last week" case but misses what matters: a behavior no longer reachable, a guard added in a sibling commit, a refactor that incidentally removed the surface the bug lived on, a feature already implemented under a different name. The code is the truth; the log is a hint. + +For **bugs**: read the code path the ticket describes. Confirm the buggy behavior is present in the source as written. If the repro steps in the ticket are concrete enough to run — a CLI command, a UI sequence, a unit test against the path — run them against the freshly-reconciled base. If both the code-read and the repro say the bug doesn't fire, surface to the user with three options: + +- (a) Close as already-fixed (or never-present). Note in the close-out what the code actually does so a future reader sees why the ticket got dropped. +- (b) Repro steps in the ticket are stale or incomplete. Ping the author or dig for a real repro before proceeding. +- (c) The bug fires under conditions not yet reproduced. Proceed to Phase 1 with reduced confidence; flag this in the Justify gate so the user can redirect. + +For **features**: read the source at the surface the feature would touch — file paths the ticket names, function or route names, config keys. Search for behavior, not just for names — a feature implemented under a different name still counts. If the code already does what the ticket asks for: + +- (a) Already implemented. Close as already-done. +- (b) Partially implemented. Re-scope the ticket to what's left and proceed. +- (c) Implemented in a shape the ticket explicitly asks to change. Proceed with the ticket's design. + +For **tests and chores**: usually skip — the work is the work. The exception is a test-for-existing-behavior ticket where the test may have been added since filing; one quick check of the test directory is enough. + +If the existence check finds nothing conclusive, that's the expected case. Proceed to Phase 1. + ## Phase 1: claim Make ownership explicit before any other work starts. The exact steps depend on where the task lives. @@ -245,6 +292,8 @@ Follow `commits.md` exactly. Summary of the flow: ## Anti-patterns +- **Skipping the pre-flight reconcile.** Cutting a new branch from a stale base means the whole task happens on top of yesterday's main. Conflicts surface at PR time instead of at the start; rebases later are noisier than a fetch up front. +- **Taking the ticket's word that the problem still exists.** Tickets age. Read the source. A `git log --grep` for a fix commit is a hint, not a check — fixes ship under all kinds of commit-message wording, and the buggy behavior may be gone for reasons that never landed in a commit titled "fix." Five minutes of source-read at Phase 0.3 saves an entire Justify-and-Approach cycle on a phantom problem. - **Skipping the Justify gate.** "This is obviously worth doing" is exactly what the gate exists to verify. If the answer really is obvious, the gate takes thirty seconds. - **Skipping the Approach gate.** Implementation without a plan is how scope creep happens. It is also how the user loses the chance to redirect. - **Marking a task In Progress before Phase 2 approval.** If the Justify gate kills the task, the Claim should roll back cleanly. |
