From f7809ebebb9dfb404e6dfde9e1fe618686215b05 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Fri, 6 Nov 2026 01:57:26 -0500 Subject: [PATCH] Drop agent-process narration from api docs and tests Rewrite the README's Jetstream section and jetstream.ts's subscribeUrl comment to state the v2 endpoint shape as fact instead of narrating the deviation from the draft spec and how it was verified. Delete test comments in backfill.test.ts and model.test.ts that only restate the fixture or assertion next to them. --- packages/api/README.md | 35 +++++++++-------------------- packages/api/src/index/jetstream.ts | 14 +++++------- packages/api/tests/backfill.test.ts | 2 -- packages/api/tests/model.test.ts | 12 +++------- 4 files changed, 19 insertions(+), 44 deletions(-) diff --git a/packages/api/README.md b/packages/api/README.md index 112818d..b075c03 100644 --- a/packages/api/README.md +++ b/packages/api/README.md @@ -81,26 +81,17 @@ Jetstream's words, delivery is at-least-once, so replaying the same create or th twice leaves the index unchanged — because the whole index can be thrown away and rebuilt from the network at any time. -### Deviation from the draft spec: Jetstream's live API has moved - -The draft spec (`api-spec.md`) assumed Jetstream's legacy `/subscribe` endpoint -(`wantedCollections=...&cursor=`). Reading the current docs -(bsky.network/docs/jetstream, 2026-11-06) instead of relying on memory, as the task asked, found -a v2 API: `wss:///xrpc/network.bsky.jetstream.subscribeEvents`, with a repeated -`collections` param (confirmed live, documented as supporting an -`app.bsky.feed.*`-style NSID-prefix wildcard, so `run.nibling.*` would also work), `kinds`, and a -`cursor` that takes either a `seq` or a `time_us`, told apart by magnitude. The index stores a -`time_us`, since that also gives the cursor's age; a live probe on 2026-11-06 with a `time_us` -two minutes old replayed from two minutes back. `src/index/jetstream.ts` targets the verified v2 shape; `wrangler.jsonc`'s -`JETSTREAM_URL` points at `wss://jetstream.us-east.bsky.network` accordingly. A live, read-only -connection to that URL with this worker's exact query string opened cleanly and returned zero -`run.nibling.*` commits in an 8-second window, which is expected: nibling.run has no real users -yet. - -`com.atproto.sync.listReposByCollection` itself matched the spec and current docs exactly -(`collection`, `limit`, `cursor` in; `{ repos: [{did}], cursor }` out); a live, read-only request -against `relay1.us-east.bsky.network` for `run.nibling.project` returned `{"repos":[]}`, as -expected for a collection nobody writes to yet. +### Jetstream v2 + +Jetstream's live API is `wss:///xrpc/network.bsky.jetstream.subscribeEvents`, with a +repeated `collections` param (an `app.bsky.feed.*`-style NSID-prefix wildcard works, so +`run.nibling.*` does too), `kinds`, and a `cursor` that takes either a `seq` or a `time_us`, told +apart by magnitude. The index stores a `time_us`, since that also gives the cursor's age. +`src/index/jetstream.ts` targets this v2 shape; `wrangler.jsonc`'s `JETSTREAM_URL` points at +`wss://jetstream.us-east.bsky.network` accordingly. + +`com.atproto.sync.listReposByCollection` takes `collection`, `limit`, `cursor` and returns +`{ repos: [{did}], cursor }`. ## Local dev @@ -121,8 +112,4 @@ The Jetstream parser and ingest tests run on frames captured from the live v2 en writes `run.nibling.*` yet, the `run.nibling.*` fixtures keep a captured envelope and change only `collection` and `record`. -A smoke run of `wrangler dev --local` confirmed `GET /oauth/client-metadata.json` (200, the exact -D19 scope string) and `GET /xrpc/run.nibling.actor.getKnown?dids=did:plc:test` (200, -`{"dids":[]}`, with CORS and cache headers) both serve correctly end to end. - This worker is never deployed from a development session: no `wrangler deploy`, ever. diff --git a/packages/api/src/index/jetstream.ts b/packages/api/src/index/jetstream.ts index da33641..e9f51ce 100644 --- a/packages/api/src/index/jetstream.ts +++ b/packages/api/src/index/jetstream.ts @@ -10,15 +10,11 @@ function isIndexCollection(value: string): value is IndexCollection { } /** - * Builds the live-tail subscribe URL. - * - * Deviation from the api-spec draft: the spec assumed Jetstream's legacy `/subscribe` endpoint - * (`wantedCollections=...&cursor=`). The current docs (bsky.network/docs/jetstream, - * read 2026-11-06) describe a v2 API at `/xrpc/network.bsky.jetstream.subscribeEvents` with - * repeated `collections` params, `kinds`, and a `cursor` that's either a `seq` or a `time_us`, - * told apart by magnitude. The index passes a `time_us` (see ingest.ts). `collections` does document NSID-prefix wildcards - * ("an `app.bsky.feed.*`-style namespace wildcard"), so `run.nibling.*` would also work, but - * since there are only four collections to ask for, this lists them explicitly instead. + * Jetstream v2 is `/xrpc/network.bsky.jetstream.subscribeEvents` with repeated `collections` + * params, `kinds`, and a `cursor` that's either a `seq` or a `time_us`, told apart by magnitude. + * The index passes a `time_us` (see ingest.ts). `collections` supports NSID-prefix wildcards + * (an `app.bsky.feed.*`-style namespace wildcard), so `run.nibling.*` would also work, but since + * there are only four collections to ask for, this lists them explicitly instead. */ export function subscribeUrl(baseUrl: string, cursor?: string): string { const url = new URL('/xrpc/network.bsky.jetstream.subscribeEvents', baseUrl); diff --git a/packages/api/tests/backfill.test.ts b/packages/api/tests/backfill.test.ts index ae0e0b1..82de17b 100644 --- a/packages/api/tests/backfill.test.ts +++ b/packages/api/tests/backfill.test.ts @@ -40,7 +40,6 @@ test('backfillCollection pages listReposByCollection and listRecords, and valida value: { $type: 'run.nibling.project', name: 'Alice Project', files: [], createdAt: '2026-11-01T00:00:00.000Z' }, }, { - // fails validation (no `name`): dropped, not thrown uri: 'at://did:plc:alice/run.nibling.project/3la2', cid: 'bafy2', value: { $type: 'run.nibling.project', files: [], createdAt: '2026-11-01T00:00:00.000Z' }, @@ -48,7 +47,6 @@ test('backfillCollection pages listReposByCollection and listRecords, and valida ], }); } - // bob's PDS is unreachable throw new Error('network down'); } diff --git a/packages/api/tests/model.test.ts b/packages/api/tests/model.test.ts index be1c2f3..059b074 100644 --- a/packages/api/tests/model.test.ts +++ b/packages/api/tests/model.test.ts @@ -127,8 +127,8 @@ test('delete removes the project from recent', () => { test('a like on a not-yet-indexed project still counts once the project appears', () => { const model = new IndexModel(sqliteSql()); - model.apply(fixtureEvents()[1]!); // like1, subject = project1, before project1 is indexed - model.apply(fixtureEvents()[0]!); // project1 now appears + model.apply(fixtureEvents()[1]!); + model.apply(fixtureEvents()[0]!); const { projects } = model.recent(); assert.equal(projects[0]!.likeCount, 1); @@ -149,13 +149,7 @@ test('known returns exactly the DIDs with a project or profile record', () => { const model = new IndexModel(sqliteSql()); for (const event of fixtureEvents()) model.apply(event); - const known = model.known([ - 'did:plc:alice', // has a project - 'did:plc:bob', // only has a like - 'did:plc:dave', // has a project - 'did:plc:erin', // only has a profile - 'did:plc:frank', // has nothing - ]); + const known = model.known(['did:plc:alice', 'did:plc:bob', 'did:plc:dave', 'did:plc:erin', 'did:plc:frank']); assert.deepStrictEqual(known, ['did:plc:alice', 'did:plc:dave', 'did:plc:erin']); }); -- knotmirror 0.0.1