Files
daily-notification-plugin/docs/alarms/03-plugin-requirements.md
Matthew Raymer 35babb3126 docs(alarms): unify and enhance alarm directive documentation stack
Create unified alarm documentation system with strict role separation:
- Doc A: Platform capability reference (canonical OS facts)
- Doc B: Plugin behavior exploration (executable test harness)
- Doc C: Plugin requirements (guarantees, JS/TS contract, traceability)

Changes:
- Add canonical rule to Doc A preventing platform fact duplication
- Convert Doc B to pure executable test spec with scenario tables
- Complete Doc C with guarantees matrix, JS/TS API contract, recovery
  contract, unsupported behaviors, and traceability matrix
- Remove implementation details from unified directive
- Add compliance milestone tracking and iOS parity gates
- Add deprecation banners to legacy platform docs

All documents now enforce strict role separation with cross-references
to prevent duplication and ensure single source of truth.
2025-11-25 10:09:46 +00:00

1048 lines
48 KiB
Markdown

# Plugin Requirements & Implementation Rules
**Author**: Matthew Raymer
**Date**: November 2025
**Status**: Active Requirements - Implementation Guide
**Version**: 1.1.0
**Last Synced With Plugin Version**: v1.1.0
## Purpose
This document defines the **rules the plugin MUST follow** to behave predictably across Android and iOS platforms. It specifies:
**Language Standards**: This document uses RFC-2119 keywords:
- **MUST** — Required for correctness. Violation breaks plugin guarantees.
- **SHOULD** — Strong recommendation. Exceptions MUST be documented.
- **MUST NOT** — Prohibited behavior. Plugin must not attempt this.
- **MAY** — Optional. Plugin may or may not implement.
**Cross-Reference Format**: All references use format `[Doc X §Y.Z]` where:
- `Doc A` = [Platform Capability Reference](./01-platform-capability-reference.md)
- `Doc B` = [Plugin Behavior Exploration](./02-plugin-behavior-exploration.md)
- `Phase N` = Implementation phase directive
* Plugin behavior guarantees and limitations
* Persistence requirements
* Recovery strategies
* Missed alarm handling contract
* JS/TS API contract and caveats
* Platform-specific requirements
* Testing requirements
**Reference**: See [Platform Capability Reference](./01-platform-capability-reference.md) for OS-level facts.
---
## 1. Plugin Behavior Guarantees & Limitations
### 1.1 Cross-Platform Guarantees Matrix
| Behavior | Android | iOS | Guarantee Level | Platform Source |
| -------- | ------- | --- | --------------- | --------------- |
| **Survives swipe-kill** | ✅ Yes | ✅ Yes | **MUST** (OS-guaranteed) | [Doc A §2.1.1](./01-platform-capability-reference.md#211-alarms-survive-ui-kills-swipe-from-recents), [Doc A §3.1.1](./01-platform-capability-reference.md#311-notifications-survive-app-termination) |
| **Survives reboot** | ⚠️ Only if rescheduled | ✅ Yes | Android: **SHOULD** (best-effort), iOS: **MUST** (OS-guaranteed) | [Doc A §2.1.2](./01-platform-capability-reference.md#212-alarms-can-be-preserved-across-device-reboot), [Doc A §3.1.2](./01-platform-capability-reference.md#312-notifications-persist-across-device-reboot) |
| **Runs code on trigger** | ✅ Yes (PendingIntent) | ❌ No (never) | Android: **MUST**, iOS: **MUST NOT** | [Doc A §2.1.1](./01-platform-capability-reference.md#211-alarms-survive-ui-kills-swipe-from-recents), [Doc A §3.2.1](./01-platform-capability-reference.md#321-app-code-does-not-run-when-notification-fires) |
| **Missed alarm detection** | ✅ Required | ✅ Required | **MUST** (Plugin-required) | [Doc A §2.1.4](./01-platform-capability-reference.md#214-alarms-can-be-restored-after-app-restart) |
| **Force stop recovery** | ✅ Required | N/A | **MUST** (Plugin-required) | [Doc A §2.2.1](./01-platform-capability-reference.md#221-you-cannot-survive-force-stop) |
| **Exact timing** | ⚠️ With permission | ⚠️ ±180s tolerance | Android: **SHOULD** (with permission), iOS: **SHOULD** (OS limitation) | [Doc A §5.2](./01-platform-capability-reference.md#52-android-s-exact-alarm-permission-decision-tree), [Doc A §6.1](./01-platform-capability-reference.md#61-notification-timing-accuracy) |
| **Background execution** | ⚠️ WorkManager | ⚠️ BGTaskScheduler | **SHOULD** (best-effort, system-controlled) | [Doc A §3.1.3](./01-platform-capability-reference.md#313-background-tasks-for-prefetching) |
**Guarantee Level Definitions**:
- **MUST** = Plugin guarantees this behavior
- **SHOULD** = Plugin attempts this but cannot guarantee (best-effort)
- **MUST NOT** = Plugin cannot and will not attempt this
### 1.2 Limitations by Platform
**See [§8 - Explicit Unsupported Behaviors](./03-plugin-requirements.md#8-explicit-unsupported-behaviors) for complete list.**
**Summary**:
* **Android Force Stop**: Cannot auto-recover - See [Doc A §2.2.1](./01-platform-capability-reference.md#221-you-cannot-survive-force-stop)
* **iOS Code Execution**: Cannot run code on notification fire - See [Doc A §3.2.1](./01-platform-capability-reference.md#321-app-code-does-not-run-when-notification-fires)
* **iOS Timing**: ±180s tolerance - See [Doc A §6.1](./01-platform-capability-reference.md#61-notification-timing-accuracy)
* **Background Execution**: System-controlled, not guaranteed - See [Doc A §3.1.3](./01-platform-capability-reference.md#313-background-tasks-for-prefetching)
---
## 2. Persistence Requirements
### 2.1 Required Persistence Items
The plugin **MUST** persist the following for each scheduled alarm/notification:
| Field | Type | Required | Purpose | Storage Location |
| ----- | ---- | -------- | ------- | ---------------- |
| `alarm_id` | String | ✅ Yes | Unique identifier | Schedule.id, NotificationContentEntity.id |
| `trigger_time` | Long/TimeInterval | ✅ Yes | When to fire | Schedule.nextRunAt, NotificationContentEntity.scheduledTime |
| `repeat_rule` | String/Enum | ✅ Yes | NONE, DAILY, WEEKLY, CUSTOM | Schedule.cron, Schedule.clockTime |
| `channel_id` | String | ✅ Yes | Notification channel (Android) | NotificationContentEntity (implicit) |
| `priority` | String/Int | ✅ Yes | Notification priority | NotificationContentEntity.priority |
| `title` | String | ✅ Yes | Notification title | NotificationContentEntity.title |
| `body` | String | ✅ Yes | Notification body | NotificationContentEntity.body |
| `sound_enabled` | Boolean | ✅ Yes | Sound preference | NotificationContentEntity.soundEnabled |
| `vibration_enabled` | Boolean | ✅ Yes | Vibration preference | NotificationContentEntity.vibrationEnabled |
| `payload` | String/JSON | ⚠️ Optional | Additional content | ContentCache.payload |
| `created_at` | Long/TimeInterval | ✅ Yes | Creation timestamp | NotificationContentEntity.createdAt |
| `updated_at` | Long/TimeInterval | ✅ Yes | Last update timestamp | NotificationContentEntity.updatedAt |
| `enabled` | Boolean | ✅ Yes | Whether alarm is active | Schedule.enabled |
### 2.2 Storage Implementation
**Android**:
* **Primary**: Room database (`DailyNotificationDatabase`)
* **Location**: `android/src/main/java/com/timesafari/dailynotification/`
* **Entities**: `Schedule`, `NotificationContentEntity`, `ContentCache`
**iOS**:
* **Primary**: UNUserNotificationCenter (OS-managed)
* **Secondary**: Plugin storage (UserDefaults, CoreData, or files)
* **Location**: `ios/Plugin/`
* **Component**: `DailyNotificationStorage?`
### 2.3 Persistence Validation
The plugin **MUST**:
* Validate persistence on every alarm schedule
* Log persistence failures
* Handle persistence errors gracefully
* Provide recovery mechanism if persistence fails
**Acceptance Criteria**:
* **Test**: Schedule alarm, kill app immediately, verify alarm persists in database
* **Test**: Schedule alarm, fill storage, verify graceful error handling
* **Test**: Schedule alarm, corrupt database, verify recovery mechanism
* **Pass**: All persistence operations succeed or fail gracefully with logging
### 2.4 Data Integrity Rules
**Required Validation**:
* **MUST** validate all required fields before persistence
* **MUST** validate schedule format (cron or HH:mm)
* **MUST** validate trigger time is in the future (or handle past times appropriately)
* **MUST** ensure foreign key relationships are valid (Schedule → NotificationContentEntity)
**Data Integrity Constraints**:
* `alarm_id` **MUST** be unique across all schedules
* `scheduleId` **MUST** reference an existing Schedule.id
* `scheduledTime` **MUST** be a valid timestamp
* `deliveryStatus` **MUST** be one of: "pending", "delivered", "missed"
### 2.5 Failure Modes
**Persistence Failure Handling**:
* Database errors: Log error, continue with alarm scheduling (best effort), retry persistence
* Storage full: Log warning, attempt cleanup, retry, notify user if critical
* Invalid data: Skip invalid entries, log warning, continue processing
* Migration failures: Rollback to backup, notify user, preserve existing data
---
## 3. Recovery Contract
### 3.1 Recovery Triggers & Required Actions
The plugin **MUST** implement recovery at the following points with the specified actions. This is the complete recovery contract that defines what the plugin guarantees for each recovery scenario.
#### 3.1.1 Boot Event (Android Only)
**Trigger**: `BOOT_COMPLETED` broadcast
**Required Actions**:
1. Load all enabled alarms from persistent storage
2. Reschedule each alarm using AlarmManager
3. Detect missed alarms (trigger_time < now)
4. Generate missed alarm events/notifications
5. Log recovery actions
**Code Reference**: `BootReceiver.kt` line 24
**Implementation Status**: See [Phase 3 Implementation](../android-implementation-directive-phase3.md)
**Platform Reference**: [Android §2.1.2](../01-platform-capability-reference.md#212-alarms-can-be-preserved-across-device-reboot)
**Acceptance Criteria**:
* **Test**: Schedule alarm for 10 minutes, reboot device, do NOT open app, wait 15 minutes
* **Expected**: Alarm does NOT fire (OS limitation - see [Doc A §2.1.2](./01-platform-capability-reference.md#212-alarms-can-be-preserved-across-device-reboot))
* **Test**: Open app after reboot
* **Expected**: Plugin detects missed alarm, reschedules future alarms
* **Pass**: Missed alarm detected exactly once, future alarms rescheduled
**Missed Alarm Detection Acceptance Criteria**:
* **Test**: Create alarm scheduled for 2 minutes, kill app, wait 5 minutes, launch app
* **Expected**: Plugin detects missed alarm, marks in database (`delivery_status = 'missed'`)
* **Test**: Create repeating alarm, miss 3 occurrences, launch app
* **Expected**: Plugin detects all 3 missed alarms, reschedules next occurrence
* **Pass**: All missed alarms detected and marked, no duplicates, future alarms rescheduled
---
#### 3.1.2 App Cold Start
**Trigger**: App launched from terminated state
**Required Actions**:
1. Load all enabled alarms from persistent storage
2. Verify active alarms match stored alarms
3. Detect missed alarms (trigger_time < now)
4. Reschedule future alarms
5. Generate missed alarm events/notifications
6. Log recovery actions
**Implementation Status**: See [Phase 1 Implementation](../android-implementation-directive-phase1.md)
**Code Location**: Plugin initialization (`DailyNotificationPlugin.load()` or equivalent)
**Platform Reference**: [Android §2.1.4](../01-platform-capability-reference.md#214-alarms-can-be-restored-after-app-restart)
**Acceptance Criteria**:
* **Test**: Schedule alarm for 5 minutes, kill app process (not force stop), wait 10 minutes
* **Expected**: Alarm fires (OS handles)
* **Test**: Launch app after alarm time passed
* **Expected**: Plugin detects missed alarm if alarm did not fire, reschedules future alarms
* **Pass**: Missed alarm detected if applicable, future alarms verified/rescheduled
---
#### 3.1.3 App Warm Start
**Trigger**: App returning from background
**Required Actions**:
1. Verify active alarms are still scheduled
2. Detect missed alarms (trigger_time < now)
3. Reschedule if needed
4. Log recovery actions
**Implementation Status**: Deferred to future phase
**Platform Reference**: [Android §2.1.4](../01-platform-capability-reference.md#214-alarms-can-be-restored-after-app-restart)
---
#### 3.1.4 Force Stop Recovery (Android Only)
**Trigger**: App launched after Force Stop
**Required Actions**:
1. Detect force stop scenario (DB has alarms, AlarmManager has zero)
2. Mark all past alarms as missed
3. Reschedule all future alarms
4. Generate missed alarm events/notifications
5. Log recovery actions
**Implementation Status**: See [Phase 2 Implementation](../android-implementation-directive-phase2.md)
**Platform Reference**: [Android §2.2.1](./01-platform-capability-reference.md#221-you-cannot-survive-force-stop), [Android §2.2.2](./01-platform-capability-reference.md#222-you-cannot-auto-resume-after-force-stop)
**Acceptance Criteria**:
* **Test**: Schedule multiple alarms (past and future), force stop app, wait past scheduled times
* **Expected**: No alarms fire (OS limitation)
* **Test**: Open app after force stop
* **Expected**: Plugin detects force stop scenario, marks all past alarms as missed, reschedules all future alarms
* **Pass**: All past alarms marked as missed, all future alarms rescheduled
---
#### 3.1.5 User Taps Notification
**Trigger**: User interaction with notification
**Required Actions**:
1. Launch app (OS handles)
2. Detect if notification was missed
3. Handle notification action
4. Update alarm state if needed
**Implementation Status**: Basic support exists
**Platform Reference**: [Android §2.1.1](../01-platform-capability-reference.md#211-alarms-survive-ui-kills-swipe-from-recents), [iOS §3.1.1](../01-platform-capability-reference.md#311-notifications-survive-app-termination)
---
### 3.2 Recovery Matrix
| Recovery Point | Android | iOS | Implementation Phase |
| -------------- | ------- | --- | -------------------- |
| Boot event | ✅ Required | ❌ Not needed (OS handles) | Phase 3 |
| Cold start | ✅ Required | ✅ Required | Phase 1 |
| Warm start | ⚠️ Optional | ⚠️ Optional | Future |
| Force stop | ✅ Required | N/A | Phase 2 |
| User tap | ✅ Required | ✅ Required | Basic |
---
## 4. Missed Alarm Handling Contract
### 4.1 Definition
An alarm is "missed" if:
* `trigger_time < now`
* Alarm was not fired (or firing status unknown)
* Alarm is still enabled
* Alarm has not been manually cancelled
### 4.2 Detection Triggers
Missed alarms **MUST** be detected at:
1. **App cold start** - When app launches from terminated state
2. **App warm start** - When app returns from background (optional, future phase)
3. **Boot event** (Android) - When device reboots
4. **Force stop recovery** (Android) - When app launches after force stop
### 4.3 Required Actions
When a missed alarm is detected, the plugin **MUST**:
1. **Detect** missed alarms during recovery
2. **Mark** missed alarms in database (`delivery_status = 'missed'`)
3. **Generate** missed alarm event/notification (optional, future phase)
4. **Reschedule** future occurrences (if repeating)
5. **Log** missed alarm for debugging
6. **Update** alarm state (mark as missed or reschedule)
### 4.4 Missed Alarm Resolution Rules
**Resolution Strategy**:
| Scenario | Detection Time | Resolution Action | Next Occurrence |
| -------- | -------------- | ----------------- | --------------- |
| **Single alarm missed** | Cold start | Mark as missed, do not reschedule | N/A (one-time alarm) |
| **Repeating alarm missed** | Cold start | Mark as missed, reschedule next occurrence | Calculate from current time |
| **Multiple alarms missed** | Force stop recovery | Mark all as missed, reschedule all future | Calculate from current time |
| **Boot recovery** | Boot event | Mark past as missed, reschedule all future | Calculate from current time |
**State Transition Table**:
```
NONE (first launch, empty DB)
COLD_START (DB populated, alarms may exist)
FORCE_STOP? (detect: DB populated & no scheduled alarms)
BOOT (detect: SharedPreferences flag set)
Recovery Actions:
- Detect missed alarms
- Mark missed in database
- Reschedule future alarms
- Update state
```
**Transition Detection**:
* **NONE → COLD_START**: DB empty on first launch
* **COLD_START → FORCE_STOP**: DB has schedules but AlarmManager has zero alarms
* **COLD_START → BOOT**: SharedPreferences `last_boot_at` flag set
* **Any → Recovery**: Execute recovery actions based on scenario
### 4.5 Implementation Requirements
* **MUST** run on app launch (cold/warm start)
* **MUST** run on boot (Android)
* **MUST NOT** duplicate missed alarm notifications
* **MUST** handle timezone changes
* **MUST** handle clock adjustments
**Implementation Status**:
- Phase 1: Basic detection and marking - See [Phase 1 Implementation](../android-implementation-directive-phase1.md)
- Phase 2: Force stop recovery - See [Phase 2 Implementation](../android-implementation-directive-phase2.md)
- Phase 3: Boot recovery - See [Phase 3 Implementation](../android-implementation-directive-phase3.md)
- Future: Event emission, user notifications
---
## 5. JS/TS API Contract
### 5.1 JS/TS API Contract
The plugin **MUST** document and guarantee the following behaviors to JavaScript/TypeScript developers:
#### 5.1.1 `scheduleDailyNotification(options)`
**Method Signature**:
```typescript
scheduleDailyNotification(options: {
schedule: string; // Cron or HH:mm format
title: string;
body: string;
sound?: boolean;
vibration?: boolean;
priority?: 'high' | 'normal' | 'low';
payload?: object;
}): Promise<{
success: boolean;
alarmId?: string;
error?: {
code: string;
message: string;
action?: 'opened_settings' | 'permission_denied';
};
}>
```
**Returned Fields**:
* `success` (boolean) - Whether scheduling succeeded
* `alarmId` (string, optional) - Unique identifier for scheduled alarm
* `error` (object, optional) - Error details if scheduling failed
* `code` (string) - Error code for programmatic handling
* `message` (string) - Human-readable error message
* `action` (string, optional) - Action taken (e.g., "opened_settings")
**Guarantees**:
* ✅ Notification will fire if app is swiped from recents - **MUST** (OS-guaranteed)
* ✅ Notification will fire if app is terminated by OS - **MUST** (OS-guaranteed)
* ⚠️ Notification will fire after reboot **only if**:
* Android: Boot receiver is registered and working - **SHOULD** (best-effort)
* iOS: Automatic (OS handles) - **MUST** (OS-guaranteed)
* ❌ Notification will **NOT** fire after Android Force Stop until app is opened - **MUST NOT** (OS limitation)
* ⚠️ iOS notifications have ±180s timing tolerance - **SHOULD** (OS limitation)
**Platform Caveats**:
* Android requires `SCHEDULE_EXACT_ALARM` permission on Android 12+ - See [Doc A §5.2](./01-platform-capability-reference.md#52-android-s-exact-alarm-permission-decision-tree)
* Android requires `RECEIVE_BOOT_COMPLETED` permission for reboot recovery - See [Doc A §2.1.2](./01-platform-capability-reference.md#212-alarms-can-be-preserved-across-device-reboot)
* iOS requires notification authorization - See [Doc A §3.1.1](./01-platform-capability-reference.md#311-notifications-survive-app-termination)
**Error States**:
* `EXACT_ALARM_PERMISSION_REQUIRED` - Android 12+ exact alarm permission needed
* **Response**: Plugin opens system settings, returns `action: "opened_settings"`
* `NOTIFICATIONS_DENIED` - Notification permission denied
* **Response**: Plugin shows error message, returns `action: "permission_denied"`
* `SCHEDULE_FAILED` - Scheduling failed (check logs)
* **Response**: Plugin logs error, returns error with message
* `STORAGE_FULL` - Cannot persist alarm (storage full)
* **Response**: Plugin attempts cleanup, retries, or returns error
* `INVALID_SCHEDULE` - Schedule format invalid
* **Response**: Plugin returns error with validation message
**Platform References**:
* [Android §2.1.1](./01-platform-capability-reference.md#211-alarms-survive-ui-kills-swipe-from-recents)
* [Android §2.1.2](./01-platform-capability-reference.md#212-alarms-can-be-preserved-across-device-reboot)
* [Android §2.2.1](./01-platform-capability-reference.md#221-you-cannot-survive-force-stop)
* [iOS §3.1.1](./01-platform-capability-reference.md#311-notifications-survive-app-termination)
* [iOS §3.1.2](./01-platform-capability-reference.md#312-notifications-persist-across-device-reboot)
**Developer Responsibilities**:
* **MUST** handle permission requests (Android 12+ exact alarm, iOS notification authorization)
* **MUST** handle error responses and provide user feedback
* **SHOULD** check `getNotificationStatus()` to verify alarm scheduling
* **MUST NOT** assume alarms will fire after Force Stop (Android) until app is opened
* **MUST NOT** assume exact timing on iOS (±180s tolerance)
* **SHOULD** implement retry logic for scheduling failures
**Platform Differences**:
* **Android**: Requires boot receiver for reboot recovery - See [Doc A §2.1.2](./01-platform-capability-reference.md#212-alarms-can-be-preserved-across-device-reboot)
* **iOS**: Notifications persist automatically across reboot - See [Doc A §3.1.2](./01-platform-capability-reference.md#312-notifications-persist-across-device-reboot)
* **Android**: App code runs when alarm fires - See [Doc A §2.1.1](./01-platform-capability-reference.md#211-alarms-survive-ui-kills-swipe-from-recents)
* **iOS**: App code does NOT run when notification fires - See [Doc A §3.2.1](./01-platform-capability-reference.md#321-app-code-does-not-run-when-notification-fires)
---
#### 5.1.2 `scheduleDailyReminder(options)`
**Method Signature**: Same as `scheduleDailyNotification()` but without `payload` option.
**Guarantees**:
* Same as `scheduleDailyNotification()` above
* Static reminder (no content dependency)
* Fires even if content fetch fails
---
#### 5.1.3 `getNotificationStatus()`
**Method Signature**:
```typescript
getNotificationStatus(): Promise<{
pendingCount: number;
lastNotificationTime?: number;
missedAlarms?: Array<{
alarmId: string;
scheduledTime: number;
detectedAt: number;
}>;
permissions: {
exactAlarm?: boolean; // Android 12+
notifications?: boolean; // iOS
bootReceiver?: boolean; // Android
};
}>
```
**Returned Fields**:
* `pendingCount` (number) - Number of scheduled alarms
* `lastNotificationTime` (number, optional) - Timestamp of last notification
* `missedAlarms` (array, optional) - Array of missed alarms
* `alarmId` (string) - Unique identifier
* `scheduledTime` (number) - When alarm was scheduled to fire
* `detectedAt` (number) - When missed alarm was detected
* `permissions` (object) - Current permission status
* `exactAlarm` (boolean, optional) - Android 12+ exact alarm permission
* `notifications` (boolean, optional) - iOS notification authorization
* `bootReceiver` (boolean, optional) - Android boot receiver capability
**Guarantees**:
* Returns current notification status - **MUST**
* Includes pending notifications - **MUST**
* Includes last notification time - **SHOULD**
* May include missed alarm information - **SHOULD** (if detected)
---
### 5.2 API Warnings
The plugin **MUST** document the following warnings in JS/TS API documentation:
**Android Warnings**:
* "Notifications will not fire after device reboot unless the app is opened at least once" - See [Doc A §2.1.2](./01-platform-capability-reference.md#212-alarms-can-be-preserved-across-device-reboot)
* "Force Stop will prevent all notifications until the app is manually opened" - See [Doc A §2.2.1](./01-platform-capability-reference.md#221-you-cannot-survive-force-stop)
* "Exact alarm permission is required on Android 12+ for precise timing" - See [Doc A §5.2](./01-platform-capability-reference.md#52-android-s-exact-alarm-permission-decision-tree)
**iOS Warnings**:
* "Notifications have ±180 seconds timing tolerance" - See [Doc A §6.1](./01-platform-capability-reference.md#61-notification-timing-accuracy)
* "App code does not run when notifications fire (unless user interacts)" - See [Doc A §3.2.1](./01-platform-capability-reference.md#321-app-code-does-not-run-when-notification-fires)
* "Background execution is system-controlled and not guaranteed" - See [Doc A §3.1.3](./01-platform-capability-reference.md#313-background-tasks-for-prefetching)
**Cross-Platform Warnings**:
* "Missed alarms are detected on app launch, not at trigger time" - See [Doc C §4.2](./03-plugin-requirements.md#42-detection-triggers)
* "Repeating alarms must be rescheduled for each occurrence (Android)" - See [Doc A §2.1.2](./01-platform-capability-reference.md#212-alarms-can-be-preserved-across-device-reboot)
* "Location-based triggers do not persist across reboot (iOS)" - See [Doc A §3.1.2](./01-platform-capability-reference.md#312-notifications-persist-across-device-reboot)
---
### 5.3 API Error Handling
The plugin **MUST**:
* Return clear error messages
* Include error codes for programmatic handling
* Open system settings when permission is needed
* Provide actionable guidance in error messages
**Example Error Response**:
```typescript
{
code: "EXACT_ALARM_PERMISSION_REQUIRED",
message: "Exact alarm permission required. Please grant 'Alarms & reminders' permission in Settings, then try again.",
action: "opened_settings" // or "permission_denied"
}
```
---
## 6. Plugin WILL NOT Guarantee
### 6.1 Hard Boundaries (Cannot Ever Guarantee)
The plugin **MUST NOT** promise or attempt to guarantee:
| Behavior | Platform | Reason | Platform Reference |
| -------- | -------- | ------ | ------------------ |
| **Auto-recovery after Force Stop** | Android | OS hard kill - cannot bypass | [Doc A §2.2.1](./01-platform-capability-reference.md#221-you-cannot-survive-force-stop) |
| **App code execution on iOS notification fire** | iOS | OS limitation - code does not run | [Doc A §3.2.1](./01-platform-capability-reference.md#321-app-code-does-not-run-when-notification-fires) |
| **Exact timing on iOS** | iOS | ±180s tolerance is OS limitation | [Doc A §6.1](./01-platform-capability-reference.md#61-notification-timing-accuracy) |
| **Background execution timing** | iOS | System-controlled, not guaranteed | [Doc A §3.1.3](./01-platform-capability-reference.md#313-background-tasks-for-prefetching) |
| **Alarm persistence without storage** | Both | Must persist in durable storage | [Doc A §2.2.3](./01-platform-capability-reference.md#223-alarms-cannot-be-preserved-solely-in-ram) |
**Enforcement**: These behaviors **MUST** be documented as unsupported in JS/TS API documentation.
---
### 6.2 Guarantee vs Best-Effort Matrix
| Behavior | Android | iOS | Guarantee Level | Notes |
| -------- | ------- | --- | -------------- | ----- |
| **Notification fires after swipe** | ✅ Guaranteed | ✅ Guaranteed | **MUST** - OS-guaranteed | [Doc A §2.1.1](./01-platform-capability-reference.md#211-alarms-survive-ui-kills-swipe-from-recents), [Doc A §3.1.1](./01-platform-capability-reference.md#311-notifications-survive-app-termination) |
| **Notification fires after reboot** | ⚠️ Best-effort | ✅ Guaranteed | Android: **SHOULD** (requires boot receiver), iOS: **MUST** | [Doc A §2.1.2](./01-platform-capability-reference.md#212-alarms-can-be-preserved-across-device-reboot), [Doc A §3.1.2](./01-platform-capability-reference.md#312-notifications-persist-across-device-reboot) |
| **Missed alarm detection** | ✅ Guaranteed | ✅ Guaranteed | **MUST** - Plugin-required | [Doc C §4.2](./03-plugin-requirements.md#42-detection-triggers) |
| **Force stop recovery** | ✅ Guaranteed | N/A | **MUST** - Plugin-required | [Doc C §3.1.4](./03-plugin-requirements.md#314-force-stop-recovery-android-only) |
| **Exact timing** | ⚠️ Best-effort | ⚠️ Best-effort | Android: **SHOULD** (with permission), iOS: **SHOULD** (±180s) | [Doc A §5.2](./01-platform-capability-reference.md#52-android-s-exact-alarm-permission-decision-tree), [Doc A §6.1](./01-platform-capability-reference.md#61-notification-timing-accuracy) |
| **Background execution** | ⚠️ Best-effort | ⚠️ Best-effort | **SHOULD** - System-controlled | [Doc A §3.1.3](./01-platform-capability-reference.md#313-background-tasks-for-prefetching) |
**Legend**:
- **MUST** = Plugin guarantees this behavior
- **SHOULD** = Plugin attempts this but cannot guarantee (best-effort)
- **MUST NOT** = Plugin cannot and will not attempt this
---
### 6.3 Failure Modes & Required Responses
| Failure Mode | Platform | Required Plugin Response | User Impact |
| ------------ | -------- | ------------------------ | ----------- |
| **Persistence failure** | Both | Log error, continue with alarm scheduling (best effort), retry persistence | Alarm may be lost if app killed |
| **Storage full** | Both | Log warning, attempt cleanup, retry, notify user if critical | User must free space |
| **Invalid data** | Both | Skip invalid entries, log warning, continue processing | Invalid alarms ignored |
| **Permission denied** | Android | Open settings, show error message, return error code | User must grant permission |
| **Boot receiver not registered** | Android | Log error, alarms not rescheduled on boot | Alarms lost on reboot |
| **Force stop** | Android | Detect on app restart, recover all alarms, mark missed | Alarms lost until app opened |
| **Background execution denied** | iOS | Log warning, schedule next attempt, notify user | Prefetch may fail |
| **Notification authorization denied** | iOS | Show error, return error code, cannot schedule | Notifications disabled |
**Required Actions**:
* **MUST** log all failures with sufficient context
* **MUST** provide user-visible error messages for critical failures
* **SHOULD** provide recovery mechanisms where possible
* **MUST NOT** crash or silently fail
---
## 7. Explicit Storage Schema
### 7.1 Required Database Schema
**Android (Room Database)**:
| Table | Field | Type | Required | Purpose |
| ----- | ----- | ----- | -------- | ------- |
| **Schedule** | `id` | String | ✅ Yes | Unique identifier |
| | `kind` | String | ✅ Yes | "notify" or "fetch" |
| | `enabled` | Boolean | ✅ Yes | Whether alarm is active |
| | `cron` | String? | ⚠️ Optional | Cron expression |
| | `clockTime` | String? | ⚠️ Optional | HH:mm format |
| | `nextRunAt` | Long? | ⚠️ Optional | Next scheduled time |
| | `createdAt` | Long | ✅ Yes | Creation timestamp |
| | `updatedAt` | Long | ✅ Yes | Last update timestamp |
| **NotificationContentEntity** | `id` | String | ✅ Yes | Unique identifier |
| | `scheduleId` | String | ✅ Yes | Foreign key to Schedule |
| | `title` | String | ✅ Yes | Notification title |
| | `body` | String | ✅ Yes | Notification body |
| | `scheduledTime` | Long | ✅ Yes | When to fire |
| | `deliveryStatus` | String | ✅ Yes | "pending", "delivered", "missed" |
| | `priority` | String | ✅ Yes | Notification priority |
| | `soundEnabled` | Boolean | ✅ Yes | Sound preference |
| | `vibrationEnabled` | Boolean | ✅ Yes | Vibration preference |
| | `createdAt` | Long | ✅ Yes | Creation timestamp |
| | `updatedAt` | Long | ✅ Yes | Last update timestamp |
| **ContentCache** | `id` | String | ✅ Yes | Unique identifier |
| | `scheduleId` | String | ✅ Yes | Foreign key to Schedule |
| | `payload` | String? | ⚠️ Optional | Additional content (JSON) |
| | `createdAt` | Long | ✅ Yes | Creation timestamp |
**iOS (Plugin Storage)**:
| Storage Type | Field | Type | Required | Purpose |
| ------------ | ----- | ----- | -------- | ------- |
| **UserDefaults/CoreData** | `alarm_id` | String | ✅ Yes | Unique identifier |
| | `trigger_time` | TimeInterval | ✅ Yes | When to fire |
| | `repeat_rule` | String | ✅ Yes | NONE, DAILY, WEEKLY, CUSTOM |
| | `title` | String | ✅ Yes | Notification title |
| | `body` | String | ✅ Yes | Notification body |
| | `enabled` | Boolean | ✅ Yes | Whether alarm is active |
| | `created_at` | TimeInterval | ✅ Yes | Creation timestamp |
| | `updated_at` | TimeInterval | ✅ Yes | Last update timestamp |
**Note**: iOS also uses UNUserNotificationCenter (OS-managed) for notification scheduling, but plugin **MUST** maintain parallel storage for missed detection.
---
## 8. Explicit Unsupported Behaviors
### 8.1 Hard Boundaries (Plugin WILL NOT Guarantee)
The plugin **MUST NOT** support or guarantee the following behaviors:
| Behavior | Platform | Reason | Platform Reference |
| -------- | -------- | ------ | ------------------ |
| **Auto-recovery after Android Force Stop** | Android | OS hard kill - cannot bypass | [Doc A §2.2.1](./01-platform-capability-reference.md#221-you-cannot-survive-force-stop) |
| **App code execution on iOS notification fire** | iOS | OS limitation - code does not run | [Doc A §3.2.1](./01-platform-capability-reference.md#321-app-code-does-not-run-when-notification-fires) |
| **Exact timing on iOS** | iOS | ±180s tolerance is OS limitation | [Doc A §6.1](./01-platform-capability-reference.md#61-notification-timing-accuracy) |
| **Background execution timing guarantees** | Both | System-controlled, not guaranteed | [Doc A §3.1.3](./01-platform-capability-reference.md#313-background-tasks-for-prefetching) |
| **Alarm persistence without durable storage** | Both | Must use database/files | [Doc A §2.2.3](./01-platform-capability-reference.md#223-alarms-cannot-be-preserved-solely-in-ram) |
| **Repeating alarms without rescheduling** | Android | Must reschedule each occurrence | [Doc A §2.1.2](./01-platform-capability-reference.md#212-alarms-can-be-preserved-across-device-reboot) |
| **Location-based triggers** | iOS | Does not persist across reboot | [Doc A §3.1.2](./01-platform-capability-reference.md#312-notifications-persist-across-device-reboot) |
| **Silent rescheduling without user launch** | Android | Force stop blocks all execution | [Doc A §2.2.1](./01-platform-capability-reference.md#221-you-cannot-survive-force-stop) |
**Documentation Requirement**: All unsupported behaviors **MUST** be documented in JS/TS API with clear warnings. See [§5.2 - API Warnings](./03-plugin-requirements.md#52-api-warnings).
---
### 8.2 Platform-Specific Limitations
**Android**:
* Force Stop is a hard kill that cannot be bypassed - See [Doc A §2.2.1](./01-platform-capability-reference.md#221-you-cannot-survive-force-stop)
* Reboot wipes all alarms; must reschedule from storage - See [Doc A §2.1.2](./01-platform-capability-reference.md#212-alarms-can-be-preserved-across-device-reboot)
* Exact alarm permission required on Android 12+ - See [Doc A §5.2](./01-platform-capability-reference.md#52-android-s-exact-alarm-permission-decision-tree)
* Doze mode may defer inexact alarms - See [Doc A §2.1.1](./01-platform-capability-reference.md#211-alarms-survive-ui-kills-swipe-from-recents)
**iOS**:
* Background execution is severely limited - See [Doc A §3.1.3](./01-platform-capability-reference.md#313-background-tasks-for-prefetching)
* App code does not run when notifications fire - See [Doc A §3.2.1](./01-platform-capability-reference.md#321-app-code-does-not-run-when-notification-fires)
* Timing has ±180s tolerance - See [Doc A §6.1](./01-platform-capability-reference.md#61-notification-timing-accuracy)
* BGTaskScheduler execution is not guaranteed - See [Doc A §3.1.3](./01-platform-capability-reference.md#313-background-tasks-for-prefetching)
---
## 9. Traceability Matrix
**Complete mapping from platform facts → requirements → tests → implementation**:
| Requirement | Platform Source (Doc A) | Expected Plugin Behavior (Doc C) | Test Scenario (Doc B) | Implemented in Phase |
| ----------- | ----------------------- | ------------------------------- | --------------------- | -------------------- |
| **Missed alarm detection** | [Android §2.1.4](./01-platform-capability-reference.md#214-alarms-can-be-restored-after-app-restart) | [§4.2 - Detection Triggers](./03-plugin-requirements.md#42-detection-triggers) | [Test 4 Step 6](./02-plugin-behavior-exploration.md#test-4-device-reboot) | Phase 1 |
| **Boot reschedule** | [Android §2.1.2](./01-platform-capability-reference.md#212-alarms-can-be-preserved-across-device-reboot) | [§3.1.1 - Boot Event](./03-plugin-requirements.md#311-boot-event-android-only) | [Test 4 Step 7](./02-plugin-behavior-exploration.md#test-4-device-reboot) | Phase 3 |
| **Force stop recovery** | [Android §2.2.1](./01-platform-capability-reference.md#221-you-cannot-survive-force-stop) | [§3.1.4 - Force Stop Recovery](./03-plugin-requirements.md#314-force-stop-recovery-android-only) | [Test 5](./02-plugin-behavior-exploration.md#test-5-android-force-stop) | Phase 2 |
| **Cold start recovery** | [Android §2.1.4](./01-platform-capability-reference.md#214-alarms-can-be-restored-after-app-restart) | [§3.1.2 - App Cold Start](./03-plugin-requirements.md#312-app-cold-start) | [Test 4 Step 5](./02-plugin-behavior-exploration.md#test-4-device-reboot) | Phase 1 |
| **Swipe from recents** | [Android §2.1.1](./01-platform-capability-reference.md#211-alarms-survive-ui-kills-swipe-from-recents), [iOS §3.1.1](./01-platform-capability-reference.md#311-notifications-survive-app-termination) | [§1.1 - Guarantees Matrix](./03-plugin-requirements.md#11-cross-platform-guarantees-matrix) | [Test 2](./02-plugin-behavior-exploration.md#test-2-swipe-from-recents) | OS-guaranteed |
| **iOS notification persistence** | [iOS §3.1.2](./01-platform-capability-reference.md#312-notifications-persist-across-device-reboot) | [§1.1 - Guarantees Matrix](./03-plugin-requirements.md#11-cross-platform-guarantees-matrix) | [Test 3](./02-plugin-behavior-exploration.md#test-3-device-reboot-1) | OS-guaranteed |
| **Persistence** | [Android §2.2.3](./01-platform-capability-reference.md#223-alarms-cannot-be-preserved-solely-in-ram) | [§2 - Persistence Requirements](./03-plugin-requirements.md#2-persistence-requirements) | [Persistence Investigation](./02-plugin-behavior-exploration.md#13-persistence-investigation) | Phase 1 |
| **Exact alarm permission** | [Android §5.2](./01-platform-capability-reference.md#52-android-s-exact-alarm-permission-decision-tree) | [§10.1.1 - Permissions](./03-plugin-requirements.md#1011-permissions) | [Test 6](./02-plugin-behavior-exploration.md#test-6-exact-alarm-permission-android-12) | Phase 1 |
---
## 10. Platform-Specific Requirements
### 10.1 Android Requirements
#### 10.1.1 Permissions
**Required Permissions**:
* `RECEIVE_BOOT_COMPLETED` - Boot receiver
* `SCHEDULE_EXACT_ALARM` - Android 12+ (API 31+) for exact alarms
* `POST_NOTIFICATIONS` - Android 13+ (API 33+) for notifications
**Permission Handling**:
* Check permission before scheduling
* Request permission if not granted
* Open system settings if permission denied
* Provide clear error messages
**Code Reference**: `DailyNotificationPlugin.kt` line 1309
**Platform Reference**: [Android §2.2.4](../01-platform-capability-reference.md#224-you-cannot-bypass-doze-or-battery-optimization-restrictions-without-permission)
---
#### 10.1.2 Manifest Entries
**Required Manifest Entries**:
```xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<receiver
android:name="com.timesafari.dailynotification.BootReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver
android:name="com.timesafari.dailynotification.DailyNotificationReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="com.timesafari.daily.NOTIFICATION" />
</intent-filter>
</receiver>
```
**Location**: Test app manifest: `test-apps/android-test-app/app/src/main/AndroidManifest.xml`
---
#### 10.1.3 Notification Channels
**Required Channels**:
* `timesafari.daily` - Primary notification channel
* `daily_reminders` - Reminder notifications (if used)
**Channel Configuration**:
* Importance: HIGH (for alarms), DEFAULT (for reminders)
* Sound: Enabled by default
* Vibration: Enabled by default
* Show badge: Enabled
**Code Reference**: `ChannelManager.java` or `NotifyReceiver.kt` line 454
---
#### 10.1.4 Alarm Scheduling
**Required API Usage**:
* `setAlarmClock()` for Android 5.0+ (preferred)
* `setExactAndAllowWhileIdle()` for Android 6.0+ (fallback)
* `setExact()` for older versions (fallback)
**Code Reference**: `NotifyReceiver.kt` line 219, 223, 231
**Platform Reference**: [Android §2.1.1](../01-platform-capability-reference.md#211-alarms-survive-ui-kills-swipe-from-recents)
---
### 10.2 iOS Requirements
#### 10.2.1 Permissions
**Required Permissions**:
* Notification authorization (requested at runtime)
**Permission Handling**:
* Request permission before scheduling
* Handle authorization status
* Provide clear error messages
---
#### 10.2.2 Background Tasks
**Required Background Task Identifiers**:
* `com.timesafari.dailynotification.fetch` - Background fetch
* `com.timesafari.dailynotification.notify` - Notification task (if used)
**Background Task Registration**:
* Register in `Info.plist`:
```xml
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.timesafari.dailynotification.fetch</string>
</array>
```
**Code Reference**: `DailyNotificationPlugin.swift` line 31-32
**Platform Reference**: [iOS §3.1.3](../01-platform-capability-reference.md#313-background-tasks-for-prefetching)
---
#### 10.2.3 Notification Scheduling
**Required API Usage**:
* `UNUserNotificationCenter.add()` - Schedule notifications
* `UNCalendarNotificationTrigger` - Calendar-based triggers (preferred)
* `UNTimeIntervalNotificationTrigger` - Time interval triggers
**Code Reference**: `DailyNotificationScheduler.swift` line 185
**Platform Reference**: [iOS §3.1.1](../01-platform-capability-reference.md#311-notifications-survive-app-termination)
---
#### 10.2.4 Notification Categories
**Required Categories**:
* `DAILY_NOTIFICATION` - Primary notification category
**Category Configuration**:
* Actions: Configure as needed
* Options: Custom sound, custom actions
**Code Reference**: `DailyNotificationScheduler.swift` line 62+
---
## 11. Testing Requirements
### 11.1 Required Test Scenarios
The plugin **must** be tested for:
**Android**:
* [ ] Base case (alarm fires on time)
* [ ] Swipe from recents
* [ ] OS kill (memory pressure)
* [ ] Device reboot (with and without app launch)
* [ ] Force stop (with app restart)
* [ ] Exact alarm permission (Android 12+)
* [ ] Boot receiver functionality
* [ ] Missed alarm detection
**iOS**:
* [ ] Base case (notification fires on time)
* [ ] Swipe app away
* [ ] Device reboot (without app launch)
* [ ] Hard termination and relaunch
* [ ] Background execution limits
* [ ] Missed notification detection
**Cross-Platform**:
* [ ] Timezone changes
* [ ] Clock adjustments
* [ ] Multiple simultaneous alarms
* [ ] Repeating alarms
* [ ] Alarm cancellation
**Test Documentation**: See [Plugin Behavior Exploration](./02-plugin-behavior-exploration.md) for test matrices.
---
## 12. Migration Rules
### 12.1 Storage Format Changes
**If plugin storage format changes**, migration **MUST** define:
1. **Version detection**: How to identify old vs new format
2. **Safe upgrade path**: Step-by-step migration process
3. **Failure fallback**: What happens if migration fails
4. **No data loss**: All existing alarms must be preserved or explicitly marked as lost
**Migration Requirements**:
* **MUST** run automatically on app launch
* **MUST** log migration steps for debugging
* **MUST** handle partial migrations gracefully
* **MUST NOT** lose user data without explicit user confirmation
**Example Migration**:
```kotlin
// Pseudo-code
if (databaseVersion < currentVersion) {
migrateDatabase(oldVersion, currentVersion)
verifyMigrationIntegrity()
if (migrationFailed) {
rollbackToBackup()
notifyUser()
}
}
```
### 12.2 API Contract Changes
**If JS/TS API changes**:
* **MUST** maintain backward compatibility for at least one major version
* **MUST** provide deprecation warnings before removal
* **MUST** document migration path in changelog
* **MUST** update Doc C before releasing breaking changes
---
## 13. API Stability Guarantees
### 13.1 Breaking Change Policy
**No breaking change may occur without**:
1. **Doc C update** - Requirements document updated first
2. **MINOR or MAJOR version bump** - Semantic versioning enforced
3. **Migration notes** - Clear upgrade path documented
4. **Deprecation period** - Old API deprecated for at least one release cycle
### 13.2 Stability Guarantees
**Plugin guarantees**:
* **MUST** maintain API contract within same major version
* **SHOULD** maintain API contract across minor versions (exceptions documented)
* **MUST NOT** break API contract without major version bump
**Example**:
* `v1.0.0` → `v1.1.0`: New features added, no breaking changes ✅
* `v1.1.0` → `v2.0.0`: Breaking API change, migration guide required ✅
* `v1.1.0` → `v1.2.0`: Breaking API change ❌ (must be v2.0.0)
---
## 14. "What Happens If We Do Nothing?" Analysis
### 14.1 No Recovery Implementation
**If plugin does NOT implement recovery**:
| Scenario | What Happens | Impact |
| -------- | ------------ | ------ |
| **Device Reboot** (Android) | All alarms wiped, never fire | **Critical**: User loses all scheduled alarms |
| **Force Stop** (Android) | All alarms cleared, never fire until app opened | **Critical**: User loses alarms until manual app launch |
| **Cold Start** | Missed alarms never detected | **Major**: User unaware of missed notifications |
| **Warm Start** | Alarms may be missing, never verified | **Minor**: Edge case, alarms usually still work |
**Conclusion**: Recovery **MUST** be implemented for Android reboot and force stop scenarios. Cold start recovery **SHOULD** be implemented for user experience.
### 14.2 No Persistence
**If plugin does NOT persist alarms**:
| Scenario | What Happens | Impact |
| -------- | ------------ | ------ |
| **App Kill** | All alarms lost | **Critical**: User loses all scheduled alarms |
| **Reboot** | Cannot reschedule | **Critical**: Recovery impossible |
| **Force Stop** | Cannot detect missed alarms | **Major**: Recovery incomplete |
**Conclusion**: Persistence **MUST** be implemented. It is foundational for all recovery scenarios.
### 14.3 No Missed Alarm Detection
**If plugin does NOT detect missed alarms**:
| Scenario | What Happens | Impact |
| -------- | ------------ | ------ |
| **Missed Alarm** | User never notified | **Major**: User unaware of missed notifications |
| **Repeating Alarm** | Next occurrence may be wrong | **Major**: Schedule drift over time |
**Conclusion**: Missed alarm detection **SHOULD** be implemented for user experience and schedule accuracy.
---
## 15. Versioning Requirements
### 15.1 Breaking Changes
Any change to alarm behavior is **breaking** and requires:
* **MAJOR version bump** (semantic versioning)
* **Migration guide** for existing users
* **Deprecation warnings** (if applicable)
* **Clear changelog entry**
### 10.2 Non-Breaking Changes
Non-breaking changes include:
* Bug fixes
* Performance improvements
* Additional features (backward compatible)
* Documentation updates
---
## 16. Cross-Reference Anchors
**All cross-references use standardized anchors**:
| Reference Format | Example | Resolves To |
| ---------------- | ------- | ----------- |
| `[Doc A §X.Y]` | `[Doc A §2.1.1]` | [Platform Reference §2.1.1](./01-platform-capability-reference.md#211-alarms-survive-ui-kills-swipe-from-recents) |
| `[Doc B §X.Y]` | `[Doc B §1.2]` | [Exploration §1.2](./02-plugin-behavior-exploration.md#12-behavior-testing-matrix) |
| `[Doc C §X.Y]` | `[Doc C §3.1.2]` | [Requirements §3.1.2](#312-app-cold-start) |
| `[Phase N §X.Y]` | `[Phase 1 §2.3]` | [Phase 1 Implementation](../android-implementation-directive-phase1.md#23-cold-start-recovery) |
**Anchor Rules**:
* All section headers MUST have unique anchors
* Cross-references MUST use exact anchor format
* Broken links MUST be fixed immediately
---
## Related Documentation
- [Platform Capability Reference](./01-platform-capability-reference.md) - OS-level facts
- [Plugin Behavior Exploration](./02-plugin-behavior-exploration.md) - Exploration template
- [Unified Alarm Directive](./000-UNIFIED-ALARM-DIRECTIVE.md) - Master coordination document
- [Phase 1: Cold Start Recovery](../android-implementation-directive-phase1.md) - Implementation
- [Phase 2: Force Stop Recovery](../android-implementation-directive-phase2.md) - Implementation
- [Phase 3: Boot Recovery](../android-implementation-directive-phase3.md) - Implementation
---
## Version History
- **v1.1.0** (November 2025): Enhanced with non-guarantees, failure modes, storage schema
- Added "Plugin WILL NOT Guarantee" section
- Added Guarantee vs Best-Effort matrix
- Added Failure Modes & Required Responses table
- Added Explicit Storage Schema
- Enhanced JS/TS API contract with returned fields and error states
- Added Missed Alarm Resolution Rules
- Added State Transition Table
- Added Explicit Unsupported Features List
- **v1.0.0** (November 2025): Initial requirements document
- Plugin behavior guarantees and limitations
- Persistence requirements
- Recovery requirements
- Missed alarm handling contract
- JS/TS API contract
- Platform-specific requirements
- Testing requirements
- Traceability matrix