// Task 5 of the fleet-api plan: the spec's central promise proved end to end // — a fleet box holding NO bucket credentials converges entirely through the // store door (spec 2026-08-11-fleet-api-surface-design.md, F1-F8; issue #73). // // The box's whole view of the platform's deployment bucket is a // fleetapi.New(...) client pointed at a REAL edge: real TunnelHub auth // (registry-backed, the same table detach/rotate converge), the real // fleet→account snapshot Reload builds, the real ACL, a DirStore behind it. // No box-side code path in this file ever touches that DirStore — every // platform-side use of it below is the OTHER role (the console/CLI writing // the bucket, or the assertion reading back what a box wrote through the // door). // // It sits beside fleet_e2e_test.go rather than inside it because the two // prove different things about the same fleet and want different worlds: // TestTwoBoxFleetEndToEnd drives the ROUTING failure sequence (channels, // leases, takeover, dark fleet) and its edge deliberately has no static // store — no door at all. This one drives the STORE loop (adopt, serial, // provision, heartbeat, bindings, logs) and needs EnableStatic wired. What // they do share is shared: e2eHashToken, startFleetBox, namedFleetHandler, // waitChannel, e2eGet and waitBody all come from that file, so the edge/hub // arrangement has exactly one source of truth per concern. // // Hermetic and fast: loopback httptest edge, real h2 reverse channels via // the production tunnelclient.Loop, real ed25519 release signing. package edge_test import ( "context" "crypto/ed25519" "encoding/json" "errors" "net/http/httptest" "net/url" "os" "path/filepath" "runtime" "slices" "strings" "testing" "time" "github.com/carlosframework/platform/internal/applog" "github.com/carlosframework/platform/internal/domains" "github.com/carlosframework/platform/internal/edge" "github.com/carlosframework/platform/internal/fleetapi" "github.com/carlosframework/platform/internal/host" "github.com/carlosframework/platform/internal/provision" "github.com/carlosframework/platform/internal/registry" "github.com/carlosframework/platform/internal/release" "github.com/carlosframework/platform/internal/status" ) const ( fapiFleet = "orchard" fapiBoxA = "box-a" fapiBoxB = "box-b" fapiTokenA = "orchard-token-a" fapiTokenB = "orchard-token-b" fapiApp = "shop" fapiDomain = "orchard.example" fapiHost = "acme." + fapiDomain fapiRegion = "ie" fapiChannel = "canary/e2e" // canary/* has no bake window: the pass applies at once fapiVersion = "v1" // The two account identities. Both are real sqids (domains.Sqid of an id), // never literals: provision.knownAccounts refuses any account manifest // whose path sqid, body sqid and Sqid(body.ID) do not all agree, so a // hardcoded string would quietly stop being an account the moment the // frozen encoding changed — and this test's whole provisioning leg would // then pass for the wrong reason (nothing known, nothing minted). fapiAcctID int64 = 7 fapiOtherID int64 = 8 fapiOtherApp = "intruder" ) // fapiPlatform is the artifact key a box of THIS machine's shape adopts — // release's own adoptPlatform, which is unexported. var fapiPlatform = runtime.GOOS + "-" + runtime.GOARCH // fleetDoorWorld is one platform + one fleet: the edge and its bucket on one // side, two fleet boxes whose only bucket access is the door on the other. type fleetDoorWorld struct { reg *registry.Registry // the PLATFORM's registry: fleet rows, box credentials, fleet-placed routes store *release.DirStore // the platform's deployment bucket — edge-side and console-side handle srvURL string hub *edge.TunnelHub priv ed25519.PrivateKey pub ed25519.PublicKey sqid string // the fleet's owning account other string // a second tenant on the same bucket, which the fleet must never see boxA release.Store boxB release.Store } // newFleetDoorWorld stands the world up and returns it with both boxes' // channels connected — the same credential that dials the tunnel is the one // their store clients authenticate with, which is F1/F2 stated as a fixture. func newFleetDoorWorld(t *testing.T) *fleetDoorWorld { t.Helper() w := &fleetDoorWorld{ sqid: domains.Sqid(fapiAcctID), other: domains.Sqid(fapiOtherID), } // Not closed at cleanup, for the reason fleet_e2e_test.go gives: Edge.Watch // may still be mid-poll when the test returns. reg, err := registry.Open(filepath.Join(t.TempDir(), "registry.db")) if err != nil { t.Fatalf("open registry: %v", err) } w.reg = reg if err := reg.UpsertFleet(registry.Fleet{Name: fapiFleet, Account: w.sqid, Bucket: "orchard-data"}); err != nil { t.Fatalf("UpsertFleet: %v", err) } for label, tok := range map[string]string{fapiBoxA: fapiTokenA, fapiBoxB: fapiTokenB} { if err := reg.AddFleetBox(registry.FleetBox{ Fleet: fapiFleet, Label: label, TokenHash: e2eHashToken(tok), Status: "active", }); err != nil { t.Fatalf("AddFleetBox(%s): %v", label, err) } } w.store = release.NewDirStore(t.TempDir()) seedB64, pubB64, err := release.GenerateKey() if err != nil { t.Fatalf("GenerateKey: %v", err) } if w.priv, err = release.ParseSigningKey(seedB64, "test"); err != nil { t.Fatalf("ParseSigningKey: %v", err) } if w.pub, err = release.ParsePublicKey(pubB64, "test"); err != nil { t.Fatalf("ParsePublicKey: %v", err) } e, err := edge.New(reg, nil) if err != nil { t.Fatalf("edge.New: %v", err) } srv := httptest.NewServer(e) t.Cleanup(srv.Close) w.srvURL = srv.URL u, err := url.Parse(srv.URL) if err != nil { t.Fatal(err) } // EnableStatic is what hands the door its store handle — the edge's OWN, // never a second client, and the door is only reachable on the hub's // reserved hostname (here the listener's own, as in production // CARLOS_TUNNEL_HOST). w.hub = edge.NewTunnelHub(u.Hostname(), nil) e.EnableStatic(w.store, w.pub, filepath.Join(t.TempDir(), "cache")) e.EnableTunnels(w.hub) if err := e.Reload(); err != nil { t.Fatalf("Reload: %v", err) } stopWatch := make(chan struct{}) t.Cleanup(func() { close(stopWatch) }) go e.Watch(stopWatch) stopA := startFleetBox(t, srv.URL, fapiFleet+"/"+fapiBoxA, fapiTokenA, namedFleetHandler(fapiBoxA)) t.Cleanup(stopA) stopB := startFleetBox(t, srv.URL, fapiFleet+"/"+fapiBoxB, fapiTokenB, namedFleetHandler(fapiBoxB)) t.Cleanup(stopB) waitChannel(t, w.hub, fapiFleet+"/"+fapiBoxA, "connected", e2eDialBound) waitChannel(t, w.hub, fapiFleet+"/"+fapiBoxB, "connected", e2eDialBound) // The boxes' deployment stores. srv.URL is the door's base exactly as // CARLOS_TUNNEL_URL is in production, and the name is the box's own // channel identity — no AWS config, no bucket name, no credentials. w.boxA = fapiStore(t, srv.URL, fapiBoxA, fapiTokenA) w.boxB = fapiStore(t, srv.URL, fapiBoxB, fapiTokenB) return w } func fapiStore(t *testing.T, base, label, token string) release.Store { t.Helper() s, err := fleetapi.New(base, fapiFleet+"/"+label, token) if err != nil { t.Fatalf("fleetapi.New(%s): %v", label, err) } return s } // put is a platform-side (console/CLI-shaped) write straight to the bucket: // create-only, the same shape every real writer of these keys uses. func (w *fleetDoorWorld) put(t *testing.T, key, body string) { t.Helper() if _, err := w.store.Put(context.Background(), key, []byte(body), ""); err != nil { t.Fatalf("seed %s: %v", key, err) } } // accountManifest is domains' account record at the key provision reads — // accounts//account.json, one level deep (never accounts/.json). func fapiAccountManifest(id int64, sqid, name string) string { b, _ := json.Marshal(map[string]any{ "id": id, "sqid": sqid, "name": name, "created_at": "2026-08-11T09:00:00Z", }) return string(b) } // TestFleetBoxConvergesWithoutBucketCredentials is Task 5's acceptance // evidence. The legs run in sequence against ONE world, each depending on // what the last left behind (a record becomes a route, the route adopts a // release, the box heartbeats about it, its binding lands in routing) — a // failure means the loop stopped there and nothing after it is meaningful. func TestFleetBoxConvergesWithoutBucketCredentials(t *testing.T) { ctx := context.Background() w := newFleetDoorWorld(t) // A second tenant on the same bucket, planted BEFORE anything else so // every listing below runs against a store that really does hold another // account's keys — the negative leg (f) is only meaningful if the data it // says is invisible is genuinely there. w.put(t, "accounts/"+w.other+"/account.json", fapiAccountManifest(fapiOtherID, w.other, "Intruder")) otherChannelKey := "apps/" + w.other + "/" + fapiOtherApp + "/channels/stable.json" w.put(t, otherChannelKey, `{"app":"intruder","version":"v9"}`) otherLogKey, err := applog.ChunkKey(w.other, fapiOtherApp, fapiBoxA, applog.HourOf(time.Now()), 1, 9) if err != nil { t.Fatal(err) } w.put(t, otherLogKey, "not yours") w.put(t, "fleets/other/status/boxes/box-a.json", `{"label":"box-a"}`) // --- (a) the 2s convergence poll: control/serial, read-only -------------- // The one shared platform key a box polls every 2 seconds. It must read, // and it must never be writable — a box that could bump the serial could // make every other box in the deployment run a full pass set on demand. w.put(t, release.SerialKey, "41") serial, _, err := w.boxA.Get(ctx, release.SerialKey) if err != nil || string(serial) != "41" { t.Fatalf("(a) serial through the door = %q, %v; want \"41\"", serial, err) } _, etag, err := w.store.Get(ctx, release.SerialKey) if err != nil { t.Fatalf("(a) read serial etag: %v", err) } if _, err := w.store.Put(ctx, release.SerialKey, []byte("42"), etag); err != nil { t.Fatalf("(a) console bump: %v", err) } if serial, _, err = w.boxA.Get(ctx, release.SerialKey); err != nil || string(serial) != "42" { t.Fatalf("(a) serial after the console bump = %q, %v; want \"42\" — the poll would never see a deploy", serial, err) } if _, err := w.boxA.Put(ctx, release.SerialKey, []byte("999"), ""); err == nil { t.Fatal("(a) a fleet box bumped control/serial through the door") } t.Log("(a) control/serial reads through the door and refuses the box's write") // --- (b) provisioning: an instance record becomes a local route ---------- // The account-scoped LISTING path end to end: knownAccounts lists // accounts/ (a shared prefix, filtered per tenant), the record scan lists // apps/ (scope-mapped to this account's subtree), and the pass mints. w.put(t, "accounts/"+w.sqid+"/account.json", fapiAccountManifest(fapiAcctID, w.sqid, "Orchard")) if err := provision.PutManifest(ctx, w.store, w.sqid, fapiApp, provision.Manifest{ Schema: 1, App: fapiApp, Domain: fapiDomain, Regions: []string{fapiRegion}, Seed: []string{"serve"}, }); err != nil { t.Fatalf("(b) PutManifest: %v", err) } if err := provision.CreateRecord(ctx, w.store, provision.Record{ Schema: 1, Host: fapiHost, Slug: "acme", App: fapiApp, Account: w.sqid, Region: fapiRegion, Channel: fapiChannel, CreatedAt: time.Now(), }); err != nil { t.Fatalf("(b) CreateRecord: %v", err) } // The other tenant's record, in THIS box's region and pool: the only thing // keeping it off this box is the door's account scope. if err := provision.CreateRecord(ctx, w.store, provision.Record{ Schema: 1, Host: "evil." + fapiDomain, Slug: "evil", App: fapiOtherApp, Account: w.other, Region: fapiRegion, Channel: "stable", CreatedAt: time.Now(), }); err != nil { t.Fatalf("(b) CreateRecord (other tenant): %v", err) } // The box's OWN registry — a fleet box has one, separate from the // platform's, and this pass is what puts routes in it. boxReg, err := registry.Open(filepath.Join(t.TempDir(), "box-registry.db")) if err != nil { t.Fatalf("(b) open box registry: %v", err) } dataDir := t.TempDir() if err := provision.Reconcile(ctx, w.boxA, boxReg, provision.ReconcileConfig{ Region: fapiRegion, DataDir: dataDir, }); err != nil { t.Fatalf("(b) provision.Reconcile through the door: %v", err) } minted, err := boxReg.Get(fapiHost) if err != nil || minted == nil { t.Fatalf("(b) route %s = %+v, %v — the record never became a route", fapiHost, minted, err) } if minted.App != fapiApp || minted.Account != w.sqid || minted.Channel != fapiChannel || !minted.Provisioned || minted.Seed != `["serve"]` { t.Fatalf("(b) minted route = %+v, want the record's app/account/channel, Provisioned and the manifest seed", minted) } if rt, err := boxReg.Get("evil." + fapiDomain); err != nil || rt != nil { t.Fatalf("(b) the other tenant's record minted a route on this box: %+v, %v", rt, err) } t.Log("(b) provision.Reconcile minted the fleet's own instance route and could not see the other tenant's") // --- (c) release adoption: pointer, artifact, staging -------------------- // The whole adoption pass over the door: the signed channel pointer is // fetched and verified, the manifest read, the artifact BODY streamed // through the edge (F8 — no presigned redirect), and the version staged // and stamped on the route. artifact := make([]byte, 64<<10) for i := range artifact { artifact[i] = byte(i * 7) } if err := release.Ship(ctx, w.store, w.sqid, release.Manifest{ App: fapiApp, Version: fapiVersion, Kind: "binary", Artifacts: map[string]release.Artifact{fapiPlatform: {}}, }, map[string][]byte{fapiPlatform: artifact}); err != nil { t.Fatalf("(c) Ship: %v", err) } if err := release.Promote(ctx, w.store, w.priv, w.sqid, fapiApp, fapiChannel, fapiVersion); err != nil { t.Fatalf("(c) Promote: %v", err) } optDir := t.TempDir() var restarted []string restart := func(h string) error { restarted = append(restarted, h); return nil } if err := release.Pass(ctx, boxReg, w.boxA, w.pub, optDir, restart); err != nil { t.Fatalf("(c) release.Pass through the door: %v", err) } if v, err := release.LiveVersion(optDir, fapiHost); v != fapiVersion { t.Fatalf("(c) live version = %q (%v), want %q — adoption did not converge through the door", v, err, fapiVersion) } staged, err := os.ReadFile(release.VersionPath(optDir, w.sqid, fapiVersion, fapiApp)) if err != nil || !slices.Equal(staged, artifact) { t.Fatalf("(c) staged artifact = %d bytes (%v), want the shipped %d — a truncated body would pass a shorter check", len(staged), err, len(artifact)) } adopted, err := boxReg.Get(fapiHost) if err != nil || adopted == nil || adopted.Version != fapiVersion { t.Fatalf("(c) route version = %+v, %v; want %q stamped", adopted, err, fapiVersion) } t.Logf("(c) adoption converged: pointer verified, %d artifact bytes streamed and staged (restarted %v)", len(artifact), restarted) // --- (d) the heartbeat, under the Task-4 default prefix ------------------ // A door-backed box gets CARLOS_STATUS_PREFIX defaulted to // fleets// (spec F5) precisely because the shared status/ root is // outside the door's write ACL. The two lines statusLoop runs, with that // rebase and the agent's label override: prefixed := release.NewPrefixStore(w.boxA, "fleets/"+fapiFleet+"/") routes, err := boxReg.List() if err != nil { t.Fatalf("(d) list box routes: %v", err) } box := status.CollectBox(routes, status.Probes{MachineID: "orchard-a", Region: "IE"}, time.Now()) box.Label = fapiBoxA // statusTick's labelOverride: the fleet label, not a machine-id hash if err := status.WriteBox(ctx, prefixed, box); err != nil { t.Fatalf("(d) status.WriteBox through the door: %v", err) } heartbeatKey := "fleets/" + fapiFleet + "/status/boxes/" + fapiBoxA + ".json" raw, _, err := w.store.Get(ctx, heartbeatKey) if err != nil { t.Fatalf("(d) heartbeat did not land at %s: %v", heartbeatKey, err) } var landed status.Box if err := json.Unmarshal(raw, &landed); err != nil { t.Fatalf("(d) heartbeat body: %v", err) } if landed.Label != fapiBoxA { t.Fatalf("(d) heartbeat label = %q, want %q", landed.Label, fapiBoxA) } // The SECOND write is the one that exercises CAS through the door: // WriteBox reads its own object's etag first (the read half of the fleet // corner, which only exists so this replace can happen) and Puts with // If-Match. A door that dropped etags would fail here, not above. if err := status.WriteBox(ctx, prefixed, box); err != nil { t.Fatalf("(d) heartbeat replace (read-etag-then-Put) through the door: %v", err) } // And a box may not heartbeat into a fleet that is not its own. if _, err := w.boxA.Put(ctx, "fleets/other/status/boxes/box-a.json", []byte("{}"), ""); err == nil { t.Fatal("(d) box-a wrote into another fleet's corner") } t.Logf("(d) heartbeat landed at %s and replaced itself under CAS", heartbeatKey) // --- (e) a fleet binding takeover, box → bucket → routing ---------------- // The platform's route for the app, placed on the fleet and currently // bound to box-b. if err := w.reg.Upsert(registry.Route{ Host: fapiHost, Kind: "instance", Status: "ready", Region: registry.PlacementTarget(fapiFleet), FleetBox: fapiBoxB, }); err != nil { t.Fatalf("(e) upsert fleet-placed route: %v", err) } // box-b's agent-startup resident pass (takeover=false), through ITS door // client — an observation, with no lease behind it. if err := host.WriteFleetBinding(ctx, w.boxB, host.FleetBinding{ Host: fapiHost, Fleet: fapiFleet, Box: fapiBoxB, BoundAt: time.Now().UnixMilli(), }, false); err != nil { t.Fatalf("(e) box-b resident binding: %v", err) } // box-a wakes the app and wins the lease (modeled in fleet_e2e_test.go; // what matters here is the WRITE): a takeover claims the binding. if err := host.WriteFleetBinding(ctx, w.boxA, host.FleetBinding{ Host: fapiHost, Fleet: fapiFleet, Box: fapiBoxA, BoundAt: time.Now().UnixMilli(), }, true); err != nil { t.Fatalf("(e) box-a takeover binding through the door: %v", err) } // The platform reads it back from its own bucket handle — the object IS // the message — and restamps routing. if err := host.ReconcileFleetBindings(ctx, w.store, w.reg); err != nil { t.Fatalf("(e) ReconcileFleetBindings: %v", err) } rt, err := w.reg.Get(fapiHost) if err != nil || rt == nil || rt.FleetBox != fapiBoxA { t.Fatalf("(e) Route.FleetBox = %+v, %v; want %q — the takeover never made it back into routing", rt, err, fapiBoxA) } // And the guard survives the round trip: box-b's next resident pass reads // the existing binding through the door and declines to steal it back. if err := host.WriteFleetBinding(ctx, w.boxB, host.FleetBinding{ Host: fapiHost, Fleet: fapiFleet, Box: fapiBoxB, BoundAt: time.Now().UnixMilli(), }, false); err != nil { t.Fatalf("(e) box-b second resident pass: %v", err) } if err := host.ReconcileFleetBindings(ctx, w.store, w.reg); err != nil { t.Fatalf("(e) ReconcileFleetBindings (after box-b's pass): %v", err) } if rt, err = w.reg.Get(fapiHost); err != nil || rt == nil || rt.FleetBox != fapiBoxA { t.Fatalf("(e) Route.FleetBox = %+v, %v; want %q — a non-takeover write stole the binding through the door", rt, err, fapiBoxA) } // End to end, from outside: the edge's 2s poll picks the restamp up and // the app is served by box-a's own channel. Record → route → release → // binding → traffic, with the box holding no bucket credential anywhere // in that chain. waitBody(t, w.srvURL, fapiHost, fapiBoxA, e2eConvergeBound) t.Log("(e) the takeover written through the door reached routing, and the bound box serves") // --- (f) the other tenant is invisible ---------------------------------- // Listings first: the easiest place to leak a neighbour, and the one // provision.Reconcile above depends on being right. appKeys, err := w.boxA.List(ctx, "apps/") if err != nil { t.Fatalf("(f) list apps/: %v", err) } for _, k := range appKeys { if !strings.HasPrefix(k, "apps/"+w.sqid+"/") { t.Fatalf("(f) list apps/ returned %q — outside this fleet's account", k) } } if len(appKeys) == 0 { t.Fatal("(f) list apps/ came back empty — the scope map is refusing the fleet's OWN estate") } acctKeys, err := w.boxA.List(ctx, "accounts/") if err != nil { t.Fatalf("(f) list accounts/: %v", err) } if !slices.Equal(acctKeys, []string{"accounts/" + w.sqid + "/account.json"}) { t.Fatalf("(f) list accounts/ = %v, want only this fleet's own account record", acctKeys) } acctDirs, err := w.boxA.ListDirs(ctx, "accounts/") if err != nil { t.Fatalf("(f) listdirs accounts/: %v", err) } if !slices.Equal(acctDirs, []string{"accounts/" + w.sqid + "/"}) { t.Fatalf("(f) listdirs accounts/ = %v, want only this fleet's own directory (one child per account exists)", acctDirs) } fleetDirs, err := w.boxA.ListDirs(ctx, "fleets/") if err != nil { t.Fatalf("(f) listdirs fleets/: %v", err) } for _, d := range fleetDirs { if !strings.HasPrefix(d, "fleets/"+fapiFleet+"/") { t.Fatalf("(f) listdirs fleets/ returned %q — another fleet's corner", d) } } // Then direct gets: every one of these keys exists in the bucket, and // every one of them is os.ErrNotExist to this box. for _, key := range []string{ "accounts/" + w.other + "/account.json", otherChannelKey, otherLogKey, "apps/" + w.other + "/" + fapiOtherApp + "/instances/evil." + fapiDomain + ".json", "fleets/other/status/boxes/box-a.json", } { if _, _, err := w.store.Get(ctx, key); err != nil { t.Fatalf("(f) fixture %s is not actually in the bucket: %v", key, err) } if _, _, err := w.boxA.Get(ctx, key); !errors.Is(err, os.ErrNotExist) { t.Fatalf("(f) GET %s through the door = %v, want os.ErrNotExist (byte-identical 404)", key, err) } } // Writes and deletes into the neighbour are refused too — including the // delete of a log chunk, which is the one write verb the account-wide logs // grant makes tempting. if _, err := w.boxA.Put(ctx, otherChannelKey, []byte(`{"version":"evil"}`), ""); err == nil { t.Fatal("(f) box-a promoted a release in another account") } if _, err := w.boxA.Put(ctx, otherLogKey, []byte("forged"), ""); err == nil { t.Fatal("(f) box-a forged a log chunk in another account") } if err := w.boxA.Delete(ctx, otherLogKey); err == nil { t.Fatal("(f) box-a deleted another account's log chunk") } if _, _, err := w.store.Get(ctx, otherChannelKey); err != nil { t.Fatalf("(f) the refused writes changed the neighbour's object anyway: %v", err) } t.Log("(f) the second tenant is invisible to this fleet: listings, gets, writes and deletes all refuse") // --- (g) log chunks: ship and prune through the door --------------------- // The Task-4 grant, exercised as logshipLoop uses it: chunks are written // UNPREFIXED under the app's own subtree (applog.Prefix — where `carlos // logs` reads them), listed back, and pruned by the same box. hour := applog.HourOf(time.Now()) chunk, err := applog.EncodeChunk([]applog.Record{{ TS: time.Now(), Box: fapiBoxA, Host: fapiHost, Stream: "stdout", Msg: "listening", Seq: 1, }}) if err != nil { t.Fatalf("(g) EncodeChunk: %v", err) } chunkKey, err := applog.ChunkKey(w.sqid, fapiApp, fapiBoxA, hour, 1, len(chunk)) if err != nil { t.Fatal(err) } if _, err := w.boxA.Put(ctx, chunkKey, chunk, ""); err != nil { t.Fatalf("(g) ship a log chunk through the door: %v", err) } landedChunk, _, err := w.store.Get(ctx, chunkKey) if err != nil { t.Fatalf("(g) chunk did not land at %s: %v", chunkKey, err) } recs, err := applog.DecodeChunk(landedChunk) if err != nil || len(recs) != 1 || recs[0].Msg != "listening" { t.Fatalf("(g) chunk round trip = %+v, %v", recs, err) } boxPrefix, err := applog.BoxPrefix(w.sqid, fapiApp, fapiBoxA) if err != nil { t.Fatal(err) } listed, err := w.boxA.List(ctx, boxPrefix) if err != nil || !slices.Contains(listed, chunkKey) { t.Fatalf("(g) list own log subtree = %v, %v; want %s", listed, err, chunkKey) } if err := w.boxA.Delete(ctx, chunkKey); err != nil { t.Fatalf("(g) prune own chunk through the door: %v", err) } if _, _, err := w.store.Get(ctx, chunkKey); !errors.Is(err, os.ErrNotExist) { t.Fatalf("(g) chunk survived its prune: %v", err) } // The grant stays segment-exact: the same account, the same app, one // segment over, is still refused. for _, key := range []string{ release.ChannelKey(w.sqid, fapiApp, fapiChannel), provision.RecordKey(w.sqid, fapiApp, fapiHost), "apps/" + w.sqid + "/" + fapiApp + "/config/production.json", } { if _, err := w.boxA.Put(ctx, key, []byte("{}"), ""); err == nil { t.Fatalf("(g) the logs grant let the box write %s", key) } } t.Log("(g) log chunks ship, list and prune through the door; neighbouring keys stay refused") } // TestFleetBoxCatchallYieldsToAnotherTenantsClaim (#215 review): the store // door withholds another account's claim BODY from a fleet box, but must // still list its NAME. An instance catch-all derives no