Skip to content

feat(insights): define storage contract and scoped reports - #1236

Open
gronxb wants to merge 72 commits into
nextfrom
codex/insights-scale
Open

feat(insights): define storage contract and scoped reports#1236
gronxb wants to merge 72 commits into
nextfrom
codex/insights-scale

Conversation

@gronxb

@gronxb gronxb commented Aug 31, 2026

Copy link
Copy Markdown
Owner

Insights now uses a fixed persistence contract with scoped operational and bundle-report views. Event history is cursor-paginated without a 50,000-event cap; providers store immutable reports and one latest row per installation instead of implementing product summaries.

Changes

  • Require five object-based methods: record, listEvents, findInstallations, countInstallations, and countEvents. Core prepares reports, filters, windows, cursors, and product responses.
  • Atomically persist event/latest-state changes. Event IDs are first-write-wins; retries and older reports cannot restore stale user or bundle state.
  • Add platform/channel/window counts and selected-bundle installed, applied, recovered-from, and adopted report counts with matching event drill-down. Recovery B → A counts against B while current state names A. Independent live counts are not presented as exact shares or success rates.
  • Keep indexed bounded pages, including sparse installation movements and native continuation under small provider page caps. DynamoDB installation counts traverse stable canonical IDs and may read all stored installation rows.
  • Scope E2E provider reset to the current job namespace and platform; preserve shared Bundle artifacts, patch bases, and unrelated Releases. Missing namespaces stop before provider I/O.
  • Add public conformance and native rollback, concurrency, Unicode identity, migration, continuation, and query-plan regression coverage.

Breaking changes and initial setup

The previous Insights method names have no aliases. This schema has not shipped, so 1.0.0 is the only initial schema. PostgreSQL, Supabase, D1, and standalone SQL include final Insights indexes and exact identity collations from initialization; Supabase includes the atomic record RPC in its initial migration. There is no 1.0.1 migration or Insights-only upgrade path.

DynamoDB writes its event-ID and outcome keys with new reports without a separate readiness marker or backfill API. Firebase uses encoded installation IDs in its initial collection and retains its existing internal adapter marker 4; the added marker-5 upgrade and copy path are removed. MongoDB initializes its final indexes directly and requires MongoDB 5+ on a replica set or sharded cluster.

Generate ORM schemas before deployment and apply emitted Prisma PostgreSQL/MySQL collation statements within the initial SQL migration. Prisma SQL Server Insights explicitly rejects before I/O because its padded string equality and ordering do not meet this contract. Its other models remain available.

Specification: accepted Insights contract, custom-provider guide.

Validation

Current commit: 8a0a38417a3dea976ce1c0ef06bbde1847eb864b adds --no-daemon and Kotlin in-process to the E2E Android build so native-build JVMs exit before scenarios run. Current-head complete ordered local build/type/lint/unit/integration checks pass: 2,611 unit tests and 374 integration tests. GitHub CI is green (integration run 34031549387, 10m9s). An initial local attempt hit DynamoDB/Supabase time limits; after reclaiming completed build artifacts, the unchanged full retry passed without changing time limits or assertions. Final managed E2E runs Firebase → Supabase → AWS → Cloudflare sequentially.

Prior validated commit: 5719b2f9168907ee3cea04bda2f21625f1c1da9f. Migration consolidation is a40e4cca7228a2c9b28ce725f3e4a8e830ca9e42; the follow-up changes E2E cleanup only, with package/provider sources unchanged.

  • Complete ordered local sequence passed on 5719b2f91: pnpm -w buildpnpm -w test:typepnpm -w lintpnpm -w testpnpm -w test:integration.
  • Unit: 2,611 tests / 281 files. Integration: 374 tests / 27 files. GitHub CI is green on the same commit (integration run 34016836602).
  • Initial-schema provider checks passed: PostgreSQL/Supabase 61, D1 105 (including 60,000 reports), DynamoDB LocalStack 57, Firestore emulator 67, and server/schema focused tests 268.
  • Added an iOS intentional-crash launch synchronization regression. Native recovery and Insights assertions remain enabled, and the full scenario manifest is unchanged.
  • Native coverage includes LocalStack DynamoDB, MongoDB replica set, Firestore emulator, D1 workerd, PostgreSQL/PGlite, Prisma PostgreSQL, and MySQL 8. The D1 movement regression traverses sparse movements in 60,000 reports and checks actual query plans for indexed order without temporary sorting.

Prior full E2E baseline on commit 54712dc4867cd6b6eb66b5d19804c76c77ba050e (before migration consolidation): all five runs passed with hot-updater-agent verify -platform full against that baseline commit: 260/260 scenarios and 260 actual Insights checks. Each profile covers all 26 default scenarios on both iOS and Android. Final audit matched every passing scenario to the commit's default manifest, verified no skipped Insights checks, and confirmed all five job statuses and commit SHAs.

