Skip to content

PAY-003A12 — Reject unusable Checkout Session-created evidence #588

Closed

Description

@daliu

Outcome

Require every newly delivered supported Checkout Event to carry usable embedded Checkout Session created evidence before any target, fallback, provider-binding, money, or business-state work.

Invariant

After exact processed-Event replay and the existing earlier realm, lifecycle, metadata, and outer Event-time checks, Checkout Session.created must be a primitive safe integer from Unix epoch second 0 through Firestore maximum second 253402300799, inclusive.

Invalid or missing evidence must produce the fixed durable result needs_review:invalid_checkout_session_created. The processed ledger retains the valid outer stripeCreatedAt, keeps target fields null, and logs no rejected value. No coercion, rejected-value timestamp construction, target/fallback query, business mutation, provider binding, money check, or state transition is allowed.

Allowed transitions and failure cases

  • Exact processed-Event replay stays first and read-only.
  • Outer Event realm, embedded Session realm, Session lifecycle, explicit claimed metadata schema, and outer Event-time results keep precedence.
  • A newly delivered invalid Session time changes from target-capable behavior to target-free durable review.
  • A valid claimed Event whose target is absent remains retryable and writes no processed ledger.
  • Valid Session times retain all current Checkout outcomes.
  • Session/Event chronology is explicitly excluded and remains compatible in this child; PAY-003A13 will own that comparison separately.
  • Refund, Dispute, and unsupported Events remain unchanged.

Exact implementation scope

  1. functions/stripeWebhook.js
    • One Checkout-only admission predicate using the existing non-coercing Stripe-created validator.
    • One fixed reason: invalid_checkout_session_created.
  2. functions/stripeWebhook.test.js
    • A valid shared Checkout Session timestamp fixture.
    • One separately named PAY-003A12 matrix covering all four Checkout lifecycles, both business domains where applicable, hostile shapes and inclusive boundaries, precedence, isolation, missing target, replay, logs, and non-Checkout compatibility.
    • Reconcile only the inherited PAY-003A9 invalid-Session-created compatibility assertion.
    • Preserve the PAY-003A10 Session/Event chronology exclusion.
  3. STRIPE_COMMERCE_DESIGN.md
    • One named SOURCE ONLY / NOT LIVE PAY-003A12 section after PAY-003A11.

Everything else is excluded.

Acceptance

  • Trustworthy test-only RED first on the exact claimed base.
  • Missing, null, negative, fractional, string, boolean, object, array, JSON-normalized non-finite, unsafe, and above-range values are rejected without coercion.
  • Post-parser hostile Proxy evidence cannot trigger user-controlled conversion or disclosure.
  • Epoch and Firestore-maximum values are admitted.
  • All four supported Checkout lifecycles are covered.
  • Registration and order paths are covered.
  • Invalid time wins before malformed/fallback references, claimed missing target, provider-binding conflict, mode, money, payment-status, PaymentIntent, and predecessor-state checks.
  • Earlier admission precedence, exact replay, valid missing-target retry, valid business outcomes, and PAY-003A8 through A11 remain compatible.
  • Ledger reads, null target fields, valid outer stripeCreatedAt, fixed redacted log, no rejected timestamp construction, and no business or binding work are proved.
  • Focused tests, complete webhook/Functions tests, frontend/safety/SPA/Rules/commerce emulator gates, lint, build, diff check, and non-forced audits pass.

Migration and compatibility

No schema, Rule, index, package, workflow, API, provider configuration, migration, backfill, or history-reprocessing change. Already-processed ledgers remain authoritative on replay. Existing business records and provider bindings are not inspected or repaired.

Dependencies and exclusions

Depends on verified webhook signature handling and completed PAY-003A2/A4/A8/A11 admission/projection slices. Excludes Session/Event chronology, current-clock freshness/skew, expires_at, endpoint API-version policy, provider retrieval/history repair, already-paid repair, paid-after-cancellation policy, PAY-003B/C, reconciliation, alerts, protected release, provider/data/payment actions, and live verification.

