You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
service-push: send through the hosted relay transport (push-relay.zod.ts wire, cloud binding credential) #29920
#29816 made transport: relay | direct the shape of PushServiceConfigSchema, with relay as the default ({} reads as relay), and added the server→relay wire in packages/spec/src/api/push-relay.zod.ts. PR #29794 (round 3) ships service-push reading only the direct arm. relay, including {}, is refused loudly at PushServicePlugin.init and names this card. The relay block keeps its refused-not-served marker until this card lands.
Ask
Implement the relay transport in service-push:
Send. POST a PushRelayRequestSchema body (one delivery per device token: token, vendor, ID-only payload, priority) to the relay endpoint, or the default endpoint when none is set.
Auth. The bearer is the server's cloud binding credential (cloud ADR-0008, the oscc_… binding). Resolve it through the binding, never inline config, and never log it. No binding means a loud init refusal that names the missing binding.
Answers. Map PushRelayResponseSchema per token: invalid retires the device row the same way the direct transports do; retry reuses the existing retry path. 401 is a loud, non-retryable failure that names the binding.
Privacy. The payload stays ID-only (phase 1). No title or body leaves the server.
Flip the refusal. Remove the init refusal, and turn the relay block and wire markers from not-served to served in the same PR, then regenerate.
Acceptance
Tests pin each arm: {}, an explicit relay endpoint, no binding, 401, and an invalid and a retry result.
Direct-transport behaviour is unchanged.
The changeset names the newly served relay transport.
Filed by the seat as the follow-up that PR #29794's relay refusal names.
Activity
objectstack-fleet commentedon Nov 3, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: first-touch audit · p2 ·
domain:serverkept ·pm:triage→pm:blocked· 2026-11-03T12:55Z⛔ Not a claim.
service-pushsends through the hosted relay (thepush-relay.zod.tswire, already declared by spec: push relay transport —transport: relay | directon PushServiceConfigSchema, and the server→relay wire shape (ruling cloud#3519) #29816, landed), authenticated by the cloud binding credential, and maps per-token answers. A server implementation of an already-declared contract, so p2. It follows cloud#3519's ruling.Blocked-by: #29794(open): that PR shipsservice-pushwith the direct arm only.Generated by Claude Code
Merge origin/main into the push channel branch (relay | direct union, #…
feat(service-push): serve the direct push transport and refuse the re…
fix(push): name no tracker id in operator-facing push text (check:doc…
objectstack-fleet commentedon Nov 3, 2026
domain:server#4 · os-warren · session_01JQwxbacSXJQqAztgt4UMrS
Carried into this card's scope (2026-11-03T14:31Z), from the PR #29794 round-3 contract review (6606491253 ③ and ④):
dataonPushRelayPayloadSchema(spec seat 2's should-fix, Push channel: build the device registry routes (/notifications/devices) and the APNs + FCM transport that ADR-0012 marks "MUST ship M1" #29041 6601310426, addressed to "the first producer of the relay wire", which is this card).retryable: trueonRATE_LIMIT_EXCEEDEDin the relay's error answer (same source).push-relay.zod.tsdocblock still says "No push channel delivers yet … until the push channel ships". After feat(notifications): the push channel — service-push (APNs + FCM) and its channel shell in service-messaging #29794 the channel ships; only the relay sender does not. Fix that sentence in the same PR that flips the markers to served.All three land with the relay sender, not before.