degraded-mode-design
Decision-aid skill for fail-closed vs fail-open behavior. Forces a degraded-mode matrix and rejects "type Y to override" prompts in favor of multi-step ceremonies
What this skill does
# degraded-mode-design
Decision aid for what a system does when something goes wrong: a key is missing, a verification fails, a sensor times out, a network partition is detected. Use when designing or reviewing any code path labeled "emergency", "fallback", "recovery", or "graceful degradation".
The skill exists because the wrong fallback can defeat the entire design. Review finding B4 ("emergency-lock copies VM disk unencrypted") is the canonical example: the fallback intended to preserve availability also preserved the assets in plaintext, defeating the encryption that was the entire point of the system.
## Triggers
- "fail closed" / "fail open"
- "emergency lock" / "panic" / "kill switch"
- "degraded mode" / "graceful degradation"
- "fallback path" / "recovery path"
- "what happens when" / "edge case in"
- "override" / "type Y to continue"
---
## Section 1: Default principle — security products fail CLOSED
The CIA triad (Confidentiality, Integrity, Availability) ranks differently for different systems:
| System type | Priority | Failure default |
|---|---|---|
| Security product (encryption, auth) | C > I > A | Fail closed: no operation rather than insecure operation |
| Safety system (medical, aviation) | A > I > C | Fail safe: known-good degraded behavior |
| Financial system | I > C > A | Fail closed for writes, log everything |
| Communication infrastructure | A > I > C | Fail open: best effort, alert on issues |
For a **security product**, the default behavior on any failure is: **stop, preserve confidentiality and integrity, alert the operator**. Preserving availability of the secret operation when its protection is failing is the wrong trade.
This is the rule review finding B4 violated: when both YubiKeys were missing, the emergency-lock script copied the VM disk **unencrypted** to "preserve the session." The premise — losing session is worse than brief unencrypted exposure — is wrong for a security-first product. The whole point of the dual-YubiKey design was that no keys = no session.
---
## Section 2: Anti-patterns (BLOCK on these)
### Plaintext fallback when encrypted operation fails
```bash
# WRONG (review B4)
if both_keys_missing; then
cp vm.disk.encrypted /backup/vm.disk.plaintext # preserve session at cost of confidentiality
fi
```
### "Type Y to override" prompts on integrity failure (review M8)
```bash
# WRONG
echo "[!] Manifest verification failed."
read -p "Type Y to continue anyway: " ans
[ "$ans" = "Y" ] && exec ./unlock.sh
```
Operators learn to autoresponse-Y. The override defeats integrity exactly when integrity matters most: when something has changed.
### Mode-mixing during failure
```bash
# WRONG
if encryption_module_unavailable; then
log "encryption disabled, continuing"
write_plaintext "$@"
fi
```
Operators forget which mode they were in. Two minutes later, they expect ciphertext on disk, but it's plaintext.
### Recovery path that reuses operational keys
If the operational path uses keys A+B and the recovery path uses keys A+B+C, then the recovery path is a *strict superset* of the operational path. An attacker with A+B has both. Recovery must use a *separate* key set (e.g., HQ escrow key, not held by the operator).
---
## Section 3: Required pattern — separate operational vs escrow paths
A system that needs both:
- **Operational availability** (the main use case must work end-to-end with all factors present), AND
- **Recovery from total factor loss** (operator stranded, hardware failure, etc.)
…must design **two distinct paths** that do not share key material:
```
Operational path:
factors {A, B, C} → unlock(...) → secret operation
Escrow path:
HQ-only key K_escrow → encrypt-to-K_escrow at provisioning
…
Recovery: HQ + K_escrow → re-derive operational state
```
Properties:
- The escrow path is **opt-in at provisioning** — the operator chooses to encrypt to HQ key
- The escrow path's keys are **never present** when operational path is active
- Use of escrow path is **logged and alertable** at HQ — no quiet recovery
- The escrow path **does not preserve the operational secrets in plaintext** at any point — the recovery target is HQ's controlled environment, not the operator's device
This is the remediation pattern for review finding B4.
---
## Section 4: Override ceremonies (when override is unavoidable)
Sometimes manual override is genuinely necessary (system migration, key rotation, legitimate emergency). When it is:
### Anti-pattern (review M8)
```
[!] Integrity check failed. Type Y to override:
```
### Required pattern: multi-step ceremony
A real override requires:
1. **Type a verification artifact** — operator types the SHA-256 prefix of the failing file (forces them to look at it, not autoresponse)
2. **Witness confirmation** — second person physically present, ideally with their own credential
3. **External logging** — override event written to a log the operator cannot suppress (HQ-side syslog, append-only ledger)
4. **Time-delay** — override takes effect after N seconds; alert fires immediately, override completes only if not aborted
```bash
read -p "Override SHA-256 prefix (first 8 hex chars of failing file): " prefix
expected=$(sha256sum failing-file | cut -c1-8)
if [ "$prefix" != "$expected" ]; then
log "Override aborted: prefix mismatch"
exit 1
fi
log_external "Override initiated by ${USER} at $(date -Is)"
sleep 30
echo "Override active. Type CONFIRM or anything else to abort:"
read confirm
[ "$confirm" = "CONFIRM" ] || { log_external "Override aborted by user"; exit 1; }
```
Better: **remove the override entirely** and require returning to HQ. If you can't, document why and accept the residual risk explicitly.
---
## Section 5: Degraded-mode matrix exercise (mandatory)
Before declaring a security design complete, fill out:
| Trigger | What the system does | Cleanup of in-memory secrets | Operator notification | Recovery path |
|---|---|---|---|---|
| One factor lost | refuse operation; preserve at-rest state | clear RAM via tmpfs unmount | display + log | bring missing factor back |
| All factors lost | refuse operation; shred any in-memory plaintext | clear RAM | display + log + HQ alert | escrow path (separate keys) |
| Network lost mid-operation | complete current op offline if safe; defer next | n/a | display | wait for network |
| Hardware failure (TPM/HSM) | refuse operation | clear RAM | display + HQ alert | replace hardware; re-provision |
| Verification failure (signature, manifest) | refuse operation | clear RAM | display + HQ alert | investigate; do not override |
| Time skew detected (HMAC TOTP) | small skew: accept; large skew: refuse | n/a | display | sync clock; investigate |
Every row must have an entry in every column. "TBD" means the design is incomplete.
---
## Section 6: Cleanup hygiene during degraded modes
When a degraded mode triggers, the system MUST clean up secrets it had in flight:
- **Memory**: zeroize all key buffers; on Linux use `mlock`+`memset_explicit` or `mlock`+exit (libsodium `sodium_memzero`); avoid signal-races
- **tmpfs**: unmount or delete-and-fsync any scratch files
- **Process state**: do not write any error message to disk that contains secret material; truncate logs that may have contained partial keys
- **Output channels**: never pass partial state to a subprocess that might persist it
See `secret-handling-runtime` skill for the full pattern; this skill just enforces that degraded-mode triggers invoke that cleanup.
---
## Section 7: Worked examples
### Review finding B4 — emergency-lock plaintext
Original:
```
When both YubiKeys are gone:
→ 31-usb-emergency-lock.sh copies VM disk UNENCRYPTED to LUKS volume
```
What this skill flags:
- Section 1: security product, default fail-closed; preserving session unencrypted violates the principle
- Section 2 anti-pattern: plaintext fallback
- Section 3: no separate escrow path; operational and recovery share the threat surRelated in Design
contribute
IncludedLocal-only OSS contribution command center. Auto-refreshes the user's in-flight PR and issue state on invoke so conversations start with full context — no need to brief Claude on what's in flight. Helps the user find issues to contribute to on GitHub, builds per-repo dossiers of what each upstream expects (CLA, DCO, branch convention, AI policy, draft-first, review bots, issue templates), runs deterministic gates before any external action so AI-assisted contributions don't reach maintainers as slop. State is markdown-only: candidate files at ~/.contribute-system/candidates/, repo dossiers at ~/.contribute-system/research/, append-only event log at ~/.contribute-system/log.jsonl. No database, no cloud calls. Use when the user asks about their PRs / issues / contributions, wants to find new work to take on, claim an issue, build/refresh a repo's dossier, or draft a Design Issue or PR. Trigger with "/contribute", "what's my PR status", "find a contribution", "claim issue X", "draft a Design Issue for Y", "refresh dossier for Z".
architectural-analysis
IncludedUser-triggered deep architectural analysis of a codebase or scoped subtree across eight modes — information architecture, data flow, integration points, UI surfaces, interaction patterns, data model, control flow, and failure modes. This skill should be used when the user asks to "diagram this codebase," "map the architecture," "show the data flow," "give me an ERD," "trace control flow," "find the integration points," "verify the layout pattern," "audit the UX architecture," or any similar request whose primary deliverable is mermaid diagrams plus cited reports under docs/architecture/. Dispatches haiku/sonnet sub-agents in parallel for per-mode exploration, then verifies every citation mechanically before any node lands in a diagram. Not for one-off prose explanations of code (use code-explanation) or for high-level system design from scratch (use system-design).
mcp
IncludedModel Context Protocol (MCP) server development and tool management. Languages: Python, TypeScript. Capabilities: build MCP servers, integrate external APIs, discover/execute MCP tools, manage multi-server configs, design agent-centric tools. Actions: create, build, integrate, discover, execute, configure MCP servers/tools. Keywords: MCP, Model Context Protocol, MCP server, MCP tool, stdio transport, SSE transport, tool discovery, resource provider, prompt template, external API integration, Gemini CLI MCP, Claude MCP, agent tools, tool execution, server config. Use when: building MCP servers, integrating external APIs as MCP tools, discovering available MCP tools, executing MCP capabilities, configuring multi-server setups, designing tools for AI agents.
react-native-skia
IncludedDesign, build, debug, and optimise high-polish animated graphics in React Native or Expo using @shopify/react-native-skia, Reanimated, and Gesture Handler. Use when the user wants canvas-driven UI, shaders, paths, rich text, image filters, sprite fields, Skottie, video frames, snapshots, web CanvasKit setup, or performance tuning for custom motion-heavy elements such as loaders, hero art, cards, charts, progress indicators, particle systems, or gesture-driven surfaces. Also use when the user asks for fluid, glow, glass, blob, parallax, 60fps/120fps, or GPU-friendly animated effects in React Native, even if they do not explicitly say "Skia". Do not use for ordinary form/layout work with standard views.
plaid
IncludedProduct Led AI Development — guides founders from idea to launched product. Six capabilities: Idea (discover a product idea), Validate (pressure-test the idea against fatal flaws, problem reality, competition, and 2-week MVP feasibility), Plan (vision intake + document generation), Design (translate image references into a design.md spec), Launch (go-to-market strategy), and Build (roadmap execution). Use when someone says "PLAID", "plaid idea", "help me find an idea", "product idea", "idea from my business", "idea from my expertise", "plaid validate", "validate my idea", "pressure-test", "is this idea good", "find fatal flaws", "validate the problem", "plan a product", "define my vision", "generate a PRD", "product strategy", "plaid design", "design from image", "translate image to design", "create design.md", "extract design tokens", "plaid launch", "go-to-market", "launch plan", "GTM strategy", "launch playbook", "plaid build", "build the app", "start building", or "execute the roadmap".
nextjs-framer-motion-animations
IncludedAdds production-safe Motion for React or Framer Motion animations to Next.js apps, including reveal, hover and tap micro-interactions, whileInView, stagger, AnimatePresence, layout and layoutId transitions, reorder, scroll-linked UI, and lightweight route-content transitions. Use when the user asks to add, refactor, or debug Motion or Framer Motion in App Router or Pages Router codebases, especially around server/client boundaries, reduced motion, LazyMotion, bundle size, hydration, or route transitions. Avoid for GSAP-style timelines, WebGL or 3D scenes, heavy scroll storytelling, or CSS-only effects unless Motion is explicitly requested.