diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-05 00:55:21 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-05 00:55:21 -0500 |
| commit | 83bf3cb50c88f91730656a2242141567551063ac (patch) | |
| tree | 069f0d9d52ac6ffe9c4a97a770be460b01e75cd5 /patterns/README.org | |
| parent | 3eed2895b2d23d1d8e468aee6f3dfd8122012fe4 (diff) | |
| download | rulesets-83bf3cb50c88f91730656a2242141567551063ac.tar.gz rulesets-83bf3cb50c88f91730656a2242141567551063ac.zip | |
feat(patterns): add cross-project pattern catalog (six seed patterns)
A good interaction-design pattern surfaces in one project, then gets lost, so the next project re-derives it. Pearl shipped six worked examples and the principle they share, but they sat as four raw notes in docs/design/ with nothing making them reusable.
I added a patterns/ directory, one file per pattern, each with frontmatter (name, principle, problem, tags, source, examples) and a Problem / Do / Anti-pattern / Applicability / Related body. The six seeds: one-prompt-picker-typed-prefix, transient-state-buttons, no-empty-input-as-meaningful, label-matches-behavior, default-most-common-friction-proportional, collapse-orthogonal-prompts. Patterns 3-6 cross-link as facets of one root principle: 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.
The catalog lives in rulesets because every project's agent already pulls from here. A thin claude-rules/patterns.md pointer tells the agent the catalog exists and when to consult it, so it reads one pattern on demand instead of carrying all of them. The pointer auto-installs via the Makefile RULES glob. README.org holds the root principle, the frontmatter contract, and the capture-on-landing/promote-on-review intake cadence.
The patterns are .org files with #+KEYWORD frontmatter. The pointer stays .md because the rules layer and the Makefile glob require it. Seed patterns keep their concrete Elisp examples. Generalize on the second caller, not up front.
Diffstat (limited to 'patterns/README.org')
| -rw-r--r-- | patterns/README.org | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/patterns/README.org b/patterns/README.org new file mode 100644 index 0000000..ac454c2 --- /dev/null +++ b/patterns/README.org @@ -0,0 +1,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. |
