diff --git a/.claude/skills/github-cli-setup/SKILL.md b/.claude/skills/github-cli-setup/SKILL.md new file mode 100644 index 0000000..f68249c --- /dev/null +++ b/.claude/skills/github-cli-setup/SKILL.md @@ -0,0 +1,59 @@ +--- +name: github-cli-setup +description: Establish a correct, least-surprise `gh` CLI session before doing any GitHub work — confirm the right account is active, that it can actually see the target repo, and that its token carries the scopes the task needs (repo, project, workflow). Use at the start of any GitHub task, or when a `gh` command fails with "Could not resolve to a Repository", "Not Found", or "missing required scopes". Domain-agnostic — the same checks apply to any repo or project. +--- + +# github-cli-setup + +Most GitHub automation failures aren't the task — they're the *session*: the wrong account is +active, that account can't see a private repo, or its token is missing a scope the command needs. +This skill front-loads those checks so the real work doesn't fail halfway through. Run it before +issue/milestone/project/PR work, and reach for it the moment a `gh` call returns a resolution, +not-found, or scope error. + +## Background: the three things that go wrong + +1. **Wrong active account.** `gh` supports several logged-in accounts but only one is *active*. + The active one may not be the account that owns (or can see) the repo you're targeting. +2. **No access to the repo.** A private repo is invisible to any account that isn't the owner or + a collaborator — the symptom is `Could not resolve to a Repository` / HTTP 404, which reads + like the repo doesn't exist when really the *active account* just can't see it. +3. **Missing token scopes.** A task needs specific OAuth scopes. Common ones: + - `repo` — repos, issues, milestones, PRs (needed for almost everything). + - `project` / `read:project` — GitHub Projects (v2) boards. **Milestones and issues do NOT + need this — only the Projects board does.** + - `workflow` — editing `.github/workflows/` files. + Adding a scope requires an **interactive** re-auth the user must run themselves. + +## Steps + +1. **Check the session.** Run `gh auth status` and read every logged-in account, which is active, + and each account's token scopes. +2. **Identify the account that owns/can-see the target repo.** If the task names a repo under a + specific owner, that owner's account (or a collaborator) is the one you need. If the active + account differs, switch: `gh auth switch --user `. +3. **Verify visibility.** Confirm the active account can actually resolve the repo: + `gh repo view / --json name,visibility,hasIssuesEnabled`. A 404 here almost + always means "active account can't see it," not "doesn't exist" — switch accounts or ask the + user to grant access, rather than concluding the repo is missing. +4. **Check the scopes the task needs** against the active account's scopes from step 1: + - issues / milestones / PRs → `repo` + - Projects (v2) board → `project` (and `read:project` to list/read) + - editing workflows → `workflow` +5. **If a scope is missing, ask the user to add it** — this is interactive and cannot be done + non-interactively. Give them the exact command to run in their session: + `gh auth refresh -s --hostname github.com` (e.g. `-s project`). It shows a one-time + code and opens a browser to approve on the correct account. Wait for them to confirm, then + re-check `gh auth status` before proceeding. +6. **Proceed only once** the active account both resolves the repo and holds the needed scopes. + Note in your summary which account you're operating as, so the user isn't surprised later. + +## Do not + +- Do not conclude a repo "doesn't exist" on a 404 without first checking whether a *different* + logged-in account can see it — private-repo visibility is account-scoped. +- Do not try to add a scope non-interactively or by editing token files — `gh auth refresh` must + be run by the user. +- Do not assume the active account is the right one just because a previous command happened to + work; a read that succeeds under `repo` scope says nothing about `project` scope. +- Do not store or echo full tokens; treat the masked values from `gh auth status` as enough. diff --git a/.claude/skills/github-project-tracking/SKILL.md b/.claude/skills/github-project-tracking/SKILL.md new file mode 100644 index 0000000..a8a3b46 --- /dev/null +++ b/.claude/skills/github-project-tracking/SKILL.md @@ -0,0 +1,55 @@ +--- +name: github-project-tracking +description: Turn a roadmap or plan into trackable GitHub artifacts — create milestones for phases, issues for concrete tasks under each milestone, a Projects (v2) board laid out by Status, and add every issue to it. Use when the user wants to track work on GitHub ("set up milestones and a project board", "track this roadmap on GitHub", "make issues for these tasks"), or to keep an existing board in sync. Assumes `gh` is ready — run github-cli-setup first if any command fails on account or scope. +--- + +# github-project-tracking + +Scaffolds a full tracking surface on GitHub from a plan: **milestones** for the phases, +**issues** for the tasks, and a **Projects (v2) board** to work them day-to-day. Milestones and +issues need only `repo` scope; the board needs `project` scope — so the skill can do the first +two even if the board step is blocked waiting on a scope grant (see `github-cli-setup`). + +## Steps + +1. **Confirm the session** is ready for the repo (right account, `repo` scope; `project` scope if + a board is wanted). If any command fails on account/scope, run `github-cli-setup` first. +2. **Agree on the breakdown before creating anything.** Restate the milestones (phases) and the + issues under each, in a compact list, and get a nod. Creating a wrong breakdown means cleanup + across many artifacts — cheap to confirm, annoying to undo. +3. **Create milestones** — one per phase. Milestones only need `repo` scope: + `gh api -X POST repos///milestones -f title="M0 — Foundations" -f description="..."`. + Keep titles short and ordered (`M0`, `M1`, …) so they sort correctly. +4. **Create issues** under each milestone. The `--milestone` flag takes the milestone *title*: + `gh issue create -R / --milestone "M0 — Foundations" --title "..." --body "..."`. + Give each issue a body that points back at the source plan (e.g. a doc section), so an issue is + self-explanatory without the surrounding chat. +5. **Create the Projects (v2) board** (needs `project` scope): + `gh project create --owner --title "" --format json` — capture the returned + project `id`, `number`, and `url`. +6. **Link the board to the repo** so issues surface in the repo's Projects tab: + `gh project link --owner --repo `. +7. **Add every issue to the board:** + `gh project item-add --owner --url https://github.com///issues/`. + The item count can lag a beat behind (eventual consistency) — verify with + `gh project item-list --owner --format json --jq '[.items[].content.number]|sort'` + and re-add any genuinely missing, rather than trusting the immediate count. +8. **Set a starting Status** so cards don't pile up under "No Status." New boards have a `Status` + single-select (`Todo` / `In Progress` / `Done`). Fetch its field id and the `Todo` option id + with `gh project field-list --owner --format json`, then for each item: + `gh project item-edit --project-id --id --field-id --single-select-option-id `. +9. **Hand off the daily workflow.** Tell the user how to drive it: drag a card to **In Progress** + when starting an issue and **Done** when finished; group the board by **Milestone** (board + menu → Group by) to see phases as swimlanes. Offer to move cards / open issues on their behalf + as work proceeds. + +## Do not + +- Do not create a pile of issues before the breakdown is confirmed — a wrong split is expensive to + reverse across milestones, issues, and board items. +- Do not block milestone/issue creation on `project` scope; only the board steps (5–8) need it. + If the scope isn't granted yet, create milestones and issues, then pause for the grant. +- Do not trust the immediate board item count after bulk-adding — verify by listing actual issue + numbers, since the count is eventually consistent. +- Do not invent a milestone breakdown the user didn't sanction; mirror their plan (or ask), don't + improvise scope. diff --git a/CLAUDE.md b/CLAUDE.md index 1e594b0..a2fb3b4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -21,7 +21,9 @@ know before touching code.}} to reach for this vs. a plain Claude Code skill. - `knowledge/` — the shared memory loops read and write between runs (`signals/`, `notes/`, `domains/`). Read `knowledge/README.md` once; it's short. -- `.claude/skills/` — `new-loop` (scaffold a domain) and `ship-loop-change` (verify-before-ship). +- `.claude/skills/` — `new-loop` (scaffold a domain), `ship-loop-change` (verify-before-ship), + `review-signals` (promote piled-up signals), and generic GitHub playbooks `github-cli-setup` + (session/scope checks) and `github-project-tracking` (milestones + issues + Projects board). - `LOG.md` — the global activity feed. Append one line here right before you commit a bulk of work from any loop run. diff --git a/LOG.md b/LOG.md index 5342463..75a3e6d 100644 --- a/LOG.md +++ b/LOG.md @@ -8,6 +8,7 @@ Format: `YYYY-MM-DD HH:MM | domain | one-line summary | link(s)` ## Entries +- 2026-07-26 22:51 | scaffold | added github-cli-setup + github-project-tracking skills (generic GitHub playbook: gh account/scope checks, milestones/issues/Projects-v2 board) | [[.claude/skills/github-project-tracking/SKILL.md]] - 2026-06-22 16:00 | scaffold | stress-tested the orchestration/execution decision rule against opposite-shape domains (event+engine, scheduled+no-engine); rule held, fixed an implicit correlation in docs/loop-engineer-pattern.md's examples | [[docs/loop-engineer-pattern.md]] - 2026-06-22 15:00 | review-signals | added review-signals skill + skill-writing recipe; dogfooded against a synthetic signal (correctly judged "leave open," then removed) | [[.claude/skills/review-signals/SKILL.md]] - 2026-06-22 14:00 | smoke-test | dogfooded new-loop skill (scaffold verified correct, then removed — throwaway test domain) | [[.claude/skills/new-loop/SKILL.md]]