Safety Principles
DiveSuite handles decompression calculations that, if incorrect, can cause serious injury or death. This document defines our non-negotiable safety principles.
Core Principles
Section titled “Core Principles”1. Deco Engine Isolation
Section titled “1. Deco Engine Isolation”All decompression calculations are meant to happen in a single, isolated Rust crate. Decision D27 (planned) makes Rust the only deco engine. Until then the TypeScript fallback still computes plans on every platform, because WASM is disabled on the web. The fallback is not validated against Subsurface; it refuses every input it cannot model (bridge-fallback-scope.ts) and never supplies stops of its own:
+-------------------------------------+| Application |+-------------------------------------+| Service Layer |+-------------------------------------+| +-----------------------+ || | Deco Engine | <- Only module that| | (Rust) | touches tissue| | | loading calculations| | - Buhlmann ZHL-16C || | - NDL calculation || | - Gas physics || +-----------------------+ |+-------------------------------------+Rules:
- Only the deco engine performs tissue loading calculations
- The engine has a clean API boundary (Input -> Output)
- No direct manipulation of engine internals from outside
- Engine code is changed only on the owner’s explicit request, in its own PR, with an independent safety review
- Planned (D27): if no Rust engine runs, the app refuses to plan (see below) and no second engine takes over
2. AI Never Overrides
Section titled “2. AI Never Overrides”AI is strictly advisory. AI cannot:
- Generate decompression schedules
- Modify gradient factors without user confirmation
- Suggest exceeding MOD, NDL, or ppO2 limits
- Override safety warnings
- Bypass the validation layer
Architecture:
User Input -+--------------------------------------> Validation -> Deco Engine -> Plan | ^ +-> AI Service -> Suggestions -> User Review --+ (advisory) (required)AI output is always treated as unverified user input that must flow through normal validation.
3. Disclaimers Always Visible
Section titled “3. Disclaimers Always Visible”Every dive plan output includes a mandatory disclaimer:
Implementation:
- The disclaimer is never removed from planning screens. It may use progressive disclosure: a compact inline hint with expandable detail, or a one-time acknowledgment stored in settings. It must always stay accessible
- First-launch acceptance is recorded with a timestamp
4. Validation Required
Section titled “4. Validation Required”Before release, the deco engine must be validated:
- Unit tests: every Rust function has a unit test, with a 95%+ coverage target
- Property-based tests: verify invariants (for example, NDL never grows with depth)
- Cross-reference: compare against Subsurface (same algorithm)
What we validate against:
| Reference | Purpose | Tolerance |
|---|---|---|
| Subsurface | Same algorithm (Buhlmann ZHL-16C), deco schedules | 1 min per stop, 2 min total runtime |
| Subsurface | No-stop limits | 1 min |
| PADI RDP, US Navy, NOAA | Upper bound for no-stop limits | The engine’s NDL is never longer than the shortest published value |
What we do NOT claim:
- Equivalence with PADI tables (they use DSAT, not Buhlmann). The tables only bound the engine’s NDL from above
- VPM-B support (not available; a clean-room version is planned, D5, P1-17)
- Medical device certification
- Guarantee of diver safety
5. Refuse When No Engine Runs (planned, D27)
Section titled “5. Refuse When No Engine Runs (planned, D27)”Target state (decision D27): where no Rust engine runs, the planner and every screen that needs the engine show only a persistent, non-dismissible “engine unavailable” card that says nothing was checked (planned, DIV-115). This covers iOS until the native module ships (P1-15), Android until after Release 1, Expo Go, a failed load and a crashed engine instance. No plan, value or gas warning is shown, and no TypeScript check runs in its place. This is an owner exception to the warning rules, since without a plan there is no computed warning. The card will be a safety alert that is never hidden and never dismissible. The TypeScript fallback is removed as soon as Rust computes on the web. Until then a persistent fallback notice is planned (P1-19), and every Rust error will map to a refusal (P1-18).
6. Offline Must Work
Section titled “6. Offline Must Work”Core safety features work without internet:
| Feature | Offline | Online Required |
|---|---|---|
| Dive planning | Yes | - |
| Dive logging | Yes | - |
| Profile visualization | Yes | - |
| Safety disclaimers | Yes | - |
| AI suggestions | No | Yes |
| Cloud sync | No | Yes |
| Community features | No | Yes |
When offline:
- AI features are disabled (not erroring)
- UI clearly indicates offline status
- All local data remains accessible
Safety-Critical Code Paths
Section titled “Safety-Critical Code Paths”Deco Engine
Section titled “Deco Engine”The engine lives in rust-engine/. Inputs are validated at the Rust boundary (rust-engine/src/validation.rs) and invalid input is refused with a typed DecoError. The Rust engine does not return a plan for a refused input. The TypeScript bridge (src/core/engine/) does not yet fully honour this: it still turns most Rust errors into a fallback plan, until the refusal mapping lands (planned, P1-18).
AI Safety Layer
Section titled “AI Safety Layer”AI output is treated as unverified user input. The AIService interface is in src/features/ai/services/types.ts. AI suggestions go through the normal validation path and the deco engine before they affect a plan.
Forbidden Actions
Section titled “Forbidden Actions”The following actions are explicitly forbidden in DiveSuite code:
| Action | Why Forbidden |
|---|---|
| Disable disclaimer display | Legal and safety requirement |
| Allow AI to modify deco output | Safety boundary violation |
| Suppress safety warnings | Could hide critical information |
| Skip validation in production | Could allow unsafe plans |
| Hide or dismiss the “engine unavailable” card (once it exists, planned D27) | The user would not know that nothing was checked |
Use any in deco-related TS |
Type safety is critical |
Use panic! on bad input in deco Rust |
Must return a typed error |
Incident Response
Section titled “Incident Response”When a safety issue is discovered:
- Assess severity – Can this cause injury?
- Notify users – In-app notification for critical issues
- Force update – CC-09 mechanism for safety-critical fixes
- Fix and test – Including regression test
- Disclose – Document in release notes
- Post-mortem – How did this pass testing?