Created ultra-compressed task block for P3.1 only (batches A-E). Contains: - Exact file paths - Exact search strings - Exact code replacements - Verification commands - Progress doc update checklist Ready for incremental execution - one batch at a time.
7.1 KiB
P3.1 Cursor Task Block — Performance Optimization & Metrics
Purpose: Ultra-compressed, mechanical execution steps for P3.1 only.
Baseline: v1.0.11-p2.3-p1.5b-complete
Invariants: See docs/progress/P3-EXECUTION-CHECKLIST-MECHANICAL.md section 0
Preflight (Before Each Batch)
./ci/run.sh
# STOP IF FAILS
Batch P3.1-A: Metrics Contract
File: src/core/metrics.ts (NEW)
Action: Create file with exact content:
/**
* Core Metrics
*
* Performance metrics contract and lightweight collector.
* Platform-agnostic, no dependencies.
*
* @author Matthew Raymer
* @version 1.0.0
*/
export interface PerformanceMetric {
operation: string;
duration: number;
timestamp: number;
success: boolean;
metadata?: Record<string, unknown>;
}
export interface MetricsCollector {
record(metric: PerformanceMetric): void;
getMetrics(): PerformanceMetric[];
clear(): void;
}
export class InMemoryMetricsCollector implements MetricsCollector {
private metrics: PerformanceMetric[] = [];
private maxMetrics = 100;
record(metric: PerformanceMetric): void {
this.metrics.push(metric);
if (this.metrics.length > this.maxMetrics) {
this.metrics = this.metrics.slice(-this.maxMetrics);
}
}
getMetrics(): PerformanceMetric[] {
return [...this.metrics];
}
clear(): void {
this.metrics = [];
}
}
File: src/core/index.ts (UPDATE)
Search: export * from './guards';
Action: Add after: export * from './metrics';
Verify:
npm run build
./ci/run.sh
grep -r "@capacitor\|react\|fs\|path\|os" src/core/metrics.ts # Must be empty
Batch P3.1-B: Instrument Scheduling
File: src/web.ts (UPDATE)
Search: async createSchedule(_schedule: CreateScheduleInput): Promise<Schedule> {
Current:
async createSchedule(_schedule: CreateScheduleInput): Promise<Schedule> {
this.throwNotSupported();
}
Replace with:
async createSchedule(_schedule: CreateScheduleInput): Promise<Schedule> {
const startTime = performance.now();
try {
this.throwNotSupported();
} catch (error) {
const duration = performance.now() - startTime;
if (this.observability) {
this.observability.logEvent('INFO', EVENT_CODES.SCHEDULE_UPDATE,
'Schedule creation attempted (not supported on web)',
{ duration, platform: 'web' });
}
throw error;
}
}
Import check: Ensure EVENT_CODES imported:
import { EVENT_CODES } from './core/events';
Repeat for:
updateSchedule()(line ~338)deleteSchedule()(line ~342)
Verify:
npm run build
./ci/run.sh
Batch P3.1-C: Instrument Recovery
File: android/src/main/java/com/timesafari/dailynotification/ReactivationManager.kt (UPDATE)
Search: private suspend fun performColdStartRecovery(): RecoveryResult {
Add at start:
val startTime = System.currentTimeMillis()
Find return statement, add before:
val duration = System.currentTimeMillis() - startTime
Log.i(TAG, "Cold start recovery completed: duration=${duration}ms, missed=$missedCount, rescheduled=$rescheduledCount, errors=$errors")
Repeat for: performForceStopRecovery()
File: ios/Plugin/DailyNotificationReactivationManager.swift (UPDATE)
Search: func performColdStartRecovery() async throws -> RecoveryResult {
Add at start:
let startTime = Date()
Find return, add before:
let duration = Date().timeIntervalSince(startTime) * 1000
os_log("Cold start recovery completed: duration=%.0fms, missed=%d, rescheduled=%d",
log: .default, type: .info, duration, missedCount, rescheduledCount)
Verify:
cd test-apps/android-test-app && ./gradlew :daily-notification-plugin:build
./ci/run.sh
Batch P3.1-D: Instrument Database
File: android/src/main/java/com/timesafari/dailynotification/ReactivationManager.kt (UPDATE)
Search: val enabledSchedules = try { db.scheduleDao().getEnabled() }
Replace with:
val dbStartTime = System.currentTimeMillis()
val enabledSchedules = try {
db.scheduleDao().getEnabled()
} catch (e: Exception) {
Log.e(TAG, "Failed to load schedules from DB", e)
emptyList()
} finally {
val dbDuration = System.currentTimeMillis() - dbStartTime
if (dbDuration > 100) {
Log.w(TAG, "Database query slow: ${dbDuration}ms for getEnabled()")
} else {
Log.d(TAG, "Database query: ${dbDuration}ms, schedules=${enabledSchedules.size}")
}
}
Verify:
cd test-apps/android-test-app && ./gradlew :daily-notification-plugin:build
./ci/run.sh
Batch P3.1-E: Performance Documentation
File: docs/PERFORMANCE.md (NEW)
Action: Create with exact content:
# Performance Characteristics
**Purpose:** Expected performance characteristics and benchmarks.
**Owner:** Development Team
**Last Updated:** 2025-12-22
**Status:** active
## Expected Operation Times
### Scheduling Operations
- Schedule creation: < 50ms (typical), < 100ms (p95)
- Schedule update: < 50ms (typical), < 100ms (p95)
- Schedule deletion: < 50ms (typical), < 100ms (p95)
### Recovery Operations
- Cold start recovery: < 500ms (typical), < 1000ms (p95)
- Force stop recovery: < 500ms (typical), < 1000ms (p95)
- Boot recovery: < 1000ms (typical), < 2000ms (p95)
### Database Operations
- Query (getEnabled): < 50ms (typical), < 100ms (p95)
- Query (getById): < 10ms (typical), < 20ms (p95)
- Insert/Update: < 50ms (typical), < 100ms (p95)
## Memory Footprint
- In-memory metrics: ~10KB per 100 metrics
- Event logs: ~5KB per 100 events
- Total overhead: < 100KB (development), < 10KB (production)
## Platform-Specific Considerations
### iOS
- Background task limits: ~30 seconds
- CoreData migrations: typically < 100ms
### Android
- WorkManager limits: flexible (minutes)
- Room migrations: typically < 200ms
### Web
- No background execution limits
- No native database operations
## Measurement Methodology
Metrics use:
- `performance.now()` (Web/TypeScript)
- `System.currentTimeMillis()` (Android)
- `Date.timeIntervalSince()` (iOS)
All timings in milliseconds.
---
**See also:**
- [SYSTEM_INVARIANTS.md](./SYSTEM_INVARIANTS.md)
- [docs/progress/03-TEST-RUNS.md](./progress/03-TEST-RUNS.md)
File: docs/00-INDEX.md (UPDATE)
Search: ## Policy & Contracts (Executable)
Add link:
- [PERFORMANCE.md](./PERFORMANCE.md) — Performance characteristics and benchmarks
Verify:
./ci/run.sh
P3.1 Acceptance
src/core/metrics.tsexists- Scheduling methods instrumented
- Recovery methods instrumented
- Database operations instrumented
docs/PERFORMANCE.mdcreated and linked./ci/run.shgreen- No new dependencies
- Tests pass
Update Progress Docs (After P3.1 Complete)
Files:
docs/progress/00-STATUS.md— Mark P3.1 completedocs/progress/01-CHANGELOG-WORK.md— Add P3.1 entrydocs/progress/03-TEST-RUNS.md— Add performance metrics note
Verify:
./ci/run.sh
Next: Proceed to P3.2 (Observability) after P3.1 is green.