Repository navigation
Conversation
The phone reads its home from FTW Cloud over Noise IK with the service as responder. cloudwire gains the prologue, the now, watch, suspend and snapshot bodies, the close codes, and golden vectors for one whole session. appwire gains the initiator half of IK, checked against the same Cacophony vector as the responder, for the service's tests and any Go client. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A responder that admits initiators by key decides before message 2 carries anything. FTW Cloud checks the phone's key against the box's roster there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cs consent
hello_ok gains an optional `cloud` field for every role while an owner
has FTW Cloud on: the box's FTW Cloud key, the home id, the uplink's boot
id and the tables from opaque source and loadpoint ids to names. A phone
checks what the service forwards with that key, never one the service
gives it. Floor mode leaves it out.
hello_ok says cloud.link when this build names a service. Release builds
name none and stay silent.
POST /api/cloud/stats {policy} adds the stats purpose under a grant
already on (409 when off or revoking), draws a 16-byte statsId once and
keeps it, saves the grant, marks the roster due and writes the audit
line. DELETE /api/cloud/stats removes the purpose and forgets the id. No
statistics are sent yet.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
View.Accept reset the view for a new boot, and turned rule N off, before it had decoded the body and checked seq, so a signed message it then dropped could still wipe what the phone held. It now checks everything first. An unknown source state ranked as live when it was the second argument of worse; it ranks as never on either side. Found by the Swift port. Adds the doc's case 11 and a changeset for C3. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 13, 2026
frahlg
added a commit
that referenced
this pull request
Oct 13, 2026
* docs: propose FTW Cloud (ADR 0008) and its protocol ADR 0008, status proposed, records Fredrik's decisions of 12 October 2026: a readable, read-only copy of what a home's owner turns on, served to the iPhone app, its widgets and APNs from ftwcloudd in srcfl/ftw-cloud on AWS eu-north-1. The box signs every message; the service never controls and never chooses actions; the relay, escrow and lane 0 do not change. It states the statistics rules now, because consent comes at first use, orders the work core first (uplink, cache, first screen), and records the turn away from #1323 and ADR 0006's single remote path. docs/protocol-cloud.md is the normative wire format: unpadded lane 1 frames, one signing rule, a handshake bound to the TLS session, a field table per class and scope, cadence, the closed set the service may send the box, roster, extension token, push, freshness with eight vectors described in text, and the new registry names. VISION.md and AGENTS.md gain the matching paragraph and invariants; architecture.md and ADR 0006 point to the ADR. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(cloud): close freshness gaps found in review An independent review found ways stale data could still show as live. - hb now names the newest live and lp it covers (liveSeq, lpSeq) and carries each source's reading age, so the phone grades a reading by the box's own ladder instead of keeping it live for another S. - The box sends no hb while a changed live or lp waits, nor past the byte budget, so an hb never vouches for values the box has not sent. - The phone keys its table by boot, tracks seq per class, takes the earlier of wallMs and arrival under rule N, adds a drift margin and a 24 h lifetime under rule U, and shows old alerts without buttons. - hello now carries the box's TLS exporter value too, so a proxy that ends TLS cannot hold a socket for the home; the label starts with EXPERIMENTAL as RFC 5705 asks. - Restores, roster expiry, purge receipts, tiles for phones, Live Activity tokens and what Apple sees are now stated; timers agree between the ADR and the protocol. Eight new vectors cover the cases. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(cloud): take in what C2 and C3 built The protocol was written before the code. #1595 (C2) and #1603 (C3) each list where the code had to differ. This moves those differences into the text so it stays normative. From C2: fieldSources travels only with sources; a roster at every connect; a deadband on lp's measured values; [] and null on the wire; session as a plug-in count; manual.reason as the limit reason; hello.caps as the classes sent; prices from the start of today; the service signs over the box's home id; no step-up on the grant; a restore never brings cloud.key back. From C3: /v1/app?home=<id>; message 2 as an unsigned snapshot envelope with spill-over frames; a phone's watch holds until it changes, and the service renews the box's every 50 s; close codes 4400, 4403, 4408, 4409, 4429 and 1013, with the phone's retries; session limits; hello_ok.cloud (K11); the statistics consent routes, which push nothing; case 12 shows no sources rather than stale ones; role names are not generated in go/protocol. ADR 0008: turning FTW Cloud on or off notifies owners, not every change; the protocol has sixteen cases, not eight. TestFieldsMatchTheProtocolDocument passes against this text on the C3 branch (c6301a0). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Member
Author
|
Included in #1607 (FTW Cloud C2, C3 and C4 joined), squash-merged to master. |
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.
FTW Cloud C3, Core's part: what the phone needs to read its home from FTW Cloud. Draft. Based on the C2 branch (#1595), so the diff here is C3 alone.
This is the first half of a wire pair. srcfl/ftw-cloud#5 pins
go/protocolto this branch atc6301a0b, and srcfl/ftw-app#19 replays the new vectors in Swift.What changes
The app session's wire, in
go/protocol.cloudwire/app.go: the prologueftw.cloud.v1:<home>, thenow,watch,suspendandsnapshotbodies, the close codes, andValidHome.cloudwire/testdata/cloud-app-vectors.json: one whole session, byte for byte. It has fixed keys on both ends, message 1 withnow, message 2 with a snapshot of the signed vectors, and transport messages both ways.appwire/initiator.go: the initiator half of Noise IK. It is checked against the same Cacophony vector as the responder. The service's tests and any Go client use it; Core never runs it.appwire.HandshakeState.RemoteStatic()names the initiator's key once message 1 has proved it. The service needs this to check the phone against the box's roster before message 2 carries anything.K11: FTW Cloud in hello_ok.
hello_ok.cloud = {pk, home, boot, sources, loadpoints}over its own Noise session:cloud.linkis in the caps when the build can run the uplink. Release builds have no service key, so they do not advertise it.What the grant flow needs.
POST /api/cloud/stats {policy}andDELETE /api/cloud/statsrecord and withdraw an owner's consent to statistics.statsIdis drawn once.statsmessages are sent; that is C7.GET /api/cloudshows the purposes. A viewer gets 403 on every cloud route.cloudwire.Viewfixes. The Swift port found two bugs in the reference.Acceptreset the view for a new boot, and turned rule N off, before it had decoded the body and checkedseq. A signed message that it then dropped could still wipe what the phone held. It now checks everything first.worse. It now ranks as never on either side.The roster's device
keyis the same X25519 key the phone uses as its Noise static toward the box.enroll.Authorise(noise.RemoteStatic, …)stores it, and the roster copies it unchanged. FTW Cloud admits phones by that key.Deviations from docs/protocol-cloud.md (#1589) the doc should absorb
/v1/app?home=<id>. The prologue binds it, so a wrong one fails the handshake.snapshotenvelope,{envelopes, lastSeenMs, online, more}. It is not a bare array. Envelopes that do not fit in one Noise message follow as frames, andmorecounts them.watch {hz}holds until it changes or the session closes, not for 60 s. While any phone looks, the service renews the box's watch every 50 s, inside the box's 60 s./v1/app:statsIdat once. C7 must keep it untilpurged {what: "stats"}arrives.statsPolicy, becausestatscarries its ownpolicy.go/protocolgenerates no role names, so ftw-cloud spells"owner"by hand. A follow-up could generate the registry's roles.Checks
go/protocol:go vet ./... && go test ./....go/:go test -race ./internal/cloudlink/, thengo test ./internal/api/ ./internal/appproto/ ./internal/appuplink/ ./cmd/ftw/. All pass.make protocol-boundary: 135 packages, none from the box.make cloudlink-boundary: 208 packages, none from the box but go/protocol.End to end
The run used a Core from this branch, a local
ftwclouddfrom srcfl/ftw-cloud#5, a simulated house and the app from srcfl/ftw-app#19 over the production relay. Numbers and screenshots are in srcfl/ftw-app#19.hello_ok.cloudnamed the key, home and boot.🤖 Generated with Claude Code