Skip to content

fix(invariants): the email-handle floor is zero now, because they are all retired - #780

Merged
catomean merged 1 commit into
mainfrom
fix/ratchet-to-zero
Aug 26, 2026
Merged

fix(invariants): the email-handle floor is zero now, because they are all retired#780
catomean merged 1 commit into
mainfrom
fix/ratchet-to-zero

Conversation

@catomean

Copy link
Copy Markdown
Collaborator

The ratchet was set to 77 — a live population that could not simply be
renamed, because a username on OrangeCat is also a Lightning address and a
public profile URL.

They are now all retired, behind profile_username_history so nothing that
pointed at an old handle broke:

INSERT 0 53   history rows recorded first
UPDATE 53     handles replaced with user_<12 hex>
UPDATE 14     display names that were also the email local part cleared

Verified against production, not assumed

check result
profiles where username = split_part(email,'@',1) 0
profiles where name = split_part(email,'@',1) 0
profile_username_history rows 54, none orphaned
count_email_derived_usernames() 0

And end to end on a real retired handle:

profile URL -> 308 https://orangecat.ch/profiles/user_a3eaa53c23cd
lnurlp      -> resolves the owner, answering under the NEW handle

That last detail is the proof: the LNURL endpoint replies about
user_a3eaa53c23cd when asked about the old handle, so the history lookup found
the right account.

Why 53 and not 77

Test-account churn between readings — the population moved 108 → 96 profiles
while E2E accounts were created and deleted, and 16 accounts had already signed
up under the fixed trigger. Every remaining one was renamed.

The constant stops being a ratchet

A violation now means a write path started minting them again. The three that
used to — the handle_new_user trigger, ensureProfile(), and two profile form
pre-fills — are each covered by a test, so a hit here means a fourth was
added. The message says that, instead of talking about a baseline that no longer
exists.

npm run verify green; 2385 tests pass.

… all retired

The ratchet was set to 77 — a live population that could not simply be
renamed, because a username on OrangeCat is also a Lightning address and
a public profile URL.

scripts/rename-email-derived-usernames.sql retired every one of them on
production, behind profile_username_history so nothing that pointed at an
old handle broke:

  INSERT 0 53   history rows recorded first
  UPDATE 53     handles replaced with user_<12 hex>
  UPDATE 14     display names that were also the email local part cleared

Verified against production afterwards, not assumed:

  email_derived_remaining      0
  name_eq_localpart_remaining  0
  history_rows                54, none orphaned
  count_email_derived_usernames()  0

And end to end on a real retired handle: the old profile URL returns 308
to the new one, and the LNURL endpoint resolves the owner through history
(it answers under the NEW handle, which is what proves the lookup found
the right account).

The count of 53 rather than the 77 originally measured is test-account
churn between the two readings — the population moved 108 -> 96 profiles
while E2E accounts were created and deleted, and 16 accounts had already
signed up under the fixed trigger.

So the constant becomes 0 and stops being a ratchet. A violation now
means a write path started minting them again; the three that used to —
the handle_new_user trigger, ensureProfile(), and two profile form
pre-fills — are each covered by a test, so a hit here means a fourth was
added. The message says that instead of talking about a baseline that no
longer exists.

npm run verify green; 2385 tests pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@catomean
catomean merged commit 315a8b9 into main Aug 26, 2026
4 of 5 checks passed
@catomean
catomean deleted the fix/ratchet-to-zero branch August 26, 2026 22:11
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