Profile Result Job
standalone-dynamodb 52/52 passed; 52 Insights checks job-20260905154207-6dmvbu
standalone-drizzle 52/52 passed; 52 Insights checks job-20260905164239-9p9vt4
standalone-prisma 52/52 passed; 52 Insights checks job-20260905175630-e7g6jr
standalone-kysely 52/52 passed; 52 Insights checks job-20260905190503-xbgq8p
standalone-mongodb 52/52 passed; 52 Insights checks job-20260905201359-rwfrvl

The first DynamoDB attempt on this commit (job-20260905144049-ssdfo0) passed 51/52 scenarios. One iOS crash recovery hit a React Native Blob response-read error before the catalog request. The unchanged full retry passed 52/52, including that scenario; no assertions were relaxed and no React Native internals were patched.

Browser QA exercised the updated views at 1280×900 and 375×844: scoped counts, B → A recovery drill-down, B → B adoption, Android empty scope, and exact user lookup. No horizontal overflow or captured console errors. Evidence.

Scoped overview Recovery drill-down
Desktop overview Mobile recovery

Managed-provider follow-up uses examples/v0.85.0 and init --provider <provider> --from-env-file .env.hotupdater. Runtime keys are synchronized to each encrypted E2E profile immediately after initialization; full verification runs one provider at a time.

Managed provider Initialization Full E2E
AWS Passed using the saved hot-updater AWS profile; runtime keys synced 52/52 scenarios and 52 Insights checks passed on 5719b2f91, job job-20260906092404-ixtqzf, with fresh native builds. Manifest, commit, and no skipped checks audited. One-off SDK cleanup and existing Insights reconciliation preserved 745 event payloads and restored 207 latest installations with indexed reads/counts verified.
Cloudflare Passed; live D1 schema 1.0.0 and latest-installation projections verified; runtime keys synced 52/52 scenarios and 52 Insights checks passed on 5719b2f91, job job-20260906071828-n7xklw, with fresh native builds. Manifest, commit, and no skipped checks audited. Previous attempt exposed an obsolete API key in cached artifacts; assertions unchanged
Firebase Init passed; runtime keys synced. One-off official SDK cleanup and projection restoration completed: all 2,143 retained documents (including 394 events) preserved, 108 latest installations created, indexed lookups/counts verified Pending
Supabase Init passed after reauthentication; runtime keys synced. Existing development schema reconciled once to initial 1.0.0: all 780 event rows preserved, 212 latest installation rows restored, indexes/RPC/RLS verified Pending

These E2E profiles exercise managed database/storage plugins behind the bot's local server harness. Initialization deploys the corresponding managed infrastructure separately.

E2E performance follow-up: AWS and Cloudflare each passed the complete suite, but took about two hours. Measured local bundle building dominates individual deploy time; upload/database and Insights checks are comparatively small. Bot fixes are pushed to its main at b1cd34d: environment-aware cache identity with the server-only job namespace excluded, runnable iOS app artifacts only, four native entries retained, and native Git worktree removal with completion checks and visible cleanup timing. The previous 15-second removal timeout fell back to recursive filesystem deletion, adding 9m30s after the last AWS test and leaving stale Git registrations. Bot full checks passed (213 tests), and the local bot was restarted successfully.

The actual bundler is Re.Pack/Rspack. Production A/B runs produced identical outputs. Limiting Rust workers increased mean time from 14.70s to 19.86s; limiting Babel/SWC loader workers reduced memory but increased mean time from 23.32s to 31.14s. Neither tuning was applied. The E2E build lifecycle follow-up is committed at 8a0a38417 so Gradle/Kotlin processes exit after native compilation. Final-head managed-provider verification is running sequentially; prior AWS/Cloudflare results above remain explicitly tied to 5719b2f91.

@vercel

vercel Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
hot-updater-docs Ready Ready Preview Sep 7, 2026 1:38am UTC

Request Review

@changeset-bot

changeset-bot Bot commented Aug 31, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e978bb6

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
Name Type
@hot-updater/console Minor
@hot-updater/server Minor
@hot-updater/plugin-core Minor
@hot-updater/aws Minor
@hot-updater/cloudflare Minor
@hot-updater/firebase Minor
@hot-updater/postgres Minor
@hot-updater/supabase Minor
@hot-updater/cli-tools Patch
@hot-updater/mock Minor
@hot-updater/test-utils Minor
hot-updater Patch
@hot-updater/android-helper Patch
@hot-updater/apple-helper Patch
@hot-updater/react-native Patch
@hot-updater/bare Patch
@hot-updater/bugsnag-plugin Patch
@hot-updater/datadog-plugin Patch
@hot-updater/expo Patch
@hot-updater/rock Patch
@hot-updater/sentry-plugin Patch
@hot-updater/standalone Patch

