Skip to content

feat(aggregator): scaffold plugin-registry aggregator#971

Merged
ascorbic merged 9 commits into
mainfrom
feat/aggregator-scaffold
May 9, 2026
Merged

feat(aggregator): scaffold plugin-registry aggregator#971
ascorbic merged 9 commits into
mainfrom
feat/aggregator-scaffold

Conversation

@ascorbic
Copy link
Copy Markdown
Collaborator

@ascorbic ascorbic commented May 9, 2026

What does this PR do?

Lands the foundational scaffold for an experimental plugin-registry aggregator. This is Slice 1, sub-PRs 1a + 1b — no business logic yet, but every subsequent PR (Records DO, Records Consumer, read endpoints, reconciliation) builds on this foundation.

Structured as four commits to keep the review surface small:

  1. feat(plugin-marketplace-test): add default export for registry-cli bundler — one-line fix; the bundler resolves descriptors via default export, the test plugin only had a named export. Same convention as forms and color.
  2. feat(aggregator): scaffold plugin-registry aggregator (Slice 1 PR 1a) — the apps/aggregator Wrangler project, full D1 schema migration, worker entrypoint stubs, Cloudflare Vite plugin for dev/build, vitest-pool-workers for tests, smoke tests proving migrations apply + FTS5 trigger fires + FK rejects orphan releases.
  3. feat(atproto-test-utils): real-crypto MockPds + mocks (Slice 1 PR 1b) — new shared test fixture package: real-crypto FakeRepo built on @atproto/repo, MockPds (multi-tenant, serves CAR via sync.getRecord exactly as a real PDS does), MockJetstream (driveable, replay on reconnect with cursor), MockDidResolver, createFakePublisherFixture. The load-bearing claim: a record signed by FakeRepo, fetched as a CAR, and fed into @atcute/repo's verifyRecord round-trips cleanly. 11 tests cover signature mismatch rejection, exclusion proofs, JSON listRecords shape, jetstream filtering + replay, and DID resolution.
  4. chore: align @vitest/browser-playwright + @vitest/ui with vitest 4.1.5@cloudflare/vitest-pool-workers@0.16 requires vitest 4.1+. Bumping vitest in the catalog left two related packages out of sync; this aligns them. Also fixes one admin test (MediaPickerModal) where playwright 4.1's tightened strict-mode role inference made /Upload/ match both the button and a hidden file input — anchored to /^Upload$/.

