Rituals pattern: confirm and acknowledge, four severity levels #182

Closed
opened 2026-10-04 20:20:33 +00:00 by peterswimm · 3 comments
Owner

Part of #177.

What it's for: a single "are you sure?" pattern that scales with how serious the action is. It replaces four hand-built dialogs and the CLI's y/N.

Where it shows up today

Please design four levels, as one pattern

  1. Simple: yes or cancel
  2. Review: shows what was flagged (for example "this sends an email to all users"), then acknowledge and proceed
  3. Ceremony: tick each policy or risk before Proceed is enabled (today's consent ceremony and safety override)
  4. Destructive: type the name to confirm

For each level, cover what's shown, what's recorded (every override is logged in the safety ledger), the default button, and Escape/cancel.

Acceptance criteria

  • The four levels are specified as one pattern with a severity setting.
  • States for blocked with no override (Tier 0–1) and override allowed (Tier 2+).
  • Say whether this is a new confirm block or a composition (see the umbrella decision). Decided: a composition that keeps CEREMONY intent and critical importance where they apply (#177).
  • CLI version for each level.
Part of #177. **What it's for:** a single "are you sure?" pattern that scales with how serious the action is. It replaces four hand-built dialogs and the CLI's `y/N`. ## Where it shows up today - macOS: [`SafetyOverrideDialog.swift`](https://git.toilville.dev/toilville/toilville_rituals/src/branch/main/apps/rituals-macos/Design/Components/SafetyOverrideDialog.swift), [`ConsentCeremonySheet.swift`](https://git.toilville.dev/toilville/toilville_rituals/src/branch/main/apps/rituals-macos/Views/ConsentCeremonySheet.swift) (tick every policy, then proceed), and [`CapabilityConsentSheet.swift`](https://git.toilville.dev/toilville/toilville_rituals/src/branch/main/apps/rituals-macos/Design/Components/CapabilityConsentSheet.swift) - Flutter: [`safety_override_dialog.dart`](https://git.toilville.dev/toilville/toilville_rituals/src/branch/main/lib/widgets/safety_override_dialog.dart) and [`consent_upgrade_prompt.dart`](https://git.toilville.dev/toilville/toilville_rituals/src/branch/main/lib/widgets/consent_upgrade_prompt.dart) - CLI: `Proceed? [y/N]` ([`run_command.dart:126`](https://git.toilville.dev/toilville/toilville_rituals/src/branch/main/packages/ritual_cli/lib/src/commands/run_command.dart#L126)), and `ritual init`'s confirm - The only served one: the `tierTransition` block ## Please design four levels, as one pattern 1. **Simple**: yes or cancel 2. **Review**: shows what was flagged (for example "this sends an email to all users"), then acknowledge and proceed 3. **Ceremony**: tick each policy or risk before Proceed is enabled (today's consent ceremony and safety override) 4. **Destructive**: type the name to confirm For each level, cover what's shown, what's recorded (every override is logged in the safety ledger), the default button, and Escape/cancel. ## Acceptance criteria - [ ] The four levels are specified as one pattern with a severity setting. - [ ] States for blocked with no override (Tier 0–1) and override allowed (Tier 2+). - [x] Say whether this is a new `confirm` block or a composition (see the umbrella decision). **Decided: a composition that keeps CEREMONY intent and critical importance where they apply ([#177](https://git.toilville.dev/Toilville/toilville-design/issues/177#issuecomment-26060)).** - [ ] CLI version for each level.
Member

Decisions for #182 (confirm and acknowledge). They answer the acceptance criteria. This decision sets no visual direction. Styling follows the existing tokens (#443).

One pattern

  • This is one confirmation pattern. The action declares a severity: Simple, Review, Ceremony or Destructive. The pattern renders it. It is not four patterns. This issue is the authoritative definition of the complete severity enum: none, Simple, Review, Ceremony, Destructive. none means no confirmation. A missing or invalid value is a contract error, not none. Other issues refer to this list. A confirmation is a composition of existing blocks (#177).
  • Simple: normal importance, not CEREMONY. Review: high importance, not CEREMONY. Ceremony, Destructive and the safety override: CEREMONY intent and critical importance.
  • Ceremony, Destructive and safety-override confirmations are sealed (#189). A lens can restyle them. It cannot remove or shorten them. Ceremony transitions follow the #189 Motion limits.

The four levels

  • Simple: a low-risk, easily reversed action. A lightweight confirmation. With inputs, submitting the completed form is the confirmation, with no second dialog. With no inputs, one click executes the command, with no second dialog.
  • Review: an action with an important consequence the person should see first. It needs no full consent ceremony.
  • Ceremony: significant consent, trust or safety implications. Each concrete consent consequence is acknowledged on its own, for example "Prompts may reach external servers." Proceed is unavailable until every required item is acknowledged. A warning callout is supporting information. It becomes an item only when it is a distinct consent consequence.
  • Destructive: a serious or hard-to-reverse action. It has deliberate extra friction (type to confirm, below).
  • The level follows the real consequence. A reversible deletion does not automatically need Destructive.

Keys and focus

  • Simple: Return may activate the primary action.
  • Review: Return does not confirm when the dialog first opens. Focus starts on Cancel or on the first item, never on the confirming action.
  • Ceremony: Return cannot bypass the acknowledgements.
  • Destructive: Return alone cannot trigger the action. The confirmation comes first.
  • Safety override: Return does not perform the override when the dialog opens.
  • Escape cancels or closes whenever cancellation is possible. Cancel, Escape and closing abort the action.

Safety block and override

  • The pattern is defined by outcome, not by tier. The UI does not decide whether an override is allowed. It presents the governing safety decision.
  • Blocked, no override: explain why, and what the person can do next. Show no override control.
  • Blocked, override available: state the specific detected risk. Require one acknowledgement: "I accept the risk of this action." Then offer the override. This is the Ceremony level with one required item. It is not a multi-checkbox ceremony.
  • The current policy uses Tier 0–1 and Tier 2+ in that decision. The pattern does not imply that every Tier 2+ block can be overridden. Existing non-overridable cases stay representable.

Type to confirm

  • Type the target's user-facing name when it has a meaningful one. Otherwise type the action's clear verb, for example DELETE or REVOKE. Never require an internal ID.
  • The match is case-sensitive. Leading and trailing spaces are trimmed. Paste is allowed.
  • The action stays unavailable until the text matches. The match state is announced to screen readers.

Tier transitions

  • The severity comes from the requested tier. Tier 1: Review. Tier 2 and Tier 3: Ceremony. "Revoke Access" needs no extra confirmation.

Existing surfaces

  • ConsentCeremonySheet: Ceremony. SafetyOverrideDialog: Ceremony, with the single acknowledgement. Safety allow-with-review: Review. CapabilityConsentSheet: Review.

Recording

  • Opening or cancelling a confirmation is not an audit event. Checkbox clicks and partly typed text are not recorded.
  • A safety block is recorded. A completed override is recorded, with the risk that was overridden. A confirmed action is recorded where that action belongs in the audit trail.

No confirmation needed

  • A genuinely non-executing preview that changes nothing, for example a dry run.

CLI

  • The CLI keeps the same meaning as the GUI. Simple: the same rule as the GUI. Completed inputs are the confirmation, and a Simple command with no inputs runs with no [y/N]. Review: the consequence, then [y/N]. Ceremony: each required item is shown and must be accepted. Destructive: the same type-to-confirm rule. Safety block: the reason and the next step, with no override prompt when none is available.
  • The CLI shows an override path only if the governing decision exposes one to the CLI. Today it does not. Adding one is a separate engineering and security decision. #182 does not require it.
  • Non-interactive runs never silently accept or bypass a confirmation. If an action needs interactive confirmation and no already-authorised non-interactive mechanism exists, the run fails with an error. This decision adds no --yes, --force or --override-safety flag.
  • No modality silently weakens a safety or consent requirement.

Accessibility (Grammar)

  • A disabled confirming action explains why in text, for example "Acknowledge every item to continue". It stays reachable by assistive technology. The change to enabled is announced.
  • The dialog traps focus and keeps an Escape way out. All controls work with the keyboard and a screen reader, and targets are at least 44 px.

@peterswimm

Decisions for #182 (confirm and acknowledge). They answer the acceptance criteria. This decision sets no visual direction. Styling follows the existing tokens (#443). One pattern - This is one confirmation pattern. The action declares a severity: Simple, Review, Ceremony or Destructive. The pattern renders it. It is not four patterns. This issue is the authoritative definition of the complete severity enum: `none`, Simple, Review, Ceremony, Destructive. `none` means no confirmation. A missing or invalid value is a contract error, not `none`. Other issues refer to this list. A confirmation is a composition of existing blocks (#177). - Simple: normal importance, not CEREMONY. Review: high importance, not CEREMONY. Ceremony, Destructive and the safety override: CEREMONY intent and critical importance. - Ceremony, Destructive and safety-override confirmations are sealed (#189). A lens can restyle them. It cannot remove or shorten them. Ceremony transitions follow the #189 Motion limits. The four levels - Simple: a low-risk, easily reversed action. A lightweight confirmation. With inputs, submitting the completed form is the confirmation, with no second dialog. With no inputs, one click executes the command, with no second dialog. - Review: an action with an important consequence the person should see first. It needs no full consent ceremony. - Ceremony: significant consent, trust or safety implications. Each concrete consent consequence is acknowledged on its own, for example "Prompts may reach external servers." Proceed is unavailable until every required item is acknowledged. A warning callout is supporting information. It becomes an item only when it is a distinct consent consequence. - Destructive: a serious or hard-to-reverse action. It has deliberate extra friction (type to confirm, below). - The level follows the real consequence. A reversible deletion does not automatically need Destructive. Keys and focus - Simple: Return may activate the primary action. - Review: Return does not confirm when the dialog first opens. Focus starts on Cancel or on the first item, never on the confirming action. - Ceremony: Return cannot bypass the acknowledgements. - Destructive: Return alone cannot trigger the action. The confirmation comes first. - Safety override: Return does not perform the override when the dialog opens. - Escape cancels or closes whenever cancellation is possible. Cancel, Escape and closing abort the action. Safety block and override - The pattern is defined by outcome, not by tier. The UI does not decide whether an override is allowed. It presents the governing safety decision. - Blocked, no override: explain why, and what the person can do next. Show no override control. - Blocked, override available: state the specific detected risk. Require one acknowledgement: "I accept the risk of this action." Then offer the override. This is the Ceremony level with one required item. It is not a multi-checkbox ceremony. - The current policy uses Tier 0–1 and Tier 2+ in that decision. The pattern does not imply that every Tier 2+ block can be overridden. Existing non-overridable cases stay representable. Type to confirm - Type the target's user-facing name when it has a meaningful one. Otherwise type the action's clear verb, for example DELETE or REVOKE. Never require an internal ID. - The match is case-sensitive. Leading and trailing spaces are trimmed. Paste is allowed. - The action stays unavailable until the text matches. The match state is announced to screen readers. Tier transitions - The severity comes from the requested tier. Tier 1: Review. Tier 2 and Tier 3: Ceremony. "Revoke Access" needs no extra confirmation. Existing surfaces - ConsentCeremonySheet: Ceremony. SafetyOverrideDialog: Ceremony, with the single acknowledgement. Safety allow-with-review: Review. CapabilityConsentSheet: Review. Recording - Opening or cancelling a confirmation is not an audit event. Checkbox clicks and partly typed text are not recorded. - A safety block is recorded. A completed override is recorded, with the risk that was overridden. A confirmed action is recorded where that action belongs in the audit trail. No confirmation needed - A genuinely non-executing preview that changes nothing, for example a dry run. CLI - The CLI keeps the same meaning as the GUI. Simple: the same rule as the GUI. Completed inputs are the confirmation, and a Simple command with no inputs runs with no `[y/N]`. Review: the consequence, then `[y/N]`. Ceremony: each required item is shown and must be accepted. Destructive: the same type-to-confirm rule. Safety block: the reason and the next step, with no override prompt when none is available. - The CLI shows an override path only if the governing decision exposes one to the CLI. Today it does not. Adding one is a separate engineering and security decision. #182 does not require it. - Non-interactive runs never silently accept or bypass a confirmation. If an action needs interactive confirmation and no already-authorised non-interactive mechanism exists, the run fails with an error. This decision adds no `--yes`, `--force` or `--override-safety` flag. - No modality silently weakens a safety or consent requirement. Accessibility (Grammar) - A disabled confirming action explains why in text, for example "Acknowledge every item to continue". It stays reachable by assistive technology. The change to enabled is announced. - The dialog traps focus and keeps an Escape way out. All controls work with the keyboard and a screen reader, and targets are at least 44 px. @peterswimm
Author
Owner

Accepted (2026-10-20). The 2026-10-16 decision covers:

  • the four levels as one composed pattern;
  • the blocked and override states;
  • the Enter and Escape rules;
  • the CLI forms;
  • the recording rules.

That ticks criteria 1 and 2 and the CLI item. Destructive is never the default action, which is right.

I'll close this once #181's Simple-with-no-inputs answer is folded in. That changes the Simple CLI rule here, and #181 also adds the full enum, including none. The override path is a separate security decision and isn't needed to close this.

**Accepted (2026-10-20).** The 2026-10-16 decision covers: - the four levels as one composed pattern; - the blocked and override states; - the Enter and Escape rules; - the CLI forms; - the recording rules. That ticks criteria 1 and 2 and the CLI item. Destructive is never the default action, which is right. I'll close this once #181's Simple-with-no-inputs answer is folded in. That changes the Simple CLI rule here, and #181 also adds the full enum, including `none`. The override path is a separate security decision and isn't needed to close this.
Author
Owner

Closing — the condition I held this open for is met.

My acceptance said: "I'll close this once #181's Simple-with-no-inputs answer is folded in. That changes the Simple CLI rule here, and #181 also adds the full enum, including none." Both are in now:

  • Simple, GUI: "With inputs, submitting the completed form is the confirmation, with no second dialog. With no inputs, one click executes the command, with no second dialog."
  • Simple, CLI: "the same rule as the GUI. Completed inputs are the confirmation, and a Simple command with no inputs runs with no [y/N]." So the two surfaces now agree for the same command, which was the problem.
  • The enum: "This issue is the authoritative definition of the complete severity enum: none, Simple, Review, Ceremony, Destructive. none means no confirmation. A missing or invalid value is a contract error, not none." One home, as asked.

That ticks criteria 1 and 2 and the CLI item. Criterion 3 was already decided in #177.

The engineering half is Toilville/rituals-api-spec#22 (item 1), which adds severity per command across the three surfaces that declare none of it today, and states the three contract errors — missing/invalid severity, two primaries, a Destructive primary — as errors rather than things a renderer repairs. Client-side work is Toilville/toilville_rituals#581: a CEREMONY + critical composition gets the focus trap and escape hatch, and the three sheets migrate one PR each, keeping their ledger writes.

The CLI override path stays out, as you decided — a separate engineering and security decision, not needed to close this. Nothing here adds --yes, --force or --override-safety.

**Closing — the condition I held this open for is met.** My acceptance said: "I'll close this once #181's Simple-with-no-inputs answer is folded in. That changes the Simple CLI rule here, and #181 also adds the full enum, including `none`." Both are in now: - **Simple, GUI**: "With inputs, submitting the completed form is the confirmation, with no second dialog. With no inputs, one click executes the command, with no second dialog." - **Simple, CLI**: "the same rule as the GUI. Completed inputs are the confirmation, and a Simple command with no inputs runs with no `[y/N]`." So the two surfaces now agree for the same command, which was the problem. - **The enum**: "This issue is the authoritative definition of the complete severity enum: `none`, Simple, Review, Ceremony, Destructive. `none` means no confirmation. A missing or invalid value is a contract error, not `none`." One home, as asked. That ticks criteria 1 and 2 and the CLI item. Criterion 3 was already decided in #177. The engineering half is **Toilville/rituals-api-spec#22** (item 1), which adds `severity` per command across the three surfaces that declare none of it today, and states the three contract errors — missing/invalid severity, two primaries, a Destructive primary — as errors rather than things a renderer repairs. Client-side work is Toilville/toilville_rituals#581: a `CEREMONY` + `critical` composition gets the focus trap and escape hatch, and the three sheets migrate one PR each, keeping their ledger writes. The CLI override path stays out, as you decided — a separate engineering and security decision, not needed to close this. Nothing here adds `--yes`, `--force` or `--override-safety`.
Sign in to join this conversation.
No description provided.