notify is core again

built 2026-07-31, switched off 2026-08-13 when it was slated to become a
plugin alongside memos and photos. those two were extracted; this one never
was, so it spent six days mounted nowhere with its schema commented out and
no pm2 entry — complete code that nothing could reach.

core rather than a plugin because the producers are the platform's own: the
job queue, an agent turn ending, mail arriving. a notifier the owner can
uninstall is one those producers cannot rely on.

- hono.ts mounts /api/notify again; verified 401 unauthenticated, so the
  permission gate covers it and assertPermissionTotality accepts the mount
- push_devices exported from the core schema and pushed: 10 columns,
  uq_push_devices_token_bundle, idx_push_devices_user
- officer-notify added to CORE_PROCESSES, so gen:ecosystem writes it
- credentials read OFFICERDEV_X ?? X, the convention it predates

safe as core because it boots with nothing configured: every channel reports
isConfigured() false and dispatch resolves empty. verified by importing it
with the env stripped — "channels: none configured", no throw. an install
with no apns key runs it as a no-op rather than crash-looping.

APNS_ENV is dropped from the doc's credential table. it was never read: the
host comes from each device's `environment` column, so one server pushes to a
testflight build and a release build at once.

doc status corrected. the app side is not started — there is no officer-suite
repo, no PUSH_NOTIFICATIONS_APP.md, and apps/chat actively strips the ios push
entitlement. recorded there rather than here.
This commit is contained in:
2026-08-19 18:05:33 +00:00
parent ab636eaa42
commit fd7c9becb6
8 changed files with 71 additions and 38 deletions
+1 -2
View File
@@ -167,8 +167,7 @@ const CORE_REGISTRY: Permission[] = [
label: 'Notifications',
description: 'Push notifications to your devices',
kind: 'app',
// api: ['/notify'], // plugin — switched off 2026-08-13
api: [],
api: ['/notify'],
// Device registration is the caller's own — a phone subscribing to its own push channel.
personal: ['/devices', '/subscriptions'],
},