Agent skill
LC Log
the only copy
data/progress.txt is the daily practice log, and nothing else in this
repo records that a problem was practised. The
review plan is compiled from it on every build, so a
line written in the wrong shape does not fail — it produces a smaller schedule.
/lc-log writes the day in the shape the parser actually reads.
1 read head of data/progress.txt โ yesterday's open buckets
top 100 like(linked list) ยท (heap) ยท (dp) ยท others ยท DP
2 sort 23, 24, 25, 138 โ top 100 like(linked list)
the other buckets carry forward untouched
3 write 20260921: top 100 like(linked list):, 23(ok), 24(again!!!), 25,
138(again) | top 100 like(heap):, 295 | ... |
^ the comma after every
label. Without it, 23 is
silently dropped.
4 scope README, again_problems.txt, solution files โ untouched
5 gate build-review-plan.js โ 822 days, 799 problems, 294 again
round-trip โ 23(ok) 24(again!!!) 25 138(again) all four present
6 assumed 25 has no verdict because none was given. Correct me.
A real run: read the open buckets, sort today into them, write one line, check it round-trips, then say what was guessed.
Why a skill and not a habit
Two shapes that lose data, silently
The log's format is hand-written and forgiving, which is the point — and also the problem. Neither of these produces a warning. Both are already in the file.
Each comma-chunk used to have to start with the digits. others: 678(todo) starts with a letter, so until Sep 2026 the site's parser read it as a named drill and dropped it whole — taking LC 678 with it. Both readers strip the label now; a reader that does not exist yet will not.
Cost, historically: 93 attempts sat in a chunk shaped like that and never reached the review plan.
2D LIS (354) is read as LC 2, because the regex takes the first digits it finds. Writing 354(2D LIS) instead records the problem you actually did.
Cost: 16 entries log the wrong problem.
suggest_review.py strips bucket labels before parsing; build-review-plan.js did not until Sep 2026, so the CLI planner saw those 93 attempts and this site's review plan did not. Both read them now.
Still: a comma after the label needs no reader to be taught.
One pass, no branches
Six steps, in order
The steps never reorder and none of them is optional. Pick one to see what it does and the rule that step exists to enforce.
What lands in the file
The format, as the parser reads it
One line, and the vocabulary inside it. The annotations are not decoration — they are the entire signal the spaced-repetition schedule runs on.
20260921: top 100 like(dp):, 32(ok), 300 | LCA:, 236(again!!) | others:, 354(2D LIS) |
^^^^^^^^ ^ ^^^^ ^
| | | |
| | | trailing pipe, like its neighbours
| | a bare number is fine: practised, no verdict
| the comma that keeps the next number alive
a real calendar date. An impossible one drops the whole day.
| Piece | Rule |
|---|---|
| YYYYMMDD: | Must be a real calendar date. Newest entry at the top of the file. |
| | | Groups the day into sessions. Cosmetic to the parser, structural to the reader. |
| , | The real separator. A . splits too, but that is typo-tolerance, not a convention. |
| 123(note) | Commas and nested parens inside the note are safe: 70(ok*, o(1) space!!) is one entry. |
| topo_sort | A named drill. Parsed and ignored — no LC number to schedule, which is intended. |
The classifier takes the first of again, todo,
ok that appears in the note — again first, on purpose:
| Written | Read as | Why it matters |
|---|---|---|
| 141(ok) | ok | graduated this pass |
| 994(ok*) | ok | the * is your own shading, carried through as the note |
| 128(again!!!) | again, emphasis 3 | bangs are counted anywhere in the note and sort it above a bare again |
| 44(again !!) | again, emphasis 2 | spaces inside the note are fine |
| 139(ok, but again) | again | again is checked first — a problem that still needs a pass |
| 79(todo) | todo | intended, not attempted — still records the intent |
| 300 | none | practised, no verdict. Legitimate; a verdict is never invented |
Your own wording is kept. again!! is not flattened to again,
and a bare again is not inflated to three bangs.
Both of these are in the log today, and neither produces a warning:
20260920: top 100 like(linked list): 23, 24(again!!!), 25 | ...
^^ dropped. 24 and 25 survive.
20260920: top 100 like(linked list):, 23, 24(again!!!), 25 | ...
^ one character. All three survive.
2D LIS (354) -> logged as LC 2, note "D LIS" discarded
354(2D LIS) -> logged as LC 354, note "2D LIS"
Fixing the 16 number-after-description entries is a separate job from writing today's line. This skill does not rewrite past days.
Arguments are inferred, not interrogated
How to call it
Say what you practised, however you would say it out loud. The verdicts are taken from your own words.
/lc-log 23 ok, 24 again!!, 25
/lc-log 141 and 142 clean, 128 still fighting me
log today's practice
record that I did the linked list set
update progress
| Left out | What happens |
|---|---|
| Bucket | Matched to the labels already in use, or others. Flagged in the report when it was a judgement call. |
| Verdict | Left blank. A bare number is a legitimate entry and a verdict is never invented. |
| Date | Today, checked rather than assumed. Back-dating happens only when you ask for it. |
| What you practised | The one thing it will ask for. It will not assemble a session out of yesterday's todo bucket. |
The guardrails
What it will not do
This file is a record of what happened. A tool that improves the record is a tool that destroys it.
- Invent an attempt.Only what you say you practised goes in — not the carried-over
todobucket, and not a problem /lc-python filed in the same session. Filing a solution is not practising it. - Rewrite a previous day.A problem that went badly on Tuesday still went badly on Tuesday. The log is append-only.
- Flatten or inflate your emphasis.
again!!is notagain. The bang count is what sorts a chronic problem above an ordinary one. - Touch README's status column.That is /lc-again's job, and a promotion there has to be earned. A practice attempt and a mastery verdict are different records.
- Report done without the round-trip.A misread line produces no error — it produces a smaller schedule. The only check that catches it is reading the numbers back.
- Commit or push unless asked.The practice log gets its own commit. It always has.
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-log ~/.claude/skills/
Already installed inside this repo at .claude/skills/lc-log/, so a clone
of CS_basics needs no setup at all. Claude Code matches it on the description, or you
can call /lc-log by name — the directory name is the command.
Zip the directory, then Customize → Skills → + → + Create skill → Upload a skill:
cd .claude/skills && zip -r lc-log.zip lc-log
Leave the YAML frontmatter in SKILL.md intact. description is
what Claude matches your request against when deciding to load the skill on its own.
Codex reads AGENTS.md at the repo root automatically. Point it at the skill:
## Logging a practice session
When asked to log practice, record what was solved today, or update the
progress file, follow `.claude/skills/lc-log/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-log/SKILL.md. \
Log today: 23 ok, 24 again!!, 25, 138 came back"
Paste SKILL.md in as the system prompt. It is self-contained and has no
references/ to carry. For Cursor or Windsurf, put the Codex pointer above
into a rule file (.cursor/rules/lc-log.mdc or the editor's equivalent).
curl -sL https://raw.githubusercontent.com/yennanliu/CS_basics/master/.claude/skills/lc-log/SKILL.md
One caveat away from this repo: step 5's gate is this repo's build and tests. Point it at whatever compiles your own log, or the round-trip check is the only one left.
Under the hood
What is inside
One file. The steps live there and nowhere else — this page describes them, but
SKILL.md is what actually runs, so the two cannot drift into two recipes.
- SKILL.md The whole recipe — the five prime directives, the format as the parser reads it, the annotation vocabulary, the two shapes that lose data, the six steps, the do-not list, and a worked run.
Gated in CI by
check_skills.py,
and the log it writes is gated by
site/test/build-review-plan.test.js, which pins the real
data/progress.txt to zero parser warnings.
The rest of the loop
Where it fits
/lc-log is the step after the practice, not after the solving:
/lc-python and /lc-java file the
code, /lc-log records the attempt, and /lc-again
moves the verdict once a problem finally sticks. What it writes is what the
review plan schedules and what
suggest review spends its picks on.