This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
mobilecritical PriorityID: capacitor-7-background-task-execution-fence-power-budget

Capacitor 7 Background Task Execution Fence & Power-Budget Policy

Enforces deterministic execution fences, abort controllers, and atomic checkpointing for SQLite batch synchronization within Capacitor 7 background tasks. Prevents immediate OS-level SIGKILL terminations and SQLite database corruption on iOS and Android when background processing limits (e.g., 30s) are exceeded.

Prohibited Anti-Pattern: Unfenced Async SQLite Loops in Capacitor App Lifecycle Transitions Causing Process Death and Corrupted State

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Capacitor 7 Background Task Execution Fence & Power-Budget Policy - Enforces deterministic execution fences, abort controllers, and atomic checkpointing for SQLite batch synchronization within Capacitor 7 background tasks. Prevents immediate OS-level SIGKILL terminations and SQLite database corruption on iOS and Android when background processing limits (e.g., 30s) are exceeded.
globs: src/**/*.{ts,tsx}, src/services/**/*.{ts,js}, src/database/**/*.{ts,js}, src/sync/**/*.{ts,js}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/capacitor-7-background-task-execution-fence-power-budget"
---

# Capacitor 7 Background Task Execution Fence & Power-Budget Policy

> **Severity**: CRITICAL | **Category**: mobile
> **Anti-Pattern Warning**: Unfenced Async SQLite Loops in Capacitor App Lifecycle Transitions Causing Process Death and Corrupted State

## System Constraints
You are a Principal Engineer enforcing the Capacitor 7 Background Task Execution Fence & Power-Budget Policy. Mandate strict execution fences around all background synchronization routines. Under Capacitor 7, background execution via @capacitor/background-task or OS triggers (iOS UIApplication beginBackgroundTaskWithName / Android WorkManager) must adhere to a strict deadline fence (maximum 25 seconds of the 30-second budget), utilize AbortController signals on every I/O operation, process SQLite mutations in idempotent batch transactions, and ensure BackgroundTask.finish({ taskId }) is called deterministically in a finally block before the OS terminates the host process.

## Strict Guidelines
- Engineers MUST ALWAYS wrap any background synchronization task registered through Capacitor's BackgroundTask API in a defensive try/finally block that guarantees calling `BackgroundTask.finish({ taskId })`.
- Engineers MUST instantiate an `AbortController` bounded by an aggressive execution fence (default 25,000ms, leaving a 5,000ms safety margin for cleanup) whenever entering background sync execution.
- Engineers MUST NOT execute open-ended, unbounded `Promise.all` or sequential unbounded loops over outbox SQLite queues in the background without checking the abort signal on every iteration.
- Engineers MUST commit SQLite mutations in chunked atomic transactions and record an explicit cursor/watermark, ensuring interrupted jobs resume without duplicate mutations or partial writes.
- Services MUST cancel and roll back in-flight SQLite write transactions immediately upon receiving an OS expiration event (`App.addListener('appStateChange')` or platform timeout) before the process is terminated.
- Components NEVER execute raw HTTP mutations or direct sync operations within UI lifecycle hooks without passing through the central gated SyncCoordinator.

## Bad vs Good Implementations
### Background Sync Execution Fence with AbortSignal & SQLite Transaction Checkpointing

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Fails to enforce a power-budget timeout fence or handle OS watchdog expiration. If network latency delays processing, iOS/Android will kill the process mid-loop, leaving uncommitted transactions or dangling locks in the SQLite database and failing to invoke `BackgroundTask.finish`.
```typescript
import { BackgroundTask } from '@capacitor/background-task';
import { App } from '@capacitor/app';
import { db } from './database';

// ANTI-PATTERN: Open-ended background queue execution without fences, timeouts, or finish guarantees
App.addListener('appStateChange', async ({ isActive }) => {
  if (!isActive) {
    const taskId = await BackgroundTask.beforeExit(async () => {
      // Unfenced loop: if the queue has 500 items, iOS terminates the app at ~30s
      // resulting in half-committed SQLite writes, lock starvation, and silent data loss.
      const pendingRecords = await db.query('SELECT * FROM outbox WHERE synced = 0');
      for (const record of pendingRecords.values) {
        await fetch('https://api.example.com/sync', {
          method: 'POST',
          body: JSON.stringify(record)
        });
        await db.run('UPDATE outbox SET synced = 1 WHERE id = ?', [record.id]);
      }
      BackgroundTask.finish({ taskId });
    });
  }
});
```

