Challenge Types
The three challenge types and how they escalate based on context
When shellfirm intercepts a dangerous command, it presents a challenge that you must solve before the command executes. There are three challenge types, ordered from least to most restrictive.
The three challenge types
| Challenge | How to pass | Friction level | Best for |
|---|---|---|---|
| Math | Solve a simple arithmetic problem (e.g., "7 + 4 = ?") | Low | Default -- forces a brief pause to think |
| Enter | Press the Enter key | Medium | Teams that want awareness without solving puzzles |
| Yes | Type the word "yes" and press Enter | High | Critical commands, production environments |
Math
The default challenge type. shellfirm generates a random arithmetic problem:
This is effective because it forces you to shift mental context -- you cannot mindlessly press Enter through it.
Enter
A simpler confirmation. You just need to press Enter:
Enter to continue Esc to cancel ›Yes
The most restrictive challenge. You must type the word "yes":
yes to continue Esc to cancel ›Setting the default challenge
Configure which challenge type shellfirm uses by default:
shellfirm config challenge Math # default
shellfirm config challenge Enter
shellfirm config challenge Yes
Challenge escalation
The challenge type is determined by a multi-layer escalation pipeline. Each layer can only make the challenge stricter, never weaker.
The ordering is: Math < Enter < Yes
The escalation pipeline
shellfirm resolves the effective challenge through six layers, applied in order:
| Layer | Source | Example |
|---|---|---|
| 1. Base | settings.challenge | Math |
| 2. Severity | Check severity level | Critical → Yes, High → Enter |
| 3. Group | group_escalation in settings | fs → Yes |
| 4. Check ID | check_escalation in settings | git:force_push → Yes |
| 5. Context | Runtime environment | SSH → Enter, root → Yes |
| 6. Policy | .shellfirm.yaml overrides | per-pattern override |
The formula is:
effective = max(base, severity_floor, group_floor, check_floor, context_floor, policy_floor)
Examples
Suppose your default challenge is Math:
- You run
rm -rf .on your laptop — you see a Yes challenge (Critical severity → Yes) - You run
git push --forceon your laptop — you see an Enter challenge (High severity → Enter) - You run
git push --forceon themainbranch — escalated to Yes (High severity → Enter, then Critical context → Yes) - You run
rm -rf .as root over SSH — still Yes (Critical severity already maxed out)
The escalation cannot weaken
If any earlier layer already set the challenge to Yes, no subsequent layer can lower it. Each layer applies max() — the stricter of the current value and the layer's floor.
Configuring escalation
Severity escalation (ON by default — omitted keys use defaults):
# In ~/.config/shellfirm/settings.yaml
severity_escalation:
critical: "Yes" # default
high: Enter # default
# medium, low, info default to Math; enabled defaults to true
Per-group and per-check-id overrides (optional):
group_escalation:
fs: "Yes" # All filesystem checks → Yes
database: Enter # All database checks → Enter
check_escalation:
git:force_push: "Yes" # This specific check → Yes
Context escalation thresholds:
context:
escalation:
elevated: Enter # default: Enter
critical: Yes # default: Yes
You can also configure escalation via CLI:
shellfirm config escalation severity --high Yes
shellfirm config escalation group fs Yes
shellfirm config escalation check git:force_push Yes
shellfirm config context
See Escalation Logic for the full details.
Project policy overrides
Team policies (.shellfirm.yaml) can also override the challenge type for specific patterns. Like context escalation, policy overrides can only make things stricter:
# .shellfirm.yaml
version: 1
overrides:
- id: git:force_push
challenge: Yes
- id: git:reset
on_branches: [main, master]
challenge: Yes
See Team Policies for more details.