Subsequent slices land sequentially:

  • PR 2: Records Jetstream DO (WebSocket + cursor persistence + reconnect/backoff)
  • PR 3: Records Queue Consumer (PDS-verified ingest via @atcute/repo's verifyRecord)
  • PR 4: Constellation cold-start backfill + 6h reconciliation Cron
  • PR 5: Five XRPC read endpoints with Sessions API first-primary on label-dependent paths
  • PR 6: Wire CLI's EMDASH_REGISTRY_URL at the deployed aggregator

Closes #

Type of change

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes
  • pnpm lint passes (no new warnings introduced)
  • pnpm test passes (4500+ tests across the workspace)
  • pnpm format has been run
  • I have added/updated tests for my changes (smoke tests for the schema; 11-test round-trip suite for the mock infrastructure)
  • User-visible strings in the admin UI are wrapped for translation — N/A (no admin UI changes)
  • I have added a changeset — N/A (no published-package changes; apps/aggregator and packages/atproto-test-utils are private)
  • New features link to an approved Discussion — opening this PR as the umbrella for review of the aggregator architecture before further slices land

AI-generated code disclosure

  • This PR includes AI-generated code — model/tool: Claude Opus 4.7 (1M context)

Test output

@emdash-cms/atproto-test-utils  Test Files  1 passed (1)    Tests  11 passed   (11)
@emdash-cms/aggregator          Test Files  1 passed (1)    Tests   3 passed    (3)
@emdash-cms/admin               Test Files 62 passed (62)   Tests 863 passed  (863)
@emdash-cms/core                Test Files 203 passed (203) Tests 3193 passed (3193)
@emdash-cms/registry-cli        Test Files  6 passed  (6)   Tests  83 passed   (83)
@emdash-cms/cloudflare          Test Files  8 passed  (8)   Tests 157 passed  (157)
[... all 18 packages green ...]

Notes for review

The biggest design decision baked in here is D1 + read replicas (vs DO SQLite). DO SQLite was tempting for simplicity, but the aggregator's workload is asymmetric — one region writes via cron + Jetstream, reads come from everywhere — which is what D1's read-replication model is built for. With Sessions API first-primary on label-dependent reads, takedowns propagate immediately while non-label-dependent reads (none today, but reserved for future use) can land on the nearest replica.

The other notable choice is @atproto/repo (Bluesky's reference) as a test-only dependency in @emdash-cms/atproto-test-utils. The production aggregator still uses @atcute/repo for verification (lighter, Workers-friendly). The test fixture wants the canonical reference implementation so any divergence between our mocks and a real PDS is the test's problem, not the mock's. Verified by the round-trip test that signs with @atproto/repo and verifies with @atcute/repo.

ascorbic added 4 commits May 9, 2026 11:44
…ndler

The registry-cli bundler resolves the plugin descriptor by looking for a
default export (function or pre-resolved descriptor) or a named
`createPlugin` export. The named-only `marketplaceTestPlugin` export wasn't
discoverable, so `emdash-registry bundle --dir packages/plugins/marketplace-test`
failed with INVALID_PLUGIN_FORMAT.

Add `export default marketplaceTestPlugin` to match the convention used by
other plugins (e.g. `forms`, `color`).
Lands the apps/aggregator project skeleton plus the shared
@emdash-cms/atproto-test-utils package skeleton. No business logic yet —
this PR establishes the structure so subsequent PRs each touch one
component.

apps/aggregator
- Wrangler config: D1, Records Queue (+ DLQ), Records DO, 6h reconciliation
  Cron, vars (JETSTREAM_URL, CONSTELLATION_URL, WANTED_COLLECTIONS).
- Cloudflare Vite plugin for dev/build (`vite dev` / `vite build`),
  `wrangler deploy` after build for ship.
- Initial D1 migration `0001_init.sql` lands every v1 table at once
  (packages, releases + FK + idx, release_duplicate_attempts,
  mirrored_artifacts, labels, label_state + partial enforce idx,
  labellers, packages_fts + triggers, ingest_state, known_publishers).
  Slices 2 and 3 read these tables but don't add new ones, so this is
  the only DDL we expect to ship before NSID stabilisation.
- Worker entrypoint exports RecordsJetstreamDO + a no-op default with
  fetch/queue/scheduled stubs; subsequent PRs fill them in.
- Test rig uses @cloudflare/vitest-pool-workers v0.16's cloudflareTest()
  plugin. Migrations are read at config time and piped into the worker
  isolate via the TEST_MIGRATIONS binding; tests apply them in beforeAll.
  Smoke test proves migrations apply, INSERT round-trips, FTS5 trigger
  fires, and the FK rejects orphan releases.

packages/atproto-test-utils (skeleton)
- Private workspace package consumed by both registry-cli (later) and
  apps/aggregator. PR 1b lands the real-crypto MockPds + MockJetstream
  + MockDidResolver + createFakePublisher helper.

Workspace
- apps/* added to pnpm-workspace.yaml.
- Catalog entries added for @atcute/{car,cbor,cid,crypto,firehose,
  jetstream,mst,repo,xrpc-server,xrpc-server-cloudflare},
  @cloudflare/{vite-plugin,vitest-pool-workers}, vite.
- vitest bumped to ^4.1.5 — required by vitest-pool-workers v0.16.
Lands the in-memory atproto fixtures so the aggregator's verification path
exercises the same code in tests as in production.

The load-bearing claim: a record signed by a FakeRepo, fetched via
MockPds.handle as a sync.getRecord CAR, and fed into @atcute/repo's
verifyRecord round-trips cleanly. Mocks that skip signing would let
verification regressions slip through; this rules that out.

Components:
- FakeRepo wraps @atproto/repo's Repo + MemoryBlockstore for one DID. Real
  P-256 keypair, real signed commits, real MST construction. getRecordCar
  uses @atproto/repo's getRecords provider (same path the cirrus PDS
  reference uses).
- MockPds is multi-tenant (mounts many FakeRepos), implements
  FetchHandlerObject for @atcute/client, and serves both publish-side
  endpoints (applyWrites, putRecord, repo.getRecord) and aggregator-side
  endpoints (sync.getRecord-as-CAR with application/vnd.ipld.car,
  listRecords). Response shapes mirror cirrus.
- MockJetstream is a driveable async iterable; tests emit commit events,
  subscribers receive filtered events, history replays on reconnect with
  cursor.
- MockDidResolver maps DIDs to DID documents with the publisher's signing
  multikey + PDS endpoint.
- createFakePublisherFixture wires all four together: createPublisher
  registers a new keypair-backed repo with the PDS and resolver in one call.

Tests (11): record round-trips for profile + release records, signature
mismatch rejection, exclusion-proof CAR for missing records, JSON
listRecords shape, Jetstream filtering + history replay, DID resolution
with PDS endpoint extraction.

Workspace: adds @atproto/repo + @atproto/crypto to catalog as test-only
deps. Production aggregator still uses @atcute/repo for verification — the
heavyweight @atproto package is private to the test fixture package.
PR 1a bumped vitest in the catalog from 4.0.18 to 4.1.5 because
`@cloudflare/vitest-pool-workers@0.16` requires it. The two related
packages had separate version pins outside the catalog and stayed at
4.0.x, producing "Running mixed versions is not supported" warnings
on every admin/core test run.

Bump both to 4.1.5 to match.

The bump to @vitest/browser-playwright 4.1.5 also tightens playwright's
strict-mode role inference: <input type="file" aria-label="Upload file">
is now treated as having an accessible name that matches a `/Upload/`
regex, which collides with the actual Upload button in
MediaPickerModal. Anchor the test's regex (`/^Upload$/`) so it only
matches the button's exact accessible name.
Copilot AI review requested due to automatic review settings May 9, 2026 12:24
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 9, 2026

⚠️ No Changeset found

Latest commit: db26582

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 9, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
emdash-i18n db26582 May 09 2026, 01:34 PM

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 9, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
emdash-perf-coordinator db26582 May 09 2026, 01:33 PM

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 9, 2026

PR template validation failed

Please fix the following issues by editing your PR description:

See CONTRIBUTING.md for the full contribution policy.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 9, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
docs db26582 May 09 2026, 01:34 PM

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 9, 2026

Scope check

This PR changes 3,981 lines across 28 files. Large PRs are harder to review and more likely to be closed without review.

If this scope is intentional, no action needed. A maintainer will review it. If not, please consider splitting this into smaller PRs.

See CONTRIBUTING.md for contribution guidelines.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 9, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
emdash-playground db26582 May 09 2026, 01:35 PM

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 9, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
emdash-demo-cache db26582 May 09 2026, 01:35 PM

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 9, 2026

Open in StackBlitz

@emdash-cms/admin

npm i https://pkg.pr.new/@emdash-cms/admin@971

@emdash-cms/auth

npm i https://pkg.pr.new/@emdash-cms/auth@971

@emdash-cms/blocks

npm i https://pkg.pr.new/@emdash-cms/blocks@971

@emdash-cms/cloudflare

npm i https://pkg.pr.new/@emdash-cms/cloudflare@971

emdash

npm i https://pkg.pr.new/emdash@971

create-emdash

npm i https://pkg.pr.new/create-emdash@971

@emdash-cms/gutenberg-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/gutenberg-to-portable-text@971

@emdash-cms/x402

npm i https://pkg.pr.new/@emdash-cms/x402@971

@emdash-cms/plugin-ai-moderation

npm i https://pkg.pr.new/@emdash-cms/plugin-ai-moderation@971

@emdash-cms/plugin-atproto

npm i https://pkg.pr.new/@emdash-cms/plugin-atproto@971

@emdash-cms/plugin-audit-log

npm i https://pkg.pr.new/@emdash-cms/plugin-audit-log@971

@emdash-cms/plugin-color

npm i https://pkg.pr.new/@emdash-cms/plugin-color@971

@emdash-cms/plugin-embeds

npm i https://pkg.pr.new/@emdash-cms/plugin-embeds@971

@emdash-cms/plugin-forms

npm i https://pkg.pr.new/@emdash-cms/plugin-forms@971

@emdash-cms/plugin-webhook-notifier

npm i https://pkg.pr.new/@emdash-cms/plugin-webhook-notifier@971

commit: db26582

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 9, 2026

Overlapping PRs

This PR modifies files that are also changed by other open PRs:

This may cause merge conflicts or duplicated work. A maintainer will coordinate.

@github-actions github-actions Bot mentioned this pull request May 9, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR lays the groundwork for the upcoming plugin-registry “aggregator” Worker by adding a new apps/aggregator project (Wrangler + D1 schema + workers-pool smoke tests), introducing a shared @emdash-cms/atproto-test-utils package for real-crypto atproto fixtures, and aligning Vitest-related dependencies needed for @cloudflare/vitest-pool-workers.

Changes:

  • Add apps/aggregator scaffold: Wrangler config, initial D1 migration (tables + FTS), Worker/DO entry stubs, and workers-pool smoke tests.
  • Add packages/atproto-test-utils: FakeRepo + MockPds/MockJetstream/MockDidResolver + round-trip verification tests.
  • Workspace/dependency wiring updates: include apps/* in pnpm workspace, add catalog entries, fix marketplace-test default export, and bump Vitest UI / browser-playwright versions.

Reviewed changes

Copilot reviewed 26 out of 28 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
pnpm-workspace.yaml Include apps/* in the workspace and add catalog entries (atproto/atcute + Cloudflare workers test tooling + Vite/Vitest).
packages/plugins/marketplace-test/src/index.ts Add a default export so descriptor bundling can resolve the plugin consistently.
packages/core/package.json Align @vitest/ui with the newer Vitest version used by the workspace.
packages/atproto-test-utils/package.json New private test-utils package definition and dependencies.
packages/atproto-test-utils/tsconfig.json New TS config for the test-utils package.
packages/atproto-test-utils/vitest.config.ts New Vitest config for the test-utils package.
packages/atproto-test-utils/src/index.ts Public exports for the atproto test utilities.
packages/atproto-test-utils/src/types.ts Shared atproto DID type re-export.
packages/atproto-test-utils/src/fake-repo.ts In-memory repo wrapper built on @atproto/repo for generating signed CAR proofs.
packages/atproto-test-utils/src/mock-pds.ts Multi-tenant in-memory PDS mock implementing XRPC endpoints and CAR responses.
packages/atproto-test-utils/src/mock-jetstream.ts Driveable Jetstream async-iterable mock with replay/cursor support.
packages/atproto-test-utils/src/mock-did-resolver.ts In-memory DID document resolver with PDS + signing-key helpers.
packages/atproto-test-utils/src/fake-publisher.ts High-level fixture wiring FakeRepo + MockPds + MockDidResolver + MockJetstream.
packages/atproto-test-utils/tests/round-trip.test.ts Round-trip tests proving CARs signed by FakeRepo verify via @atcute/repo.
packages/admin/package.json Align @vitest/browser-playwright version with Vitest 4.1.x.
packages/admin/tests/components/MediaPickerModal.test.tsx Anchor the “Upload” locator to avoid strict-mode ambiguity.
apps/aggregator/package.json New aggregator app package scripts and dependencies/devDependencies.
apps/aggregator/tsconfig.json New TS config for the aggregator app.
apps/aggregator/vite.config.ts Cloudflare Vite plugin config for dev/build.
apps/aggregator/vitest.config.ts Workers-pool Vitest config that reads and exposes D1 migrations to tests.
apps/aggregator/wrangler.jsonc Wrangler config (D1, Queue, DO, cron trigger, env vars) for the aggregator worker.
apps/aggregator/migrations/0001_init.sql Initial D1 schema: packages/releases, labels, mirror tracking, FTS, ingest state.
apps/aggregator/src/env.ts Env binding types + Records queue job shape (DI seam).
apps/aggregator/src/index.ts Worker entrypoint stub for fetch/queue/scheduled handlers and DO export.
apps/aggregator/src/records-do.ts Skeleton Durable Object class for Jetstream connection (to be implemented later).
apps/aggregator/test/env.d.ts Type references for @cloudflare/vitest-pool-workers test environment.
apps/aggregator/test/smoke.test.ts Smoke tests proving migrations apply + FTS trigger works + FK enforcement rejects orphans.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/atproto-test-utils/tsconfig.json
Comment thread apps/aggregator/tsconfig.json
Comment thread packages/atproto-test-utils/src/fake-repo.ts
Comment thread packages/atproto-test-utils/src/mock-pds.ts Outdated
ascorbic added 2 commits May 9, 2026 13:57
- Bump catalog wrangler from ^4.80.0 to ^4.83.0. @cloudflare/vite-plugin
  (pulled in transitively via @astrojs/cloudflare) requires this; the
  outdated catalog version broke demos/cloudflare typecheck and the
  Cloudflare-template smoke tests on CI. infra/cache-demo had already
  pinned ^4.83.0, so this brings the catalog in line with the highest
  in-tree pin.

- Drop redundant `| undefined` from FakeRepo.getRecordValue's return type;
  `unknown` already includes undefined (typescript-eslint:no-redundant-type-constituents).

- Replace deep import `@atproto/repo/dist/sync/provider.js` with the
  package's public `getRecords` export. Same function, no exports-map
  brittleness on upgrade. (Per Copilot review.)

- Validate did:plc:/did:web: prefix in MockPds parseDid instead of
  accepting any did:* and casting. Matches the AtprotoDid type's runtime
  guarantee — invalid methods (e.g. did:key:) now reject at the boundary
  instead of slipping through tests. (Per Copilot review.)

- Drop rootDir from apps/aggregator and packages/atproto-test-utils
  tsconfigs; both `include` test directories that sit outside `./src`,
  which trips TS6059 in some tooling. Without rootDir, TS infers from
  include and tests live cleanly alongside source. (Per Copilot review.)
Six bugs/gaps found in adversarial review of the mock infrastructure.
Each fix lands with a regression test so the same bug can't slip back.

1. MockJetstream cursor was off-by-one. The replay filter used
   `event.time_us < cursor`, which redelivered the cursor event itself.
   Real Jetstream treats the cursor as "last seen, don't redeliver" —
   replay must be strict-after. Fixed to `<=` and added a test that emits
   two events, subscribes with cursor = first event's time_us, and
   asserts only the second is delivered.

2. MockJetstreamSubscription.cursor returned the global last event time,
   not the per-subscriber position. A subscriber that had consumed only
   event 3 of 10 read sub.cursor → time of event 10; reconnecting with
   that value would silently lose events 4-9. Now tracks
   lastDeliveredTimeUs per subscriber and exposes it through the cursor
   getter. Added a test that emits two events, consumes one, and asserts
   sub.cursor reflects the consumed event.

3. MockJetstreamSubscription.next() now throws when called concurrently
   from two consumers (previous behaviour silently orphaned the first
   resolver). Concurrent next() is legal for AsyncIterator; this mock
   doesn't support it, so failing loudly beats hanging.

4. MockPds dispatched on URL pathname only, ignoring HTTP method —
   `GET applyWrites` returned 200. Now switches on `(method, pathname)`
   and returns 405 MethodNotAllowed for known endpoints used with the
   wrong verb. Added a test asserting GET on applyWrites returns 405.

5. MockPds.repoApplyWrites only handled #create. PR 3's tests will need
   update + delete flows to model profile updates and tombstoning. Added
   FakeRepo.updateRecord + deleteRecord that drive @atproto/repo's
   applyWrites with the right WriteOpAction, and dispatched on $type in
   MockPds. Added a round-trip test that publishes a profile, updates
   its license, then deletes it.

6. FakePublisher.publishProfile defaulted authors to [] and let security
   end up empty if neither securityEmail nor securityUrl was passed —
   both fields require minLength: 1 in the lexicon. Now throws when no
   security contact is provided, and defaults authors to a single entry
   derived from the publisher's handle. Added two tests: one asserts the
   throw, the other asserts the default authors entry uses the handle.

Also reverted a misguided `cursor: undefined` addition to listRecords —
JSON.stringify drops undefined keys, which IS the cirrus end-of-stream
shape (the `cursor` field is optional). The reviewer's concern there was
misread; updated the comment to spell out the contract.
@ascorbic ascorbic changed the title feat(aggregator): scaffold plugin-registry aggregator (Slice 1 PR 1) feat(aggregator): scaffold plugin-registry aggregator May 9, 2026
ascorbic added 3 commits May 9, 2026 14:18
A literal placeholder ID makes wrangler think the binding is already
configured and skip provisioning on first deploy, then fail when trying
to use a non-existent database. Omit the field entirely so auto-provision
fires.
Per the project's CLAUDE.md and wrangler's own guidance, the Env type
should come from `worker-configuration.d.ts` (generated by
`wrangler types`) rather than being maintained by hand. The hand-rolled
shape would drift from the actual bindings any time wrangler.jsonc
changed.

- Add `worker-configuration.d.ts` (generated, committed alongside the
  similar files in packages/marketplace, infra/perf-monitor, the
  cloudflare templates, etc.).
- Drop the manual `Env` interface from src/env.ts; keep only the
  project-specific `RecordsJob` type.
- Drop `@cloudflare/workers-types` from devDependencies + tsconfig
  `types` array. Wrangler now ships the runtime types in the generated
  d.ts; the workers-types package is superseded.
- Drop `test/env.d.ts` — its single triple-slash for vitest-pool-workers
  is now covered by the tsconfig's `types` entry.
- Update records-do.ts and index.ts to consume the global `Env`.

Re-run `wrangler types` after editing wrangler.jsonc to keep the
generated file in sync.
…R refs

WANTED_COLLECTIONS is part of the protocol contract, not a per-deployment
tunable. Move to apps/aggregator/src/constants.ts where the type system
can keep it honest, and drop it from wrangler.jsonc `vars`. Production,
staging, dev, and self-hosted instances all subscribe to the same NSIDs.

Also strip slice/PR scaffolding language from comments — those refs
mean nothing to anyone reading the code outside the immediate dev
context. Replace with descriptions of what the placeholder will become
(e.g. "PDS-verified ingest will land here") rather than which sub-PR
will land it.

Regenerated worker-configuration.d.ts after the wrangler.jsonc change.
@ascorbic ascorbic merged commit 908787a into main May 9, 2026
35 of 36 checks passed
@ascorbic ascorbic deleted the feat/aggregator-scaffold branch May 9, 2026 13:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants