Skip to content

feat(billing): persist authoritative subscription observations - #526

Draft
seonghobae wants to merge 19 commits into
feat/stripe-subscription-authoritative-read-488from
feat/stripe-subscription-observation-ledger-488
Draft

feat(billing): persist authoritative subscription observations#526
seonghobae wants to merge 19 commits into
feat/stripe-subscription-authoritative-read-488from
feat/stripe-subscription-observation-ledger-488

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Buyer/data-integrity objective

Refs #488. This Draft stacked slice creates the durable observation boundary between current Stripe provider reads and any later local lifecycle/entitlement state machine. It stores tenant-verified provider facts append-only and normalized instead of overwriting local plan state or treating webhook arrival order as entitlement authority.

Exact current stack

  • protected develop: df0fa17bd5035af6455c889022c540b4f439e3d6;
  • exact parent/base: feat(billing): fetch authoritative Stripe subscription state #525 feat/stripe-subscription-authoritative-read-488@e4f75a48c248b4c6cf8cc9f97d75803a58415b75;
  • exact contributor head: cf01a755f1f64a5838033a94b4ba17a1622e0021;
  • fresh parent→child comparison: ahead 15, behind 0, exact parent as merge base, exactly seven changed paths, +778/-3.

The current head is a non-destructive reconciliation of predecessor child 0793054fea87ff94230b3690edec7f85d18a2421 with the exact current provider-read parent. The effective delta is limited to CHANGELOG.md, doctoring, package.json, server/db.mjs, the observation-ledger module, the coverage contract, and the focused ledger regression. CHANGELOG.md adds exactly five observation-ledger lines with zero parent deletions.

The semantic package/coverage merge preserves the parent’s composed server/app.mjs/server/application_routes.mjs toast route, OpenCode/changelog tests, contextual-orchestrator attribution/routing regressions, Checkout attempt/reconciliation/provider tests, webhook trust/event-ledger coverage, authoritative provider-read coverage, and accessibility suites while adding only the observation-ledger production/test registrations.

Any parent, contributor-head, or protected-base movement invalidates ancestry- and head-specific evidence until freshly reconciled.

Implemented persistence boundary

server/stripe_subscription_observation_ledger.mjs owns five normalized relations:

  • billing_stripe_customers permanently binds one Stripe customer to one ScopeWeave organization;
  • billing_stripe_subscriptions permanently binds one Stripe subscription to one customer;
  • billing_stripe_prices deduplicates provider price identities;
  • billing_stripe_subscription_observations appends authoritative lifecycle snapshots; and
  • billing_stripe_subscription_observation_prices preserves ordered observation/price membership.

The persistence boundary rejects tenant/customer/subscription rebinding, malformed or unsafe timestamps, unknown lifecycle states, empty or unbounded price sets, missing local organizations, and nonexistent optional source-event provenance. Repeated reads append evidence, local observation time remains monotonic under wall-clock rollback, and even an active provider snapshot cannot mutate local entitlement state in this slice.

Customer identity, subscription identity, price identities, observation, and price memberships are written under one SQLite savepoint. Cleanup preserves the causal operation error, releases only after rollback is confirmed, suppresses cleanup-release errors only after confirmed rollback, and leaves an unconfirmed failed savepoint open rather than risk partial commit.

Causal failure repair

Predecessor Server Tests run 32086145334, unit-and-api job 95558979873, passed the full unit suite including the observation ledger but failed the API smoke contract because stale child application composition returned 404 for protected /toast-state.css. The current repair starts from exact parent #525’s composed application tree and overlays only the seven observation-ledger paths, so the shipped static accessibility asset is preserved without weakening the smoke test.

tests/unit/coverage-script-contract.test.mjs now proves both server/application_routes.mjs and server/stripe_subscription_observation_ledger.mjs remain instrumented while the focused observation suite executes under normal unit CI and c8 coverage.

Current exact-head evidence

Fresh repository-native workflows for exact contributor head cf01a755f1f64a5838033a94b4ba17a1622e0021 are queued and therefore non-passing:

  • Server Tests 32274470166;
  • Dependency Review 32274470133; and
  • OSV Scanner 32274470647.

No submitted review or review thread exists on the current head and no qualifying independent current-head approval exists. Queued, pending, skipped-required, cancelled, absent, neutral, failed, stale, predecessor, synthetic, status-only, author-only, or model-only evidence is non-passing.

Scope and merge boundary

This PR deliberately does not implement current-subscription projection, monotonic lifecycle/entitlement policy, invoice/payment state, local grants or revocations, operator reconciliation API, retention/export UI, or release acceptance. #527 owns the current-subscription projection child and must be reconciled to this exact parent. This PR must not integrate independently of #525 and the earlier #488 billing stack.

After the prerequisite stack reaches protected develop, reconcile this bounded semantic diff onto the resulting live head and rerun every then-applicable exact-head CI, browser E2E, statement/branch/function/line coverage, docstring, SAST, security, dependency, supply-chain, package/provenance, migration/recovery, resolved-thread, and qualifying independent-approval gate required by live policy.

@coderabbitai

coderabbitai Bot commented Aug 16, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@opencode-agent opencode-agent Bot added area: auth Authentication, authorization, identity, or tenant isolation priority: medium Normal-priority or P2 work status: draft Draft pull request type: feature New or expanded product capability labels Aug 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: auth Authentication, authorization, identity, or tenant isolation priority: medium Normal-priority or P2 work status: draft Draft pull request type: feature New or expanded product capability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant