Skip to content

PAY-003A15 — Reject impossible Dispute/Event chronology #594

Closed

Description

@daliu

Outcome

Reject a newly delivered supported Dispute lifecycle Event when the structurally valid embedded Dispute.created second is later than the structurally valid outer Event.created second.

The fixed result is durable target-free needs_review:invalid_dispute_event_chronology. Equality and an earlier Dispute time remain admissible.

Provider and policy basis

Stripe describes Dispute created and Event created as object-creation time in Unix seconds. Its Event-type reference says the supported created, updated, and closed lifecycle Events carry a Dispute in data.object and occur when that Dispute is created, updated, or closed.

This child makes a bounded source-policy inference: an Event snapshot cannot coherently contain a Dispute that says it was created after the Event itself. It does not claim an exact dispute occurrence time, delivery order, clock-freshness policy, endpoint/API-version truth, canonical provider history, or live provider behavior.

Dependencies

Invariant and admission order

For a new supported Dispute Event:

  1. Exact processed replay remains first and read-only.
  2. Outer realm, embedded Dispute realm, Event/status lifecycle, claimed metadata version, outer Event time, and embedded Dispute time structure keep precedence.
  3. After both timestamps are valid, require Dispute.created <= Event.created.
  4. A contradiction persists fixed review with valid outer stripeCreatedAt and null target fields.
  5. No reference/fallback query, target or business read/change, provider-binding work, object/money/predecessor check, rejected-time conversion, or raw-value disclosure may occur.
  6. Equality and earlier chronology continue to existing processing.
  7. A valid claimed missing target remains retryable; impossible chronology is final evidence review.

Exact scope

  • functions/stripeWebhook.js: one Dispute-only chronology condition immediately after PAY-003A14 structure admission.
  • functions/stripeWebhook.test.js: one named PAY-003A15 matrix/helpers plus only the chronology-valid compatibility corrections required in historical A7/A10/A13/A14 controls.
  • STRIPE_COMMERCE_DESIGN.md: one named source-only A15 section and minimal historical reconciliation.

Acceptance proof

Signed synthetic tests must cover:

  • created, updated, and closed lifecycle Events;
  • registration and order domains;
  • one-second contradiction;
  • equality, one-second-earlier, Unix-epoch equality, and Firestore-maximum equality;
  • exact outer-ledger time, target-free response/ledger, two ledger reads, timestamp isolation, fixed redacted log, and no current-clock use;
  • metadata, client reference, matching dual reference, legacy PaymentIntent, legacy Charge, unmatched, malformed/conflicting, ambiguous fallback, binding conflict, claimed missing target, object, currency, amount, provider IDs, and predecessor isolation;
  • all earlier admission precedence including invalid embedded Dispute structure;
  • exact replay/log-once and richer historical-ledger preservation;
  • valid missing-target retry;
  • Checkout Session, refund Charge, unsupported Event, and unsupported dispute-like Event compatibility;
  • complete webhook, Functions, frontend, Rules, and commerce gates.

Tests must reject reversed comparison, strict-equality, tolerance, off-by-one, wrong field, wrong gate, broad prefix, wrong reason, retryable, late-check, raw-value/timestamp leakage, embedded-time ledger substitution, replay recomputation, clock-freshness, and non-Dispute spillover implementations.

Exclusions and migration

No schema, Rules, index, package, workflow, API, provider configuration, migration, backfill, or history reprocessing. Already-processed ledgers remain authoritative. Existing records, bindings, and historical rows are not repaired.

Clock freshness/skew, provider retrieval/history proof, PAY-003B/C, reconciliation, alerts, protected release, Firebase/Stripe deployment, provider action, production data, payment/refund/dispute activity, and live verification remain outside this child.

Officer impact: None — server-only pre-target evidence comparison.

Officer documentation: None — no officer screen, task, field, permission, approval, topology, incident step, or recovery action changes.

Deployment evidence: Not started. No source change, test result, merge, website publication, runmprc.com verification, Firebase deployment, provider configuration/action, production-data change, checkout/payment/refund/dispute activity, or live verification is claimed by this issue definition.

