Agent skill

Comment Lint

by nooga in nooga/let-go

Act on the devlog/breadcrumb comment findings from scripts/lint.lg — decide per hit whether to rewrite or delete a comment, and rewrite it so it describes the code rather than the change that…

MITAuto-check passedDevelopment

Install Comment Lint

skills CLI
$ npx skills add nooga/let-go --skill comment-lint -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install nooga/let-go comment-lint --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/nooga/let-go.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/comment-lint .claude/skills/comment-lint && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
comment-lint
GitHub stars
568
Token cost
~2.5k tokens
SKILL.md length
1,508 words
Files
1
Skills in repo
3
Repo updated
First seen
Licence
MIT

At a glance

Act on the devlog/breadcrumb comment findings from scripts/lint.lg — decide per hit whether to rewrite or delete a comment, and rewrite it so it describes the code rather than the change that…

  • Works in 3 steps: Trim. The narration is a clause on an… → Delete the comment. What remains is a… → Rewrite from the code. The comment…
  • Running the comment linter
  • SKILL.md covers How to run, What a hit means, The test and Counterfactual, yes;…, plus 6 more sections
  • Calls make

What it does

Comment Lint is an agent skill from nooga/let-go. Act on the devlog/breadcrumb comment findings from scripts/lint.lg — decide per hit whether to rewrite or delete a comment, and rewrite it so it describes the code rather than the change that produced it. Use when running the comment linter, cleaning up flagged comments, reviewing a comment-cleanup diff, or writing a comment that describes why code has its current shape.

Its SKILL.md is about 2.5k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Development, covering Linting and formatting. The repository describes itself as: Almost Clojure written in Go. The licence is MIT.

When your agent uses it

  • Running the comment linter
  • Cleaning up flagged comments
  • Reviewing a comment-cleanup diff
  • Writing a comment that describes why code has its current shape

Example prompts

  • “/comment-lint”

Workflow steps

3 steps, taken from the first numbered list in SKILL.md.

  1. Trim. The narration is a clause on an otherwise good comment. Drop the
  2. Delete the comment. What remains is a fact about the code's history that
  3. Rewrite from the code. The comment records something real — an

What it can do on your machine

Read from SKILL.md and the folder at commit a13e042. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • make

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Comment Lint loads about 2.5k tokens when it runs. Until then it costs about 97 tokens; SKILL.md has 1,508 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~97
When it runs · the whole SKILL.md, loaded when a task matches
~2.5k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from nooga/let-go at commit a13e042, republished under its MIT licence (© nooga). 1,508 words, ~2,509 tokens.

