Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
ea6a860
Add durable local artifact storage
dr0uleau Oct 21, 2026
d9f7662
Preserve artifact scope and revision homes
dr0uleau Oct 21, 2026
db4bb1b
Verify collection upgrades across windows
dr0uleau Oct 21, 2026
0a3ed19
Sync saved artifacts and track agent receipt
dr0uleau Oct 21, 2026
1ada2a6
Preserve delivery intent and scope ownership
dr0uleau Oct 21, 2026
ad1b12d
Preserve artifact envelopes during managed publication
dr0uleau Oct 21, 2026
675cfbb
Count live control bytes once per input chunk
dr0uleau Oct 21, 2026
92d61c8
Preserve receipt deadlines across stale journal reads
dr0uleau Oct 21, 2026
b938440
Simplify confirmed artifact snapshots
dr0uleau Oct 21, 2026
968eceb
Merge simplified artifact storage
dr0uleau Oct 21, 2026
44dee9c
Refresh confirmed artifacts from one query
dr0uleau Oct 21, 2026
d836bbd
Verify artifact enqueue order at one clock tick
dr0uleau Oct 21, 2026
fac55a0
Preserve delivery and live route bounds
dr0uleau Oct 21, 2026
17dead4
Commit explicit artifact deltas
dr0uleau Oct 21, 2026
dfbe319
Sync artifacts through ordered relay reads
dr0uleau Oct 21, 2026
ef501cd
Keep sync retries and repair timing separate
dr0uleau Oct 21, 2026
fd3ff77
Keep artifact repair independent of confirmation
dr0uleau Oct 21, 2026
3a7b0d8
Keep artifact sync within existing relay paths
dr0uleau Oct 21, 2026
48e7d9a
Narrow artifact transaction scopes
dr0uleau Oct 21, 2026
513638a
Allow time for signed overflow fixtures
dr0uleau Oct 21, 2026
5ee2df4
Fix artifact sync protocol and reconnect
dr0uleau Oct 22, 2026
9fbdc61
Merge main into artifact storage
dr0uleau Oct 28, 2026
f59cb0d
Use the incremental artifact protocol
dr0uleau Oct 28, 2026
0355d15
Test failed artifact index upgrades
dr0uleau Oct 28, 2026
cf2efd7
Keep artifact import rollback coverage
dr0uleau Oct 28, 2026
e1a29e1
Merge host base and preserve both sync paths
dr0uleau Oct 28, 2026
8d3e9b6
Merge host storage test fixes
dr0uleau Oct 28, 2026
0bfc540
Keep artifact scale checks local
dr0uleau Oct 28, 2026
59bae1c
Align CI discovery with local scale checks
dr0uleau Oct 28, 2026
1f91e2a
Publish artifact commits after handle close
dr0uleau Oct 28, 2026
02c9cb7
Report unsupported incremental scope at once
dr0uleau Oct 29, 2026
030a48c
Merge main into artifact storage
dr0uleau Oct 29, 2026
8906ea5
Merge the artifact storage base updates
dr0uleau Oct 29, 2026
5c5a738
Limit channel removal batches to 100 records
dr0uleau Oct 29, 2026
d7654f6
Merge main after artifact storage lands
dr0uleau Oct 30, 2026
eb518c3
Spread long artifact sync retries over time
dr0uleau Oct 30, 2026
2ffb139
Merge main and retain incremental sync imports
dr0uleau Nov 2, 2026
3739f6d
Match the agent claim revision in source test
dr0uleau Nov 2, 2026
d99a1a3
Recover rejected saved sync checkpoints
dr0uleau Nov 2, 2026
09ee7d1
Merge main into artifact sync branch
dr0uleau Nov 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions docs/artifact-sync.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Local artifact sync

The host saves relay records through `ArtifactStorageService`. Each plugin defines one collection and one fixed query. A Web Lock covers `{viewer,relay,owner,collectionName}`. Its owner cancels reads and waits for commits before it releases the lock.

The native transport exposes `session.artifactIncremental` when the relay advertises the exact `artifacts.incremental` v1 contract. It covers permanent channels, 100-row pages, 100-ID current reads, an 8 MiB response bound, and a 30-day checkpoint lifetime. The relay prerequisite is [PR 8523](https://github.com/block/buzz/pull/8523).

The client sends `artifact: "incremental"` requests. WebSocket sync uses `artifacts.sync` and `session.artifacts.sync()` for a complete initial set followed by live changes. Each capability works independently. The saved store uses incremental reads so a restart can resume from its last checkpoint.

The first read discovers authorized records. Later reads use a checkpoint with a 120-second overlap from the last successful server start time. Only a full paged pass saves progress. Live pushes request current-ID reads through the same collection queue. They do not advance progress or directly write saved rows. The existing outbox acceptance observer also requests a current read.

The client applies signed upserts and explicit removals. A removal uses the locally observed revision for a conditional write. It retains the body and preferences, and marks the record unavailable. A failed commit prevents progress. Empty replies never establish absence.

A policy change or an expired checkpoint requires a fresh query plus bounded revalidation of saved IDs. Missing, unmatched, and unauthorized IDs return the same unavailable result. Recovery saves progress only after both steps succeed. It does not return a hidden roster.

Refresh generations, schema checks, and owner cancellation fence each commit. Failed reads keep saved progress and data. Transient failures get three short retries, then a delay of 60–90 seconds. Invalid replies and capacity failures use that delay directly. Each long retry adds a fresh random delay of less than 30 seconds to the 60-second minimum. A persistent failure exposes `refreshError()`. Successful delta completion clears it. A 60-second repair runs independently of live traffic and respects a pending retry delay. A bounded set holds up to 1,000 live IDs; overflow requests another delta.

The 120-second overlap assumes bounded database delay. It does not prove recovery from every delayed commit. TTL retirement is outside this contract. Native end-to-end verification needs the compatible relay and client together.
2 changes: 2 additions & 0 deletions src/app/services.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ArtifactStorageService } from "../features/artifact-storage/service";
import { provideArtifactStoreSync } from "../features/relay/artifact-store-sync";
import { createAdminAccess } from "../bundled/admin-access";
import { nativeRelayStaff } from "../features/relay-staff/native";
import { createLocalAgentActivity } from "../features/agents/local-activity";
Expand Down Expand Up @@ -122,6 +123,7 @@ export function createServices() {
});
const relay = communities.relay;
const artifactStorage = new ArtifactStorageService(ctx);
provideArtifactStoreSync(ctx, artifactStorage);
// Expose v2 only with the complete label/projection/frame/Destination/guard slice.
new SoloNavigationService(ctx, relay, plugins);
// The one recovery point for federated sign-in; see onSignedIn.
Expand Down
Loading
Loading