You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(implement): make OpenSpec mandatory when configured (Phase 0) (#13)
* feat(implement): make OpenSpec mandatory when configured (Phase 0)
Introduces a new Phase 0 in /make-no-mistakes:implement that runs BEFORE
Phase 1 (Setup). When linear-setup.json has openspec.changesPath
configured, every issue MUST have a corresponding OpenSpec change
(proposal.md + design.md + tasks.md) before implementation begins.
Previously, step 4b in Phase 2 read OpenSpec context only "if found",
which made the spec-first discipline silently skippable. Since OpenSpec
was officially adopted at Dojo Coding on 2026-03-30 (Slack thread
C0AE5MKAX7B), that gap re-introduces exactly the failure mode adoption
was meant to prevent: implementations diverging from intent because
nobody wrote the intent down.
Behavior change:
- When openspec.changesPath is set AND the issue is non-trivial
(>2 files, architectural decisions, or reviewer-flagged risk),
the implementer STOPS and creates the OpenSpec change as the
first commit on the implementation branch.
- Trivial issues (typo fixes, dependency bumps, single-line changes)
may opt out with a one-line PR note.
- Repos without openspec.changesPath are unaffected — Phase 0 is
skipped entirely, preserving back-compat.
Bumps version to 1.4.1 across plugin.json, marketplace.json, and
package.json.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(implement): use \$CHANGES_PATH in step 4a + renumber phases sequentially
Greptile re-review on PR #13 caught two real defects in the new Phase 0/Phase 1 text:
1. Phase 1 step 4a's git add command used an undefined placeholder
"{changes-path}" — the variable established in Phase 0 step 1 is
"\$CHANGES_PATH" (set via jq from linear-setup.json). An agent
running the step verbatim would stage nothing, producing an empty
first commit and silently breaking the spec-first guarantee the
entire phase enforces. Step 4a now re-exports CHANGES_PATH inside
the worktree (the parent shell's variable doesn't survive the cd
into a fresh worktree) and uses "\$CHANGES_PATH/{change-slug}/"
in the git add.
2. The original document restarted step numbering at 4 in Phase 2,
colliding with Phase 1's existing step 4 + 4a. Cross-phase
references like "step 4" became ambiguous. Renumbered the entire
chain so steps run sequentially across all four phases:
- Phase 1: 1, 2, 3, 4, 4a
- Phase 2: 5, 6, 7
- Phase 3: 8, 9, 10, 11, 12
- Phase 4: 13, 14, 15, 16, 17
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(implement): make step 4a's source path explicit via git worktree list
Greptile re-review on PR #13 caught a P1 ambiguity in step 4a: Phase 0
drafts spec files in the main working tree at {main-tree}/\$CHANGES_PATH/
{change-slug}/, but Phase 1 step 3 cd's into a freshly created worktree
that does NOT carry over uncommitted files. The previous wording said
"move/copy if not already there" without naming the source path — an
agent inside the worktree could resolve it incorrectly and end up
running git add on a non-existent path, producing a silently empty
docs(openspec) commit and defeating the spec-first guarantee.
Step 4a now:
1. Re-exports \$CHANGES_PATH inside the worktree (the parent shell's
variable doesn't survive the cd).
2. Computes \$MAIN_TREE via git worktree list --porcelain (first
entry is always the primary tree, regardless of which worktree we're
currently in).
3. Skips the copy when the directory already exists in the worktree
(idempotent on retry).
4. Copies "\$MAIN_TREE/\$CHANGES_PATH/{change-slug}" into the worktree
before git add — explicit, unambiguous, agent-runnable verbatim.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(implement): bind {change-slug} as $CHANGE_SLUG + define naming rule
Greptile round-4 caught the same class of defect as round 2 but for a
different placeholder: {change-slug} was a bare template literal in the
step 4a bash block, sitting next to a properly bound \$CHANGES_PATH. An
agent running the block verbatim would execute
git add "\$CHANGES_PATH/{change-slug}/"
which stages a literal path containing the brace string — staging
nothing — and produces a silently empty docs(openspec) commit.
Two paired fixes:
1. Phase 0 step 3 now states the slug naming convention explicitly:
{issue-id-lowercase}-{short-kebab-description} (lowercase ASCII +
hyphens, e.g. doj-3946-atomic-primitives-sprint). Same shape as
the implementation branch so agents and humans converge on the same
directory name across runs.
2. Step 4a bash block now binds CHANGE_SLUG="<change-slug>" at the top
(placeholder agents/humans MUST replace before running) and uses
"\$CHANGE_SLUG" in every file path expression. mkdir/cp/git add/git
commit all reference the bound variable, so verbatim execution
produces a non-empty commit even if the surrounding text is unread.
Documentation-template uses of {change-slug} elsewhere in the file are
left intact — they refer to the literal directory name in prose, not
shell variables, and agents reading prose interpret them correctly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
"description": "The disciplined dev lifecycle — implement issues, review PRs, sync releases, test E2E, manage sessions, and stash secrets via OS-native prompts. One plugin to make no mistakes.",
6
6
"owner": {
7
7
"name": "Luis Andres Pena Castillo",
@@ -11,7 +11,7 @@
11
11
{
12
12
"name": "make-no-mistakes",
13
13
"description": "Dev lifecycle orchestrator: disciplined Linear issue execution with worktree isolation, PR review with Greptile gating, team release sync, E2E test generation and execution, test suite previewer, security pentesting, MoSCoW + RICE prioritization, cross-platform secret stash via OS-native GUI prompts (zenity / kdialog / osascript / Get-Credential), and session management. 18 commands, 6 auto-activating skills, 2 specialized agents.",
Copy file name to clipboardExpand all lines: .claude-plugin/plugin.json
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
{
2
2
"name": "make-no-mistakes",
3
-
"version": "1.5.0",
3
+
"version": "1.6.0",
4
4
"description": "The disciplined dev lifecycle — implement issues, review PRs, sync releases, test E2E, manage sessions, stash secrets, and enforce manifest-driven tool-call hooks. One plugin to make no mistakes.",
Copy file name to clipboardExpand all lines: commands/implement.md
+73-24Lines changed: 73 additions & 24 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -181,6 +181,37 @@ If any check fails, STOP and resolve before proceeding.
181
181
182
182
For EACH issue in the sequence, follow this exact workflow. No shortcuts. No exceptions.
183
183
184
+
### Phase 0: OpenSpec Context (MANDATORY when configured)
185
+
186
+
Run this BEFORE Phase 1 (Setup). If `linear-setup.json` has `openspec.changesPath`:
187
+
188
+
1.**Resolve the configured changes directory** and check for an existing OpenSpec change that references this issue. The grep MUST use the configured path — projects may set `openspec.changesPath` to anything (e.g., `specs/changes/`) and a hardcoded `openspec/changes/` would silently miss every existing spec there:
-`<changes>/{change-slug}/tasks.md` — atomic task list with file paths and commit messages
199
+
200
+
These three files are the CONTRACT. The Linear issue is the WHAT; OpenSpec is the HOW. Do not deviate from the spec without going back to it first.
201
+
202
+
3.**If MISSING and the issue is non-trivial** (touches >2 files OR involves architectural decisions OR has reviewer-flagged risk): STOP and prepare the OpenSpec change BEFORE proceeding.
203
+
- Use `/superpowers:brainstorming` if the design needs more thinking
204
+
- Use `/make-no-mistakes:premortem` if the change is load-bearing in production
205
+
-**Compute the change slug deterministically** so every later step (and any restart) targets the same directory. The slug MUST follow the same shape as the implementation branch: `{issue-id-lowercase}-{short-kebab-description}` (e.g., `doj-3946-atomic-primitives-sprint`). Lowercase only, ASCII alphanumerics + hyphens, no leading/trailing hyphens, no other separators.
206
+
-**Draft the three artifacts** in `<changes>/<change-slug>/`: proposal.md (intent + scope + out-of-scope), design.md (decisions + rationale), tasks.md (atomic checklist with commit messages). Leave them uncommitted on disk — the implementation branch does not exist yet.
207
+
-**Defer the commit to Phase 1 step 4a** (below). Phase 1 creates the branch and worktree; the OpenSpec files are then committed as the very first commit on that branch.
208
+
209
+
4.**If MISSING but the issue is trivial** (typo fix, dependency bump, single-line change): proceed to Phase 1 without OpenSpec. Add a one-line note to the PR description explaining why OpenSpec was skipped.
210
+
211
+
5.**If `openspec.changesPath` is not configured** in `linear-setup.json`: skip this phase entirely. The project hasn't adopted OpenSpec yet.
212
+
213
+
**Why mandatory**: per the adoption decision (Slack 2026-03-30, channel C0AE5MKAX7B), OpenSpec is the durable persistence of design decisions. A skill that makes it optional re-introduces the failure mode it was adopted to prevent — implementations diverging from intent because nobody wrote the intent down.
214
+
184
215
### Phase 1: Setup
185
216
186
217
1.**Claim the issue in Linear:**
@@ -209,24 +240,42 @@ For EACH issue in the sequence, follow this exact workflow. No shortcuts. No exc
209
240
- Create sub-issues in Linear for each PR if decomposing.
210
241
- Comment the decomposition plan on the parent issue.
211
242
212
-
### Phase 2: Implement
243
+
4a. **Commit the OpenSpec change as the first commit** (only if Phase 0 step 3 drafted artifacts because none existed):
244
+
- Phase 0 wrote the artifacts to the **main working tree** at `{main-tree}/$CHANGES_PATH/<change-slug>/`. Phase 1 step 3 created a fresh worktree from `{baseBranch}`, which does NOT carry over those uncommitted files. Copy them into the current worktree explicitly. The `CHANGE_SLUG` value MUST match the slug Phase 0 step 3 chose (same `{issue-id-lowercase}-{short-kebab-description}` rule):
245
+
```bash
246
+
# Inside the new worktree (Phase 1 step 3 cd'd here).
- The `docs(openspec)` commit MUST be commit #1 on the branch — reviewers and future agents read the spec before the diff.
265
+
- If Phase 0 found an existing change (step 2), skip this entire step — the spec is already on `{baseBranch}` and inherited by the new worktree.
213
266
214
-
4.**Implement in the worktree.** Follow all project conventions from CLAUDE.md.
267
+
### Phase 2: Implement
215
268
216
-
4b. **Check for OpenSpec context:**
217
-
- If `linear-setup.json` has `openspec.changesPath`, check if an OpenSpec change exists that references this issue
218
-
- Look in `openspec/changes/*/proposal.md` for the issue ID
219
-
- If found, read ALL artifacts (proposal.md, design.md, tasks.md) as implementation context
220
-
- This provides richer context than the Linear issue description alone
269
+
5. **Implement in the worktree.** Follow all project conventions from CLAUDE.md. If Phase 0 produced an OpenSpec change, treat its `tasks.md` as the authoritative checklist — work through it in order and do not improvise file paths or commit messages outside the spec.
221
270
222
-
5.**If multiple approaches exist:**
271
+
6. **If multiple approaches exist:**
223
272
- Dispatch one sub-agent per approach via Mode A (each gets its own worktree automatically)
224
273
- Run all approaches in parallel with `run_in_background: true`
225
274
- Each approach may discover new issues — document them in its final report
226
275
- Synthesize the best parts of multiple solutions if needed
227
276
- Close losing sub-agent branches/PRs after synthesis
228
277
229
-
6.**Write tests:**
278
+
7. **Write tests:**
230
279
- Model E2E test cases with Slack MCP first (plan them in a test channel or thread)
231
280
- Split test cases: some for**Playwright**, others for**Chrome DevTools MCP**
232
281
- Browser ALWAYS in focus. **NEVER headless.** Both Playwright and Chrome DevTools MCP.
@@ -238,33 +287,33 @@ For EACH issue in the sequence, follow this exact workflow. No shortcuts. No exc
Copy file name to clipboardExpand all lines: package.json
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
{
2
2
"name": "@lapc506/make-no-mistakes",
3
-
"version": "1.5.0",
3
+
"version": "1.6.0",
4
4
"description": "The disciplined dev lifecycle — implement issues, review PRs, sync releases, test E2E, manage sessions, stash secrets, and enforce manifest-driven tool-call hooks (no SSH+DB, no manual prod, no minified build, no secret leaks, Slack format). OpenCode + Claude Code plugin.",
0 commit comments