A recording runs against a server that may not be up again soon, so an administrator missing one permission shouldn't throw away the whole pass. Each of the three is recorded on its own now: what the server allows is written, what it refuses is named at the end with the permission it wants, and the exit is still non-zero so an incomplete recording can't pass for a finished one. A refusal used to print the raw JMAP error. It now reads, for example, "[email protected] may not x:Tenant/get: You are not authorized to perform this action (needs sysTenantGet)". Checked both ways: the refusal path against a stubbed client, where the other two sections still record; the whole thing against a live test server, which recorded 3 tenants and 53 masked addresses and exited 0.
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'