Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions commands/tech-plan-doc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
description: Consolidate a completed tech-plan's learnings and decisions into a Slite page for end users and future engineers.
argument-hint: [optional: path to tech-plan.md]
---

# /tech-plan-doc — Slite Write-Up

Run after **all** steps in a `tech-plan.md` are done. Consolidates the plan's `Decisions & corrections`, `Notes / learnings`, and PR links into a Slite page aimed at end users and future engineers.

## Inputs

`$ARGUMENTS` — optional path to a specific `tech-plan.md`. The plan can live anywhere — in this docs repo, another repo, or an arbitrary path. If empty, search starting from cwd, then `specs/`, `docs/`, repo root, and `~/dev/dam-creation-specifications/specs/projects/`. If multiple exist, ask which one. If none found, ask the user for the path.

---

## Phase 1: VALIDATE

Read the plan. Check:
- **Plan status is `In progress`.** Reject `Draft`, `Reviewing`, `Approved`, `Done`, `Superseded`. (Edge case: a plan that skipped tracker sync may be in `Synced` instead — accept with explicit user confirmation.)
- **All steps are in a terminal state** — `merged`, `skipped`, or `superseded`. Steps in `pending`, `in_progress`, `pr_open`, or `blocked` block the write-up. List any non-terminal steps and ask the user to resolve them before continuing.
- Every `merged` step has a `PR:` URL.
- `Decisions & corrections` and `Notes / learnings` are non-empty (otherwise there's not much to write up — confirm the user still wants to proceed).

If anything is missing, list the gaps and ask whether to proceed anyway, fix the plan first, or abort.

---

## Phase 2: DRAFT

Build a Slite-flavored markdown writeup. **Audience: end users and future engineers**, not the team that just shipped it. Lead with what changed for users, not the technical journey.

Structure:

```markdown
# [Initiative Title]

**Shipped:** YYYY-MM (latest PR merge month)
**Spec:** [link to .spec.md on GitHub]
**Tech plan:** [link to tech-plan.md on GitHub]

## What changed

[2–4 sentences. User-visible behavior. Plain language. No jargon. Pull from the functional spec's Goal + acceptance criteria.]

## How it works now

[Brief description of the new behavior. If this was a migration, describe the new shape — not the old one. If a flag was introduced, name it and where it lives.]

## Migration approach (for engineers)

[One paragraph. The expand/contract / flag-ramp / additive shape we used. Why. Pulled from the plan's Migration strategy section.]

## Key decisions

[Bulleted, from Decisions & corrections. Each bullet: the decision + one-line why.]

## Gotchas and learnings

[The meaty section. From Notes / learnings. Things that surprised us, things future engineers should know, edge cases discovered during implementation.]

## Reference

- Functional spec: [link]
- Tech plan: [link]
- PRs:
- Step 1 — <title>: [PR link]
- Step 2 — <title>: [PR link]
- ...
- Tracker: [parent ticket link]
```

Show the draft inline. Ask the user to review and request edits. Iterate until they approve.

---

## Phase 3: PUBLISH

**Always ask the user where in Slite the page should go.** Do not assume a default space or parent doc.

Ask:
- Which **Slite space** (e.g. Engineering, Product Docs, a team-specific space)?
- Which **parent doc/folder** within that space, if any?
- Final **page title** (default to the initiative title)?

Then create the page via the Slite MCP tool (`mcp__slite__` or `mcp__claude_ai_Slite__` — authenticate if needed). Capture the resulting page URL.

If creation fails, save the draft to `<dir-of-spec>/slite-draft.md` and tell the user to publish manually.

---

## Phase 4: WIRE BACK

After publishing:
- Update `tech-plan.md` — add a `**Slite write-up:**` line near the top with the page URL.
- **Transition plan status: `In progress → Done`.** Validate against the plan's State machine — if not currently in `In progress`, refuse and surface the inconsistency to the user.
- Update `Last updated:` to today.

Print the Slite URL. Done.

---

## Don'ts

- Don't publish without showing the draft first.
- Don't pick a Slite location without asking.
- Don't include code-level detail unless it's a genuine gotcha — the audience is broader than the implementing team.
- Don't duplicate the functional spec — link to it.
138 changes: 138 additions & 0 deletions commands/tech-plan-progress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
---
description: Sync a tech-plan step's status with its PR (opened/merged/closed), update the tracker ticket, and capture learnings.
argument-hint: [optional: PR url or path to tech-plan.md]
---

# /tech-plan-progress — Sync Step Status

Run after opening, merging, or closing a PR for a step in `tech-plan.md`. Updates the step's status to match the PR state (`pr_open` / `merged` / `in_progress`), syncs the tracker ticket to a matching status, and captures any learnings.

Idempotent — re-run it across a step's lifecycle (after opening the PR, after merging, after a force-close, etc.).

## Inputs

`$ARGUMENTS` — optional. Either:
- A PR URL (`https://github.com/.../pull/123`), or
- A path to a specific `tech-plan.md` (when multiple are active)

If empty, infer everything from current branch and `gh`.

---

## Phase 1: LOCATE THE PLAN AND STEP

1. **Find the active `tech-plan.md`:**
- If `$ARGUMENTS` is a path ending in `tech-plan.md`, use it.
- Else, the plan can live anywhere (this docs repo, another repo, an arbitrary path). Search broadly: start at cwd, then check common locations like `specs/`, `docs/`, the repo root, and `~/dev/dam-creation-specifications/specs/projects/`. Use `find <path> -name tech-plan.md -not -path '*/node_modules/*'`.
- If multiple exist, match by current branch name to a step's `Branch:` field. If still ambiguous, ask the user which one.
- If none found, ask the user for the path.

2. **Identify the step in progress.** Try in order, stopping at the first unique match:
- **PR URL match** (when `$ARGUMENTS` is a URL or `gh pr view` returned one): match the URL against each step's `PR:` field. Useful when the user has already switched off the branch (e.g. marking a step `merged` from `main`).
- **Branch match:** `git rev-parse --abbrev-ref HEAD` against each step's `Branch:` field.
- **Step ID prompt:** ask the user which Step `ID:` (e.g. `step-03-backfill`) corresponds to this PR. Step IDs are stable across renames and reorders, so this is the reliable fallback when branches have drifted.

3. **Read the step.** Confirm to the user: "Syncing Step N (`<ID>`): <title>." Wait for one-line confirmation if anything looks off; otherwise proceed.

---

## Phase 2: GET THE PR

1. If `$ARGUMENTS` is a URL, use it.
2. Else, run from the code repo with the PR's branch checked out (typically `~/dev/app-server/` or `~/dev/web-app/`):
```
gh pr view --json url,number,title,state --jq '.'
```
3. If no PR exists yet, tell the user and stop — this command is for **after** a PR is opened.
4. Note: the plan and the code may live in different repos. Don't assume cwd contains the plan.

---

## Phase 3: UPDATE THE PLAN

Determine the new step status from the PR's `state` field returned by `gh pr view`:
- `OPEN` → step status becomes `pr_open`
- `MERGED` → step status becomes `merged`
- `CLOSED` (without merge) → step status becomes `in_progress` (work resumes)

**Validate the transition against the plan's State machine.** Allowed paths from each current state:
- `pending → in_progress → pr_open → merged`
- `pr_open → in_progress` (PR closed without merge)
- `blocked` requires user action — leave alone unless user explicitly resolves it

If the current step status doesn't allow the target directly (e.g. plan still says `pending` but the PR is already `MERGED`), apply intermediate transitions in order (`pending → in_progress → pr_open → merged`) so the audit trail is consistent.

**Dependency check (when transitioning out of `pending`):** If the step has a `Depends on:` field referencing other steps, look up each dependency's `Status:`. If any dependency isn't in a terminal state (`merged` / `skipped` / `superseded`), warn the user and ask whether to proceed anyway. Some teams allow parallel work despite stated dependencies; the warning lets them make that call explicitly.

**Validation hint (when transitioning to `pr_open`):** Surface the step's `Validation commands:` from the plan and ask the user to confirm they ran (or that CI will run them on the PR). Soft check — don't block — but don't skip the prompt either, since validation gaps are a common source of regressions.

In `tech-plan.md`:
- Update the step's `Status:` to the new value.
- Set `PR:` to the PR URL.
- Update the top-of-file `Last updated:` to today's date.

**Plan-status transition:**
- If plan is `Synced` and any step is now non-`pending`, set plan to `In progress`.
- This command never sets plan to `Done` — that transition is owned by `/tech-plan-doc`.

Then ask the user **one** question:
> Any learnings worth capturing for the final write-up? (Gotchas, surprises, things future engineers should know. Press enter to skip.)

If the user provides text, append a bullet under `## Notes / learnings` with the date and the learning. If they reference a decision that emerged during this step, add it under `## Decisions & corrections` instead.

---

## Phase 4: UPDATE THE TICKET

Read the step's `Tracker ticket:` field. Use the parent plan's `Tracker:` field to choose the integration.

### Step status → tracker status mapping

| Step status | Suggested Linear status | Suggested ClickUp status |
| --- | --- | --- |
| `in_progress` | "In Progress" / "Started" | "in progress" |
| `pr_open` | "In Review" | "in review" / "review" |
| `merged` | "Done" / "Closed" | "complete" / "closed" |
| `blocked` | "Blocked" (or add a comment if no such status) | "blocked" (or add a comment) |
| `skipped` / `superseded` | "Cancelled" / "Won't do" | "cancelled" / "archived" |

Each team's workflow has its own status names. **List the available statuses and pick the closest match**; if uncertain, surface the candidates and ask the user.

### Linear
- Authenticate via `mcp__claude_ai_Linear__` if needed.
- Update the issue:
- **Status:** the mapped value (see table above; ask if your team's workflow uses different names).
- **Description:** append `PR: <url>` if not already present. Preserve the `<!-- tech-plan-step: <ID> -->` marker block written by `/tech-plan-sync`.
- Confirm the update succeeded.

### ClickUp
- Authenticate via `mcp__clickup__` if needed.
- Update the task:
- **Status:** the mapped value (see table above).
- Add a comment with the PR URL, or set a custom field if one exists for "PR link". Preserve the `<!-- tech-plan-step: <ID> -->` marker.
- Confirm.

If the ticket update fails, log the error and continue — the plan update is the source of truth; the ticket can be reconciled manually.

---

## Phase 5: NEXT

Print a short status line:
- "Step N → `<new status>`. Next pending: Step M — <title>."
- Or, if all steps are in terminal states (`merged`, `skipped`, `superseded`): "All steps complete. Run `/tech-plan-doc` to write up learnings and transition the plan to `Done`."

Ask whether to proceed to the next step, hand off, or pause. Do **not** auto-start the next step.

---

## Don'ts

- Don't mark a step `merged` without a real PR URL whose state is `MERGED`.
- Don't skip intermediate step transitions — even if the PR is already merged, walk the state through `in_progress → pr_open → merged` so the audit trail is consistent.
- Don't transition the plan to `Done` — that's `/tech-plan-doc`'s job.
- Don't assign `blocked` / `skipped` / `superseded` automatically — only when the user explicitly says so.
- Don't leave the tracker on "In Review" once the PR has merged — re-run progress to map `merged` → "Done".
- Don't strip the `<!-- tech-plan-step: -->` marker from ticket descriptions — `/tech-plan-sync` relies on it for idempotent re-syncs.
- Don't merge unrelated edits into `tech-plan.md` — only the step status, PR link, learnings, plan status, and `Last updated`.
- Don't auto-progress to the next step.
106 changes: 106 additions & 0 deletions commands/tech-plan-sync.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
description: Push an approved tech-plan.md to Linear or ClickUp, creating one child ticket per step under a parent.
argument-hint: [optional: path to tech-plan.md]
---

# /tech-plan-sync — Sync Plan to Tracker

Creates tracker tickets (Linear or ClickUp) from an approved `tech-plan.md`. One child ticket per step, parented under a single epic / work package, assigned to the current user.

**Sync must be idempotent. Each tracker child must include a stable Step ID from `tech-plan.md`. On repeated sync, update existing children rather than creating duplicates.**

This is **separate from `/tech-plan`** so the planning artifact and the tracker sync stay decoupled. You can iterate on the plan without spamming the tracker; you can re-sync after adding/splitting steps.

## Inputs

`$ARGUMENTS` — optional path to a specific `tech-plan.md`. The plan can live anywhere — in this docs repo, another repo, or an arbitrary path. If empty, search starting from cwd, then `specs/`, `docs/`, repo root, and `~/dev/dam-creation-specifications/specs/projects/`. If multiple exist, ask which one. If none found, ask for the path.

---

## Phase 1: VALIDATE

1. Read the plan.
2. **Plan-status guard.** Plan status must be one of `Approved`, `Synced`, `In progress`.
- `Draft` / `Reviewing` → reject. Tell the user to approve via `/tech-plan` first.
- `Done` / `Superseded` → reject. Confirm explicitly with the user before continuing (they may be re-syncing a closed plan intentionally).
- Any other value → treat as malformed; ask the user to fix the header.
3. **Verify every step has a stable `ID:` field** (e.g. `step-01-<slug>`). If any step is missing one — typically because the plan was authored before this rule existed — assign IDs (matching their current numeric order) and persist them to the plan before going further. IDs must never change after first sync.
4. **Skip terminal-state steps.** Steps in `merged`, `skipped`, or `superseded` are not synced or updated — they're frozen. Tell the user the count of skipped-due-to-terminal-state steps.
5. **Classify each remaining step:**
- **New** — has an `ID:` but no `Tracker ticket:` and no existing child found with that Step ID under the parent.
- **Existing-cached** — has both `ID:` and `Tracker ticket:`. Re-fetch by URL to confirm the ticket still exists and still encodes the same Step ID.
- **Existing-orphan** — has `ID:` but no `Tracker ticket:`, yet a search under the parent finds a child whose description encodes that Step ID. Reattach the URL to the plan; treat as existing.
Tell the user the count per category before creating or updating anything.

---

## Phase 2: TRACKER CHOICE

If the plan's `Tracker:` field is already set (e.g. `Linear` or `ClickUp` from a prior sync), use that. Otherwise ask:

- **Linear** or **ClickUp**? (Different teams use different ones.)

Then ask for the parent:

- **Linear:** the parent issue or project ID/URL.
- **ClickUp:** the **work package** (parent task) ID/URL.

Confirm assignee defaults to the current authenticated user unless the user says otherwise.

Persist these choices into the plan's header (`Tracker:`, `Parent ticket:`) before creating any children. That way a re-run picks up where you left off.

---

## Phase 3: CREATE OR UPDATE CHILD TICKETS

For each step, decide based on its classification from Phase 1.4: **create** (New) or **update** (Existing-cached / Existing-orphan).

### Step ID embedding

Every child ticket — created or updated — must carry the Step ID in a machine-readable line at the top of its description, so future sync runs can find it without relying on the cached URL alone:

```
<!-- tech-plan-step: <ID> -->
```

This is the source of truth for matching on re-sync. Do not remove or alter it.

### Linear
- Authenticate via `mcp__claude_ai_Linear__` if needed.
- **Create** (New step):
- **Title:** `[Step N] <step title>`
- **Description:** `<!-- tech-plan-step: <ID> -->` line, then Step's Scope + Acceptance + Backward-compat guarantee + link to `tech-plan.md` + link to functional spec.
- **Parent:** the parent issue.
- **Assignee:** current user.
- **Labels/team:** match the parent's team.
- **Update** (Existing step): rewrite **title** (step number may have changed) and **description** (scope/acceptance may have changed) to match the current plan. **Preserve** status, comments, custom fields, and the `<!-- tech-plan-step: -->` marker. Do not change the assignee unless the user asks.

### ClickUp
- Authenticate via `mcp__clickup__` if needed.
- **Create** (New step): same shape as Linear above — title, description with Step ID marker, parent = work package, assignee = current user.
- **Update** (Existing step): rewrite title and description to match the current plan; preserve status, comments, custom fields, and the Step ID marker.

After each successful create/update, write the ticket URL into the matching step's `Tracker ticket:` field in `tech-plan.md`. Save after each step (incremental persistence) so a partial run isn't lost.

---

## Phase 4: REPORT

Print a summary:
- Tracker + parent link
- Per-step result: `Step N (<ID>) — <title> → <ticket URL> [created | updated | unchanged | skipped-terminal | failed: <reason>]`
- Update `Last updated:` in the plan.
- **Plan-status transition:** if the plan was `Approved`, set to `Synced`. If already `Synced` or `In progress`, leave unchanged — re-syncs do not roll the plan back. Validate against the plan's State machine before writing.

If any creations failed, ask whether to retry the failures, fix them manually, or accept and move on.

---

## Don'ts

- Don't create duplicate tickets for steps that already exist on the tracker — match by Step ID, not just by `Tracker ticket:` URL presence.
- Don't change a step's `ID:` once assigned. Renames, reorders, and splits keep the original ID; new steps get a new ID. Changing IDs breaks idempotency.
- Don't strip the `<!-- tech-plan-step: -->` marker from ticket descriptions. It is the matching anchor.
- Don't overwrite tracker status, comments, or custom fields during sync. Status belongs to `/tech-plan-progress`.
- Don't change the plan's step ordering or content during sync. This command writes only `Tracker:`, `Parent ticket:`, per-step `Tracker ticket:`, missing `ID:` backfills, and `Last updated:`.
- Don't pick a tracker without asking, unless the plan already has `Tracker:` set.
Loading