Not sure what this means? Click here to learn what changesets are.

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

@pkg-pr-new

pkg-pr-new Bot commented Aug 31, 2026

Copy link
Copy Markdown

Open in StackBlitz

@hot-updater/android-helper

npm i https://pkg.pr.new/@hot-updater/android-helper@1236

@hot-updater/apple-helper

npm i https://pkg.pr.new/@hot-updater/apple-helper@1236

@hot-updater/bsdiff

npm i https://pkg.pr.new/@hot-updater/bsdiff@1236

@hot-updater/cli-tools

npm i https://pkg.pr.new/@hot-updater/cli-tools@1236

@hot-updater/console

npm i https://pkg.pr.new/@hot-updater/console@1236

@hot-updater/core

npm i https://pkg.pr.new/@hot-updater/core@1236

hot-updater

npm i https://pkg.pr.new/hot-updater@1236

@hot-updater/react-native

npm i https://pkg.pr.new/@hot-updater/react-native@1236

@hot-updater/server

npm i https://pkg.pr.new/@hot-updater/server@1236

@hot-updater/aws

npm i https://pkg.pr.new/@hot-updater/aws@1236

@hot-updater/bare

npm i https://pkg.pr.new/@hot-updater/bare@1236

@hot-updater/bugsnag-plugin

npm i https://pkg.pr.new/@hot-updater/bugsnag-plugin@1236

@hot-updater/cloudflare

npm i https://pkg.pr.new/@hot-updater/cloudflare@1236

@hot-updater/datadog-plugin

npm i https://pkg.pr.new/@hot-updater/datadog-plugin@1236

@hot-updater/expo

npm i https://pkg.pr.new/@hot-updater/expo@1236

@hot-updater/firebase

npm i https://pkg.pr.new/@hot-updater/firebase@1236

@hot-updater/js

npm i https://pkg.pr.new/@hot-updater/js@1236

@hot-updater/plugin-core

npm i https://pkg.pr.new/@hot-updater/plugin-core@1236

@hot-updater/postgres

npm i https://pkg.pr.new/@hot-updater/postgres@1236

@hot-updater/rock

npm i https://pkg.pr.new/@hot-updater/rock@1236

@hot-updater/sentry-plugin

npm i https://pkg.pr.new/@hot-updater/sentry-plugin@1236

@hot-updater/standalone

npm i https://pkg.pr.new/@hot-updater/standalone@1236

@hot-updater/supabase

npm i https://pkg.pr.new/@hot-updater/supabase@1236

commit: e978bb6

@hot-updater-e2e

hot-updater-e2e Bot commented Aug 31, 2026

Copy link
Copy Markdown

🟡 HotUpdater E2E is running.

  • Job: job-20260907020802-658oz0
  • Target: full
  • Source: PR feat(insights): define storage contract and scoped reports #1236
  • Profile: standalone-dynamodb
  • Env target: examples/v0.85.0/.env.hotupdater
  • Head: e978bb65be9c3b49bc3cadf9f2a53d7ccdeb406e
  • Started: 2026-09-07T02:08:05.064Z
  • Elapsed: 1h 29m 1s
  • Updated: 2026-09-07T03:37:06.262Z

Logs are available in the dashboard.

@hot-updater-e2e

Copy link
Copy Markdown

@hot-updater-agent HotUpdater E2E completed successfully. 🟢

@gronxb gronxb changed the title feat(insights): keep operational history bounded feat(insights): define storage contract and scoped reports Sep 5, 2026
@hot-updater-e2e

Copy link
Copy Markdown

@hot-updater-agent HotUpdater E2E completed successfully. 🟢

@hot-updater-e2e

Copy link
Copy Markdown

@hot-updater-agent HotUpdater E2E completed successfully. 🟢

@hot-updater-e2e

Copy link
Copy Markdown

@hot-updater-agent HotUpdater E2E completed successfully. 🟢

@hot-updater-e2e

Copy link
Copy Markdown

@hot-updater-agent HotUpdater E2E completed successfully. 🟢

@hot-updater-e2e

Copy link
Copy Markdown

@hot-updater-agent HotUpdater E2E completed successfully. 🟢

@hot-updater-e2e

Copy link
Copy Markdown

@hot-updater-agent HotUpdater E2E completed successfully. 🟢

@hot-updater-e2e

Copy link
Copy Markdown

@hot-updater-agent HotUpdater E2E completed successfully. 🟢

@hot-updater-e2e

Copy link
Copy Markdown

@hot-updater-agent HotUpdater E2E completed successfully. 🟢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant