Step 2 stops stalwart.service and step 4 points the fork at a store path. Between those two moments nothing protects the original, and the rehearsal had already shown that one open by the fork costs the rollback for good. What protects it until then turns out to be the running server itself: RocksDB refuses a second opener with "While lock file: LOCK: Resource temporarily unavailable". So the intuition that a service shutdown prevents the mistake is backwards — the shutdown is what enables it. Measured, in probe_guard.py, in the three states that matter: held by the running server, the fork is refused and the rollback is intact; stopped but read-only, the fork is refused while rotating its own log and the Enterprise build still starts on it afterwards; stopped and writable, the fork opens, adds its column family, and upstream never starts again. So step 3 now makes the original read-only as soon as the copy is taken, which turns a discipline problem into a one-line one, and the answered section carries the table.
Fork tooling
strip.py
Makes an Enterprise-free snapshot of an upstream release. See the docstring and docs/spec/SPEC.md §2.2 for what it does and why.
git clone https://github.com/stalwartlabs/stalwart.git ~/src/stalwart-upstream # outside this repo
git -C ~/src/stalwart-upstream fetch --tags
tools/fork/strip.py --upstream ~/src/stalwart-upstream --ref v0.16.22 --out /tmp/strip-v0.16.22
It writes OUT/tree (the stripped source) and OUT/STRIP-REPORT.md and
.json. Exit 0 means verified clean. Exit 1 means malformed markers, or
something Enterprise-only survived. Read the report's Problems section.
The report's Third-party code section lists upstream code under other
licenses. Files marked new need their notice added to THIRD-PARTY.md
at the repository root before the import is merged.
It needs Python 3.12+ (for tarfile's data filter) and git.
record-compat.py
Records what the *_compat tests compare against, from the Enterprise
server, while it is still running. Read-only: /get and /query only.
See docs/spec/compat-tests.md.
tools/fork/record-compat.py --server https://mail.example.org \
--admin '[email protected]:PASSWORD' --out ./compat \
--tenant-admin '[email protected]:PASSWORD'
run-compat.sh
Runs the *_compat tests against a copy of INBUXA's RocksDB store, making
a fresh copy for each one. See docs/spec/compat-tests.md.
tools/fork/run-compat.sh --store /srv/inbuxa-copy/rocks.db \
--admin '[email protected]:PASSWORD' --recordings ~/compat