Files

7.1 KiB

name, description
name description
campaign-issues Create GitHub issues for this LeetCode campaign — individual problem issues and the topic issues that own them — using the repo's exact title, label, milestone, body, and sub-issue conventions. Use when asked to add/create an issue for a LeetCode problem or a topic, attach a problem to its topic, or backfill the issue catalog.

Campaign issues

The GitHub issue tracker is the campaign catalog: ~24 topic issues each own a set of problem sub-issues. The Worker reconciles this catalog into D1 nightly (/admin/reconcile), so a correctly-labelled issue is all that's needed — the SRS, digest, charts, and Project mirror pick it up automatically. Get the labels/body shape right; everything downstream is reconciliation.

All commands use gh against prdlk/leetcode and fall back to gh auth token.

Problem issue

One issue per LeetCode problem, attached as a sub-issue of its topic.

  • 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.
    • deferred → Review — Transfer & Mocks (deferred Hards are parked until week 8).
    • Pass the milestone title, not its number, to --milestone.
  • Body (exact shape; <slug> is the LeetCode URL slug, <topic-issue> the owning topic's number):

    https://leetcode.com/problems/<slug>/
    
    - **Topic:** #<topic-issue>
    - **Set:** <core|optional|deferred>
    - **Language:** Python
    
    ### Close-out (paste before closing this issue)
    - Time: O(?)
    - Space: O(?)
    - Edge case traced:
    - First attempt passed: yes / no
    - Miss note:
    

Create it:

gh issue create --repo prdlk/leetcode \
  --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/

- **Topic:** #9
- **Set:** core
- **Language:** Python

### Close-out (paste before closing this issue)
- Time: O(?)
- Space: O(?)
- Edge case traced:
- First attempt passed: yes / no
- Miss note:"

Then attach it as a sub-issue of the topic (this is a separate API call — creating the issue does not link it). The sub-issues API wants the child's internal id, not its issue number, and the field is integer-typed, so use -F (not -f):

child_id=$(gh api repos/prdlk/leetcode/issues/211 --jq '.id')
gh api --method POST repos/prdlk/leetcode/issues/9/sub_issues -F sub_issue_id=$child_id
# verify
gh api repos/prdlk/leetcode/issues/9/sub_issues --jq '.[] | "\(.number)  \(.title)"'

Topic issue

One issue per curriculum topic; owns the problem sub-issues.

  • Title: Topic NN — <Name> (zero-padded number, em dash, e.g. Topic 07 — Monotonic Stack).

  • Labels: topic, phase:N.

  • Milestone: that phase's milestone (title, not number).

  • Body:

    **Scheduled:** <Weekday Mon DD, YYYY>
    **Phase:** <Roman> — <Phase name> (Week N)
    **Builds on:** Topic <n>
    
    ### Trigger
    TODO
    
    ### Invariant
    TODO
    
    ### Trap
    TODO
    
    ### Close-out ritual
    Before every submit, out loud:
    1. State time and space complexity.
    2. Trace one edge case.
    
    ### Day rules
    - 90-minute coding cap. Stop at the cap, even mid-problem.
    - Core problems first. Optional only if the core is done.
    - Finished early? Do this topic's optional set. Do not start tomorrow.
    

Scheduled should come from the calendar of record — apps/api/data/schedule.json (date → { topics: [issue, …] }; a doubled day lists two) — not guessed.

Gate problems (gate: [...] in the same file) must exist in the catalog before their Saturday, or the Worker refuses to create the review issue: create each as a set:optional problem sub-issue of its natural topic. Being named in the plan keeps it out of the drill pool, so it stays unseen until the gate.

Reference tables

Set semantics (from the label descriptions):

set meaning milestone
core must solve on the topic day topic's phase milestone
optional solve only if the clock allows topic's phase milestone
deferred a Hard, parked until week 8 Review — Transfer & Mocks

Milestones (--milestone takes the title):

# title
1 Phase I — Linear Structures
2 Phase II — Nodal & Grid
3 Phase III — Hierarchical
4 Phase IV — Relational
5 Phase V — Decision Space
6 Review — Transfer & Mocks

Find a topic issue and confirm its phase before creating problems under it:

gh issue list --repo prdlk/leetcode --label topic --state all --limit 30 \
  --json number,title,labels,milestone

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:

    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 integer), never its display #number.

  • --milestone wants the title string, not the numeric id ('1' not found otherwise).

  • Reconcile, don't react: don't edit D1 or the Project by hand — a correct issue is reconciled into SRS state on the nightly cron. Solutions landing in work/ are what close problem issues (via close-solved.yml), which then roll up to close topics.

  • Difficulty is LeetCode's, set is our scheduling choice — they're independent. A Hard can be core if we deliberately schedule it (vs the usual deferred).