···11----
22-"@atmo-dev/contrail-appview": minor
33-"@atmo-dev/contrail-base": minor
44----
55-66-perf: gate schema replay on a fingerprint; add opt-in planner-stat maintenance
77-88-Two independent performance fixes found while profiling a D1 consumer.
99-1010-**Cold-start schema replay (always on).** `initSchema` ran ~40 base/collection/
1111-index/fts/feed/spaces DDL statements serially on every `init()` call, with no
1212-gate. Consumers call `init()` once per isolate and Workers isolates recycle
1313-constantly, so the first request to each cold isolate paid ~40 sequential
1414-round-trips to the D1 storage object before any real work. `initSchema` now
1515-records a fingerprint of the resolved schema (hash of the generated DDL +
1616-`CONTRAIL_SCHEMA_VERSION`) in a new `_contrail_meta` table and, on a match,
1717-skips all DDL after a single read. Steady-state cold start drops from ~40
1818-round-trips to one; the full apply only runs on first init or an actual schema
1919-change. Concurrent-init safety on Postgres is unchanged (the gate just wraps the
2020-existing idempotent apply).
2121-2222-**Query-planner statistics (opt-in).** Without `ANALYZE`, SQLite's planner picks
2323-the least-selective index for multi-predicate queries (measured ~50x more rows
2424-read on a `subject.uri` + `status` filter). New opt-in config:
2525-2626-```ts
2727-maintenance: { optimize: true } // or { intervalMs, analysisLimit }
2828-```
2929-3030-When enabled, the ingest tick runs a CPU-bounded `PRAGMA analysis_limit=400;
3131-PRAGMA optimize` on a persisted daily cadence (stored in `_contrail_meta`, so it
3232-isn't defeated by recycled isolates — the same in-memory-state bug the feed
3333-prune had). `analysis_limit` bounds the work so it can't exceed D1's per-query
3434-CPU budget and reset the DO. Also exposed as `contrail.optimize(db)` for
3535-consumers that prefer to schedule it themselves. No-op on Postgres
3636-(autovacuum/autoanalyze handles planner stats).
+45
packages/contrail-appview/CHANGELOG.md
···11# @atmo-dev/contrail-appview
2233+## 0.10.0
44+55+### Minor Changes
66+77+- 89aee1b: perf: gate schema replay on a fingerprint; add opt-in planner-stat maintenance
88+99+ Two independent performance fixes found while profiling a D1 consumer.
1010+1111+ **Cold-start schema replay (always on).** `initSchema` ran ~40 base/collection/
1212+ index/fts/feed/spaces DDL statements serially on every `init()` call, with no
1313+ gate. Consumers call `init()` once per isolate and Workers isolates recycle
1414+ constantly, so the first request to each cold isolate paid ~40 sequential
1515+ round-trips to the D1 storage object before any real work. `initSchema` now
1616+ records a fingerprint of the resolved schema (hash of the generated DDL +
1717+ `CONTRAIL_SCHEMA_VERSION`) in a new `_contrail_meta` table and, on a match,
1818+ skips all DDL after a single read. Steady-state cold start drops from ~40
1919+ round-trips to one; the full apply only runs on first init or an actual schema
2020+ change. Concurrent-init safety on Postgres is unchanged (the gate just wraps the
2121+ existing idempotent apply).
2222+2323+ **Query-planner statistics (opt-in).** Without `ANALYZE`, SQLite's planner picks
2424+ the least-selective index for multi-predicate queries (measured ~50x more rows
2525+ read on a `subject.uri` + `status` filter). New opt-in config:
2626+2727+ ```ts
2828+ maintenance: {
2929+ optimize: true;
3030+ } // or { intervalMs, analysisLimit }
3131+ ```
3232+3333+ When enabled, the ingest tick runs a CPU-bounded `PRAGMA analysis_limit=400;
3434+PRAGMA optimize` on a persisted daily cadence (stored in `_contrail_meta`, so it
3535+ isn't defeated by recycled isolates — the same in-memory-state bug the feed
3636+ prune had). `analysis_limit` bounds the work so it can't exceed D1's per-query
3737+ CPU budget and reset the DO. Also exposed as `contrail.optimize(db)` for
3838+ consumers that prefer to schedule it themselves. No-op on Postgres
3939+ (autovacuum/autoanalyze handles planner stats).
4040+4141+### Patch Changes
4242+4343+- Updated dependencies [89aee1b]
4444+ - @atmo-dev/contrail-base@0.10.0
4545+ - @atmo-dev/contrail-authority@0.10.0
4646+ - @atmo-dev/contrail-record-host@0.10.0
4747+348## 0.9.1
449550### Patch Changes
···11# @atmo-dev/contrail-base
2233+## 0.10.0
44+55+### Minor Changes
66+77+- 89aee1b: perf: gate schema replay on a fingerprint; add opt-in planner-stat maintenance
88+99+ Two independent performance fixes found while profiling a D1 consumer.
1010+1111+ **Cold-start schema replay (always on).** `initSchema` ran ~40 base/collection/
1212+ index/fts/feed/spaces DDL statements serially on every `init()` call, with no
1313+ gate. Consumers call `init()` once per isolate and Workers isolates recycle
1414+ constantly, so the first request to each cold isolate paid ~40 sequential
1515+ round-trips to the D1 storage object before any real work. `initSchema` now
1616+ records a fingerprint of the resolved schema (hash of the generated DDL +
1717+ `CONTRAIL_SCHEMA_VERSION`) in a new `_contrail_meta` table and, on a match,
1818+ skips all DDL after a single read. Steady-state cold start drops from ~40
1919+ round-trips to one; the full apply only runs on first init or an actual schema
2020+ change. Concurrent-init safety on Postgres is unchanged (the gate just wraps the
2121+ existing idempotent apply).
2222+2323+ **Query-planner statistics (opt-in).** Without `ANALYZE`, SQLite's planner picks
2424+ the least-selective index for multi-predicate queries (measured ~50x more rows
2525+ read on a `subject.uri` + `status` filter). New opt-in config:
2626+2727+ ```ts
2828+ maintenance: {
2929+ optimize: true;
3030+ } // or { intervalMs, analysisLimit }
3131+ ```
3232+3333+ When enabled, the ingest tick runs a CPU-bounded `PRAGMA analysis_limit=400;
3434+PRAGMA optimize` on a persisted daily cadence (stored in `_contrail_meta`, so it
3535+ isn't defeated by recycled isolates — the same in-memory-state bug the feed
3636+ prune had). `analysis_limit` bounds the work so it can't exceed D1's per-query
3737+ CPU budget and reset the DO. Also exposed as `contrail.optimize(db)` for
3838+ consumers that prefer to schedule it themselves. No-op on Postgres
3939+ (autovacuum/autoanalyze handles planner stats).
4040+341## 0.9.1
442543### Patch Changes
+1-1
packages/contrail-base/package.json
···11{
22 "name": "@atmo-dev/contrail-base",
33- "version": "0.9.1",
33+ "version": "0.10.0",
44 "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.",
55 "type": "module",
66 "sideEffects": false,