aboutsummaryrefslogtreecommitdiff
path: root/patterns/README.org
blob: ac454c2e30167fa14d3e66ab9f57a67d6891c8c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#+TITLE: Pattern Catalog

Reusable interaction-design patterns, one file per pattern. Each is a small principle with wide surface area, found in one project and written down so the next one doesn't re-derive it.

The catalog lives in rulesets because every project's agent already pulls from here. The thin pointer rule =claude-rules/patterns.md= tells the agent the catalog exists and when to consult it. The agent reads a single pattern file on demand rather than carrying all of them. Humans grep this directory.

* The root principle

The six seed patterns are one principle in different shapes:

#+begin_quote
The choices the user has should all be on screen, accurately labeled, ordered by what they'll most often want, with friction sized to the cost of being wrong.
#+end_quote

* The catalog

| Pattern | Principle |
|---------+-----------|
| [[file:one-prompt-picker-typed-prefix.org][one-prompt-picker-typed-prefix]] | When the kind of candidate matters as much as its name, put kind and name in one picker with a typed prefix. Pick once, no disambiguation chain. |
| [[file:transient-state-buttons.org][transient-state-buttons]] | Put all the levers in one place with their state and key affordances visible, reachable by one chord from anywhere. |
| [[file:no-empty-input-as-meaningful.org][no-empty-input-as-meaningful]] | If "no value" is a meaningful choice, it's a candidate in the list, not a hidden empty-input convention. |
| [[file:label-matches-behavior.org][label-matches-behavior]] | A visible choice's label has to match what picking it does. "none" must not mean "any." |
| [[file:default-most-common-friction-proportional.org][default-most-common-friction-proportional]] | Default the choice the user most often wants, and size the friction to the cost of being wrong. |
| [[file:collapse-orthogonal-prompts.org][collapse-orthogonal-prompts]] | When prompts compose, show the cross-product with each row labeled as a complete end-state. Let the user pick the destination, not the coordinates. |

Patterns 3-6 are facets of the same idea and cross-link to each other.

* Frontmatter contract

Each pattern file opens with =#+KEYWORD:= metadata lines (greppable across the directory):

#+begin_example
#+TITLE:     <human-readable title>
#+SLUG:      <kebab-case slug, matches the filename>
#+PRINCIPLE: <one line, the rule stated once>
#+PROBLEM:   <one line, what goes wrong without it>
#+TAGS:      <surface-area keywords for grep>
#+SOURCE:    <where it was first articulated: project, note, commit>
#+EXAMPLES:  <links or grep targets for real uses>
#+end_example

The body carries the worked detail under these headings: Problem, Do (with a before/after), Anti-pattern, Applicability (when it applies and when it doesn't), Related.

* Intake cadence: capture on landing, promote on review

When a pattern lands (a handoff note from another project, a discovery mid-session), the raw note drops into that project's =docs/design/= as it does today. Promotion into this catalog happens in a batched review, folded into =task-audit= or a periodic pass, so the catalog stays curated instead of accreting every rough note. The six seed patterns came from four pearl notes formalized in one pass on 2026-06-05.

* Generalization

Seed patterns keep their concrete Elisp examples rather than being abstracted up front. Generalize a pattern beyond its origin domain when a second caller in a different domain arrives, not before. The principle lines are already domain-neutral; the worked examples stay concrete.