Activity

  1. added
    priority:P0Launch blocker or urgent security risk
    type:securitySecurity or privacy boundary
    area:firebaseFirebase services and data
    size:SSmall focused issue
    status:readyDependencies complete and ready to claim
    area:stripeStripe payments and financial lifecycle
    type:testingTest infrastructure and quality gates
    status:in-progressClaimed and actively being implemented
    and removed
    status:readyDependencies complete and ready to claim
    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-02T02:53:33Z on exact released base 102209dd99b331797f139dde7e209de75ea73a63.

    Branch: codex/issue-594-dispute-chronology

    Atomic outcome: after all existing Dispute admission checks pass, Dispute.created > Event.created becomes durable target-free needs_review:invalid_dispute_event_chronology; equality and earlier chronology remain admitted.

    Exact path/hunk claim:

    • functions/stripeWebhook.js: one Dispute-only comparison immediately after A14 structure admission.
    • functions/stripeWebhook.test.js: one named A15 matrix/helpers and only the required chronology-valid historical compatibility corrections in A7/A10/A13/A14.
    • STRIPE_COMMERCE_DESIGN.md: one A15 SOURCE ONLY/NOT LIVE section and minimal A7/A10/A13/A14 historical reconciliation.

    Excluded: freshness/skew, provider/API-version/history, schema/Rules/index/package/workflow/API changes, migration/backfill/reprocessing, PAY-003B/C, deployment/provider/data/payment/refund/dispute/live work, active #571/#504, and draft #462.

    Officer impact: none.
    Officer documentation: None — no officer procedure changes.
    Deployment evidence: claim/source work only; no test, merge, website, Firebase, provider, production-data, transaction, or live claim yet.

    No tracked edit preceded this claim. The claim stays active until exact-main verification and an explicit COMPLETE/CLOSED/CLAIM RELEASED marker.

  4. daliu commented on Aug 2, 2026

    @daliu
    ContributorAuthor

    TEST-ONLY RED marker on exact base 102209dd99b331797f139dde7e209de75ea73a63

    Test-only diff SHA-256:
    42293fa5b73f111a753f32ab5e13008ff3aa18470d626d7250fe5b043b148461

    Focused Node 20 command:
    npm --prefix functions run test:run -- --runInBand --testNamePattern='PAY-003A15 Dispute/Event chronology' --silent

    Expected RED:

    • 6 failed: created, updated, and closed lifecycles across registration and order.
    • 7,486 unrelated tests skipped.
    • Each otherwise-valid signed Event used outer created=1800000000 and embedded Dispute.created=1800000001.
    • Current source reached dispute_needs_response, dispute_under_review, or dispute_won, resolved a target, mutated the business record, and created Dispute/Charge/PaymentIntent bindings.
    • Expected behavior is durable target-free needs_review:invalid_dispute_event_chronology with the valid outer ledger time and no target/binding/business work.

    Officer impact: none — test-only proof.
    Officer documentation: None — no officer procedure changes.
    Deployment evidence: no runtime/shared-fixture/documentation implementation, commit, push, PR, merge, website, runmprc.com, Firebase, provider, production-data, checkout/payment/refund/dispute, or live work occurred at this marker.

    This is the intended failing proof. Runtime, historical compatibility corrections, and documentation remain untouched.

  5. daliu commented on Aug 2, 2026

    @daliu
    ContributorAuthor

    IMPLEMENTED / PR OPEN on exact reviewed candidate b4f6b1d67c888d79284b7ac6b1afbe0fde5db406.

    PR: #595
    Tree: d4f64a11bf20696492e0394f55dd74fcc5acbc89
    Patch SHA-256: d97cd93c7779245b180865437b9eb789ae1d6c80c896c260ef8f6a0f5d07d1aa
    Exact base: 102209dd99b331797f139dde7e209de75ea73a63

    Local exact-Node-20 proof is complete: A15 65; webhook 1,025; Functions 7,487 with 64 intended skips; frontend 951; safety 86; SPA 11; Rules 418; commerce emulator 63; Functions/frontend lint, direct build, YAML, and diff checks passed. Three independent final reviews returned GO after correcting two documentation-only wording contradictions.

    Officer impact: none.
    Officer documentation: None — no officer procedure changes.
    Deployment evidence: source/test candidate only. Hosted CI and preview are pending. No merge, website publication, runmprc.com verification, Firebase deployment/readback, outside-provider configuration/action, production-data change, checkout/payment/refund/dispute activity, or live verification is claimed. The #594 claim remains active until exact-main verification and an explicit COMPLETE/CLOSED/CLAIM RELEASED marker.

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

    @daliu
    ContributorAuthor

    FINAL RELEASE AUDIT — COMPLETE / CLOSED / CLAIM RELEASED

    PR #595 squash-merged exact reviewed head b4f6b1d67c888d79284b7ac6b1afbe0fde5db406 as exact main 3ac4acee407220f34ef5ced1f43efe69279dfa09. The merge tree is the reviewed tree d4f64a11bf20696492e0394f55dd74fcc5acbc89; patch SHA-256 is d97cd93c7779245b180865437b9eb789ae1d6c80c896c260ef8f6a0f5d07d1aa.

    PR CI 30730499205 and exact-main CI 30730603255 passed all five required jobs. Preview 6a6eb7dc8db5610008dfb87e was ready, exact-head, non-production, HTTP 200, and noindex. GitHub deployments for exact main are []; exact-main workflows show CI only.

    Netlify production attempt 6a6eb8b626561400087f4372 used exact main but ended error with published_at: null. The live Netlify production source remains 9ad6837756cdd409d296009fde5082eeeae5c059; runmprc.com returns HTTP 200 and its release marker still names #473 control/source, so #594 is not live there.

    Officer impact: none — server-only evidence comparison.
    Officer documentation: None — no officer procedure changed.
    Deployment evidence: source, synthetic tests, merge, exact-main CI, preview, failed production attempt, and live older-source distinction are verified. Website publication for #594, Firebase deployment/readback, Stripe or outside-provider configuration/action, production-data change, checkout/payment/refund/dispute activity, and live behavior were not performed or verified.

    Issue #594 is closed, status/assignee are cleared, the remote branch is deleted, no review finding remains, and every #594 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