diff --git a/.claude/skills/campaign-issues/SKILL.md b/.claude/skills/campaign-issues/SKILL.md index 3ce928b..ea3f222 100644 --- a/.claude/skills/campaign-issues/SKILL.md +++ b/.claude/skills/campaign-issues/SKILL.md @@ -17,14 +17,14 @@ All commands use `gh` against `prdlk/leetcode` and fall back to `gh auth token`. One issue per LeetCode problem, attached as a sub-issue of its topic. -- **Title:** `LC · · <Difficulty> · <set>` - - `<Difficulty>` ∈ `Easy | Medium | Hard` (LeetCode's own rating — do not invent). - - `<set>` ∈ `core | optional | deferred` (see set semantics below). - - Separators are middle dots `·` (U+00B7), single spaces around each. -- **Labels** (four, all required): - - `problem` - - `diff:easy` | `diff:medium` | `diff:hard` — matches `<Difficulty>`. - - `set:core` | `set:optional` | `set:deferred` — matches `<set>`. +- **Title:** `LC <num> · <Title>` — the LC number and the problem's name, nothing + else. Separator is a middle dot `·` (U+00B7) with single spaces. Difficulty and + set are **labels only**; never repeat them in the title (they used to be a `· + Hard · core` suffix — that is gone, and `catalog.ts` no longer parses it). +- **Labels** (four, all required — these are what the Worker reads): + - `problem` — marks the sub-issue as curriculum; without it the reconcile skips it. + - `diff:easy` | `diff:medium` | `diff:hard` — LeetCode's own rating, do not invent. + - `set:core` | `set:optional` | `set:deferred` — see set semantics below. - `phase:N` — the **topic's** phase (same phase label the topic issue carries). - **Milestone:** - `core` / `optional` → the topic's phase milestone. @@ -51,7 +51,7 @@ Create it: ```sh gh issue create --repo prdlk/leetcode \ - --title "LC 42 · Trapping Rain Water · Hard · core" \ + --title "LC 42 · Trapping Rain Water" \ --label problem --label set:core --label diff:hard --label phase:1 \ --milestone "Phase I — Linear Structures" \ --body "https://leetcode.com/problems/trapping-rain-water/ @@ -146,6 +146,23 @@ gh issue list --repo prdlk/leetcode --label topic --state all --limit 30 \ ## Gotchas +- **Check the LC number is not already in the curriculum BEFORE creating.** D1 keys + `problems` on `lc_number` (`ON CONFLICT(lc_number)`), so two issues for one LC number + silently fight over a single row — whichever the reconcile walks last wins, and the + loser's issue number ends up orphaned in D1. A problem can legitimately move topic or + set; that is a relabel/re-parent of the *existing* issue, never a second issue: + + ```sh + gh issue list --repo prdlk/leetcode --label problem --state all --limit 300 \ + --search "LC 42" --json number,title,labels,state + ``` + + If a row already exists, change the existing issue instead: swap its `set:*` label, + move the sub-issue to the new topic, and fix its milestone. Then reconcile the board + (`project-fields` skill). If a duplicate did get created and one is deleted, the + surviving issue number and set only reach D1 on the next catalog reconcile — SRS + columns (`stage`, `next_review`) are preserved, since they are the real attempt history. + - **`-F` vs `-f`:** `sub_issue_id` must be an integer; `-f` sends a string and the API rejects it with `is not of type integer`. - **id, not number:** the sub-issue payload wants the child's `.id` (a large opaque diff --git a/AGENTS.md b/AGENTS.md index 85a139f..96464e9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ ## Project Overview -LeetCode interview-prep campaign (8 weeks, 2026-08-17 → Oct 11) run as a repo: solution files under `work/`, a Blume docs site under `apps/docs/`, GitHub Actions that reconcile issues and publish docs, and a Cloudflare Worker (`apps/api/`) that runs the spaced-repetition system (SRS) — daily digest email, one-tap logging, weekly review issues, live charts. Issues model the curriculum: ~24 `topic` issues own ~161 `problem` sub-issues (`set:core|optional|deferred`, `diff:*`); milestones are phases; a user-level GitHub Project ("Interview Prep", #2) mirrors review state. +LeetCode interview-prep campaign (8 weeks, 2026-08-17 → Oct 11) run as a repo: solution files under `work/`, a Blume docs site under `apps/docs/`, GitHub Actions that reconcile issues and publish docs, and a Cloudflare Worker (`apps/api/`) that runs the spaced-repetition system (SRS) — daily digest email, one-tap logging, weekly review issues, live charts. Issues model the curriculum: ~24 `topic` issues (`Topic NN — Name`) own ~161 `problem` sub-issues titled `LC <num> · <Name>`, with difficulty and set carried **only** by labels (`set:core|optional|deferred`, `diff:*`) — never by the title; milestones are phases; a user-level GitHub Project ("Interview Prep", #2) mirrors review state. ## Architecture & Data Flow