stupid-comments
Enforces your comment policy at write time, inside DeepSeek Harness. Reads the policy from your AGENTS.md or CLAUDE.md, blocks violating writes, and re-injects the policy verbatim so the model stops drifting from it.
安装
dsh plugin --profile web add github:nmindz/stupid-comments
需要可复现安装时,可在仓库后追加 #commit 固定提交。
Enforces your comment policy at write time, inside DeepSeek Harness. Reads the policy from your AGENTS.md or CLAUDE.md, blocks violating writes, and re-injects the policy verbatim so the model stops drifting from it.
该插件未提供要点说明,请参考仓库 README。
- 安装并启动 DeepSeek Harness:
npx @deepseek-ai/dsh web - 在终端执行上面的安装命令(CLI 会解析插件并核验来源)
- 用 dsh plugins list 确认已安装,必要时重启 Harness 生效
插件以当前 dsh 进程的权限运行,安装时可能执行代码。请先通读仓库源码与许可证,确认无破坏性命令与越权访问;本站只做索引,不对第三方插件安全性作担保。
| 代码仓库 | github.com/nmindz/stupid-comments |
| 许可证 | GPL-3.0 |
| 主要语言 | master |
| 下载量 | 1 |
| GitHub 星标 | 0 |
| 最近推送 | 2026-09-06 |
| 收录日期 | 2026-09-19 |
| 分类 | 工具与能力 |
事实信息来自公开插件目录快照(2026-10-01),介绍文案由本站再加工。
以下为插件仓库 README 全文(原始内容,由公开目录抓取整理)。
# stupid-comments
**Runtime enforcement for your code comment policy.** A Rust CLI that parses what an LLM is about to write, checks it against *your* policy, and refuses the write when it violates. It ships as a plugin for both [Claude Code](https://claude.com/claude-code) and [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness), off the same binary and the same rules.
[](LICENSE)
[](https://github.com/nmindz/stupid-comments/releases)
[](https://www.rust-lang.org)
---
## The problem
Every model tier, at every reasoning level, eventually forgets your comment policy and starts writing `// Increment the counter` above `counter++`. That is an attention problem, and no amount of restating the rule in `CLAUDE.md` fixes it — the instruction is simply too far back in the context by the time the code gets written.
So this moves enforcement out of the prompt and into the runtime, re-injecting your policy text verbatim at the exact moment it matters.
The policy is never baked in. It is yours, it is prose, and it lives where you already keep it.
## Quick start
```sh
git clone https://github.com/nmindz/stupid-comments && cd stupid-comments
make install
```
Then register the plugin with whichever harness you run. Inside Claude Code:
```
/plugin marketplace add nmindz/stupid-comments
/plugin install stupid-comments@stupid-comments
```
Or, for DeepSeek Harness:
```sh
dsh plugin --profile tui add github:nmindz/stupid-comments
```
Finally, add a `# Comments Policy` section to your agent memory — `~/.claude/CLAUDE.md` or `~/.dsh/AGENTS.md` — in your own words, and confirm it was picked up:
```sh
stupid-comments policy
```
Without that section and without a config file, the plugin stays completely silent. There is no default policy, because a default policy would be someone else's taste.
## Table of contents
- [How it works](#how-it-works)
- [Installation](#installation)
- [AI agent instructions](#ai-agent-instructions)
- [Configuration](#configuration)
- [Rules](#rules)
- [CLI usage](#cli-usage)
- [Slash commands](#slash-commands)
- [Semantic judging](#semantic-judging)
- [Escaping it](#escaping-it)
- [Detecting evasion](#detecting-evasion)
- [Languages](#languages)
- [Development](#development)
- [Known limits](#known-limits)
- [Contributing](#contributing)
- [License](#license)
## How it works
Your policy is read from the `# Comments Policy` section of your agent memory (any heading level, case-insensitive). That text is quoted verbatim in every rejection, never paraphrased. If no such section and no config file exist, the plugin does nothing at all and says nothing at all.
**Memory is searched in a fixed order,** and the first file carrying the section wins: `$CLAUDE_CONFIG_DIR/CLAUDE.md` (default `~/.claude/CLAUDE.md`), then `$DSH_HOME/AGENTS.md` (default `~/.dsh/AGENTS.md`), then `$AGENTS_HOME/AGENTS.md` (default `~/.agents/AGENTS.md`), then the nearest `CLAUDE.md` and `AGENTS.md` at or above the file being checked. The order is fixed rather than harness-derived on purpose: a machine running both must not get a different policy depending on which agent asked.
**Enforcement is layered.** The pre-write gate catches Write/Edit/MultiEdit early, reconstructing the post-edit file in memory so rules see whole-file context while reporting only the lines the edit introduced. The stop gate is the real guarantee: it diffs the working tree and analyzes added lines only, which makes it indifferent to *how* the file was written — heredoc, `sed`, or a subagent all land in the same net.
**Both harnesses run the same engine.** Claude Code wires those gates through `PreToolUse`, `Stop`, and `SubagentStop`; DSH wires them through `tools/pre-execute`, `agent/turn-stopping`, and `subagent/end`. Each adapter builds the identical JSON payload and hands it to the same binary, so a rule only ever exists in one place.
**Nothing is judged until it is classified.** Every comment is sorted into `directive`, `license-header`, `doc-comment`, or `prose`, and only `prose` faces the ratio and redundancy rules. Lint pragmas, `go:build` lines, shebangs, SPDX headers, and JSDoc are structurally exempt rather than merely tolerated — and a pragma placed above a comment block never launders the block beneath it.
**Deletion is not compliance.** A gate you can satisfy by removing the comment trains the model to write none at all, which inverts a policy that asks for *just enough* commenting. So findings name the offending span, demand a rewrite, and say outright that removing it does not count. Bulk deletion is legitimate on a legacy codebase, but only under `/stupid-comments:fix`, where a human is present and there is nothing to game.
## Installation
Two pieces, installed separately and on purpose. The plugin never downloads or executes anything on your behalf — a marketplace plugin that silently fetches a remote binary is exactly the supply-chain pattern worth distrusting.
Requires a Rust toolchain. Get one from if you have none.
### 1. The CLI
**From a clone (recommended):**
```sh
make install # installs to ~/.local/bin
make install ROOT=$HOME/.cargo # or wherever your PATH points
```
`make install` runs the cargo command below, then reports what `command -v` actually resolves to and its version.
**With cargo directly:**
```sh
# from a clone
cargo install --path crates/stupid-comments --root ~/.local --force
# or straight from git, without cloning
cargo install --root ~/.local --git https://github.com/nmindz/stupid-comments stupid-comments
```
Drop `--root ~/.local` to use cargo's own default of `~/.cargo/bin`.
> [!IMPORTANT]
> Pick whichever directory is already on your `PATH`. The plugin decides whether to enforce by looking the binary up on `PATH`, so installing somewhere the shell cannot resolve leaves enforcement **permanently inert**. Confirm with `command -v stupid-comments`, not by checking that the file exists.
Verify with `stupid-comments --version`.
### 2. The plugin
**Claude Code:**
```
/plugin marketplace add nmindz/stupid-comments
/plugin install stupid-comments@stupid-comments
```
**DeepSeek Harness:**
```sh
dsh plugin --profile tui add github:nmindz/stupid-comments
dsh plugin --profile tui add /path/to/clone # from a checkout
```
The package declares a `dsh.bundle` patch, so `dsh plugin add` installs it and reconciles it into that profile's bundle list on its own. Nothing else needs editing.
Restart the session so the hooks register. If a policy exists but the CLI is missing, the plugin says so once and enforces nothing.
To upgrade later, every piece moves independently:
```sh
make install
claude plugin marketplace update stupid-comments
claude plugin update stupid-comments@stupid-comments
dsh plugin --profile tui update stupid-comments
```
### 3. A policy
Add a `# Comments Policy` section to `~/.claude/CLAUDE.md` or `~/.dsh/AGENTS.md` describing, in your own words, how you want comments written. Confirm it was picked up with `stupid-comments policy`.
To keep the policy somewhere else, point at it with the `prose` config key.
### Verify
```sh
stupid-comments check path/to/your/code
```
The CLI stands alone, so the same command works as a pre-commit hook or a CI step with `--json`.
## AI agent instructions
Paste this into a Claude Code session and it will do the setup for you:
```text
Set up the stupid-comments comment policy enforcer on this machine.
1. If `command -v stupid-comments` already resolves, it is installed and
reachable — skip straight to step 4.
2. Pick the install root by checking my PATH FIRST. Never install into a
directory PATH cannot resolve:
- if ~/.local/bin is in $PATH -> cargo install --root ~/.local --git \
https://github.com/nmindz/stupid-comments stupid-comments
- else if ~/.cargo/bin is in $PATH -> same command without --root
- else STOP. Do not install. Tell me which directories cargo can target
and ask which one I want, or give me the export line to add to my
shell profile first.
Check with: case ":$PATH:" in *":$HOME/.local/bin:"*) ...
If cargo itself is missing, point me at https://rustup.rs and stop there.
3. Verify by running `command -v stupid-comments` and `stupid-comments
--version`. If `command -v` does not resolve, the binary went somewhere
PATH cannot see it — say so plainly instead of reporting success.
4. Register the plugin with the harness you are running in.
In Claude Code, tell me to run these two myself, since you cannot run
slash commands:
/plugin marketplace add nmindz/stupid-comments
/plugin install stupid-comments@stupid-comments
In DeepSeek Harness, run it yourself and name the profile you targeted:
dsh plugin --profile add github:nmindz/stupid-comments
5. Read my agent memory — ~/.claude/CLAUDE.md, or ~/.dsh/AGENTS.md under
DeepSeek Harness — and look for a heading matching "Comments Policy" at
any level, case-insensitive. If it is missing, DO NOT invent a policy.
Show me where the section goes, ask what my rules are, and write exactly
what I tell you.
6. Run `stupid-comments policy` and show me the resolved source, mode and rules.
7. Explain that mode defaults to `shadow` — findings reported, nothing blocked —
and that I should stay there until the reports look right before adding a
.stupid-comments.jsonc with "mode": "block".
8. Do not enable the `semantic` option. Tell me it exists, that it spends a
`claude -p` call per checked file, and that turning it on is my call.
```
## Configuration
Everything here is optional. Drop a `.stupid-comments.jsonc` anywhere at or above the file being checked; the nearest one upward wins.
```jsonc
{
"mode": "block", // shadow (default) | warn | block
"bannedPatterns": ["\\bPRDs?[- ]?\\d*\\b"],
"maxProseCommentLines": 5,
"maxDocCommentLines": 40,
"maxCommentRatio": 0.35,
"minProseCommentsForRatio": 4,
"redundancy": "warn",
"semantic": "shadow", // shadow (default) | warn | block
"exclude": ["**/generated/**"]
}
```
| Key | Type | Default | Purpose |
| --- | --- | --- | --- |
| `mode` | `shadow` \| `warn` \| `block` | `shadow` | Global severity ceiling. `shadow` reports without blocking |
| `prose` | path | — | Read the policy from this file instead of agent memory. `~` expands |
| `maxProseCommentLines` | integer | `5` | Longest permitted prose comment block |
| `maxDocCommentLines` | integer | `40` | Longest permitted doc comment |
| `maxCommentRatio` | float | `0.35` | Share of a file that may be prose comments |
| `minProseCommentsForRatio` | integer | `4` | Comment *blocks* required before the ratio rule applies |
| `bannedPatterns` | regex list | empty | Text that may never appear in a comment |
| `redundancy` | `shadow` \| `warn` \| `block` | `warn` | Comments that restate the line below them |
| `semantic` | `shadow` \| `warn` \| `block` | `shadow` | LLM taste judgement. See [Semantic judging](#semantic-judging) |
| `semanticCommand` | string list | `["claude", "-p"]` | Command the semantic judge shells out to |
| `exclude` | glob list | empty | Paths to skip entirely |
These are *calibration*, not policy. The defaults are deliberately loose, because a threshold tight enough to be opinionated would be smuggling in someone else's taste.
> [!TIP]
> `mode` defaults to `shadow`: findings are reported, nothing is blocked. Stay there until the log convinces you the blocks would have been right, then switch to `block`.
An unparseable config is an error, not silence — `check` and `policy` print the reason and exit non-zero. Only the hook still fails open, since an unreadable config must never block a write.
## Rules
| Rule | Default severity | Fires when |
| --- | --- | --- |
| `banned-pattern` | block | A comment matches one of your `bannedPatterns` |
| `prose-comment-too-long` | block | A prose block exceeds `maxProseCommentLines` |
| `doc-comment-too-long` | warn | A doc comment exceeds `maxDocCommentLines` |
| `comment-ratio` | block | Prose comments cover more than `maxCommentRatio` of the file |
| `redundant-comment` | warn | A comment restates the code directly below it |
| `semantic` | warn | The judge decides a comment has not earned its place |
| `comments-removed` | warn | A file that had prose comments now has none |
Severities are ceilings, not floors: under `"mode": "shadow"` or `"warn"` every finding is downgraded, and findings recovered from a file whose grammar failed are always warn-only.
## CLI usage
```sh
stupid-comments check [PATH]... # report findings, change nothing
stupid-comments check --json # machine-readable, for CI
stupid-comments check --adjudicate # permit deletion as a remedy
stupid-comments policy # show the resolved policy and its source
stupid-comments hook claude|dsh # consume a hook payload on stdin
```
Every run prints a coverage summary to **stderr**, leaving stdout clean for `--json`:
```
Checked 17 files (rust 12, json 2, toml 2, make 1).
Not checked — no grammar for 8 files: .md 5, .gitignore 1, .lock 1, LICENSE 1
Not checked — excluded by config: 10 files
```
A file with no grammar is not a passing file, so it is never folded into the checked count. The numbers add up on purpose.
| Exit code | Meaning |
| --- | --- |
| `0` | No blocking findings |
| `1` | A blocking finding, an unreadable config, or a path that does not exist |
| `2` | Hook only: block the pending write |
## Slash commands
| Claude Code | DeepSeek Harness | Purpose |
| --- | --- | --- |
| `/stupid-comments:policy` | `/stupid-comments-policy` | Show the policy in force and where it came from |
| `/stupid-comments:check [path]` | `/stupid-comments-check [path]` | Report findings, change nothing |
| `/stupid-comments:fix [path]` | `/stupid-comments-fix [path]` | Adjudicated sweep of an existing codebase; deletion permitted |
| `/stupid-comments:off` | `/stupid-comments-off` | How to disarm for a session |
The names differ only because DSH command names cannot carry a colon. The prompts do not: both harnesses read the same markdown files under `plugins/stupid-comments/commands/`, so the wording has exactly one home.
## Semantic judging
Deterministic rules cannot decide whether a comment earns its place. Setting `"semantic": "warn"` (or `"block"`) sends the prose comments and your policy text to `claude -p`, using the session authentication you already have — there is no API key to configure and none is wanted. Every failure is silent: no `claude` on PATH, a timeout, unparseable output, all mean no findings.
The judge is a subprocess, not a harness binding. Point `semanticCommand` at anything that reads a prompt on stdin and answers with JSON, and it works the same from either plugin.
It is off by default because it spends a model call per checked file. It is also the only rule that catches `// Adds a and b` sitting above `const sum = a + b`, which is probably the comment that made you look for this tool.
## Escaping it
Set `STUPID_COMMENTS=0` in the session environment. That is deliberately the only mid-session hatch — it lives somewhere the model cannot write, so the enforced party cannot disable its own gate. Both plugins honor it, and the DSH one registers no seams at all when it is set.
Permanently: change `mode` in `.stupid-comments.jsonc`, or remove the plugin with `/plugin uninstall stupid-comments@stupid-comments` or `dsh plugin --profile tui remove stupid-comments`.
Suppression pragmas exist, but they are anchored to git:
```ts
// stupid-comments: ignore -> suppresses findings on the next 3 lines
// stupid-comments: ignore-file -> suppresses the whole file
```
> [!NOTE]
> A pragma is honored **only if the identical line already exists in `HEAD`**. One introduced in the same change as the violation it silences is ignored entirely, so the model cannot write its own exemption. Outside a git repository no pragma is honored.
## Detecting evasion
A gate that counts only violations cannot tell "learned taste" from "stopped writing comments". Prose-comment counts are tracked per file for the session, and a file that had comments and now has none raises a `comments-removed` warning naming what was lost. Bulk removal is legitimate, but only under `/stupid-comments:fix`, where a human asked for it.
## Languages
JavaScript, TypeScript, TSX/JSX, Rust, Go, Kotlin, JSON/JSONC/JSON5, TOML, YAML, HCL/Terraform, shell (sh/bash/zsh/ksh), and Make, via native tree-sitter grammars.
**Not every file carries its language in its extension.** `Makefile`, `GNUmakefile`, `Makefile.*` and `*.mk` are matched by name, as are the usual shell rc files, and an extensionless file is checked for a shell shebang — a `scripts/` directory is mostly extensionless, and skipping one silently is indistinguishable from checking it and finding nothing. `#!/usr/bin/env bash` counts; `#!/usr/bin/env python3` does not, and neither does `fish`.
**A `#` inside a shell string, a heredoc body, or a Make recipe is data, not commentary.** Telling those apart is the whole reason this uses grammars rather than a regex over lines starting with `#`.
**Config formats answer to exactly the same rules as code**, `maxCommentRatio` included. They have twice been given something gentler — first an outright exemption from the ratio rule, then a looser threshold of their own — and both times the result was a manifest sitting at a comment load that would be flagged on sight in a `.go` file. A YAML at 43% comments is a YAML at 43% comments; there is no version of "just enough" that reads differently because the file ends in `.yaml`.
**Templating defeats the YAML grammar.** A Helm chart parses to a single error node with no comments in it, which would make every templated manifest in a repository look clean. When the grammar fails on a `#`-comment format, comments are recovered by a line scan instead — whole-line comments only, block scalars left alone, so the failure direction is a missed comment rather than an invented one.
Failure is otherwise open. Parse error, missing binary, unreadable config — inside the hook all of them mean *no findings*, never a blocked write.
## Development
Requires a Rust toolchain. `make help` lists every target.
| Make | Cargo equivalent | Purpose |
| --- | --- | --- |
| `make build` | `cargo build --release` | Compile the release binary |
| `make test` | `cargo test` | Run the test suite |
| `make dsh-test` | `node plugins/stupid-comments/dsh/test.mjs` | Drive the DSH adapter against the release binary |
| `make lint` | `cargo clippy --all-targets` | Lint every target |
| `make version` | `node scripts/sync-version.mjs X.Y.Z` | Write one version into all five manifests |
| `make validate` | `claude plugin validate` + `scripts/validate-dsh-manifest.mjs` | Check both plugin manifests |
| `make check` | all of the above | Everything CI would run |
| `make install` | `cargo install --path crates/stupid-comments --root ~/.local --force` | Install the binary |
| `make uninstall` | `cargo uninstall --root ~/.local stupid-comments` | Remove it |
| `make dsh-install` | `dsh plugin --profile tui add $(pwd)` | Register this checkout with a dsh profile |
| `make dsh-uninstall` | `dsh plugin --profile tui remove stupid-comments` | Unregister it |
| `make selfcheck` | `./target/release/stupid-comments check .` | Enforce this repo's policy on itself |
| `make clean` | `cargo clean` | Remove build artifacts |
`make selfcheck` is the one that matters: the enforcer answers to its own policy, and a change that makes this repo fail its own gate is not ready.
```
crates/stupid-comments/src/
├── lang.rs # language detection and grammar bindings
├── comments.rs # extraction and classification
├── rules.rs # the deterministic rules
├── semantic.rs # the opt-in LLM judge
├── policy.rs # config and policy resolution
├── hook.rs # hook payloads, shared by every harness
├── suppress.rs # git-anchored pragmas
├── session.rs # cross-turn evasion tracking
└── main.rs # CLI
```
The harness plugins are adapters over that binary, and neither carries a rule of its own:
```
plugins/stupid-comments/
├── .claude-plugin/plugin.json # Claude Code manifest
├── hooks/hooks.json # Claude Code hook wiring
├── commands/*.md # slash command prompts, read by both harnesses
└── dsh/
├── index.js # DSH cordis plugin: seams, payloads, commands
├── cordis.patch.yml # the bundle layer dsh composes
└── test.mjs # drives the adapter against the real binary
```
`package.json` at the repo root is the DSH bundle manifest: it points `dsh.bundle.patch` at that patch file, which is the whole reason `dsh plugin add` can install this repository directly.
Releases are derived from Conventional Commits by semantic-release, and the npm package is *staged* rather than published: CI authenticates through OIDC trusted publishing and holds no credential that can ship a version on its own, so a human approves the tarball with a 2FA code. See [CONTRIBUTING.md](CONTRIBUTING.md) for the commit convention, the release flow, and a walkthrough of adding a language.
## Known limits
- Redundancy detection is warn-only. It is the most false-positive-prone rule here and has not earned blocking authority.
- Kotlin findings are warn-only while its grammar earns trust, as are findings recovered by line scan from a templated config file.
- The line-scan fallback reads whole-line comments only, so a trailing `# comment` on a value line goes unchecked in a templated file.
- Python has no grammar yet, so `.py` files are named as unchecked rather than checked.
- `minProseCommentsForRatio` counts comment *blocks*, not lines, so a file carrying fewer than four separate blocks never trips the ratio rule however much of the file they cover. Long blocks are caught by the length rule instead.
- Semantic judging costs a model call per checked file, so it is off by default.
- The `Stop` gate diffs against `HEAD`, so a tree that was already dirty before the session has those earlier changes considered too.
- DSH also ships a text-editor tool. Its `create` and `str_replace` commands are translated and checked before the write; its `insert` command carries no anchor to reconstruct from, so it falls to the stop gate.
- Under DSH, `subagent/end` is an observation point rather than a decision point. A subagent that ends on a violation is handed the finding as context; only the parent's own stop gate can force the rewrite.
- The DSH plugin reports a missing binary the first time a write is about to be checked, not at session start, so a session that never writes code stays silent about it.
## Contributing
Bug reports and pull requests are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).
## License
GPL-3.0-or-later. See [LICENSE](LICENSE).
数据来源:公开的 DeepSeek Harness 插件目录与各插件 GitHub 仓库。本站为独立第三方目录,与 DeepSeek、幻方(High-Flyer)及插件作者均无隶属或背书关系。