Skip to content

fix(e2e): green prod LIVE suite — provision+reap as minted pro account#176

Merged
mastermanas805 merged 1 commit into
mainfrom
fix/e2e-prod-green
Jun 5, 2026
Merged

fix(e2e): green prod LIVE suite — provision+reap as minted pro account#176
mastermanas805 merged 1 commit into
mainfrom
fix/e2e-prod-green

Conversation

@mastermanas805

Copy link
Copy Markdown
Member

Problem

e2e-prod.yml (run 26997362193) was RED on prod with two failure classes:

  1. Anon provisions 402 (free_tier_recycle_requires_claim). The X-E2E-Test-Token fingerprint bypass was only sending X-Forwarded-For, but the api's internal/middleware/fingerprint.go reads the dedicated X-E2E-Source-IP header for the override (ingress-nginx overwrites XFF on prod). So every anon provision collapsed onto a single fingerprint carrying a recycle_seen marker → 402.
  2. Anon reap 401. There is no unauthed resource-delete on the api, so the ledger reaper's DELETE /api/v1/resources/:id 401'd on anonymous resources — the "0 failed reaps" assertion failed.

Fix (provision + reap AS the minted account on prod)

  • cohort.ts: anonProvisionHeaders() now sends X-E2E-Source-IP (the header the bypass actually reads) with a unique IP per call → fresh fingerprint → no recycle gate. New authedProvisionHeaders() + provisionIdentity(): when E2E_SESSION_JWT is set (sanctioned prod run), resources are provisioned as the minted is_test_cohort PRO account (no recycle gate, tier headroom) and the provision bearer is recorded on the ledger so the reaper's authed DELETE returns 200, not 401. Staging/local keep the anon-with-bypass path.
  • live-provision-smoke.spec.ts / live-anon-provision.spec.ts: use provisionIdentity(); assert the identity's tier (pro authed / anonymous otherwise); record id.bearer for the authed reap.
  • live-claim-deploy.spec.ts: anon claim/replay/env legs get fresh fingerprints via the source-IP fix; the deploy-lifecycle leg now deploys as the minted pro account directly (deployments_apps=10) instead of skipping on prod — falls back to the dev-only set-tier path on staging.

Verification

npm run gate green (tsc + build + vitest: 1115 passed, 3 skipped). The e2e-prod workflow run will be the live verification.

🤖 Generated with Claude Code

Two prod-only failures from run 26997362193:
  1. Anon provisions 402 (free_tier_recycle_requires_claim) — the
     X-E2E-Test-Token bypass was sending X-Forwarded-For, but the api's
     fingerprint middleware reads the dedicated X-E2E-Source-IP header for
     the override (XFF is overwritten by ingress-nginx on prod). So every
     anon provision collapsed onto one fingerprint that had a recycle_seen
     marker → 402.
  2. Anon reap 401 — there is no unauthed resource-delete on the api, so the
     ledger reaper's DELETE /api/v1/resources/:id 401'd on anon resources.

Fix (decisive: provision + reap AS the minted account on prod):
  - cohort.ts: anonProvisionHeaders now sends X-E2E-Source-IP (the header
    the bypass actually reads) with a unique IP per call → fresh fingerprint
    → no recycle gate. Adds authedProvisionHeaders() + provisionIdentity():
    when E2E_SESSION_JWT is set (sanctioned prod run) resources are
    provisioned AS the minted is_test_cohort PRO account (no recycle gate,
    tier has headroom) and the provision bearer is recorded on the ledger so
    the reaper's authed DELETE returns 200, not 401.
  - live-provision-smoke + live-anon-provision: use provisionIdentity();
    assert the identity's tier ('pro' authed / 'anonymous' otherwise);
    record id.bearer for the authed reap.
  - live-claim-deploy: anon claim legs get fresh fingerprints via the
    source-IP fix; the deploy-lifecycle leg now deploys AS the minted pro
    account directly (deployments_apps=10) instead of skipping on prod —
    falls back to the dev-only set-tier path on staging.

npm run gate green (tsc + build + vitest: 1115 passed, 3 skipped).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown

size-limit report 📦

Path Size
dist/assets/index-902QtfQT.js 161.98 KB (0%)
dist/assets/index-BsJUZYRr.css 6.13 KB (0%)

@mastermanas805
mastermanas805 merged commit f2b9e0f into main Jun 5, 2026
18 checks passed
mastermanas805 added a commit that referenced this pull request Jun 5, 2026
…on (#177)

Run 26998139097 (the #176 fix) got most legs green but 3 still red:

1. A10 logout-revocation (live-auth.spec.ts) revoked the WORKFLOW-MINTED
   E2E_SESSION_JWT. That assumption ("A10 is the last authed leg") broke once
   #176 made live-claim-deploy (deploy leg) and live-provision-smoke also
   provision/reap AS that minted session — they run AFTER live-auth, so the
   deploy POST got 401 revoked_session and smoke's /db fell through to the anon
   path (tier=anonymous, then 402/401-on-reap). Fix: A10 now ALWAYS revokes a
   DISPOSABLE bearer it owns — provisionAndClaim now returns the claim's real
   session_token (onboarding.go:537), and A10 revokes THAT throwaway team's
   session, reaping its resource BEFORE the logout (the logout kills the only
   bearer that authorizes the DELETE). Never touches E2E_SESSION_JWT.

2. Authed (pro) /queue/new HANGS on prod (90s timeout) — the isolated
   per-tenant NATS path blocks until the operator seeds NATS NKeys (CLAUDE.md
   P1 gap). Fix: provisionIdentity(extra, forceAnon) pins the queue flow to the
   anonymous path (fast, returns auth_mode=legacy_open). The anon resource is
   TTL-reaped (no authed DELETE for anon resources); the anon-provision spec's
   reap is best-effort for no-bearer resources (asserts only 401/403 — the
   expected "no unauthed delete" outcome — so a different failure still reds).

3. Smoke tier=anonymous + 402 was a downstream symptom of (1); fixed by it.

npm run gate green (1115 passed, 3 skipped).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant