feat(notes): centralize the project's notes in docs/notes.md, queryable without reading it - #28
Merged
Merged
Conversation
…le without reading it A comment says what a thing is and how to use it. Everything else written beside code — the gotcha, the why-not, the "careful, this looks wrong and is not" — reaches exactly one reader, the one already looking at that line: no command lists it, and it dies with the file. It moves to one log, and the log answers questions instead of being read. One note is one line, index fields first: - n-0042 2026-02-09 #gotcha @internal/cli/launch.go — wrap writes MCP config The single line is the whole design. A match is a *whole note*, so `grep ' #gotcha ' docs/notes.md` and `scc notes find --tag gotcha` answer the same question without either reasoning about where a record ends — which is what lets the file that centralizes every note never be a file anybody reads. It also closes the door the v1 plan format left open, where `## Notes` grew to half the file because nothing forbade it: there is nowhere for prose to go, and a thought needing a second line is a wiki page, an ADR, or a task. - internal/notes: the grammar, the log region, the query, the splice. - scc notes add | find | show | tags | paths | rm | validate. `add` allocates the id and writes the format, because a format nobody can be made to type decays; it writes under the same verify-and-roll-back contract as `scc patch`. --tag is required and has no default: a default is one tag on everything, which is the drift the index exists to prevent. - rm leaves an HTML-comment tombstone, so a number is spent and never reused: a citation to n-0042 may dangle, but can never mean a different note. - A ninth validator. The finding that matters is a hand-written line that missed the grammar — invisible to every query, so the note is already lost. A @path that no longer resolves is the notes half of the codewiki citation rule, and at write time it warns rather than blocks: a note about a file this branch has not created yet is the note most worth having. - rules/notes.md is the trigger — you are about to type a comment that is not a docstring — with the read side in prior-art.md, since notes are now the one corpus under docs/ that has an index. The init skill harvests the TODO/HACK comments already in a repository, without touching code. Template version 19; docs/notes.md is the fifth seeded anchor. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YbWPnnFpqu4wa71ri76iw2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A comment says what a thing is and how to use it. Everything else that gets written beside code — the gotcha, the why-not, the "careful, this looks wrong and is not" — reaches exactly one reader: the one already looking at that line. Nobody asking what do we know about this area ever finds it, no command lists it, and it dies with the file. So it moves to one log, and the log answers questions instead of being read.
One note is one line
id· date ·#tags(at least one) ·@paths(repo-relative) · em dash · the note. The single line is the entire design, and it buys three things at once:grep ' #gotcha ' docs/notes.mdandscc notes find --tag gotchaanswer the same question and neither has to reason about where a record ends. That is what lets the file that centralizes every note never be a file anybody reads.## Notesgrew to half the file because nothing forbade it. A thought needing a second line is a wiki page, an ADR, or a task — all three already exist, andrules/notes.mdsays which is which.#tagis the index the log is queried by,@pathis what keeps a note attached to code without living inside it, and the id is what a commit message or a spec cites.scc notes— the writer, never a gatekeeperaddallocates the id and gets the format right, because a format nobody can be made to type is one that decays — and it writes under the same verify-and-roll-back contract asscc patch.--tagis required and has no default: a default would be one tag on everything, which is the drift the index exists to prevent.findputs the notes and nothing else on stdout, in the form the file holds them, so a--limitthat truncates says what it dropped on stderr rather than looking complete.A number is spent, never reused.
rmtakes the text out and leaves an HTML-comment tombstone where the note stood, so a citation ton-0042can dangle but can never come to mean a different note.mdscanblanks comments, so the tombstone is invisible to a rendered read, to a grep for a tag, and to every parser except the one allocating the next id.A ninth validator
The finding that matters is
notes.malformed: a hand-written line that missed the grammar is invisible to every query, so the note is already lost — silently, which is the one way this file can fail without anybody noticing.notes.stale-pathis the notes half of the codewiki citation rule, since a note about code that no longer exists is read as current — worse than the comment it replaced, which at least died with the file. At write time it warns and never blocks: a note about a file this branch has not created yet is the note most worth having.Also
notes.duplicate-id,notes.outside-log,notes.untagged,notes.bad-tag,notes.bad-date,notes.bad-path,notes.no-log-section.The instructions
rules/notes.md(53 lines) — the trigger is a keystroke: you are about to type a comment that is not a docstring. NoTODO,FIXME,HACK,NOTE,XXX, no commented-out code.entry.mdgains one trigger line carrying its own query, paid for by merging a paragraph — the 60-line cap still holds exactly.prior-art.mdgains the read side:docs/is in no index but one now.knowledge-base.mdnames the fifth anchor, at its 81-line cap unchanged.initskill harvests theTODO/HACKcomments already in a repository into the log, without touching code — the comment goes when its file is next edited.code-reviewflags a non-docstring comment in a diff.Template version 19.
docs/notes.mdis the fifth seeded anchor, soscc updatedelivers the rule to existing workspaces and the firstscc notes addseeds the log itself.Two things worth knowing
internal/*is full of long why comments and CLAUDE.md treats that as a value. The rule ships to the workspaces the binary scaffolds; this repo is not one, and nothing in it was touched on that account.notesskill. That breaks the one-skill-per-validated-artifact symmetry on purpose: the format is written byscc notes addand the judgment fits in the rule, so a skill would be a second copy of one fact.Checks
gofmt -lclean ·go vet ./...clean ·go test ./...green ·golangci-lint run→ 0 issues. The race detector could not run locally (no cgo toolchain on this machine); CI covers it.🤖 Generated with Claude Code
https://claude.ai/code/session_01YbWPnnFpqu4wa71ri76iw2