Stripe documents Checkout Session created as its Unix timestamp, and the installed Stripe 14.25.0 type declares it required. Provider endpoint/API-version and live evidence remain unverified and are not claimed by this source-only boundary.

Officer and deployment truth

Officer impact: None — server-only pre-target admission; no officer screen, task, field, permission, topology, or available recovery step changes.

Officer documentation: None — the engineering contract belongs in STRIPE_COMMERCE_DESIGN.md; current officer procedures remain factual.

Deployment evidence: Source, tests, merge, website publication, runmprc.com, Firebase deployment/readback, Stripe/provider configuration/action, production data, checkout/payment/refund/dispute activity, and live behavior must be reported separately. Source/tests alone prove none of the later states.

Claim rule

Claim only this atomic child after confirming the exact base and disjoint active ownership. Stop on any path/hunk overlap, provider/API-version dependency, need for production data or secrets, or change outside the exact scope.

Activity

  1. added
    priority:P0Launch blocker or urgent security risk
    type:securitySecurity or privacy boundary
    area:firebaseFirebase services and data
    size:SSmall focused issue
    area:stripeStripe payments and financial lifecycle
    type:testingTest infrastructure and quality gates
    status:in-progressClaimed and actively being implemented
    on Aug 2, 2026
  2. self-assigned this
    on Aug 2, 2026
  3. daliu commented on Aug 2, 2026

    @daliu
    ContributorAuthor

    CLAIMED by /root at 2026-08-02T01:23:44Z on codex/issue-588-checkout-session-created, exact base 51723b487ec67bb74620c97e47449ae1319f0daa, tree 65ce5004636699a0b7f56ee1a787bcf9107fcdc1.

    Exact ownership:

    • functions/stripeWebhook.js: one Checkout Session-created admission predicate and fixed reason only.
    • functions/stripeWebhook.test.js: one separately named PAY-003A12 matrix/helpers, valid Checkout Session fixture defaults, and only the inherited PAY-003A9 invalid-Session-created compatibility reconciliation. PAY-003A10 chronology remains admitted and unchanged in behavior.
    • STRIPE_COMMERCE_DESIGN.md: one separately named PAY-003A12 SOURCE ONLY / NOT LIVE section immediately after A11.

    Invariant: after exact replay and existing realm/lifecycle/metadata/outer-Event-time checks, every supported Checkout Session created must be a primitive safe integer from 0 through 253402300799 inclusive. Invalid evidence becomes target-free durable needs_review:invalid_checkout_session_created with the valid outer ledger time, null target fields, fixed redacted log, no coercion, no rejected timestamp construction, and no target/fallback/binding/money/state work.

    Excluded: Session/Event chronology (future A13), clock freshness/skew, expires_at, API-version/provider decisions, other Event families, schema/Rules/index/packages/workflows/migration/history, PAY-003B/C, deployment/provider/data/payment/live work, active #571/#504 paths, and draft #462. Any exact overlap or provider/version dependency is STOP-and-coordinate. No edit preceded this claim.

  4. daliu commented on Aug 2, 2026

    @daliu
    ContributorAuthor

    TRUSTWORTHY TEST-ONLY RED on exact base 51723b487ec67bb74620c97e47449ae1319f0daa.

    Only the separately named PAY-003A12 test block exists at this marker. Runtime, shared fixtures, design documentation, packages, provider state, data, deployment, and live behavior are unchanged. Test-only diff SHA-256: d3d31782b39377a7f247cdae98817f3767dcda0cdbf3c1c5777d8e441f066bdf.

    Node 20 command: npm --prefix functions run test:run -- --runInBand stripeWebhook.test.js -t 'PAY-003A12 Checkout Session-created admission'

    Expected result: 2 failed / 603 skipped. Both claimed registration and order completions with missing embedded Session time returned payment_confirmed, mutated the target path, and therefore failed the required target-free needs_review:invalid_checkout_session_created assertion. This proves the exact pre-target admission gap without a provider, credential, payment, customer/member record, production service, or live mutation. Claim remains held.

  5. daliu commented on Aug 2, 2026

    @daliu
    ContributorAuthor

    CANDIDATE READY on unchanged exact base 51723b487ec67bb74620c97e47449ae1319f0daa. Exact three-file diff SHA-256: fa3d8148d33ef8fb5dbd43efb772055c4c43a732d3b77ad72a5b36064adedfc0; git diff --check passes.

    Outcome: one Checkout-only admission condition now applies the existing non-coercing safe-integer/range predicate to embedded Session created after outer Event-time admission and before any target work. Invalid evidence receives fixed target-free needs_review:invalid_checkout_session_created; valid outer stripeCreatedAt, null targets, fixed redacted logs, replay, valid missing-target retry, and all existing lifecycle outcomes are preserved. Session/Event chronology remains deliberately unchanged for future PAY-003A13.

    Evidence on Node 20 / Java 21, demo emulators only:

    • Trustworthy test-only RED: 2 expected failures, diff SHA d3d31782b39377a7f247cdae98817f3767dcda0cdbf3c1c5777d8e441f066bdf.
    • PAY-003A12: 157/157.
    • Complete webhook: 760/760.
    • Functions lint: pass; Functions full: 7,222 passed / 64 intended skips.
    • Frontend: 951/951; workflow/artifact/supply safety: 86/86; SPA: 11/11.
    • Firestore Rules demo emulator: 418/418.
    • Commerce command-journal demo emulator: 63/63.
    • Frontend lint baseline: 118 files / 113 reviewed legacy errors / 6 reviewed legacy warnings.
    • Diagnostic production build: pass; workflow YAML and diff checks: pass.
    • Dependency audits unchanged by this no-package patch: root full 59, root production 4, Functions 8; no forced upgrade applied.

    Independent exact-diff reviews:

    • Security/runtime: GO — correct precedence, non-coercing bounds, target/binding/money/state isolation, redacted logs, replay/missing-target compatibility, provider-contract boundary, chronology exclusion.
    • Tests/compatibility: GO — trustworthy RED; 4 lifecycles x 2 domains x 14 invalid forms; Proxy, bounds, precedence, references/fallbacks, bindings, replay, positive and non-Checkout coverage; atomic despite test volume.
    • Design/backup officer: GO — factual source-only contract; purpose, approvers, prerequisites, order, result, stop/proof/undo/escalation, Mermaid/text alternative, migration/residuals, and separate deployment truths are complete; no officer procedure changed.

    Officer impact: None — server-only pre-target admission.

    Officer documentation: None — no officer screen, task, field, permission, topology, approval path, or available recovery step changed; engineering truth is in STRIPE_COMMERCE_DESIGN.md.

    Deployment evidence: Source/tests only. No code is merged yet. No website publication, runmprc.com verification, Firebase deployment/readback, Stripe/provider action or configuration, production-data change, checkout/payment/refund/dispute, or live verification occurred. Claim remains held pending commit, hosted CI, merge, exact-main verification, and explicit release.

  6. daliu commented on Aug 2, 2026

    @daliu
    ContributorAuthor

    PR #589 is ready at exact reviewed head 0645e3977e87797c5b69848339801d42e75b5426, tree dd970cd2994ffeafa52b603ea3094ca8224552cf, patch SHA-256 fa3d8148d33ef8fb5dbd43efb772055c4c43a732d3b77ad72a5b36064adedfc0. Exact base remains 51723b487ec67bb74620c97e47449ae1319f0daa; the PR contains only the three claimed files. Self-review and all three independent reviews are GO. Hosted CI/preview checks are running; no merge, deploy, provider, data, payment, or live action is claimed. Claim remains held.

  7. removed their assignment
    on Aug 2, 2026
  8. daliu commented on Aug 2, 2026

    @daliu
    ContributorAuthor

    COMPLETE / CLOSED / CLAIM RELEASED — PAY-003A12.

    PR #589 squash-merged exact reviewed head 0645e3977e87797c5b69848339801d42e75b5426 as exact main 56332507f394f419616acfa6320f1bfbb16c60b5. Reviewed and merged tree dd970cd2994ffeafa52b603ea3094ca8224552cf is identical. Patch SHA-256 remained fa3d8148d33ef8fb5dbd43efb772055c4c43a732d3b77ad72a5b36064adedfc0. Ordinary merge was refused only by the repository approval rule after all checks/reviews were GO; the administrator merge did not bypass a failing code or deployment check.

    Outcome: after exact replay and the existing realm, lifecycle, metadata, and outer Event-time checks, every newly delivered supported Checkout Event now requires embedded Session created to be a primitive safe integer from 0 through 253402300799 inclusive. Invalid evidence becomes fixed target-free needs_review:invalid_checkout_session_created with valid outer ledger time, null targets, fixed redacted logging, no coercion, and no target/fallback/binding/money/state work. Valid lifecycle behavior, valid missing-target retry, historical replay, refund/Dispute/unsupported behavior, and Session/Event chronology remain unchanged.

    Verification:

    • Trustworthy test-only RED: 2 expected failures on exact base.
    • Local PAY-003A12: 157/157; webhook: 760/760.
    • Functions lint passed; Functions full: 7,222 passed / 64 intended skips.
    • Frontend 951/951; safety 86/86; SPA 11/11.
    • Firestore Rules demo emulator 418/418; commerce command-journal demo emulator 63/63.
    • Frontend lint baseline and diagnostic build passed; diff/YAML checks passed.
    • Independent security/runtime, tests/compatibility, and design/backup-officer reviews: GO.
    • Exact-head CI 30727364335: all five jobs passed.
    • Exact-main CI 30727456137: all five jobs passed.

    Delivery truth:

    • Source changed: yes, exact main above.
    • Synthetic tests passed: yes, as listed.
    • Code merged: yes.
    • Website preview: yes; Netlify deploy-preview 6a6e9f32db2e2a0008b38afb is ready but unpublished and non-production.
    • Website published: no. Exact-main Netlify attempt 6a6e9fe9a611ae0008db491f ended error with published_at: null.
    • runmprc.com verified: no. Netlify still identifies bounded WEB-002A — Publish bounded Shop and Events permissions containment #473 deploy 6a6dc9ea588b0c0008036312, source 9ad6837756cdd409d296009fde5082eeeae5c059, as published.
    • GitHub deployment/protected release: none; exact-main deployments are [], and the only exact-commit workflow is CI.
    • Firebase deployed/read back: no.
    • Stripe/outside provider configured or contacted: no.
    • Production data changed: no.
    • Checkout/payment/refund/dispute performed: no.
    • Production behavior verified: no.

    Officer impact: None — server-only pre-target admission.

    Officer documentation: None — no officer screen, task, field, permission, topology, approval path, or available recovery step changed. Engineering truth is in STRIPE_COMMERCE_DESIGN.md.

    Residual risk remains explicit under #106: Session/Event chronology (PAY-003A13), clock freshness/skew, expires_at, endpoint API-version/provider proof, history repair, already-paid missing-time repair, paid-after-cancellation policy, PAY-003B/C, reconciliation, alerts, protected release, and live verification.

    Issue is closed, status:in-progress and assignee are removed, the remote branch is absent, and every PAY-003A12 path/hunk claim is RELEASED.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:firebaseFirebase services and dataarea:stripeStripe payments and financial lifecyclepriority:P0Launch blocker or urgent security risksize:SSmall focused issuetype:reliabilityReliability and recoverytype:securitySecurity or privacy boundarytype:testingTest infrastructure and quality gates

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions