Skip to main content

max / makenotwork

server: fix public legal/developer docs - sse.md: rewrite SyncKit SSE example to the real synckit-client API (subscribe()/next_change()->Option<()>, struct-literal PullFilter, pull_filtered(device_id, cursor, filter)); drop false auto-reconnect claim - license-keys.md: reframe offline verify as a time-boxed HS256 grace credential; the client cannot verify the signature locally (secret not distributed) - transparency.md: switch existence claims to future tense, add pre-launch status banner - copyright.md: replace residential DMCA agent address with the registered agent (Northwest, 1500 N Grant St Ste N, Denver CO 80203) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-06-13 23:06 UTC
Commit: ca2e08a693d050b3c779e322ebeb117f94b56824
Parent: 7752f4f
4 files changed, +29 insertions, -22 deletions
@@ -111,7 +111,9 @@ Response:
111 111
112 112 ## License Verification (Offline Grace Period)
113 113
114 - For apps that need to work offline, use the verification endpoint. It validates and activates the key, then returns a signed JWT token valid for 7 days. Your app can verify this token locally without contacting the server.
114 + For apps that need to work offline, use the verification endpoint. It validates and activates the key, then returns a signed JWT token valid for 7 days. The token acts as a time-boxed offline grace credential: your app caches it and honors it until the `exp` claim passes, without contacting the server in between.
115 +
116 + The token is signed with HS256, a symmetric scheme keyed on the server's secret. That secret is never distributed, so your app cannot cryptographically verify the signature locally — genuine signature verification happens server-side on the next re-verify. Treat the cached token as a trusted receipt of a recent successful verification (read its `exp` to know when to re-verify), not as something you can independently authenticate offline. As with any client-side licensing, offline enforcement is a soft grace window, not a tamper-proof gate.
115 117
116 118 This endpoint requires the project to have license verification enabled (configured by the creator in project settings).
117 119
@@ -157,7 +159,7 @@ The token contains:
157 159
158 160 1. Call `/api/v1/license/verify` on app launch (when online)
159 161 2. Cache the returned JWT locally
160 - 3. On subsequent launches, verify the JWT signature and `exp` claim locally
162 + 3. On subsequent offline launches, read the `exp` claim and honor the license until it passes (the signature is not locally verifiable — see above)
161 163 4. Re-verify with the server when the token nears expiry or when connectivity returns
162 164
163 165 ### Deactivation via Verify API
@@ -43,34 +43,36 @@ This is a standard SSE comment and is ignored by conforming clients.
43 43
44 44 ### With the Rust SDK
45 45
46 - The `synckit-client` crate provides `SyncNotifyStream` for SSE integration:
46 + The `synckit-client` crate provides `SyncNotifyStream` for SSE integration. `SyncKitClient::subscribe` opens the connection; `next_change()` yields `Some(())` for each `changed` event and `None` when the stream ends:
47 47
48 48 ```rust
49 - let stream = client.subscribe_notifications().await?;
49 + let mut stream = client.subscribe().await?;
50 50
51 51 // In your sync loop:
52 - while let Some(notification) = stream.next().await {
53 - match notification {
54 - SyncNotification::Changed => {
55 - client.pull().await?;
56 - }
57 - SyncNotification::Keepalive => {}
58 - }
52 + while stream.next_change().await.is_some() {
53 + // The server signaled new changes — pull them.
54 + let (changes, new_cursor, _has_more) = client.pull(device_id, cursor).await?;
55 + cursor = new_cursor;
59 56 }
57 + // next_change() returned None: the stream ended. Reconnect (typically after a
58 + // short delay), refreshing the token first if it has expired.
60 59 ```
61 60
62 - The SDK handles reconnection, keepalive parsing, and token refresh automatically.
61 + Keepalive comments are parsed and ignored for you. The stream does **not** auto-reconnect: when `next_change()` returns `None`, the caller reconnects.
63 62
64 63 ### Selective Sync
65 64
66 65 Combine SSE notifications with `PullFilter` to pull only specific tables or time ranges:
67 66
68 67 ```rust
69 - let filter = PullFilter::new()
70 - .table("tasks")
71 - .since(last_sync_time);
72 -
73 - let changes = client.pull_filtered(filter).await?;
68 + let filter = PullFilter {
69 + tables: Some(vec!["tasks".into()]),
70 + since: Some(last_sync_time),
71 + ..Default::default()
72 + };
73 +
74 + let (changes, new_cursor, has_more) =
75 + client.pull_filtered(device_id, cursor, filter).await?;
74 76 ```
75 77
76 78 This reduces bandwidth and processing when your app only needs a subset of changes.
@@ -24,9 +24,10 @@ DMCA takedown notices should be sent to:
24 24
25 25 **Mail:**
26 26 Make Creative, LLC
27 + c/o Northwest Registered Agent LLC
27 28 ATTN: DMCA Agent
28 - 2055 Main St, Apt 502
29 - Irvine, CA 92614
29 + 1500 N Grant St, Ste N
30 + Denver, CO 80203
30 31
31 32 ---
32 33
@@ -1,12 +1,14 @@
1 1 # Transparency Reports
2 2
3 - What we publish about moderation and legal requests.
3 + What we will publish about moderation and legal requests.
4 +
5 + > **Status: pre-launch.** No transparency reports have been published yet. The first report will appear once moderation volume is high enough to anonymize effectively (see [Pre-Launch Note](#pre-launch-note)). This page describes the program we are committing to, not reports that already exist.
4 6
5 7 ---
6 8
7 9 ## Our Commitment
8 10
9 - We publish regular transparency reports so you can verify that our enforcement matches our stated policies:
11 + We will publish regular transparency reports so you can verify that our enforcement matches our stated policies:
10 12
11 13 - Content moderation actions
12 14 - Account enforcement
@@ -57,7 +59,7 @@ Reports are published as blog posts and archived in this documentation.
57 59
58 60 ## Publication Schedule
59 61
60 - Reports are published quarterly, within 30 days of quarter end:
62 + Once reporting begins, reports will be published quarterly, within 30 days of quarter end:
61 63
62 64 - Q1 (Jan-Mar): Published by April 30
63 65 - Q2 (Apr-Jun): Published by July 31