aboutsummaryrefslogtreecommitdiff
path: root/patterns/default-most-common-friction-proportional.org
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-05 00:55:21 -0500
committerCraig Jennings <c@cjennings.net>2026-06-05 00:55:21 -0500
commit83bf3cb50c88f91730656a2242141567551063ac (patch)
tree069f0d9d52ac6ffe9c4a97a770be460b01e75cd5 /patterns/default-most-common-friction-proportional.org
parent3eed2895b2d23d1d8e468aee6f3dfd8122012fe4 (diff)
downloadrulesets-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/default-most-common-friction-proportional.org')
-rw-r--r--patterns/default-most-common-friction-proportional.org33
1 files changed, 33 insertions, 0 deletions
diff --git a/patterns/default-most-common-friction-proportional.org b/patterns/default-most-common-friction-proportional.org
new file mode 100644
index 0000000..4011cf5
--- /dev/null
+++ b/patterns/default-most-common-friction-proportional.org
@@ -0,0 +1,33 @@
+#+TITLE: Default the most-common choice, friction proportional to consequence
+#+SLUG: default-most-common-friction-proportional
+#+PRINCIPLE: Default the choice the user most often wants, and size the friction to the cost of being wrong.
+#+PROBLEM: "Always default to yes" optimizes the wrong thing; the right default is the most-common choice, and destructive choices should keep their friction.
+#+TAGS: prompts defaults yes-no confirmation safety
+#+SOURCE: pearl commit 505e707 (read-yes-no helper), handoff note 2026-05-28
+#+EXAMPLES: pearl read-yes-no helper; destructive prompts stay yes-or-no-p
+
+* Problem
+
+A first cut at yes/no prompts is "default to yes so RET takes it." That defaults to a fixed answer rather than the right one. What the user actually wants is the most-common or preferred option on top, and sometimes that's "no." A blanket default-and-go is also wrong for destructive choices, where typing the answer is a safety feature, not friction to remove.
+
+* Do
+
+Take the default as a parameter and order the candidate list with it first, so the framework highlights it and RET takes it without typing:
+
+#+begin_example
+read-yes-no PROMPT &optional DEFAULT ; default-first ordering
+#+end_example
+
+Size the friction to the consequence. Non-destructive confirmations get the default-on-top, one-keystroke treatment. Destructive ones (delete issue, delete saved query) deliberately stay full =yes-or-no-p=. The user types "yes" on purpose. Naming this companion rule keeps the principle from collapsing into "always default-yes."
+
+* Anti-pattern
+
+Two failure modes. Hardcoding "yes" as the default regardless of which answer is actually most common. And stripping friction uniformly, so a destructive action is one accidental RET away.
+
+* Applicability
+
+Every confirmation or small multiple-choice prompt. The default-first helper makes the next prompt where "no" is more common a one-argument change rather than a special case. The friction rule applies wherever an action is hard to undo.
+
+* Related
+
+The ordering and friction halves of the root principle. Composes with [[file:no-empty-input-as-meaningful.org][no-empty-input-as-meaningful]] and [[file:label-matches-behavior.org][label-matches-behavior]].