Skip to content
Merged
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
47 changes: 47 additions & 0 deletions .claude/skills/handoff/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
name: handoff
description: Safely commit, verify, and push completed work on a feature branch in this repo, then open a PR and record the review in the ledger. Use when work is finished and you want to hand it off — it runs the repo's verification gate, preserves unrelated work, and never touches protected branches without the required confirmation.
---

# handoff — commit, verify, push, PR

Encodes this repo's safe Git handoff. The goal is to leave completed work committed and
pushed on a `claude/*` feature branch with a PR; NOT to merge into a protected branch,
force-push, or discard work.

## Preconditions

- You are on a `claude/*` (or other non-protected) feature branch, not `main`/`master`/
`develop`/`release/*`. If on a protected branch, create a feature branch first.
- Only your own paths are staged (this worktree may hold other sessions' WIP).

## Steps

1. **Inspect first (read-only):** `git status --short --branch`, `git diff`, `git diff --cached`,
and the ahead/behind from `node scripts/check-base-freshness.mjs`. If staged paths are found
that aren't part of the current session's own work (leftover from other sessions' WIP),
unstage them with `git restore --staged <path>` before proceeding.
Comment on lines +21 to +23

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve unrelated staged files

When another session has intentionally staged WIP in this shared worktree, this instruction mutates their index by unstaging those paths, even though the repo workflows require preserving unrelated staged work. The handoff can avoid committing unrelated files by staging explicit paths and stopping/asking when foreign staged paths are present, without running git restore --staged on someone else's state.

Useful? React with 👍 / 👎.

2. **Stage coherent, completed changes only.** Stage explicit paths — never `git add -A`
blindly. Do not stage `.env*`, secrets, build output, logs, or unrelated WIP; if you
see a possible secret, report the path (never the value) and stop.
3. **Verify** with the smallest sufficient gate:
- Default: `npm run verify:pr-local` (format + cheap gate, plus build/RAG when the
scope needs them).
- Touched UI/routing/styling: add `npm run verify:ui`.
- Touched Supabase env/config: `npm run check:supabase-project` (provider — confirm first).
Do not claim a gate passed unless it actually ran.
4. **Commit** with a clear message. End the message with:
`Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>`.
5. **Push** the feature branch: `git push -u origin <branch>`. The pre-push guards run
(auto-merge sentinel, format, drift) — heed a block rather than overriding blindly.
6. **Open a PR** with `gh pr create --base main`, body ending with the Claude Code
attribution line. Enabling squash-auto-merge (`gh pr merge --squash --auto`) is the
repo norm but requires explicit user confirmation before enabling; the PR lands on green.
7. **Record** the review in `docs/branch-review-ledger.md` (Date | Branch/ref | Reviewed
HEAD | Scope | Outcome | Checks).

## Requires explicit confirmation (do not do automatically)

Merging into a protected branch, enabling auto-merge (`gh pr merge --squash --auto`),
force-push, rebasing a shared branch, deleting/renaming branches, `git reset --hard`,
`git clean -fd`, or any provider-touching verification.
38 changes: 38 additions & 0 deletions .claude/skills/newtask/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
name: newtask
description: Bootstrap a clean session for new work in this repo — create a fresh git worktree off the latest origin/main, install deps, warm routes, and confirm the base is current. Use at the start of a task when you want an isolated, up-to-date working copy and want to avoid the stale-base, cold-worktree, and reserved-port traps this repo is prone to.
---

# newtask — start a clean, current working copy

This repo moves fast (`claude/*` branches auto-merge on green) and shares ~40 worktrees
and one stash stack, so starting work on a stale base or a cold worktree is the default
failure. This skill sets up an isolated, current worktree so new work starts clean.

## Steps

1. **Sync main.** `git fetch --quiet origin main`.
2. **Create an isolated worktree** off the latest main (never reuse another session's
checkout, and never switch the main checkout's branch):
```bash
git worktree add -b claude/<task-slug> ../wt-<task-slug> origin/main
```
Use a short, descriptive `<task-slug>`.
3. **Install deps in the new worktree** (worktrees do NOT share `node_modules`; a cold
worktree fails `vitest`/`tsc`). `npm ci` keeps the lockfile untouched:
```bash
cd ../wt-<task-slug> && npm ci --no-audit --no-fund
```
`postinstall` installs the pre-push guards automatically.
4. **Confirm the base is current:** `node scripts/check-base-freshness.mjs` — expect
`behind 0`. If it reports behind, the fetch/worktree base is stale; recreate.
5. **Warm routes before any browser/UI work** (fresh worktrees can hash onto a
Next-reserved port and 404 all routes until warmed): `npm run ensure`, then hit
`/` and `/applications` once.

## Notes

- Never `git stash` here — the stash stack is global across all worktrees. Use a
throwaway worktree or a patch file instead.
- Do the work on the `claude/<task-slug>` branch; commit only your own paths.
- When done, hand off with the `handoff` skill.
42 changes: 42 additions & 0 deletions .claude/skills/prlanded/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
name: prlanded
description: Verify a merged PR actually landed correctly in this repo and clean up after it. Use right after a PR merges (especially squash + auto-merge) to confirm the squashed commit matches your branch by content, catch late commits that were orphaned by the auto-merge race, and update the ledger and memory.
---

# prlanded — confirm a merge landed and tidy up

This repo squash-merges and auto-merges `claude/*` on green, which has twice orphaned a
late follow-up commit and once needed a fix-forward. Run this after a merge to confirm the
work actually landed and to clean up.

## Steps

Note: Step 1 is a read-only, non-mutating query exempt from the explicit-confirmation
requirement that applies to mutating provider operations (merging, closing PRs, etc.).

1. **Confirm the merge:** `gh pr view <pr> --json state,mergeCommit,mergedAt` → `MERGED`.
Comment on lines +14 to +17

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Ask before read-only GitHub CLI queries

When this skill runs in a normal post-merge cleanup without a separate confirmation, these lines explicitly exempt gh pr view from the repo's GitHub/GitLab confirmation boundary. The GitHub CLI manual for gh pr view says it displays pull-request information and supports JSON fields, so this is still a GitHub PR read/API interaction; require confirmation before Step 1 instead of declaring it exempt.

Useful? React with 👍 / 👎.

2. **Verify by content, not ancestry** (squash rewrites history, so `git branch --merged`
is misleading). Diff your branch tip against merged `main`:
```bash
git fetch --quiet origin main
git diff --stat origin/main...<your-branch>
Comment thread
BigSimmo marked this conversation as resolved.
```
An empty diff means everything landed. Any remaining lines are work that did NOT make
it — the classic auto-merge race. Investigate before deleting the branch.
3. **Check for orphaned late commits:** if you pushed after enabling auto-merge, confirm
those commits are in the squashed result (search the merge commit / `git log origin/main`
for their content). If missing, fix-forward with a new PR — do not force-push.
4. **Clean up the branch** only once the content diff is empty: the PR's
`--delete-branch` handles the remote; prune locally by running `git worktree remove <explicit-path>`
from a different worktree (not the one being removed), then use `git branch -D <branch>`
only after confirming the content diff is empty. For squash-merged branches, `-d` will
refuse (no ancestry merge) even though the content landed, so `-D` is required once
the empty diff confirms the work is fully landed. Do not force-delete before verification.
5. **Update the ledger** (`docs/branch-review-ledger.md`) and any relevant memory note with
the merged HEAD SHA and outcome.

## Notes

- Do not re-review a branch/HEAD already recorded in the ledger for the same scope.
- If the content diff is non-empty and you are unsure why, stop and report rather than
deleting anything.