Conversation
… rename The lease is taken and renewed with one conditional update, every save checks it still holds, and the runner registry, password vault and preflight result live on globalThis so the instrumentation and route copies of the module share them. Abort queues a cancel the runner acts on before the cut-over, and refuses once the cut-over has begun whatever the step status says. Startup drops a lease from the container that went away and a rescan picks up what nobody is watching.
A rename copies roles and the password as they were when it started, so a change made meanwhile would land on the login that is about to be deleted. Role items and step-down are refused for the duration, and both password resets wait until the sign-up record points at the new login. A name edit only counts as a rename when the new name derives a different username from the old name, so a member allocated janesmith2 can fix their capitalisation without migrating. The email-change notice now goes out only where Keycloak was actually updated.
A target message counts as the copy of an old one only when its Message-ID, size and received date match and no other message has claimed it, so a reused Message-ID cannot swallow a message. The final delta and its strict check run while both sides are quiet; after the cut-over verification only compares what the member cannot have changed, and the old mailbox's app passwords go when it is frozen. Retired local parts and their aliases are never reissued, a dotted alias dropped by a name edit is retired the same way, and the sweep moves expired addresses onto a sink that bounces instead of letting them fall to the co-presidents catch-all. Names can no longer derive into role addresses such as postmaster or hostmaster. Mail rules without a blob fail the copy rather than being skipped, the retired-address notice hands activation back to the member's own script, and the preflight covers the calls the migration makes that it did not.
sync-from-prod checked that the prod schema exists, but not that each table in its copy list does. This branch's own retired_usernames table doesn't exist in prod yet, which crashed every preview build. Skip missing tables instead of crashing.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
retired_usernamesand is never reissued (sign-up allocation now checks it)Stalwart behaviour that only the preflight can prove (Email/copy, account destroy, alias re-attach, sieve notice) is unverified until it runs in production.
Checklist
npm run typecheck,npm run lint,npm run format:checkandnpm run buildpassnpm run db:generate).env.example,.env.local.example,deploy/docker-compose.ymlandkomodo/deploy-context.mjsrequireAdmin/requireApproverTesting Evidence
To follow: screenshots from the preview deploy (account details, rename confirmation, progress, Identity changes panel, preflight report).