[READ-ONLY] Mirror of https://github.com/flo-bit/contrail. atproto backend in a bottle flo-bit.dev/contrail/
0

Configure Feed

Select the types of activity you want to include in your feed.

Version Packages

github-actions[bot] (Jun 7, 2026, 7:30 PM UTC) d1e1166b c2e34697

+131 -44
-36
.changeset/cold-start-and-planner-stats.md
··· 1 - --- 2 - "@atmo-dev/contrail-appview": minor 3 - "@atmo-dev/contrail-base": minor 4 - --- 5 - 6 - perf: gate schema replay on a fingerprint; add opt-in planner-stat maintenance 7 - 8 - Two independent performance fixes found while profiling a D1 consumer. 9 - 10 - **Cold-start schema replay (always on).** `initSchema` ran ~40 base/collection/ 11 - index/fts/feed/spaces DDL statements serially on every `init()` call, with no 12 - gate. Consumers call `init()` once per isolate and Workers isolates recycle 13 - constantly, so the first request to each cold isolate paid ~40 sequential 14 - round-trips to the D1 storage object before any real work. `initSchema` now 15 - records a fingerprint of the resolved schema (hash of the generated DDL + 16 - `CONTRAIL_SCHEMA_VERSION`) in a new `_contrail_meta` table and, on a match, 17 - skips all DDL after a single read. Steady-state cold start drops from ~40 18 - round-trips to one; the full apply only runs on first init or an actual schema 19 - change. Concurrent-init safety on Postgres is unchanged (the gate just wraps the 20 - existing idempotent apply). 21 - 22 - **Query-planner statistics (opt-in).** Without `ANALYZE`, SQLite's planner picks 23 - the least-selective index for multi-predicate queries (measured ~50x more rows 24 - read on a `subject.uri` + `status` filter). New opt-in config: 25 - 26 - ```ts 27 - maintenance: { optimize: true } // or { intervalMs, analysisLimit } 28 - ``` 29 - 30 - When enabled, the ingest tick runs a CPU-bounded `PRAGMA analysis_limit=400; 31 - PRAGMA optimize` on a persisted daily cadence (stored in `_contrail_meta`, so it 32 - isn't defeated by recycled isolates — the same in-memory-state bug the feed 33 - prune had). `analysis_limit` bounds the work so it can't exceed D1's per-query 34 - CPU budget and reset the DO. Also exposed as `contrail.optimize(db)` for 35 - consumers that prefer to schedule it themselves. No-op on Postgres 36 - (autovacuum/autoanalyze handles planner stats).
+45
packages/contrail-appview/CHANGELOG.md
··· 1 1 # @atmo-dev/contrail-appview 2 2 3 + ## 0.10.0 4 + 5 + ### Minor Changes 6 + 7 + - 89aee1b: perf: gate schema replay on a fingerprint; add opt-in planner-stat maintenance 8 + 9 + Two independent performance fixes found while profiling a D1 consumer. 10 + 11 + **Cold-start schema replay (always on).** `initSchema` ran ~40 base/collection/ 12 + index/fts/feed/spaces DDL statements serially on every `init()` call, with no 13 + gate. Consumers call `init()` once per isolate and Workers isolates recycle 14 + constantly, so the first request to each cold isolate paid ~40 sequential 15 + round-trips to the D1 storage object before any real work. `initSchema` now 16 + records a fingerprint of the resolved schema (hash of the generated DDL + 17 + `CONTRAIL_SCHEMA_VERSION`) in a new `_contrail_meta` table and, on a match, 18 + skips all DDL after a single read. Steady-state cold start drops from ~40 19 + round-trips to one; the full apply only runs on first init or an actual schema 20 + change. Concurrent-init safety on Postgres is unchanged (the gate just wraps the 21 + existing idempotent apply). 22 + 23 + **Query-planner statistics (opt-in).** Without `ANALYZE`, SQLite's planner picks 24 + the least-selective index for multi-predicate queries (measured ~50x more rows 25 + read on a `subject.uri` + `status` filter). New opt-in config: 26 + 27 + ```ts 28 + maintenance: { 29 + optimize: true; 30 + } // or { intervalMs, analysisLimit } 31 + ``` 32 + 33 + When enabled, the ingest tick runs a CPU-bounded `PRAGMA analysis_limit=400; 34 + PRAGMA optimize` on a persisted daily cadence (stored in `_contrail_meta`, so it 35 + isn't defeated by recycled isolates — the same in-memory-state bug the feed 36 + prune had). `analysis_limit` bounds the work so it can't exceed D1's per-query 37 + CPU budget and reset the DO. Also exposed as `contrail.optimize(db)` for 38 + consumers that prefer to schedule it themselves. No-op on Postgres 39 + (autovacuum/autoanalyze handles planner stats). 40 + 41 + ### Patch Changes 42 + 43 + - Updated dependencies [89aee1b] 44 + - @atmo-dev/contrail-base@0.10.0 45 + - @atmo-dev/contrail-authority@0.10.0 46 + - @atmo-dev/contrail-record-host@0.10.0 47 + 3 48 ## 0.9.1 4 49 5 50 ### Patch Changes
+1 -1
packages/contrail-appview/package.json
··· 1 1 { 2 2 "name": "@atmo-dev/contrail-appview", 3 - "version": "0.9.1", 3 + "version": "0.10.0", 4 4 "description": "Public-records appview for contrail — jetstream ingestion, backfill, query layer, feeds, labels, profiles, per-collection XRPC routes.", 5 5 "type": "module", 6 6 "sideEffects": false,
+7
packages/contrail-authority/CHANGELOG.md
··· 1 1 # @atmo-dev/contrail-authority 2 2 3 + ## 0.10.0 4 + 5 + ### Patch Changes 6 + 7 + - Updated dependencies [89aee1b] 8 + - @atmo-dev/contrail-base@0.10.0 9 + 3 10 ## 0.9.1 4 11 5 12 ### Patch Changes
+1 -1
packages/contrail-authority/package.json
··· 1 1 { 2 2 "name": "@atmo-dev/contrail-authority", 3 - "version": "0.9.1", 3 + "version": "0.10.0", 4 4 "description": "Default space-authority implementation for contrail — member list, invites, app policy, credential issuance. Contrail's binary-membership ACL flavor; for ladder-style access levels see @atmo-dev/contrail-community.", 5 5 "type": "module", 6 6 "sideEffects": false,
+38
packages/contrail-base/CHANGELOG.md
··· 1 1 # @atmo-dev/contrail-base 2 2 3 + ## 0.10.0 4 + 5 + ### Minor Changes 6 + 7 + - 89aee1b: perf: gate schema replay on a fingerprint; add opt-in planner-stat maintenance 8 + 9 + Two independent performance fixes found while profiling a D1 consumer. 10 + 11 + **Cold-start schema replay (always on).** `initSchema` ran ~40 base/collection/ 12 + index/fts/feed/spaces DDL statements serially on every `init()` call, with no 13 + gate. Consumers call `init()` once per isolate and Workers isolates recycle 14 + constantly, so the first request to each cold isolate paid ~40 sequential 15 + round-trips to the D1 storage object before any real work. `initSchema` now 16 + records a fingerprint of the resolved schema (hash of the generated DDL + 17 + `CONTRAIL_SCHEMA_VERSION`) in a new `_contrail_meta` table and, on a match, 18 + skips all DDL after a single read. Steady-state cold start drops from ~40 19 + round-trips to one; the full apply only runs on first init or an actual schema 20 + change. Concurrent-init safety on Postgres is unchanged (the gate just wraps the 21 + existing idempotent apply). 22 + 23 + **Query-planner statistics (opt-in).** Without `ANALYZE`, SQLite's planner picks 24 + the least-selective index for multi-predicate queries (measured ~50x more rows 25 + read on a `subject.uri` + `status` filter). New opt-in config: 26 + 27 + ```ts 28 + maintenance: { 29 + optimize: true; 30 + } // or { intervalMs, analysisLimit } 31 + ``` 32 + 33 + When enabled, the ingest tick runs a CPU-bounded `PRAGMA analysis_limit=400; 34 + PRAGMA optimize` on a persisted daily cadence (stored in `_contrail_meta`, so it 35 + isn't defeated by recycled isolates — the same in-memory-state bug the feed 36 + prune had). `analysis_limit` bounds the work so it can't exceed D1's per-query 37 + CPU budget and reset the DO. Also exposed as `contrail.optimize(db)` for 38 + consumers that prefer to schedule it themselves. No-op on Postgres 39 + (autovacuum/autoanalyze handles planner stats). 40 + 3 41 ## 0.9.1 4 42 5 43 ### Patch Changes
+1 -1
packages/contrail-base/package.json
··· 1 1 { 2 2 "name": "@atmo-dev/contrail-base", 3 - "version": "0.9.1", 3 + "version": "0.10.0", 4 4 "description": "Shared infrastructure for the contrail family of packages — interfaces (SpaceAuthority, RecordHost, CommunityIntegration), credential primitives, binding resolvers, realtime infra, schema scaffolding. No routes, no tables of its own.", 5 5 "type": "module", 6 6 "sideEffects": false,
+8
packages/contrail-community/CHANGELOG.md
··· 1 1 # @atmo-dev/contrail-community 2 2 3 + ## 0.10.0 4 + 5 + ### Patch Changes 6 + 7 + - Updated dependencies [89aee1b] 8 + - @atmo-dev/contrail-base@0.10.0 9 + - @atmo-dev/contrail@0.10.0 10 + 3 11 ## 0.9.1 4 12 5 13 ### Patch Changes
+1 -1
packages/contrail-community/package.json
··· 1 1 { 2 2 "name": "@atmo-dev/contrail-community", 3 - "version": "0.9.1", 3 + "version": "0.10.0", 4 4 "description": "Community module for contrail — community-owned spaces with tiered access levels (member → moderator → admin), invite tokens, DID provisioning, and the access-level reconciler that keeps spaces_members in sync.", 5 5 "type": "module", 6 6 "sideEffects": false,
+7
packages/contrail-record-host/CHANGELOG.md
··· 1 1 # @atmo-dev/contrail-record-host 2 2 3 + ## 0.10.0 4 + 5 + ### Patch Changes 6 + 7 + - Updated dependencies [89aee1b] 8 + - @atmo-dev/contrail-base@0.10.0 9 + 3 10 ## 0.9.1 4 11 5 12 ### Patch Changes
+1 -1
packages/contrail-record-host/package.json
··· 1 1 { 2 2 "name": "@atmo-dev/contrail-record-host", 3 - "version": "0.9.1", 3 + "version": "0.10.0", 4 4 "description": "Default record-host implementation for contrail — stores records and blobs for permissioned spaces, enforces local enrollment as the host's consent layer.", 5 5 "type": "module", 6 6 "sideEffects": false,
+10
packages/contrail/CHANGELOG.md
··· 1 1 # @atmo-dev/contrail 2 2 3 + ## 0.10.0 4 + 5 + ### Patch Changes 6 + 7 + - Updated dependencies [89aee1b] 8 + - @atmo-dev/contrail-appview@0.10.0 9 + - @atmo-dev/contrail-base@0.10.0 10 + - @atmo-dev/contrail-authority@0.10.0 11 + - @atmo-dev/contrail-record-host@0.10.0 12 + 3 13 ## 0.9.1 4 14 5 15 ### Patch Changes
+1 -1
packages/contrail/package.json
··· 1 1 { 2 2 "name": "@atmo-dev/contrail", 3 - "version": "0.9.1", 3 + "version": "0.10.0", 4 4 "description": "Index AT Protocol records with typed XRPC endpoints. Cloudflare Workers + D1, SvelteKit, Node.js.", 5 5 "type": "module", 6 6 "sideEffects": false,
+6
packages/lexicons/CHANGELOG.md
··· 1 1 # @atmo-dev/contrail-lexicons 2 2 3 + ## 0.4.11 4 + 5 + ### Patch Changes 6 + 7 + - @atmo-dev/contrail@0.10.0 8 + 3 9 ## 0.4.10 4 10 5 11 ### Patch Changes
+1 -1
packages/lexicons/package.json
··· 1 1 { 2 2 "name": "@atmo-dev/contrail-lexicons", 3 - "version": "0.4.10", 3 + "version": "0.4.11", 4 4 "description": "Generate atproto lexicon JSON (and optionally TypeScript types via @atcute/lex-cli) from a Contrail config.", 5 5 "type": "module", 6 6 "files": [
+2
packages/sync/CHANGELOG.md
··· 1 1 # @atmo-dev/contrail-sync 2 2 3 + ## 0.10.0 4 + 3 5 ## 0.9.1 4 6 5 7 ## 0.9.0
+1 -1
packages/sync/package.json
··· 1 1 { 2 2 "name": "@atmo-dev/contrail-sync", 3 - "version": "0.9.1", 3 + "version": "0.10.0", 4 4 "description": "Client-side reactive watch-store over contrail's watchRecords endpoints. SSE + WebSocket transports, optimistic updates, optional IndexedDB cache.", 5 5 "type": "module", 6 6 "sideEffects": false,