Step 5: The References
Two rules that apply everywhere, written down once.
Two short files. These are the cheapest definitions to write and the ones that pay off first, because they are the rules you would otherwise repeat in every review.
Voice
src/references/Voice.psy:
use "@psy/morphic"
export reference Voice:
description: How the program speaks to the user.
guidance:
Plain and direct. This is a paint program, not a companion.
Name the thing being acted on, not the act. Users think about their
drawing, not about our verbs.
Errors say what happened and what to do, one sentence each.
examples:
- "Discard this drawing?" — not "Are you sure you want to continue?"
- "Could not save. The disk is full." — not "An error occurred (E_NOSPC)"
- "800 × 600" — not "Width: 800 pixels, Height: 600 pixels"
avoid:
- Exclamation marks
- "Please" and "Sorry"
- Naming our own internals in anything a user reads.claude/skills/voice/SKILL.md:
---
name: voice
description: "Reference: How the program speaks to the user."
---
# Voice
## Guidance
Plain and direct. This is a paint program, not a companion.
Name the thing being acted on, not the act. Users think about their drawing, not
about our verbs.
Errors say what happened and what to do, one sentence each.
## Examples
- "Discard this drawing?" — not "Are you sure you want to continue?"
- "Could not save. The disk is full." — not "An error occurred (E_NOSPC)"
- "800 × 600" — not "Width: 800 pixels, Height: 600 pixels"
## Avoid
- Exclamation marks
- "Please" and "Sorry"
- Naming our own internals in anything a user reads
## Authority
This describes the product as it is meant to work. Where the implementation
disagrees, treat this as correct unless the task is explicitly to change it.The good/bad pairs are doing the work. "Be plain and direct" is a mood; "Discard this drawing?" not "Are you sure you want to continue?" is a rule you can apply to a string you are writing right now.
Naming
src/references/Naming.psy:
use "@psy/morphic"
export reference Naming:
description: Naming conventions in the codebase.
guidance:
Use the program's own words. We have a drawing, a bitmap, a stamp and a
stroke. We do not have documents, canvases-as-data, brushes-as-objects
or shapes.
Anything that writes to the bitmap has a name ending in Stroke or
Stamp. Anything that only reads it does not.
examples:
- `PencilStamp`, `applyStroke()` — writes
- `snapshot()`, `presentBuffer()` — reads
avoid:
- `Manager`, `Helper`, `Util` and `Service` as suffixes. They mean
"I could not decide what this is."
- `layer`, in any casing. We do not have layers and using the word
suggests we might.
exceptions:
- Generated files are exempt. They are output, not source..claude/skills/naming/SKILL.md:
---
name: naming
description: "Reference: Naming conventions in the codebase."
---
# Naming
## Guidance
Use the program's own words. We have a drawing, a bitmap, a stamp and a stroke.
We do not have documents, canvases-as-data, brushes-as-objects or shapes.
Anything that writes to the bitmap has a name ending in Stroke or Stamp.
Anything that only reads it does not.
## Examples
- `PencilStamp`, `applyStroke()` — writes
- `snapshot()`, `presentBuffer()` — reads
## Avoid
- `Manager`, `Helper`, `Util` and `Service` as suffixes. They mean "I could not
decide what this is."
- `layer`, in any casing. We do not have layers and using the word suggests we
might.
## Exceptions
- Generated files are exempt. They are output, not source.
## Authority
This describes the product as it is meant to work. Where the implementation
disagrees, treat this as correct unless the task is explicitly to change it.The layer line is the one to notice. We already said in
Step 1 that layers are a non-goal. This says the word is
banned too — because vocabulary leaks into design, and a codebase with
layerBuffer in it grows layers eventually.
Why these are references and not skills
Both of these would still be true if there were no AI agent anywhere near this project. They are facts about the product, not about how work gets done.
That is the test. A skill is an instruction — read the whole
diff before commenting. A reference is knowledge — errors say what happened and
what to do. References get named by context; skills get named by use.
Getting it backwards is caught:
export skill Careless:
when: Always.
prompt: Do the thing.
context:
- CanvasRulessrc/skills/Careless.psy:5:5 error PSY6001: `Careless.context` references
`CanvasRules`, which is not a definition (concept, domain, feature, component,
reference).Check
psy checkcheck: no problems found in 19 file(s)Fourteen definitions. The product is fully described. Now we describe how to work on it.
Next: Skills And An Agent