#### Production Standard (Correct)
> **Standard**: Wraps execution in a bounded 25-second fence via `AbortController`, executes updates within isolated transactions, handles `AbortError` cleanly, and deterministically resolves `BackgroundTask.finish({ taskId })` in a `finally` block before the operating system's 30-second hard kill trigger.
```typescript
import { BackgroundTask } from '@capacitor/background-task';
import { App } from '@capacitor/app';
import { SQLiteDBConnection } from '@capacitor-community/sqlite';

interface SyncItem {
  id: string;
  payload: string;
}

const BACKGROUND_BUDGET_MS = 25000; // 25s fence against 30s OS budget

export async function executeBoundedSync(
  connection: SQLiteDBConnection,
  apiUrl: string
): Promise<void> {
  const taskId = await BackgroundTask.beforeExit(async () => {
    const abortController = new AbortController();
    const timeoutId = setTimeout(() => abortController.abort(), BACKGROUND_BUDGET_MS);

    try {
      const result = await connection.query('SELECT id, payload FROM outbox WHERE synced = 0 ORDER BY created_at ASC LIMIT 100;');
      const items = (result.values ?? []) as SyncItem[];

      for (const item of items) {
        if (abortController.signal.aborted) {
          console.warn('Sync budget expired; gracefully halting loop before OS watchdog kills process.');
          break;
        }

        // Atomic fetch with abort signal
        const response = await fetch(`${apiUrl}/sync`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: item.payload,
          signal: abortController.signal
        });

        if (!response.ok) {
          throw new Error(`Sync failed with HTTP status ${response.status}`);
        }

        // Atomic transaction per item or chunked watermark
        await connection.executeTransaction([
          {
            statement: 'UPDATE outbox SET synced = 1, synced_at = ? WHERE id = ?;',
            values: [Date.now(), item.id]
          }
        ]);
      }
    } catch (error: unknown) {
      if (error instanceof Error && error.name === 'AbortError') {
        console.info('Background sync cleanly aborted by power-budget fence.');
      } else {
        console.error('Fatal sync failure during background execution:', error);
      }
    } finally {
      clearTimeout(timeoutId);
      // Invariant: Finish task deterministically before OS terminates host process
      BackgroundTask.finish({ taskId });
    }
  });
}

App.addListener('appStateChange', ({ isActive }) => {
  if (!isActive) {
    void executeBoundedSync(window.dbConnection, 'https://api.example.com');
  }
});
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Capacitor 7 Background Task Execution Fence & Power-Budget Policy

Capacitor 7 Background Task Execution Fence & Power-Budget Policy defines an industrial-grade behavioral standard for mobile engineering. Enforces deterministic execution fences, abort controllers, and atomic checkpointing for SQLite batch synchronization within Capacitor 7 background tasks. Prevents immediate OS-level SIGKILL terminations and SQLite database corruption on iOS and Android when background processing limits (e.g., 30s) are exceeded. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Unfenced Async SQLite Loops in Capacitor App Lifecycle Transitions Causing Process Death and Corrupted State Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftUnfenced Async SQLite Loops in Capacitor App Lifecycle Transitions Causing Process Death and Corrupted StateCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS wrap any background synchronization task registered through Capacitor's BackgroundTask API in a defensive try/finally block that guarantees calling `BackgroundTask.finish({ taskId })`.

Engineers MUST ALWAYS wrap any background synchronization task registered through Capacitor's BackgroundTask API in a defensive try/finally block that guarantees calling `BackgroundTask.finish({ taskId })`.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST instantiate an `AbortController` bounded by an aggressive execution fence (default 25,000ms, leaving a 5,000ms safety margin for cleanup) whenever entering background sync execution.

Engineers MUST instantiate an `AbortController` bounded by an aggressive execution fence (default 25,000ms, leaving a 5,000ms safety margin for cleanup) whenever entering background sync execution.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Engineers MUST NOT execute open-ended, unbounded `Promise.all` or sequential unbounded loops over outbox SQLite queues in the background without checking the abort signal on every iteration.

Engineers MUST NOT execute open-ended, unbounded `Promise.all` or sequential unbounded loops over outbox SQLite queues in the background without checking the abort signal on every iteration.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Engineers MUST commit SQLite mutations in chunked atomic transactions and record an explicit cursor/watermark, ensuring interrupted jobs resume without duplicate mutations or partial writes.

Engineers MUST commit SQLite mutations in chunked atomic transactions and record an explicit cursor/watermark, ensuring interrupted jobs resume without duplicate mutations or partial writes.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Services MUST cancel and roll back in-flight SQLite write transactions immediately upon receiving an OS expiration event (`App.addListener('appStateChange')` or platform timeout) before the process is terminated.

Services MUST cancel and roll back in-flight SQLite write transactions immediately upon receiving an OS expiration event (`App.addListener('appStateChange')` or platform timeout) before the process is terminated.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
6

Components NEVER execute raw HTTP mutations or direct sync operations within UI lifecycle hooks without passing through the central gated SyncCoordinator.

Components NEVER execute raw HTTP mutations or direct sync operations within UI lifecycle hooks without passing through the central gated SyncCoordinator.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is Capacitor 7 Background Task Execution Fence & Power-Budget Policy critical for AI coding assistants?

Enforces deterministic execution fences, abort controllers, and atomic checkpointing for SQLite batch synchronization within Capacitor 7 background tasks. Prevents immediate OS-level SIGKILL terminations and SQLite database corruption on iOS and Android when background processing limits (e.g., 30s) are exceeded. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Unfenced Async SQLite Loops in Capacitor App Lifecycle Transitions Causing Process Death and Corrupted State) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

Related MOBILE Rules

View all rules →
1 Rule in Stack

Capacitor