Skip to content

Audit fixes: three rounds of fixes from the multi-track Codex audits - #49

Merged
Shaan-Shoukath merged 99 commits into
mainfrom
dev
Oct 30, 2026
Merged

Shaan-Shoukath merged 99 commits into
mainfrom
dev

Conversation

@Shaan-Shoukath

@Shaan-Shoukath Shaan-Shoukath commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Fixes everything from two multi-track Codex audits of main, in three rounds:

  • Round 1: the 38 findings from the 10-track audit of 40d1e274.
  • Round 2: about 45 findings from the 13-track re-audit of the merged result, 3256e71f.
  • Round 3: the findings from a final data/privacy track and a Codex re-verification of round 2.

Claude built rounds 1 and 2. From round 2's review fixes onwards, Codex did the fixes and reviewed every branch before merge.

What changes

Auth and accounts

  • The super admin can't sign in with Google, on web or mobile.
  • Sign-in redirects are checked after dot segments are resolved, closing the open redirect.
  • A missing or malformed device id counts as an unknown device for alerts and audit.

Payments and finance

  • Time is read after the locks are taken, and ticket types, promo codes and extras are checked again before an ended hold is revived.
  • Refunds stay pending when a provider lookup fails. Stripe refund lookup pages through every result.
  • A payment captured after cancellation is refunded in full.
  • An organisation fence comes first in the lock order. Organisation deletion is refused while money is owed, a payment is in progress, or a cancelled event or date still has money to refund. Deletion retries if a deadlock aborts it.
  • There's a new list of refundable orders. Orders on cancelled targets that were checked in can be refunded by hand, and this never stacks on the automatic refund.
  • An event or series that still holds money can't be deleted.
  • Test payments are left out of live totals.
  • Finishing refunds works for already-cancelled dates and events at any time. Series cancellation queues its notices in bulk.

Registration and holders

  • Invite-only registration and ticket orders allow one seat, for the signed-in invitee.
  • A transfer or a holder email change retires every capability of the old holder:
    • the attendance link and the submission link;
    • the team management link;
    • the ticket token is rotated;
    • their expense claims are detached from the ticket.
  • Queued emails only resolve capability links for the current holder.
  • Cancellation, claims and admission actions recheck the ticket under the lock.
  • Team moves are checked against check-in races. There are no team promotions or admission offers on cancelled events.

Programmes

  • Mobile judging is pinned to the current round.
  • Claim withdrawal is scoped to its claim.
  • Mobile shows reviewing workspaces.
  • Application webhooks are crash-safe, with stable event ids, and are built inside the drain transaction.

Lock order

  • Deadlocks are fixed across office hours, grants, mobile sessions, list undo, crew, help reassignment, shifts and claims.
  • A person lock serialises a mentor's bookings against their volunteer shifts.
  • Changing a mentor's access, issuing their crew ticket and linking their account now happen in one transaction.

Operations and storage

  • Storage deletion uses a durable queue that removes every version and delete marker, falls back to plain deletes on R2, and is fenced by attempt count.
  • Uploads are registered before their first byte.
  • Backups refuse to run without encryption.
  • Runner root safety, pinned GitHub Actions, and Docker dependencies installed from the lockfile.
  • Deploys check migrations under the install lock and refuse an unsafe rollback.
  • Restore resets the schema and restores in one transaction.
  • vps-status works when there are no backups yet.
  • Trigger timestamps are UTC, and offline check-in replays are recorded.

Migrations

  • 20261120000000_payment_audit_fixes
  • 20261120010000_utc_trigger_timestamps
  • 20261120010100_storage_deletion_queue
  • 20261120010200_offline_check_in_mutations

Owner decisions and accepted residuals

  • Everyone signs in again once after the deploy.
  • Older instances must be stopped within 1 hour of migration 20261120010100.
  • Don't change the storage bucket without migrating the files first. There's a residual 26-hour window for uploads.
  • A multi-date pass with a cancelled date blocks organisation deletion until its whole remaining balance is refunded.
  • Replaced event covers, organisation logos and event page logos are not deleted from storage. This is documented.
  • An Event-locked command that writes a row referencing the Organisation can deadlock with a concurrent organisation deletion. PostgreSQL aborts one of them and the deletion retries. This is documented.
  • The admission backfill on populated pre-release admission schemas (dev/staging only) is documented, not changed.

