YOU500 + other default-group players couldn't use /sethome /balance
/list /hs etc — commands ran but Essentials/Homestead returned
permission-denied (perm absent on default group), denial appearing
silent client-side. Granted 17 essentials perms + 1 homestead.user
perm via RCON. Verified by YOU500 in chat: list/balance/sethome work.
JSON export attached for audit trail (H2 DB is gitignored).
Carbon viewer-context bug: <luckperms_prefix> resolves against viewer
not sender. Researched two open-source alternatives.
Both fix the bug. ChatChat (HelpChat fork) renders per-recipient with
PlaceholderAPI.setPlaceholders(sender, ...) + Kyorifier converts legacy
& codes to MM. VentureChat resolves PAPI once vs sender, splits packets
via ProtocolLib.
Concerns:
- ChatChat: 0 GitHub releases, last commit 2025-04-02, apiVersion 1.21.4,
uses deprecated AsyncPlayerChatEvent
- VentureChat: built for 1.21.8, open issues #154/#156/#157 report
1.21.10+ breakage with no maintainer response 4+ months
Both verdicts: cautious recommend. Operator decision pending player
input + migration plan synthesis.
Repairs the orphaned synapse-signing-key block at scripts/backup.sh
lines 119-122 that was exiting the script under set -e before the
Minecraft block could run, leaving 5 of the last 7 days without a
world backup and zero usable snapshots after 7-day retention.
Phase 1 (deployed today to /opt/docker/backup.sh on nullstone):
- Repaired script — orphan block removed, MC arm wrapped so failures
in one tar don't kill the run
- tar exit code 1 ("file changed as we read it") now treated as
success on the live MC world; spark profiler tmp file noise
silenced via --ignore-failed-read --warning=no-file-changed
- Plugin DBs (homestead, AuthMe, CoreProtect, LuckPerms) and configs
now backed up alongside the world
- Sentinel /opt/backups/.last-success stamped only when the world
arm succeeds — gives outside monitors a single mtime to alert on
- Manually verified end-to-end: 12G world tarball, 492M plugins,
279M dbs, 14 config files, sentinel updated. Pre-fix script saved
at /opt/docker/backup.sh.bak-20260507-pre-phase1.
Phase 2 (scripts in repo, deployment pending operator sudo):
- scripts/restic-backup-playerdata.sh — Class A 5-min restic snapshots
of playerdata/, stats/, advancements/, plugin DBs, LuckPerms;
rcon save-all flush before snapshot; tag-scoped retention
- scripts/restic-init.sh — one-time bootstrap (root-only) for
/etc/mc-backup.{env,pw} + repo init at /home/user/restic/
- scripts/systemd/mc-backup-playerdata.{service,timer} — 5-min timer
with hardening (ProtectSystem=strict, ReadOnlyPaths, etc)
- docs/RUNBOOK-BACKUP-RESTORE.md updated with both phases'
deployment steps and the operator-action checklist
Off-host mirror to onyx (Phase 4) and class B/C/D world snapshots
(Phase 3) are still TODO — see BACKUP-STRATEGY.md §11 phase plan.
PAT whitelist was missing region/rg/hs/homestead/unclaim, blocking the
only entry-points to Homestead's claim flow for default players.
Added them to ProAntiTab/storage.yml on the live box and reloaded.
EssentialsX shadows /help by load-order, hiding the branded HelpCommand
page behind hide-permissionless-help. Added a help -> helpcommand:help
alias to commands.yml. Takes effect on next restart.
Lands plugin's jar is not installed (only its config dir remains);
docs explain why /lands references in HelpCommand and PAT are dead.
Adds:
- docs/DEFAULT-RANK-COMMANDS-2026-05-07.md diagnosis + fix log
- docs/PLAYER-SMOKE-TEST.md regression checklist for
YOU500 as the test rig
- scripts/test-default-perms.sh snapshot dump for diffing
before/after config edits
H2 (F-06): cap_drop ALL + minimum cap_add (CHOWN, SETUID, SETGID, FOWNER),
no-new-privileges, deploy.resources.limits.pids=4096. compose config valid.
DAC_OVERRIDE deliberately omitted; re-add only if entrypoint chown fails.
H3 (F-05): Xmx 16384M -> 14336M, MEMORY_SIZE 16G -> 14G. Leaves ~3.5G
headroom for off-heap inside the unchanged 18G container limit. Host has
no spare RAM to raise the cap (other workloads).
H1 (F-02): server-wide gamerule keepInventory true planned but RCON path
for gamerule is broken (F-16) so it's deferred to operator in-game on next
op session. Documented in INTERIM-MITIGATIONS.md with a clear revert
trigger (when AuthLimbo F1+F2+F4 ship).
H4: pre-edit compose backed up to docker-compose.yml.bak-2026-05-07-before-H2H3
(deployed and repo). Restore commands in INTERIM-MITIGATIONS.md.
Live restart deferred: 2 players online (s8n actively restoring YOU500's
gear via /give). H2/H3 go live on next compose recreate.
Defensive belt-and-suspenders for "no /help hint on join":
1. motd.txt already emptied (commit 7e7d18e)
2. LP: 'lp group default permission set essentials.motd false' applied
live (h2 db updated at 18:35). Default group can no longer trigger
on-join motd even if motd.txt gets refilled later.
ProAntiTab storage.yml: add lp + luckperms to global allow-list so the
deny-perm command itself can run via rcon (whitelist mode was blocking).
Note: LP h2 storage isn't tracked in repo (.empty-103450 placeholder
files only). Live server is source of truth for LP state.
welcome.txt isn't read by current AuthMe — Settings.useWelcomeMessage
key is absent from config and the file was empty. The post-login
message is actually login.success in messages_en.yml, which was set
to '' (silenced).
- messages_en.yml: login.success now multi-line via \n escape:
"successfully logged in" + "type /help for a list of commands"
- welcome.txt: emptied (unused)
Live reloaded via authme reload.
Players are still in AuthLimbo when motd fires on join, so the hint
scrolls past while they type /register or /login. Move it into AuthMe
welcome.txt which fires after successful login.
- Essentials/motd.txt: emptied (hint moved out)
- AuthMe/welcome.txt: appended "type /help for a list of commands"
below the existing "successfully logged in" line
Live: applied via docker exec + essentials/authme reload.
- purpur.yml: broadcasts.advancement.only-broadcast-to-affected-player
false -> true. Player still sees own advancement, no global chat spam.
- ProAntiTab storage.yml: add gamerule/execute to global allow-list
(vanilla gamerule still blocked by Brigadier even from datapacks —
switched to Purpur broadcast option as workaround).
- ProAntiTab config.yml: auto-lowercase-commands disabled (was
toggled while debugging gamerule failure; harmless either way).
Synced from /opt/docker/minecraft live, applied via purpur reload.
Captures live config state of nullstone Purpur 1.21.11 server:
- docker-compose.yml (itzg/minecraft-server image, MODRINTH_PROJECTS + PLUGINS lists)
- All plugin configs under live-server/plugins/ (no DBs, no jars, no world data)
- Server core: bukkit.yml, spigot.yml, purpur.yml, paper-global.yml, paper-world-defaults.yml, server.properties
Excluded via .gitignore:
- World data (world/, world_nether/, world_the_end/, auth_limbo/)
- Sensitive: AuthMe DB (password hashes), Lands DB, CoreProtect DB, Essentials userdata
- Jars (auto-fetched), logs, caches, .paper-remapped