Agent skill
LC Site Data
the validator is the spec
The Study Roadmap and the
Complexity Quiz are each driven by one JSON file,
and both fail the build rather than warn — deliberately, so nothing lands in
an unsorted bucket. That turns a five-line edit into a break-and-retry loop unless every
constraint is satisfied at once. /lc-site-data satisfies them in one pass.
1 check monotonic-stack not present ยท stack is row 1
doc/cheatsheet/monotonic_stack.md exists
doc/cheatsheet/monotonic_queue.md exists
496 503 85 901 907 all in README
2 write row 2, prereqs: ["stack"]
"array" left OFF โ stack already requires it, and an
implied edge fails the transitive-reduction check
3 build 30 topics over 7 rows, 1564 distinct problems
every "shown of" tally unchanged
4 look edge lands one column over. Short. Good.
5 assumed row 2 over row 3 โ nothing on row 2 depends on it
Never repeat a title, a difficulty or a solution link in either file. They are read from README at build time; a typed copy is one that goes stale.
Why a skill and not a habit
Three constraints that are easy to miss
These files are short. The contracts around them are not — each spans three or four other files, and the build is the only thing that tells you.
The roadmap has to stay a transitive reduction. If monotonic-stack needs stack and stack already needs array, then listing array too is an implied edge.
Cost of allowing it: the drawing turns into spaghetti.
site/complexity.js's identifiers are single letters. O(n * amount) does not parse; O(n * a) with a vars line saying what a is does.
The single most common quiz failure.
The build fails on a taxonomy key that is missing, points at an unknown topic, or is mapped but unused — so a renamed upstream category cannot quietly drop a whole group of problems.
Watch the per-list "shown of" tally.
One pass, no branches
Five steps, in order
Pick one to see what it does and the rule that step exists to enforce.
What lands in the tree
The two files, and what fails
One entry each. The rules are all build-time, and all of them exist because something would otherwise land in an unsorted bucket.
{
"id": "monotonic-stack",
"title": "Monotonic Stack",
"row": 2, <- strictly > every prereq's row
"prereqs": ["stack"], <- IMMEDIATE prereqs only
"sheets": ["monotonic_stack", "monotonic_queue"],
"blurb": "One sentence on what the topic buys you.",
"problems": [496, 503, 85, 901, 907] <- README must know each one
}
| Fails the build if | Why the rule exists |
|---|---|
a problems id is not in a README table | a number README does not know has no title, difficulty or solution link to attach |
a sheets slug is not a file | a dead sheet link on a teaching page is worse than no link |
row is not strictly greater than every prereq's | edges must point downward |
| the prereqs contain a cycle | — |
| an edge the graph already implies | the roadmap has to stay a transitive reduction, or the drawing turns into spaghetti |
Within a row, topics are drawn in the order they appear in the file — so put a topic near the column its prerequisite sits in, to keep the edges short.
{
"id": "two-sum-hash",
"lc": 1, <- README must know it; title/difficulty come from there
"topic": "Arrays & Hashing",
"vars": "n = len(nums)", <- what the single letters mean
"code": ["def twoSum(nums, target):", " ..."],
"time": "O(n)",
"space": "O(n)",
"why": "One sentence on where each bound comes from.",
"trap": "The wrong answer people actually give, and why it is wrong."
}
| Fails the build if | Note |
|---|---|
an id repeats | — |
an lc number is not in a README table | — |
an entry with an lc sets its own title/difficulty | they come from README |
an entry without an lc omits them | a pure algorithm or Python drill |
accept is a bare string | it survives validation and then breaks the page's feedback |
| any answer does not parse | time, space, and each accept |
why says where each bound comes from. trap is the wrong
answer people actually give, and why it is wrong — not a restatement of the
right one.
The roadmap page shows one problem set at a time, and all of them are declared in the same file:
| Key | What it does |
|---|---|
| lists | The picker's entries. from says where membership comes from: curated (the ids on the nodes), list:<flag> (a flag in problem_lists.json), or readme:<field> (google / must, read out of README's own columns). |
| topicSources | Each source files problems under its own taxonomy — NeetCode's Arrays & Hashing, LeetCode's plan group Hashing, README's ## Array heading. These maps put them on roadmap topics. null means deliberately off the roadmap (SQL, shell, JavaScript-only exercises). |
| topicFrom | Which taxonomies a list tries, in order, so a coarse group falls through to a finer one. |
data/problem_lists.json is vendored, not built — Blind 75 and
the NeetCode lists come from the neetcode.io app bundle, Top 100 Liked from LeetCode's
GraphQL. Refresh it by hand with script/fetch_problem_lists.py; the site
build never touches the network.
Arguments are inferred, not interrogated
How to call it
/lc-site-data roadmap monotonic-stack
/lc-site-data quiz for LC 239
add monotonic stack to the roadmap
add a complexity question
the roadmap build is failing
| Left out | What happens |
|---|---|
| Row | Chosen as the lowest row strictly below every prereq, then named in the report. |
| Prereqs | Reduced to the immediate ones. An implied edge would fail the build anyway. |
| Title / difficulty / links | Never written. They come from README at build time, in both files. |
| Which file | Inferred from what you asked for — a topic or a question. |
The guardrails
What it will not do
- Type a title, difficulty or solution link.They come from README at build time. A typed copy is one that goes stale the first week nobody re-checks it.
- List an implied prereq.The roadmap stays a transitive reduction. Only the immediate prerequisites go in.
- Write a multi-letter identifier.
O(n * amount)does not parse.O(n * a)plus avarsline does. - Use
acceptfor spelling variants.O(n log n),nlognandNยทlogNalready grade the same.acceptis for a genuinely defensible different answer. - Hand-edit
problem_lists.json.It is vendored from upstream.fetch_problem_lists.pyrewrites it;--checksays whether it is stale. - Ignore a "shown of" tally that moved.That is the signal that a taxonomy mapping broke, and it is the only signal you get.
One markdown file, no dependencies
Install
SKILL.md is the whole recipe — nothing to build and no network calls,
so the same source runs on any agent that takes a system prompt. Pick yours.
Drop the skill directory into your user-level skills folder and it loads in every repo:
git clone --depth 1 https://github.com/yennanliu/CS_basics.git /tmp/cs_basics
mkdir -p ~/.claude/skills
cp -r /tmp/cs_basics/.claude/skills/lc-site-data ~/.claude/skills/
Already installed inside this repo at .claude/skills/lc-site-data/. The
directory name is the command.
Zip the directory, then Customize → Skills → + → + Create skill → Upload a skill:
cd .claude/skills && zip -r lc-site-data.zip lc-site-data
Leave the YAML frontmatter intact — description is what Claude matches your request against.
Codex reads AGENTS.md at the repo root automatically. Point it at the skill:
## Roadmap and quiz data
When asked to add a roadmap topic, wire prerequisites, or add a complexity
question, follow `.claude/skills/lc-site-data/SKILL.md`.
A pointer, not a copy — one source of truth means a fix reaches every agent at once.
Same shape in GEMINI.md, or point at it for a single session:
gemini -p "Follow the recipe in .claude/skills/lc-site-data/SKILL.md. \
Add monotonic stack to the roadmap."
Paste SKILL.md in as the system prompt. For Cursor or Windsurf, put the
Codex pointer above into a rule file
(.cursor/rules/lc-site-data.mdc or the editor's equivalent).
curl -sL https://raw.githubusercontent.com/yennanliu/CS_basics/master/.claude/skills/lc-site-data/SKILL.md
This one is the most schema-specific of the family. Away from here, the transferable idea is the one the two validators share: a generated page should read its labels from the source of truth, and fail the build rather than warn.
Under the hood
What is inside
- SKILL.md The whole recipe — both schemas, every rule that fails the build and why it exists, the list picker's three sources, the five steps, the do-not list, and a worked run.
Gated in CI by
check_skills.py,
and the data it writes is gated by site/build-roadmap.js and
site/build-quiz.js, which fail the build rather than warn.
The rest of the loop
Where it fits
/lc-site-data maintains the two pages that tell you what to learn next and
whether you can analyse it: the roadmap and the
complexity quiz. The topics it wires point at the
cheatsheets, and the problems it lists are the ones
/lc-python and /lc-java file.