Checks run locally on f99b0ae8 (Windows)

Passed:

  • prisma generate, migrate deploy, migrate status, db:verify and the schema drift check
  • lint, the help index check, the frontend catalog check, next typegen and tsc
  • integration: 1037 / 1037
  • production:check, with the CI placeholder environment
  • npm run build

Unit: 2959 passed, 15 failed. The failures are vps-installer and docker-entrypoint, which hit Windows path and shell limits and fail the same way before this work; plus 3 timeout-prone files that pass when run alone.

Not run locally: e2e, production e2e and the Docker image build (not enough memory on this machine). CI covers them.

QA before release

  • Test the runner and backups on a real VPS: encrypted-only backups, the deploy migration guard, rollback refusal, and restore.
  • CI builds the Docker image.
  • Check the storage deletion queue against real Silo or S3; and R2 if it's used.
  • Remind users that everyone signs in again once after the deploy.

🤖 Generated with Claude Code

Shaan-Shoukath and others added 30 commits October 29, 2026 17:20
Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…from committed lockfiles

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hows it

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ackfill clash

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rows sent

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…like

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ound to sign-in

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…k, review grants in /me

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s all: true

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r the queue

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…g per mentor

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ation, Razorpay refund idempotency

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…to them, recheck add-on stock

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…check-in races and attendance releases

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… admin, sign-in-bound MFA proof, signup limit, team undo access, feedback privacy)
… target, reviewer queue filter, office-hour lock, results freeze)
…ecute its files as root

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…show why

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…iew grants, crew claims, pinned chat and ops webhooks, shared address classifier)
Shaan-Shoukath and others added 28 commits October 30, 2026 00:11
Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…has a use left

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	content/help/attending/registering.mdx
…ansaction

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
…ests lock the event first, lock-wait race tests

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
…tity links recheck duties

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
…hange capability retirement, check-in races on team moves, no team promotion on cancelled events, report access before metrics, offline roster audit, admission-aware answer edits, ticket authority rechecked under the lock)

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
…mobile judging round pin, claim withdrawal scope, mobile reviewing workspaces, crash-safe application webhooks built in the drain transaction, promo recheck on reopened admission holds)

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

# Conflicts:
#	lib/core/mentorDesk/shared.ts
…ices, queue replaced files for version-aware deletion, atomic schema reset on restore

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
…nd logos are not deleted

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
…e alerts, own-property broadcast placeholders, absolute webhook deadlines, version-aware storage deletion with R2 fallback and attempt fencing, migration-aware deploy and rollback under the install lock, atomic restore, vps-status without backups)

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
…ne transaction; mentor commands lock the event first

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
…s it

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
…rialization codes

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
…ile sessions, list undo, crew, help reassignment and shifts; person lock; mentor and volunteer clashes refused both ways; atomic mentor grant, crew ticket and identity links; organisation deletion retried after a deadlock)

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
…ound 2

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eletion; refundable orders filtered before the limit

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
…e with the old holder; claim and admission actions recheck the ticket under the lock

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
…y refunded orders no longer block deletion

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
…nt first

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
…nt holder, claims leave with the previous holder, claim and admission actions recheck the ticket under the lock, claim paths lock the event first)

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
…ied refunds resolve; bulk series cancellation notices

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…omatic refund can't act

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
…at any time

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
…ganisation deletion, refundable orders filtered before the limit, checked-in cancelled orders refundable by hand without stacking on automatic refunds, events and series holding money can't be deleted, bulk series cancellation notices, finish refunds for already cancelled dates)

Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: Shaan-Shoukath <shaanshoukath4522@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Shaan-Shoukath
Shaan-Shoukath merged commit 5204b0b into main Oct 30, 2026
10 checks passed
@Shaan-Shoukath Shaan-Shoukath mentioned this pull request Oct 30, 2026
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