Download SKILL.mdSave it as .claude/skills/comment-lint/SKILL.md (or your agent's skills folder).
name
comment-lint
description
Act on the devlog/breadcrumb comment findings from scripts/lint.lg — decide per hit whether to rewrite or delete a comment, and rewrite it so it describes the code rather than the change that produced it. Use when running the comment linter, cleaning up flagged comments, reviewing a comment-cleanup diff, or writing a comment that describes why code has its current shape.

comment-lint — acting on the devlog-comment report

Drives scripts/lint.lg, the report-only scan for comments that narrate a change instead of describing the code. The script decides what to look at; everything below is the judgement it deliberately leaves out. Rationale and the open phrase-list questions: nooga/let-go#835.

How to run

From the repository root:

lg scripts/lint.lg                  # default: pkg scripts
lg scripts/lint.lg pkg scripts cmd  # widen the scan

Report-only. It never edits source, and findings do not affect the exit status (a run that finds 13 things still exits 0), so a hit is never a build gate and never an instruction on its own.

What a hit means

A hit flags a comment block to re-read, not a phrase to delete. The phrase list matches tense markers — "used to be", "moved from", "this PR" — because those are cheap to match and rarely appear in a description of working code. The thing being flagged is the narration underneath, which can survive any edit that only removes the matched words.

So the linter going quiet is not the goal. The goal is a comment that a reader who has never seen a previous version of the file can use.

The test

Would this sentence still be true and useful to someone reading this file for the first time, who has no idea it was ever different?

If removing the comparison leaves the sentence incomplete, the comparison was history and the sentence needs rewriting, not trimming.

Counterfactual, yes; historical contrast, no

These two look alike and are not alike.

Counterfactual — keep. What goes wrong without the code as it stands. This is the honest content of most regression-test and benchmark comments, and it is frequently the right rewrite:

go
// derefSink defeats dead-code elimination: without a package-level sink the
// compiler may elide the Deref call entirely, producing impossible sub-ns
// numbers that say nothing about the real cost.

A reader can check that against the code in front of them, and nothing in it needs a previous version of the file to parse.

Historical contrast — rewrite. The previous design, re-tensed. The giveaway words are rather than, instead, not X but Y, alone could do without, only got away without:

go
// It is passed to the module scaffolder rather than baked in, because the
// AOT native path shares that code.

rather than baked in only parses if you know it was once baked in. The second clause is subtler, and it is the reason the rule above exists: the AOT rationale is true — pkg/gomod's package doc states it, naming #596 and the three behaviors — but it is a fact about pkg/gomod, already written on pkg/gomod. Restating it on a constant in pkg/cli is a second copy that only the change's author would think to put there. When a kept claim checks out, ask where it already lives before keeping it here.

Removing the flagged phrase without removing the history is the failure mode this skill exists to prevent. It passes the linter and changes nothing for the reader.

A counterfactual is not automatically correct

Passing the test above does not make a sentence true. A rewrite that keeps the old comment's shape keeps its claims, and the claims are the part most likely to have gone stale:

go
// asBytes backs the binary file/stream sinks (spit, write!). The byte-array
// case is the one that needs it: without the coercion, a byte-array handed to
// spit/write! stringifies to its #byte-array[…] repr, so bytes >127 never
// reach the sink.

Two defects, neither of them visible to the linter. The stringify claim is true of write! — iort.go falls back to vs[1].String() — and false of spit, which returns spit expected String or byte-array rather than writing anything. One sentence asserts one behavior for two callers that do different things. And where the claim does hold, iort.go already states it on the code itself, so repeating it on a test is the second-copy defect from the wasm.go case above.

Rewrite from the function instead: it converts a String or a byte-kind TypedArray and rejects everything else. That is checkable in one place and stays true whatever the callers do next.

Rewrite or delete

Do not assume every flagged comment has a salvageable core. Three outcomes, in rough order of frequency:

  1. Trim. The narration is a clause on an otherwise good comment. Drop the clause. (the miscompile this PR fixes → the miscompile.)
  2. Delete the comment. What remains is a fact about the code's history that a reader of this file does not need, or a forwarding address to code that is already reachable by name. A pointer saying four helpers "moved to" another namespace tells a reader of the file they left nothing about the file they are in.
  3. Rewrite from the code. The comment records something real — an invariant, a hazard, why an obvious simpler form is wrong — stated as history. Re-derive it by reading the code, not by re-tensing the sentence.

Every causal claim you keep must name code you can point at. A rewrite inherits the old comment's assertions, and those were true of a tree that has moved. Before keeping "because X shares this" or "so that Y can Z", find X and Y in the current tree — repository-wide, including tests and build-tagged files, not just the package in front of you. If you cannot, the claim is history and goes; if you can, check whether the place it is already documented is a better home than this one.

Outcome 3 is where accuracy slips. A comment written as history was true of code that no longer exists, so its details can be stale in ways the linter cannot see: a benchmark comment naming the fields root and curr survived a rename to root and rootBind, and re-tensing it would have preserved the wrong names. Read the code before rewriting; do not paraphrase the old comment.

Show full SKILL.md (630 more words)Show less

Writing the replacement

The rewrite is not free space. Every clause you add is a claim you now own and that someone has to maintain, so the bar for adding one is the bar for any new comment: not "is it true" but "does a reader of this file need it here."

Prefer removal to replacement. Most flagged blocks are a good comment with a clause welded on. Cutting the clause is finished work. Replacing the block invites you to restate things that are already written somewhere better.

Before adding a fact, find where it already lives. If the claim belongs to another file's code, that file is its home; a copy here is the wasm.go defect, and it rots independently of the original.

Stop when the sentence is checkable against the code in front of you. Not when it is complete, not when it explains the design — when a reader with this file open can verify it without opening another.

Naming a symbol buys precision and a rename hazard. Name one when it is the only handle a reader has, and prefer a symbol a rename would have to touch over a file path or a line number, which nothing keeps honest.

Two smaller rules

Do not rank what the code does not rank. "The byte-array case is the one that needs it" elevates one of the three cases TestAsBytes covers. That emphasis is the author's view of which case was interesting — a fact about the change, not about the code — and it is often the re-tensed ghost of a superlative like "the one that used to be impossible". Describe the cases and let the reader decide which one they came for.

Do not carry a bare issue or PR number into a block you are rewriting. A number that only records where a change was discussed is provenance; git blame and the PR already hold it, and in a comment it rots silently. An identifier that is the only name a thing has may stay: the native adapters #438 Def'd at init names something with no other handle, while (#506) trailing a list of three functions names nothing the sentence has not already said.

This is scoped to the block you already have open. It is not a license to sweep every ID in the tree — that question, and the phrase list generally, is open on nooga/let-go#835, and the split above is the current lean rather than a settled position.

The one hard rule

Never drop an invariant. Flagged comments often carry the only written record of why something must be done in a particular order, why a simpler form breaks, or what a test is actually pinning. Losing that to satisfy a report-only linter is a strictly worse outcome than leaving the comment alone. When the narration and the invariant cannot be separated, keep the comment and say so in the PR rather than shipping a lossy rewrite.

Two operational gotchas

  • A block reports one phrase and stops — the first match in devlog-phrases order, not the one appearing earliest in the comment. Fixing it can expose a second in the same block, so re-run the linter after a sweep rather than trusting one pass.
  • Editing a comment in a .lg file that pkg/rt/generated.manifest lists changes generated artifacts. The manifest digests its source inputs and generated.sums digests the manifest, so a comment-only edit to one needs make generate, and both files are committed. Being git-tracked is not the test — most .lg files under pkg/ are inputs, while scripts/lint.lg and cmd/lginterop/lginterop.lg are not. Grep the manifest for the path. The compiled outputs are byte-identical — comments never reach the reader's form tree, which is also why the linter has to scan raw source.

The tool reports; you exercise the judgement.

© nooga, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/comment-lint of nooga/let-go.

Open the folder on GitHubat commit a13e042

Compare with similar skills

Comment Lint next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Comment Lint compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Comment Lint this skillnooga/let-go568—~2.5kAutomated safety check: PassMIT
Minimizing Ty Ecosystem Changesastral-sh/ruff50k—~4.6kAutomated safety check: PassMIT
Install Anti-Slop Oxlint Rulesdmmulroy/anti-slop5.3k—~2.2kAutomated safety check: PassMIT
Babysit PR To Pass CIsgl-project/sglang37k2 repos~3kAutomated safety check: PassApache-2.0
Rust Best Practicesfarm-fe/farm5.6k3 repos~1.1kAutomated safety check: PassMIT
Summarise Ecosystem Resultsastral-sh/ruff50k—~2.2kAutomated safety check: PassMIT

Similar skills

  • Official

    A skill your agent uses when a user says "minimize this ty ecosystem change", "reproduce this ecosystem result", "investigate a primer difference", "investigate a mypyprimer difference"…

    50k GitHub stars~4.6k tokensUpdated today
    DevelopmentAuto-check passed
  • Installs, updates or migrates the vendored anti-slop Oxlint plugin in a repository, keeping local rule changes and the plugin's license and provenance files.

    5.3k GitHub stars~2.2k tokensUpdated 29 days ago
    DevelopmentAuto-check passed
  • Babysit PR To Pass CI

    sgl-project/sglang

    Start and persistently pursue a goal to babysit an SGLang pull request until selected GitHub Actions workflows pass on the latest PR head.

    37k GitHub starsUsed in 2 repos~3k tokens
    DevelopmentAuto-check passed
  • Guide for writing idiomatic Rust code based on Apollo GraphQL's best practices handbook.

    5.6k GitHub starsUsed in 3 repos~1.1k tokens
    DevelopmentAuto-check passed
  • Official

    A skill your agent uses when a user says "summarise ecosystem results", "summarize this ty ecosystem report", "what changed in this ecosystem run?", or asks to summarise or summarize ty ecosystem…

    50k GitHub stars~2.2k tokensUpdated today
    DevelopmentAuto-check passed
  • Go Pedantry

    chromedp/chromedp

    This skill should be used when the user is writing Go code and needs guidance on Go-specific pedantry: error wrapping with fmt.Errorf and %w, interface design (accept interfaces return structs)…

    13k GitHub stars~3.7k tokensUpdated 3 days ago
    DevelopmentAuto-check passed

More from nooga/let-go

  • Bench Baton

    nooga/let-go

    Coordinate heavy local workloads across worktrees, processes, and subagents — benchmarks and timing-sensitive gates run exclusively on a quiesced machine, while builds, test suites, regeneration…

    568 GitHub stars~821 tokensUpdated today
    Auto-check passed
  • Docs Status

    nooga/let-go

    Audit documentation hygiene for the let-go docs/ tree — find stale or unverified docs, dangling or one-sided supersession links, duplicate authoritative-for claims, and docs missing from the README…

    568 GitHub stars~589 tokensUpdated today
    Auto-check passed

Categories

Questions about Comment Lint

What does Comment Lint do?

Act on the devlog/breadcrumb comment findings from scripts/lint.lg — decide per hit whether to rewrite or delete a comment, and rewrite it so it describes the code rather than the change that…. Comment Lint is an agent skill from nooga/let-go.lg — decide per hit whether to rewrite or delete a comment, and rewrite it so it describes the code rather than the change that produced it.

When should I use Comment Lint?

Comment Lint fits situations like: running the comment linter; cleaning up flagged comments; reviewing a comment-cleanup diff; writing a comment that describes why code has its current shape.

How do I install Comment Lint in Claude Code?

Run `npx skills add nooga/let-go --skill comment-lint -a claude-code`. Or copy the skill folder (.agents/skills/comment-lint in nooga/let-go) into .claude/skills/comment-lint in your project. Claude Code loads it when a task matches its description.

How do I install Comment Lint in Codex?

Run `npx skills add nooga/let-go --skill comment-lint -a codex`. Or copy the skill folder (.agents/skills/comment-lint in nooga/let-go) into .agents/skills/comment-lint in your project. Codex loads it when a task matches its description.

Can I use Comment Lint in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add nooga/let-go --skill comment-lint -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/comment-lint, .gemini/skills/comment-lint, .github/skills/comment-lint and .opencode/skills/comment-lint in your project.

What does Comment Lint need to run?

Going by SKILL.md and its folder, Comment Lint needs the command-line tools its instructions call (make).

Does Comment Lint access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Comment Lint safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Comment Lint use?

Comment Lint is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Comment Lint use?

About 2.5k tokens (SKILL.md is roughly 10k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Comment Lint?

Skills that share tags, products or a category with Comment Lint: Minimizing Ty Ecosystem Changes (astral-sh/ruff, 50k stars), Install Anti-Slop Oxlint Rules (dmmulroy/anti-slop, 5.3k stars), Babysit PR To Pass CI (sgl-project/sglang, 37k stars) and Rust Best Practices (farm-fe/farm, 5.6k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Comment Lint?

nooga (a GitHub user) maintains it in nooga/let-go, which has 568 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on October 9, 2026.

Source: nooga/let-go on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.