Skip to content

feat(notes): centralize the project's notes in docs/notes.md, queryable without reading it - #28

Merged
protonspy merged 1 commit into
mainfrom
feat/notes-log
Aug 27, 2026
Merged

feat(notes): centralize the project's notes in docs/notes.md, queryable without reading it#28
protonspy merged 1 commit into
mainfrom
feat/notes-log

Conversation

@protonspy

Copy link
Copy Markdown
Owner

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

- n-0042 2026-02-09 #gotcha @internal/cli/launch.go — wrap writes MCP config to the agent's own file, so it outlives the session

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:

  • A match is a whole note, so grep ' #gotcha ' docs/notes.md and scc notes find --tag gotcha answer 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.
  • There is nowhere for prose to go. This is the door the v1 plan format left open, where ## Notes grew 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, and rules/notes.md says which is which.
  • The fields are addressable. #tag is the index the log is queried by, @path is 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 gatekeeper

scc notes add "the observation" --tag gotcha --path internal/cli/notes.go
scc notes find --path internal/cli          # a directory covers what is under it
scc notes find --tag gotcha --since 2026-01-01 --limit 5
scc notes tags                              # read before coining a fourth name for one concern
scc notes show n-0042 · rm n-0042 · validate

add allocates 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 as scc patch. --tag is required and has no default: a default would be one tag on everything, which is the drift the index exists to prevent. find puts the notes and nothing else on stdout, in the form the file holds them, so a --limit that truncates says what it dropped on stderr rather than looking complete.

A number is spent, never reused. rm takes the text out and leaves an HTML-comment tombstone where the note stood, so a citation to n-0042 can dangle but can never come to mean a different note. mdscan blanks 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-path is 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. No TODO, FIXME, HACK, NOTE, XXX, no commented-out code.
  • entry.md gains one trigger line carrying its own query, paid for by merging a paragraph — the 60-line cap still holds exactly.
  • prior-art.md gains the read side: docs/ is in no index but one now.
  • knowledge-base.md names the fifth anchor, at its 81-line cap unchanged.
  • The init skill harvests the TODO/HACK comments already in a repository into the log, without touching code — the comment goes when its file is next edited.
  • code-review flags a non-docstring comment in a diff.

Template version 19. docs/notes.md is the fifth seeded anchor, so scc update delivers the rule to existing workspaces and the first scc notes add seeds the log itself.

Two things worth knowing

  1. scc's own code is the opposite of this ruleinternal/* 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.
  2. No notes skill. That breaks the one-skill-per-validated-artifact symmetry on purpose: the format is written by scc notes add and the judgment fits in the rule, so a skill would be a second copy of one fact.

Checks

gofmt -l clean · 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

…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
@protonspy
protonspy merged commit a2116fa into main Aug 27, 2026
4 checks passed
@protonspy
protonspy deleted the feat/notes-log branch August 27, 2026 20:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant