Govern Stripe commercial remediation preparation

This commit is contained in:
rcourtman 2026-07-14 21:46:32 +01:00
parent c11bf5c757
commit d2bcfac2f6
4 changed files with 103 additions and 3 deletions

View file

@ -0,0 +1,57 @@
# Self-Hosted Commercial Stripe Remediation Prepared Record
- Date: `2026-07-14`
- Gate: `self-hosted-commercial-transition-coherence`
- Result: `repository preparation complete; production remains blocked`
- Evidence tier: `test-proof`
## Fact
The repository now contains a bounded Stripe commercial-state remediation tool
at `pulse-pro:scripts/remediate_stripe_commercial_state.py`. Its default mode
performs only GET requests and emits a machine-readable plan. Apply mode
requires the exact `APPLY_STRIPE_COMMERCIAL_STATE` confirmation and a Stripe
key whose live/test mode matches the operator's declared expected mode.
The tool derives the public Relay and Pro price IDs from the public pricing
model, validates their amount, cadence, activity, product identity, shared-
product shape, and Stripe mode, then plans at most these operations:
1. align the descriptions of the existing public Pulse Relay and Pulse Pro
products with the canonical offer;
2. reuse an exact Pulse-owned invoice/payment-method-only Customer Portal
configuration, or create a new dedicated one if none exists.
It does not contain an apply path for prices, customers, subscriptions,
webhooks, licenses, or runtime configuration. A nonconforming or unrelated
portal configuration is not modified. The dormant new-environment price
creation helper now carries the same canonical Relay and Pro descriptions.
## Offline Proof
`pulse-pro:scripts/tests/test_remediate_stripe_commercial_state.py` proves:
- monthly and annual prices must share one product per tier;
- Relay and Pro must use distinct products;
- catalog or mode drift fails before mutation;
- shared product updates are deduplicated;
- only an exact dedicated portal configuration is reused;
- a nonconforming portal causes safe dedicated creation rather than mutation;
- portal lifecycle mutation features are disabled;
- apply requires the exact confirmation token; and
- the bounded apply path posts only product descriptions and, when required,
a dedicated portal configuration.
`pulse-pro:scripts/tests/test_create_v6_stripe_prices.py` proves the dormant
creation helper carries the governed descriptions and still excludes Pro+ from
public creation.
## Non-Claim And Remaining Gate
No Stripe mutation, customer-data access, runtime configuration change,
deployment, or production re-audit was performed in this slice. This is not
production proof and does not raise the gate above `test-proof`. The production
blocking record remains authoritative until a separately approved apply and
deployment are followed by a passing GET-only audit. The external Stripe
transition/reconciliation matrix and Relay license-version-floor exercise also
remain required.

View file

@ -4791,6 +4791,12 @@
"kind": "file",
"evidence_tier": "test-proof"
},
{
"repo": "pulse-pro",
"path": "scripts/tests/test_remediate_stripe_commercial_state.py",
"kind": "file",
"evidence_tier": "test-proof"
},
{
"repo": "pulse-pro",
"path": "scripts/tests/test_validate_stripe_catalog.py",
@ -8032,6 +8038,12 @@
"path": "docs/release-control/v6/internal/records/self-hosted-commercial-transition-coherence-production-audit-blocked-2026-07-14.md",
"kind": "file"
},
{
"repo": "pulse",
"path": "docs/release-control/v6/internal/records/self-hosted-commercial-transition-coherence-remediation-prepared-2026-07-14.md",
"kind": "file",
"evidence_tier": "test-proof"
},
{
"repo": "pulse",
"path": "internal/api/contract_test.go",
@ -8091,6 +8103,12 @@
"path": "relay-server/revocation_feed_test.go",
"kind": "file",
"evidence_tier": "test-proof"
},
{
"repo": "pulse-pro",
"path": "scripts/tests/test_remediate_stripe_commercial_state.py",
"kind": "file",
"evidence_tier": "test-proof"
}
]
},

View file

@ -224,9 +224,10 @@ avoids a cloud-control-plane report data path across clients.
84. `pulse-pro:relay-server/revocation_feed.go`
85. `pulse-pro:landing-page/index.html`
86. `pulse-pro:scripts/validate_stripe_catalog.py`
87. `pulse-pro:license-server/README.md`
88. `pulse-pro:license-server/entrypoint.sh.template`
89. `pulse-pro:license-server/secrets.env.template`
87. `pulse-pro:scripts/remediate_stripe_commercial_state.py`
88. `pulse-pro:license-server/README.md`
89. `pulse-pro:license-server/entrypoint.sh.template`
90. `pulse-pro:license-server/secrets.env.template`
## Shared Boundaries
@ -1331,6 +1332,17 @@ hands-on Patrol modes, issue investigation, verified fixes, and longer history`.
inbox event for one fresh retry cycle, but it must claim the event before
dispatch, retain the original payload, use the cursor-aware retry path, and
return to bounded backoff when the replay still fails.
28. Keep production Stripe catalog remediation bounded, reviewable, and
separate from runtime deployment. The canonical tool must default to
GET-only planning, derive public price identity from the pricing model,
refuse catalog or Stripe-mode drift before writes, require an explicit
apply confirmation, update only the two public self-hosted product
descriptions, and create or reuse an exact Pulse-owned invoice/payment-
method-only portal configuration. It must not mutate an unknown portal
configuration, price, customer, subscription, webhook, license, or
deployed environment. The returned portal identifier is a separate
approved configuration/deployment input, and a passing GET-only production
re-audit remains the postcondition.
## Current State
@ -1362,6 +1374,15 @@ or customer record was mutated or inspected. The dated blocked record is
the gate stays blocked until separately approved remediation is deployed and
the same read-only audit passes.
Repository-side remediation preparation now exists in
`pulse-pro:scripts/remediate_stripe_commercial_state.py`. Offline proof covers
shared-product deduplication, strict price and mode preconditions, exact portal
reuse, safe creation instead of mutation of a nonconforming portal, bounded
write endpoints, and apply confirmation. The dormant new-environment price
creation helper also uses the same canonical descriptions. This preparation
does not change the production finding: no live apply or runtime deployment
has been authorized or executed, and the gate remains blocked.
The Relay side now fails closed on missing feed authority, drains the feed
before serving, exposes feed staleness through readiness, and tears down stale
already-connected v6 sessions while clearing their reconnect tokens. Customer

View file

@ -2975,11 +2975,15 @@
"label": "public Stripe catalog contract proof",
"match_prefixes": [],
"match_files": [
"pulse-pro:license-server/scripts/create-v6-stripe-prices.sh",
"pulse-pro:scripts/remediate_stripe_commercial_state.py",
"pulse-pro:scripts/validate_stripe_catalog.py"
],
"allow_same_subsystem_tests": false,
"test_prefixes": [],
"exact_files": [
"pulse-pro:scripts/tests/test_create_v6_stripe_prices.py",
"pulse-pro:scripts/tests/test_remediate_stripe_commercial_state.py",
"pulse-pro:scripts/tests/test_validate_stripe_catalog.py"
]
},