#+TITLE: Collapse N orthogonal prompts into one enriched prompt #+SLUG: collapse-orthogonal-prompts #+PRINCIPLE: When prompts compose, show the cross-product with each row labeled as a complete end-state, so the user picks the destination rather than the coordinates. #+PROBLEM: Two or more sequential prompts force the user to mentally assemble the combination and to defend against meaningless combinations in code. #+TAGS: completing-read prompts cross-product end-state #+SOURCE: pearl saved-query-sync-spec.org (sync command), handoff note 2026-05-28 #+EXAMPLES: pearl saved-query sync, team scope x visibility collapsed to one prompt * Problem Two sequential prompts, team scope then shared/personal visibility, make the user assemble the combination in their head. Some combinations are meaningless (personal scope + shared visibility, since there's no team to share with) and have to be defended against in code. Each prompt conveys a coordinate, not the outcome. * Do Collapse to one prompt where each candidate spells out the complete end-state: #+begin_example Where does this view live? [ Team: Engineering, visible to the team ] <- default [ Personal, only I see it ] [ Team: Engineering, only I see it ] [ Team: Marketing, visible to the team ] ... [ Cancel. ] #+end_example One fewer modal moment. Each row reads as its consequence ("visible to the team"), not its mechanism. The meaningless combination simply isn't in the list, so there's nothing to defend against. The default sits on top per [[file:default-most-common-friction-proportional.org][default-most-common-friction-proportional]]. When dimensions compose, each combination is itself a meaningful choice, so show the cross-product and let the user pick the destination, not the coordinates. * Anti-pattern Sequential orthogonal prompts the user has to combine mentally, where degenerate combinations exist and must be coded around. * Applicability Only when the cross-product is small enough to scan (roughly 5-20 rows). It doesn't work when: - The cross-product is large (many teams x many statuses becomes a wall). - A dimension is re-set independently and often (the user wants to change one without re-picking the rest). - A dimension is free text rather than a small enumerable set. For those, sequential prompts stay right. * Related The cross-product form of the root principle. Builds on [[file:label-matches-behavior.org][label-matches-behavior]] (each row accurately labeled) and [[file:default-most-common-friction-proportional.org][default-most-common-friction-proportional]] (default on top).