Add the core, contest, storage and format layers
Frequencies, bands, modes, callsigns, grid squares and the country file live in Nonemm.Core. Nonemm.Contests holds the scoring engine and CQ WW and CQ WPX. Nonemm.Storage writes N1MM's DXLOG schema, and Nonemm.Formats writes Cabrillo 3.0 and reads and writes ADIF. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
92
CLAUDE.md
Normal file
92
CLAUDE.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# CLAUDE.md
|
||||
|
||||
Rules for writing code or prose in this project.
|
||||
|
||||
These are language-neutral: they apply to TypeScript, C++, Java, PHP, Python and anything else.
|
||||
|
||||
Section 1 covers prose and is loaded every session. Sections 2 to 10 cover code
|
||||
and live in `.claude/skills/code-style/SKILL.md`, which loads on demand.
|
||||
|
||||
IMPORTANT: when compacting, keep section 1 in full.
|
||||
|
||||
## 1. How to write prose
|
||||
|
||||
This applies to chat replies, commit messages, PR descriptions, docs and
|
||||
comments.
|
||||
|
||||
Write like a senior engineer who is tired and hates long emails. Plain English,
|
||||
short sentences, to an intelligent colleague who knows how to program.
|
||||
Use ASD-STE100 Simplified Technical English for prose, including casual replies.
|
||||
|
||||
**Optimize for comprehension, not for style.** The reader should understand
|
||||
the text with the least effort. If you have to re-read a sentence to parse it,
|
||||
rewrite it.
|
||||
|
||||
### Banned patterns
|
||||
|
||||
| Pattern | Example | Instead |
|
||||
| --- | --- | --- |
|
||||
| "is X, never Y" constructions | "the catalogue is walked off disk, never listed" | "it scans the directory instead of reading a list" |
|
||||
| Personified code | "every specimen owes every applicable feature" | "each test case must cover every feature" |
|
||||
| Blog-speak | "footgun", "load-bearing", "this lands", "source of truth", "by design" | say what actually happens |
|
||||
| Em-dash pile-ups and aphorisms | "an undeclared specimen fails rather than being skipped — and a suite that skipped a file looks exactly like one that passed it" | "unknown files fail the suite, so a skipped file can't be mistaken for a passing one" |
|
||||
| Invented nouns | "specimen", "matrix", "catalogue" for ordinary things | "test file", "config table", "directory" |
|
||||
| Ownership metaphors | "the module that owns this data", "a single owner for the value" | "the module where the data is defined" |
|
||||
| Virtue and morality | "keeps the invariant honest", "respects the contract", "a well-behaved caller" | "checks the count matches before returning" |
|
||||
| Intent and knowledge verbs | "the matrix decides", "the runner knows about", "the module wants", "the config owes" | "the matrix selects", "the runner reads", "the module requires", "the config must define" |
|
||||
|
||||
### The literal test
|
||||
|
||||
Read each sentence literally. If the subject cannot literally perform the verb,
|
||||
rewrite it. Modules don't want, know, own, decide, care or owe. Invariants
|
||||
aren't honest. Code isn't well-behaved.
|
||||
|
||||
This bans intent, desire, knowledge and virtue. It does not ban ordinary
|
||||
mechanical vocabulary: a function returns, throws, reads, writes and requires;
|
||||
a parser expects an argument; a compiler reports an error. Those describe what
|
||||
actually happens.
|
||||
|
||||
### Required
|
||||
|
||||
- Use lists and tables where the content is a list or a table.
|
||||
- Name things by their real names: file names, function names, types.
|
||||
- State the conclusion first, then the reasoning. Don't build up to it.
|
||||
- If something is uncertain, say "I'm not sure" and say why.
|
||||
|
||||
### Length
|
||||
|
||||
- Answer in the fewest sentences that fully answer. A one-fact answer is one sentence.
|
||||
- Don't restate the question before answering it.
|
||||
- Don't pad a short answer to make it look thorough.
|
||||
|
||||
### State rules as instructions, not slogans
|
||||
|
||||
A rule must say what to do. If the reader has to decode a metaphor to work out
|
||||
the action, rewrite it as an instruction. This applies to this file too: check
|
||||
each line against "could I hand this to someone and have them do it?"
|
||||
|
||||
| Slogan | Instruction |
|
||||
| --- | --- |
|
||||
| "if two modules need each other, a third thing wants to exist" | "move the shared code into a module both can import" |
|
||||
| "that's a module with extra steps" | "export the functions from a module instead" |
|
||||
| "one of them is wrong" | "delete one and import it from the other" |
|
||||
| "that comment earns its place" | "keep that comment: the type doesn't say the value is a root URL" |
|
||||
| "the worker reaches for global state" | "the class imports a module-level singleton instead of taking it as an argument" |
|
||||
|
||||
The same applies to judgments. Don't call something "clean", "solid",
|
||||
"idiomatic" or "the right call". Say what it does, or what breaks without it.
|
||||
|
||||
### Example
|
||||
|
||||
Bad:
|
||||
|
||||
> Every specimen owes every applicable feature, and the matrix decides which.
|
||||
> The smoke-repo catalogue is walked off disk, never listed, so new syntax
|
||||
> cannot arrive untested.
|
||||
|
||||
Good:
|
||||
|
||||
> The test runner scans `tests/smoke/` at startup rather than reading a
|
||||
> hardcoded list, so a new test file is picked up automatically. Files that
|
||||
> aren't registered in the test matrix fail instead of being skipped.
|
||||
|
||||
Reference in New Issue
Block a user