Summary
Move APNs registration runtime state from push/apns-registrations.json into the shared OpenClaw SQLite state database.
Problem to solve
APNs device tokens and relay grants are durable runtime state, but the current store is a JSON sidecar. Whole-file rewrites have only process-local serialization, and the file remains outside the database-first state model. Removing the runtime reader without an explicit migration would strand shipped registrations; retaining a fallback would let stale JSON resurrect registrations that SQLite has replaced or deleted.
Proposed solution
- Make
apns_registrations the only runtime read/write path, using the shared Kysely-backed state database.
- Persist registration deletions as tombstones until the retired JSON source has a migration receipt.
- Add an exclusive
openclaw doctor --fix migration that safely claims the legacy file, streams and validates every shipped record shape, preserves newer canonical rows, suppresses deleted rows, records a transactional receipt, verifies the result, and then removes the legacy file.
- Treat a receipt as authoritative so recreated or interrupted legacy files are cleanup-only and cannot resurrect state.
- Keep APNs delivery/authentication separate from the storage owner.
Alternatives considered
- Dual-write or read-through fallback: rejected because it leaves two authorities and creates stale-state resurrection races.
- Discard the JSON file: rejected because APNs registrations are persistent user state required for iOS wake and approval delivery.
- Dedicated APNs database: rejected because the shared state database already owns global runtime state and the record volume/lifecycle fits it.
Impact
Affected: Gateways with paired iOS devices using direct or relay APNs registrations.
Severity: High during upgrade if registration continuity or invalidation semantics are lost.
Frequency: One migration per existing state directory; all later reads and writes use SQLite.
Consequence: Correct migration preserves push delivery across restart. The database-only runtime removes whole-map rewrites and prevents retired JSON from reviving invalidated device registrations.
Evidence/examples
- Current runtime store:
src/infra/push-apns.ts
- Shared state schema:
src/state/openclaw-state-schema.sql
- Database-first contract:
docs/refactor/database-first.md
Additional information
Implementation and migration design were produced with AI assistance and will use focused upgrade tests, changed gates, and exact-head CI before landing.
Summary
Move APNs registration runtime state from
push/apns-registrations.jsoninto the shared OpenClaw SQLite state database.Problem to solve
APNs device tokens and relay grants are durable runtime state, but the current store is a JSON sidecar. Whole-file rewrites have only process-local serialization, and the file remains outside the database-first state model. Removing the runtime reader without an explicit migration would strand shipped registrations; retaining a fallback would let stale JSON resurrect registrations that SQLite has replaced or deleted.
Proposed solution
apns_registrationsthe only runtime read/write path, using the shared Kysely-backed state database.openclaw doctor --fixmigration that safely claims the legacy file, streams and validates every shipped record shape, preserves newer canonical rows, suppresses deleted rows, records a transactional receipt, verifies the result, and then removes the legacy file.Alternatives considered
Impact
Affected: Gateways with paired iOS devices using direct or relay APNs registrations.
Severity: High during upgrade if registration continuity or invalidation semantics are lost.
Frequency: One migration per existing state directory; all later reads and writes use SQLite.
Consequence: Correct migration preserves push delivery across restart. The database-only runtime removes whole-map rewrites and prevents retired JSON from reviving invalidated device registrations.
Evidence/examples
src/infra/push-apns.tssrc/state/openclaw-state-schema.sqldocs/refactor/database-first.mdAdditional information
Implementation and migration design were produced with AI assistance and will use focused upgrade tests, changed gates, and exact-head CI before landing.