Phase/9c migration reconciliation operations - #13
Merged
Mujhtech merged 25 commits intoJul 31, 2026
Conversation
Mujhtech
force-pushed
the
phase/9c-migration-reconciliation-operations
branch
from
July 31, 2026 09:35
26cdf88 to
0b52731
Compare
Mujhtech
force-pushed
the
phase/9c-migration-reconciliation-operations
branch
from
July 31, 2026 09:36
0b52731 to
fc36891
Compare
Mujhtech
force-pushed
the
phase/9c-migration-reconciliation-operations
branch
from
July 31, 2026 09:36
fc36891 to
b524d2d
Compare
Mujhtech
force-pushed
the
phase/9c-migration-reconciliation-operations
branch
from
July 31, 2026 09:37
b524d2d to
32c6e66
Compare
Mujhtech
force-pushed
the
phase/9c-migration-reconciliation-operations
branch
from
July 31, 2026 09:37
32c6e66 to
42c4ed4
Compare
Mujhtech
force-pushed
the
phase/9c-migration-reconciliation-operations
branch
from
July 31, 2026 09:38
42c4ed4 to
6339eb9
Compare
Mujhtech
force-pushed
the
phase/9c-migration-reconciliation-operations
branch
from
July 31, 2026 09:38
6339eb9 to
25c9a18
Compare
Mujhtech
force-pushed
the
phase/9c-migration-reconciliation-operations
branch
from
July 31, 2026 09:39
25c9a18 to
12cd068
Compare
Mujhtech
force-pushed
the
phase/9c-migration-reconciliation-operations
branch
from
July 31, 2026 09:39
12cd068 to
ba84fd1
Compare
Base automatically changed from
phase/9b-subscription-state-entitlements
to
development
July 31, 2026 09:41
OTLP export was hard-wired to HTTP with no way to authenticate to a collector, and logs never left stdout. Add OTEL_EXPORTER_OTLP_PROTOCOL to select http/protobuf or grpc for every signal, OTEL_EXPORTER_OTLP_HEADERS for collector credentials, and MOSAIC_OTEL_EXPORTER_TLS_SKIP_VERIFY for a private CA or self-signed certificate. Header values are secrets: they are never logged and never echoed in a validation problem. Skip-verify applies only to an https endpoint, since attaching TLS credentials to a plaintext gRPC endpoint would silently upgrade a connection the collector is not serving. Outside development and test, a plaintext or unverified collector connection is refused at startup unless MOSAIC_OTEL_EXPORTER_ALLOW_INSECURE acknowledges it, matching the existing database and object-store guards. Logs now go to stdout and the collector at once, so they are readable beside the traces they belong to. The bridge sits at the zerolog writer rather than a hook so exported records keep every structured field. MOSAIC_OTEL_LOGS_ENABLED=false drops the export half without touching stdout, traces, or metrics. Telemetry keeps a local-only logger for its own SDK errors so an export failure cannot feed the failing exporter. One generic helper applies the endpoint, header, and TLS policy to all three exporter packages, which otherwise expose the same options under unrelated types and drift apart.
update some import issue
Add routeHead() in src/lib/routing/route-head.ts so each file route only supplies its own title (and an optional description) instead of repeating the product-name suffix and meta shape. Wire it into the root route and every page route.
…onent Register application, create Plan/Product/Entitlement/Placement/Paywall, create Migration Program, add member, and the grant version wizard now open from a header action in a dialog instead of a form panel below the list. Each closes on success and resets its form and mutation error on close; the grant wizard keeps its three steps and moves from a Sheet to the dialog. Purchase setup no longer carries its own Environment picker or environmentId search param. It reads the Environment the address names, so the workspace switcher is the single place that scope changes. Replaces all 90 native selects with a Base UI Select wrapper. Two things the primitive imposes are handled once rather than at every call site: the trigger label resolves from `items`, so callers build one options list and pass it to both, and `onValueChange` is narrowed to a non-null value because nothing here uses a null-valued item. The paywall editor inspector derives its items from the SelectItem children instead, keeping its sixty-odd fields unchanged. Tests drive the new control through `chooseSelectOption`. An option commits on pointer release, so a bare click leaves the value untouched, and options only exist in the DOM while the list is open.
…re v2 contracts Adds the Billing Migration Operations v1 command and resource schemas, the Authoritative Entitlement v2 and Billing State Webhook v2 contracts that carry authority epoch, scope, and transition metadata, their compatibility rules and cross-platform fixtures, and the Phase 9C contract validation tooling. Customer Access Token v1, Delivery v3, Commerce Provider, and Billing Ingestion v1 are unchanged.
Introduces the Phase 9C billingmigration module: program lifecycle with compare-and-swap state versions, immutable source snapshots/records/manifests, versioned mapping sets, import batches, shadow projection, divergences, cases, checkpoints, repairs, stabilization, and completion/retention state, together with their PostgreSQL repositories and schema migrations 00052-00061. Source evidence is encrypted with a chunked AES-GCM envelope into a private bucket and keyring that are validated to be distinct from the public Asset bucket and the provider credential keyring. Migration credentials are a separate encrypted subject kind, and the execution plane is off by default behind MOSAIC_BILLING_MIGRATION_ENABLED.
…on import Normalizes RevenueCat REST API v2 evidence through the published resource graph - paginated customers, subscriptions, aliases, and Product bindings - into append-only source records while keeping exact response pages as raw encrypted evidence. Unsupported stores quarantine instead of being inferred from identifier syntax. Source-pull commands carry snapshot, delta, and final_delta intent and run as durable, resumable worker jobs; a completed final_delta queues the lease-bound final-delta evaluation once its provider-validation import settles. Provider revalidation reuses the accepted Phase 9A ingestion and validation seams, so source evidence never inserts a Transaction Fact directly.
…uthority Adds server-owned authority per (project, environment, application, platform) scope and serves Authoritative Entitlement v2: authority epoch and kind, explicit scope, transition state, snapshot authority digest, and server-directed minimum supported SDK/app metadata. An optional known snapshot digest yields snapshotUnchanged only on an exact match and never selects authority, scope, or customer. Unknown authority stays a safe unavailable result rather than inactive access, and policy_unavailable fabricates no minimum-support policy. Sync observations are append-only, bounded, and non-sensitive, and serving does not fail when an observation write fails. Prepared snapshot pointers stay inert until cutover.
Emits authority scope, epoch, and transition events over Billing State Webhook v2 while preserving HMAC signing, delivery attempts, redelivery idempotency, and tolerant-consumer policy. V1 destinations keep receiving only v1 events and never see authority transitions, so they cannot satisfy the authority-aware readiness gate. Production programs with active destinations require at least one healthy active v2 destination with an active signing secret, proven fresh against the per-Program watermark_max_age_seconds at both promotion and atomic cutover.
…tion Mounts the Project-scoped Billing Migration Operations v1 surface behind Environment and Application membership, with command-specific capabilities - view, manage-source, manage-mappings, run-import, resolve-cases, propose-cutover, approve-cutover, execute-cutover, execute-rollback, execute-repair, delete-source - returned by the server as a closed set derived from the actor and current Program state. Wires the migration services, worker jobs, and the migration keyring into the api, worker, keyring, and billing demo commands. Commands carry idempotency keys, expected state version, and expected digests; a stale digest returns a stable 409 and leaves authority unchanged.
Adds the Project-scoped migration journey cockpit, guided mapping and mapping freeze, impact review, and the command, query, and mutation layer against the frozen Billing Migration Operations v1 API. Every dangerous command gets an impact preview, an explicit reason, a server-derived capability check, stale 409 handling, and irreversible or rollback consequences; secret inputs clear after submission and are never read back. Migration semantics stay server-side.
Implements Authoritative Entitlement v2 in the customer entitlement runtime: a replaying current-authority stream, authority epoch monotonicity ahead of snapshot version, a cache digest bound to customer, environment, application and platform scope, and epoch, urgent sync on authority transition ahead of normal configuration refresh, and authority_unknown for legacy caches and unsupported contracts. Access-result APIs are unchanged and unknown or unavailable stays safe. Placement targeting uses Mosaic-authoritative access only while the current epoch says Mosaic and never unions it with provider-observed access. Purchase and restore remain provider-owned, and the Customer Access Token remains memory-only.
Implements Authoritative Entitlement v2 in the Swift SDK: a replaying current-authority publisher, authority epoch monotonicity ahead of snapshot version, a cache digest bound to customer, environment, application and platform scope, and epoch, urgent sync on authority transition, and authority_unknown for legacy caches and unsupported contracts. Access-result APIs are unchanged and unknown or unavailable stays safe. Placement targeting uses Mosaic-authoritative access only while the current epoch says Mosaic and never unions it with provider-observed access. StoreKit purchase and restore remain independent, and the Customer Access Token remains memory-only.
Implements Authoritative Entitlement v2 in the Kotlin SDK: a replaying current-authority flow, authority epoch monotonicity ahead of snapshot version, a cache digest bound to customer, environment, application and platform scope, and epoch, urgent sync on authority transition, and authority_unknown for legacy caches and unsupported contracts. Access-result APIs are unchanged and unknown or unavailable stays safe. Placement targeting uses Mosaic-authoritative access only while the current epoch says Mosaic and never unions it with provider-observed access. Play Billing purchase and restore remain independent, the Customer Access Token remains memory-only, and no background scheduler is introduced: foreground recovery plus the existing refresh mechanisms carry the transition.
Resolving workspace entry from the paginated Organization and Project lists cost one request per Organization and could not pick a destination without a round trip per candidate. Bootstrap returns every Organization the actor belongs to with the actor's role and that Organization's active Projects in a single read, bounded to 25 Projects per Organization with a truncation flag.
Adds the Phase 9C plan and review notes, ADR 0025 on monotonic scoped billing authority, the backend notes for the migration foundation, source pull, source execution, candidate evaluation, webhook v2 transition delivery, and stabilization/rollback readiness, and the migration keyring rotation procedure. Regenerates docs/backend/openapi.yaml for the Billing Migration Operations v1 surface, the Authoritative Entitlement v2 sync response, and the workspace bootstrap read.
OTEL_EXPORTER_OTLP_ENDPOINT is a base endpoint and each signal hangs off it, as the OpenTelemetry specification defines the variable, so traces, metrics, and logs now resolve /v1/traces, /v1/metrics, and /v1/logs against it, preserving any path prefix a gateway mounts OTLP behind. Plaintext is stated to the exporter explicitly instead of being inferred from the endpoint, so a bare host:port can no longer silently become TLS.
Moves the organizations feature imports to orgs, replaces the old /organizations/... links with the current /orgs/.../env/... routes, drops the monetization workspace's duplicate environment switcher and tab strip now that the route shell owns them, and clears the transparent scrollbar track.
Pins that the gRPC transport works from the same base endpoint as HTTP: an in-process collector receives trace, metric, and log exports, so the signal path the HTTP exporters need stays inert over gRPC, where only the host and the plaintext flag are read from the endpoint URL. Also pins endpoint validation for gRPC operators. http:// and https:// URLs are accepted, including behind a gateway path prefix, and a bare host:port is rejected: the OpenTelemetry specification defines the variable as a URL, and the SDK would otherwise fall back to its own default collector instead of the address that was configured.
Mujhtech
force-pushed
the
phase/9c-migration-reconciliation-operations
branch
from
July 31, 2026 09:41
ba84fd1 to
11ffc24
Compare
Mujhtech
marked this pull request as ready for review
July 31, 2026 09:41
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.