Repository navigation
PAY-002B2C2 — Persist pre-POST Stripe send evidence and stop unsafe retries #182
Description
Officer impact: None. This adds an unused server safety boundary and tests; it does not change any current officer task, website page, payment flow, or production system.
Officer documentation: None — no officer-visible or operational behavior becomes available.
Deployment evidence: Closure must distinguish source, tests, merge, website publication, Firebase deployment, Stripe/provider configuration, and production behavior. This issue must not deploy or contact Stripe.
Outcome
Add an unused server-only transaction boundary that records durable evidence immediately before a possible Stripe POST and refuses unsafe automatic retries.
Invariant
A retry may reuse only provider attempt 1, the exact immutable PAY-002B2C1 plan, parameters, account, mode, API version, endpoint, operation, and deterministic Stripe key. It is permitted only inside a fixed source-owned safe window that is strictly shorter than 24 hours. At or after the deadline, or when the first-send time is missing or untrustworthy, the result is reconciliation_required. This child never advances to attempt 2.
Timeout, connection loss, Stripe 5xx, a missing object reference, or an incomplete search never prove that Stripe did not execute the POST.
Exact scope
- functions/commerceCommandJournal.js
- functions/commerceCommandJournal.test.js
- functions/commerceCommandJournal.emulator.test.js
- tests/firestore-rules/shop-and-locked.test.js
- STRIPE_COMMERCE_DESIGN.md
- SYSTEM_DESIGN.md
- SECURITY.md
- IMPLEMENTATION_PLAN.md
- GITHUB_ISSUES.md
- GITHUB_ISSUE_SLICES.md
Explicitly excluded: stripeWebhook.js, checkout creators, commerceState.js, functions/index.js, packages/lockfiles, workflow files, Firestore Rules source, provider configuration, real data, and officer procedures.
Required behavior
- Recompute and validate the complete PAY-002B1 identity and exact PAY-002B2C1 plan.
- Require the exact active PAY-002B2B lease holder and fence.
- Atomically create first-send evidence and its deterministic audit before returning a fixed send_permitted result.
- Bind every retry to provider attempt 1 and the identical immutable plan.
- Use one trusted transaction timestamp and a fixed retry deadline strictly under 24 hours.
- Accept an exact retry only before the deadline.
- At deadline equality, after the deadline, on clock rollback, or with absent/malformed send time, return reconciliation_required.
- Never infer non-execution from timeout, network loss, 5xx, missing provider reference, or incomplete search.
- Preserve B2A, B2B, and C1 records byte-for-byte.
- Add no Stripe/network call, endpoint export, runtime adopter, deployment, or provider configuration.
Required tests
- First pre-send marker and deterministic audit commit together.
- Twenty-four concurrent calls create one marker and one audit.
- Exact same-plan retry is permitted only inside the fixed window.
- Boundary checks immediately before, exactly at, and after cutoff.
- Timeout, connection-loss, and 5xx fixtures remain ambiguous and never advance attempts.
- Changed plan/key/account/mode/version/parameters conflict.
- Wrong holder/fence, expired lease, terminal lifecycle, and clock rollback fail closed.
- Missing, orphaned, malformed, future-version, or preseeded partner records remain untouched.
- Commit failure produces no half-record.
- Transaction reruns reuse prepared immutable values and one trusted timestamp.
- Raw key, account, parameters, caller, UUID, PII, provider response, and hostile canaries never enter storage, output, errors, logs, or audits.
- Anonymous, member, and browser-admin clients cannot access the path.
- Static boundary proves no endpoint/index import and no Stripe, network, logger, random, environment, or attempt-advancement API.
- Focused tests, full Functions suite/lint, hosted journal emulator, Rules, frontend/SPA/build, artifact scrubber, and diff checks pass.
Dependencies
Complete: #157, #161, #163, #165, #167, #169, #173, #175, and #177.
#110 blocks retention/deletion policy, not this additive unused record. #113 blocks real inventory/adoption, not synthetic source-only validation.
Coordination
This is the live child for PAY-002B2C2. Do not create a duplicate. The parent PAY-002 design remains partial after this issue: B2C3 reconciliation/attempt advancement and every runtime checkout adopter stay open.
Do not begin until assigned and a timestamped CLAIMED marker names the agent, branch, base commit, and exact paths.
Activity
daliu commentedon Jul 13, 2026
CLAIMED by Codex agent /root at 2026-07-13T21:04:52Z on branch codex/issue-182-pay-002b2c2-presend from exact base 97ec6ee. Ownership is limited to functions/commerceCommandJournal.js, functions/commerceCommandJournal.test.js, functions/commerceCommandJournal.emulator.test.js, tests/firestore-rules/shop-and-locked.test.js, STRIPE_COMMERCE_DESIGN.md, SYSTEM_DESIGN.md, SECURITY.md, IMPLEMENTATION_PLAN.md, GITHUB_ISSUES.md, and GITHUB_ISSUE_SLICES.md. Excluded runtime/provider/workflow/package/Rules-source/officer paths remain immutable. One unused source/test outcome only.
daliu commentedon Jul 13, 2026
EXTRACTION FINISHED — 2026-07-13T21:36:35Z
Branch:
codex/issue-182-pay-002b2c2-presendBase:
97ec6eeccc99e27d00ca271a0c874cbba9f36420The staged index contains exactly the 10 claimed paths. No runtime/index import, Stripe/network call, package/lock/workflow change, Firestore Rules source change, provider configuration, production data, or officer procedure is included.
Safety result:
Verification on Node 20 / Java 17:
Three independent read-only reviews (security, test/coverage, and documentation/status) approve the exact staged diff with no findings.
Deployment evidence: source and synthetic tests only. Website, runmprc.com, Firebase, Stripe/provider settings, and production behavior were not changed or claimed.
PAY-002B2C2: persist Stripe pre-send retry evidence (#183)
daliu commentedon Jul 13, 2026
COMPLETE / CLAIM RELEASED — 2026-07-13T21:40:55Z
PR #183 was admin squash-merged from exact reviewed head
db70adc610d55c4a5c8e04e2279b5ebf4fa5ee37as main commit95be260d08377b7e931dd3526da91b59c5fbf755.Exact-head CI run 29287012581 passed Frontend, Functions, Firestore Rules, Test artifact scrubber, and the 31-case Commerce command journal emulator. Post-merge main CI run 29287130585 passed the same five jobs, including the named real Firestore concurrency suite.
The issue closed through the merged PR and
status:in-progressis removed. The 10-path claim is released for work refreshed from95be260or later.Release truth: source/tests/docs are merged. This API is deliberately not imported by any runtime endpoint. No website publication, runmprc.com verification, Firebase deployment, Stripe/provider configuration, production data action, or live behavior occurred. PAY-002B2C3 reconciliation and all runtime adoption remain open.