Repository navigation
feat: hold 48 hours of history tiles and answer tiles.get (C6) - #48
Merged
Merged
Conversation
A box with ftw.history.read in its grant sends tiles. The service checks
each against the protocol's three shapes and keeps it in memory as the
box signed it: five closed tiles and 16 pieces of the filling tile per
home, 256 MiB in all, each until 48 hours after it ends, box online or
not. hello_ok.have names the closed tiles held. A phone that may read
history asks with tiles.get {have}, gets what it lacks and tiles.end,
and gets each new tile as it comes. A revoke, a grant without history,
a purge or the 90-day expiry deletes them.
Pins go/protocol at srcfl/ftw 7dedcbf4 (feat/cloud-c6-tiles).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
So an end-to-end run can check what a real box sent. 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. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 59c9410677
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
This was referenced Oct 23, 2026
An assistant reads history from the box only, never from FTW Cloud's copy, so every read stays one the box audits and a revoke stops. While the box is away, history_query now says so, with when FTW Cloud last heard from it, instead of only that it is offline. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…by net change At the bound of 16 pieces the store dropped the oldest, which is the whole piece the appends lay on, so a phone could no longer rebuild the tile. It now refuses the extra append and keeps what lays back together; the box's next whole piece carries it. The memory cap counted a tile's full size before what it replaces, so near the cap it refused a whole piece or a closed tile that would have freed bytes. It counts the net change now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- An envelope over 4 KiB is dropped, Check takes only the four series
(go/protocol pinned at srcfl/ftw b10a6939), and a home holds at most
64 KiB of tiles, so padded tiles from a few boxes cannot fill memory
for every home.
- A closed tile is replaced only by one the box sent later, by wallMs
then seq; a piece sent before the newest held piece is dropped.
- Tiles go when the roster runs out: no phone can read them then, and a
revoke made while the box was away cannot arrive.
- The service sends resync {what: [tiles]}, at most once per 5 minutes,
when a roster gives history back or room frees after a drop.
- Tests: an agent gets no tiles, the ordering, the home's share, roster
expiry, an oversized envelope, and the resync.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Step C6 of ADR 0008: the service keeps each home's last 48 hours of 5-minute history tiles and serves them to the home's phones, also while the box is away.
Paired with srcfl/ftw#1817 (wire format and box) and srcfl/ftw-app#98 (the app).
go.modpinsgo/protocolat srcfl/ftwb10a6939on that branch. Move the pin to its merge commit before this merges.What changes
Uplink: a signed
tilesmessage is checked against the protocol's three shapes (cloudwire.Tiles.Check) and held as the box signed it.box_tile_of_no_shape); the uplink goes on.hello_ok.havenow names the closed tiles held, so a box that comes back sends only what is missing.Store: tiles live in memory only, apart from the newest-of-each-class map.
ftw.history.read.DropCopy, a purge or the 90-day expiry deletes them.App session:
tiles.get {have}gets each closed tile the phone lacks at its etag, oldest first, then the pieces in the order the box sent them, thentiles.end {n}.ftw.history.readgetstiles.end {n: 0}./v1/app/onceand/v1/nowcarry no tiles.Dev route:
/dev/held(ftwclouddev builds only) lists the tiles a home holds.README: a section on tiles, and C6 leaves "Not built yet".
MCP:
history_querystill reads from the box only. The protocol says an agent never reads the readable copy, so every agent read is one the box audits and a revoke stops. While the box is away, the tool now says so plainly, for example: "The box is away. FTW Cloud last heard from it at 2026-10-23T14:25:31Z, 12 minutes ago. Its history is read from the box only, so ask again when it is back." It used to say only that the box is offline. The README says so too.Open question for the owner: should
history_queryanswer from these tiles while the box is away? That would change the rule that an agent never reads the copy, and the box would not see the read in its audit. It is not built.Tests
go vet ./...,go test -race -count=1 ./...,go test -tags ftwclouddev ./...andscripts/check-imports.shall pass.FuzzBoxMessageran for 20 s.internal/store, unit tests:internal/uplink, with srcfl/ftw's signed vectors over a real TLS uplink:havenames the closed tile at reconnect;internal/mcp: with the box away,history_querysays so and gives the time FTW Cloud last heard from it;agoWords.internal/appsession, over a real Noise session:tiles.getreturns the vectors byte for byte;have, only the pieces come back;tiles.endmatches its vector.ftwcloudd. At connect the box sent the filling tile whole and the four closed tiles of the last 48 hours. They were empty, since that box's ledger was new. At 14:25:30 UTC it sent a one-point append for 14:20–14:25 with the measured values. A small checker read what the service held from/dev/held. Every tile verified with the box key and passedCheck, andLayrebuilt the filling tile through 14:25. Nothing touched the home box, the FTW Cloud host or AWS.After review
Bytes are bounded:
box_tile_too_large);Checktakes only the four series;tile_home_full).So padded, validly signed tiles from a few boxes cannot fill the 256 MiB for every home.
A closed tile is replaced only by one the box sent later, by
wallMsand thenseq. A piece sent before the newest held piece is dropped (tile_older_than_held).Sweepdrops a home's tiles once its roster runs out. No phone can read them then, and a revoke made while the box was away cannot arrive.The service sends
resync {what: [tiles]}, at most once per 5 minutes, when a roster gives history back during a connection, and when room frees after a tile was dropped for lack of it.New tests:
go vet,go test -race ./..., theftwclouddevrun and the import check pass;FuzzBoxMessageran 15 s.🤖 Generated with Claude Code