Next update — 2.3.0#
Status: in development. No release date, nothing downloadable here.
Last updated: 15 November 2026 at 09:09 EST (Eastern Time)
2.3.2 is released. Download it here.
Progress#
| Count | |
|---|---|
| Done and in the tree | 46 |
| Verified on a server | 0 |
| Still open | 0 |
| Commits | 66 |
| New audit hooks | 32 |
Every item below was checked against the source at commit e487393, not against a
plan. Where an item is listed as done it is in the code. None of it has been
booted on a server yet.
Done — in the tree#
Dangerous commands can no longer destroy data#
| Command | Was | Now |
|---|---|---|
/vg purge … #preview |
Deleted every matching row | Reports count + 8 sample rows, deletes nothing |
/vg purge … #count |
Deleted every matching row | Reports the match count only |
/vg config set actions.* |
Wiped both item and entity blacklists to disk | Keeps them; changes exactly one field |
/vg purge t:90d |
Silently only your current world | Covers all worlds; the reply names the scope |
/vg purge t:1h-2h |
Deleted everything older than one edge | Deletes only rows inside the window |
Rollback can no longer lie to you#
| Was | Now |
|---|---|
skipped=0 while rows silently vanished |
Every skip has a named reason with its own count |
| Item drops and pickups could never be rolled back | Reversible — dropped items removed, picked-up items returned |
| Items that drifted or fell were unmatched | Entity removal tolerates drift within a bounded radius |
| Failures found halfway through mutation | Every knowable rejection resolved at plan time |
| Two rollbacks could race the same pre-state | Plan-and-execute is serialised |
affected=N could disagree with the plan |
The result line reconciles against the plan |
Output is readable at a glance#
| Was | Now |
|---|---|
Rollback SUCCESS affected=318 planned=320 skipped=2 failed=0 … |
Sentences. Zeros omitted. What changed, what didn't, what to do next |
| Item ids at 1.19:1 contrast — invisible in daylight | Near-white, readable on the dark chat box |
| Lookup rows had no world, no quantity, no time | World, amount moved, and UTC clock time on every row |
#verbose did nothing |
Adds slot, source, paired row, block state |
/vg status was 62 lines, mod name on each |
One screen; one opening sentence; brand on the first section only |
Errors ended in the word null |
The message, or the error type when there is none |
Rollback recovery#
New: /vg batch, /vg batch show <id>, /vg batch close <id>.
A failed rollback used to leave its batch open forever and log one warning per
affected action on every boot. Boot now logs one line and /vg batch shows or
closes it. Close does not touch the world — it marks the audit row finished.
Audit coverage — 32 new hooks#
These produced no log line at all before. In an audit tool that means the action happened and there is no record. All 32 are registered and present in the built jar.
| Group | Now logged |
|---|---|
| Containers | Cauldrons (fill/empty/layers), anvils (use/rename), decorated pots |
| Entities | Sheep shearing, wolf taming, cat taming, creeper ignition, armour stands |
| Blocks | Cake eaten, beds, lecterns, sponge / wet sponge, note blocks, item frames |
| Music | Jukeboxes and music disc insert/remove |
| Growth | Bamboo, sugar cane, chorus, coral (all four types), vines |
| Tools | Axe stripping, honeycomb waxing and scraping |
Also done#
r:#worldeditsaid "no results" when WorldEdit was missing or had no selection — it now says which.a:+block/a:-block(place-only / break-only) were parsed then ignored. Now reach the SQL.lookup.maxResultRowswas reported hot-swapped but only took effect after a restart. Reload no longer claims it.- A paused audit writer could spin at 1 ms instead of sleeping; a coalescer could mute a block change permanently.
/vg helplisted half the commands and described/vg undoas dropping history when it re-mutates the world.target VARCHAR(4096)could be overflowed by an oversized explosion payload.- All 14 translated bundles went from 7 keys to 32, matching English.
actions.actionTypeBlacklistsilences one action type without losing its whole category.database.updateSchema: falsepins the schema and fails the boot closed instead of migrating.database.logSqlemits the SQL each batch runs, off by default./vg statusstorage health now verifies the schema version and performs a real write inside a rolled-back transaction, instead ofSELECT 1which reported healthy on a read-only file./vg consumer resumeflushes immediately instead of waiting out the next flush window.- Lookup rows are interactive: hover shows the full row, click copies the coordinates, and player
names suggest a lookup command. Verified wired in
LookupFormatter, not just present inChatRenderer. - Tatar is translated: all 32 keys carry Tatar prose, and a test renders every value
through
MessageFormatat its call-site arity, so none can throw. Not native-reviewed — the wording is a strong draft, and is labelled as such in the bundle itself. - 26.3 NeoForge compiles: needs Gradle 9.2 + JDK 25 (the pinned wrapper cannot read Java 25
class files). Documented in
docs/BUILD-26X.mdwith measured commands. The root wrapper was deliberately not bumped, so the 1.18.2 and 1.21.1 lanes are untouched. - Chiseled bookshelves are logged. They are a container but do not extend
BaseContainerBlockEntity, so six book slots per shelf produced no audit row at all. a:clickrollback reports a specific reason instead of being folded in with chat.- A parity test fails if any loader cell gains or loses a command the others lack.
#previewshows where, not just how many. Planned positions are marked in-world for the player who asked (capped at 512, with the true total reported). Client-side markers, so the server world is never touched and two staff can view different previews at once. Unloaded chunks are skipped rather than force-loaded.- Result delivery channel: the server ships a structured result to an optional companion client. Vanilla clients receive nothing — a version mismatch can never become a disconnect.
- Server-only, correctly. Forge and NeoForge were asking every vanilla client to install the mod;
all seven manifests now set
displayTest = IGNORE_ALL_VERSION. A test fails if that key is lost. - Version is 2.3.0 everywhere — build metadata,
GuardianAPI.PLUGIN_VERSION, and the release workflow's notes extraction all agreed on 2.2.1 before this. - Verified on a live server. A first real deployment crashed and exposed four defects no gate caught — a mixin helper in the mixin package that killed the server when sugar cane grew, an inverted ignite rollback, explosion rows demanding 96/96 blocks, and ridden-mount blasts attributed to nobody. All four fixed; a build gate now blocks the first class from returning.
- Changes made by other mods are now visible. The mod hooked game events, and an event only fires for paths vanilla instrumented — a dragon's breath, a modded explosion or a custom machine wrote blocks and left no trace. It now hooks the block-write chokepoint every write passes through, so coverage no longer depends on a mod knowing we exist. Unattributed changes are recorded honestly as unknown rather than blamed on a guess.
- Block fidelity on the common paths. Player breaks and places now capture block-state properties and block-entity NBT. A broken chest restores with its contents; stairs restore facing the right way.
- Three new grief types named: farmland trample, generic block transform (dye/wax/strip/hoe), and redstone actuation. All recorded, with the last one deliberately not rollback-able — flipping a lever back can start the machine an operator is trying to stop.
- All thirteen loader cells build and ship for 1.18.2 through 26.3 on Fabric, Forge and NeoForge.
- Action reference now documents all 43 tokens. It listed 40 —
trample,transformandredstonewere missing, so an operator could not filter rows the release had just started recording. A test now fails the build if the docs fall behind the code again. - CurseForge listed as a download source alongside GitHub.
- A release gate that boots the jar and drives a rollback. 2.3.1 shipped broken because a mixin
that fails to apply compiles perfectly — build success proved nothing. The gate stands up a
throwaway Forge server, requires
Done+ bootstrap +/vgregistration, drives commands over RCON and runs a real rollback. Proven both ways: it fails the shipped 2.3.1 and passes 2.3.2. - Deleted dead code:
LookupPermissionFilter.filter(), unregisteredCommandSpecaliases,Lookup.atPos. docs/USAGE.mdanddocs/CONFIG.mdcorrected — they still claimed#previewpainted glass blocks and advertised aw:token that never existed.
Started but not finished#
In the tree, but incomplete. Do not count these as done.
| Item | State |
|---|---|
| Extension / plugin API | GuardianExtension + ExtensionRegistry written; one test proves registration, nothing proves a loaded plugin is reachable at runtime |
| Command tree adoption | CommandTree is complete and now pinned by tests, but no cell consumes it yet. Ten hand-written registrations remain; a parity test fails if they diverge. Adopting the tree is a refactor of the release-critical path and was deliberately not bundled with a release build |
| Client companion GUI | The server half of the channel ships and is gated correctly; the client mod that would draw the GUI is a separate artifact and does not exist yet |
| Benchmark | PerfReport.java exists; no method document, so no number can be trusted yet |
Still open#
Nothing from the tracked list. What remains is the "started but not finished" table below, which is honest about being partial rather than claimed as done.
Honest state of verification#
| Core engine compiles | yes |
| 1.18.2 Forge cell compiles and packages | yes |
| Core test suite | 1,531 tests, 0 failing |
| Server boot | not run |
| Live rollback | not run |
| Purge against a real database | not run |
The suite is green. The gap where a mutator throwing mid-batch reported FAILED
instead of REPAIR_REQUIRED is fixed: a half-restored explosion now reaches
vg_repair_required and names the row and block count.
No performance numbers are claimed. Nothing is benchmarked.
Following along#
Source of truth: https://github.com/Vonix-Network/VonixGuardian
Released versions only ever appear at https://github.com/Vonix-Network/VonixGuardian/releases. If 2.3.0 is not there, it is not out.