Repository navigation
Conversation
A widget registers its push token with push.register {kind: widgets},
which needs ftw.live.read. When a box's priced hours reach further than
before, as when tomorrow's prices arrive, or a car is plugged in, the
service sends Apple's widgets push: no data, only content-changed, to
the app's .push-type.widgets topic. The widgets then read /v1/now with
their token. At most 4 an hour per home, since Apple budgets reloads.
The uplink's OnEvent hook becomes OnHeld, which hands push every held
envelope with its class. A roster prunes each kind by the scope it
needs. The APNs client takes the push type and the app's bundle id.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
…nly its kind From review: - Widgets need only ftw.live.read, so a viewer may now register, and nothing capped how many tokens a device held. One push then called Apple once per row on the single send goroutine, holding up other homes' alerts. A device now keeps its newest 4 tokens per kind. - PushGone deleted every registration of a token, so Apple refusing the widgets topic also deleted the same token's alert registration. It now deletes only the kind Apple refused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
frahlg
added a commit
that referenced
this pull request
Oct 14, 2026
…ssion gets 403 Merges claude/cloud-widget-push. Register now stores the app and trims the device's tokens of that kind. From review: token.get over the one-shot read answered 500 when Issue found the device shut out after admission; it is a refusal, 403. The README no longer says the service checks the watch role: it checks none. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
frahlg
added a commit
that referenced
this pull request
Oct 14, 2026
…at /v1/app/once (#11, #12, #13) One squash for three stacked PRs, ADR 0008 C6 and ADR 0009 step 7: - #11: the extension token (token.get, hashed, bound to a roster entry) and GET /v1/now. - #12: widget reloads through Apple when prices or a car change. - #13: a watch reads its home at /v1/app/once in one HTTPS request, Noise one-shot per the golden vectors. An independent review found no admission bypass, limit leak or logged secret; its smaller findings are fixed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #11. Merge #11 first; this PR then shows only its own commit.
What
Widget push from ADR 0008 (C6) and the protocol's Push table. ADR 0009 step 7
needs it first: a watch registers its widget token the same way, with
app: watch.push.register {kind: widgets}. It needsftw.live.read, as the protocolsays, so a viewer's widgets may register; alerts still need
ftw.events.read.than before, as when tomorrow's prices arrive, and when a loadpoint goes
from unplugged to plugged. The first
pricesandlpafter a start onlyset what the next is compared with. The midnight shift and an unplug send
nothing.
apns-push-type: widgets, topicenergy.ftw.app.push-type.widgets, body{"aps":{"content-changed":true}},no data and no priority header, as in Apple's sample. The widgets then read
/v1/nowwith their token (feat: widgets read /v1/now with a token bound to a roster entry #11).budgets widget reloads, so a car that flaps cannot spend that budget.
ftw.events.readdrops a device's alert tokens and keeps its widget tokens.
OnEventhook becomesOnHeld, which hands push every heldenvelope with its class, after the box's signature has been checked.
bundle id for the watch.
deploy/apns.md: a topic-specific key needs the widgets topic, and thewidget extension needs Push Notifications.
cloudwirenames onlyPushKindAlert; this PR spellswidgetsininternal/pushbeside it. The protocol's Push table names the type.Tests
ftw.live.read, and one without it is refused.body, and nothing goes to the alert tokens. Today's prices, a resend and
midnight send nothing.
lp, staying plugged and unplugging send nothing;a new plug-in sends one.
separate.
<bundle id>.push-type.widgetswithout a priority, and an alert to the named app with priority 10.
pricesandlpwith their class.Local:
go vet(with and withoutftwclouddev),go test -race ./...,go test -tags ftwclouddev ./...,scripts/check-imports.shand the arm64build all pass.
Not tried
No widget push has gone through Apple yet; the phone's widget does not
register a token. That needs a build of the app with the push handler.
After review (b4da95a)
An independent review found two defects here:
ftw.live.read, so a viewer may register, and nothingcapped a device's tokens. One push then called Apple once per row on the
single send goroutine, which held up other homes' alerts. A device now
keeps its newest 4 tokens per kind.
PushGonedeleted every registration of a token, so Apple refusing thewidgets topic also deleted the same token's alert registration. It now
deletes only the refused kind.
Each has a test. The branch also carries #11's review fixes.
🤖 Generated with Claude Code