2026-07-22
Newest entry on top.
Session — v1.5.0 groundwork: throttling, void/catch-all, automated screenshots, publishing, README
Owner mandate, two messages. First: automated per-release screenshots driven by the Mineflayer harness (particles + a group of items disappearing), per-user throttling with a set of strategies, a configurable void chance and catch-all storage, gh-pages screenshots page so the README self-refreshes, a complete README rewrite, and automated multi-platform publishing. Second: a full survey of server platforms (Purpur, Folia, Sponge, Velocity, Fabric, NeoForge, …) with "target as many of these as possible".
Ledger (verbatim clauses, C1–C24):
plans/mandate-2026-07-22-screenshots-throttling-publishing.md.
What landed
Two commits on dev, both green through the full CI suite:
5b88aec— per-user throttling + void chance + catch-all storage (see the changelog entry for the design). ~60 new assertions across six test files;koverVerify≥ 90 and detekt/ktlint stayed green with no baseline and no new suppressions.38884c3— automated screenshots, publishing, artifact bundle, README rewrite, platform matrix.
Decisions worth remembering
- Catch-alls are config-driven, not flagged
DespawnLocations. Adding acatchAllcolumn would have meant a schema migration across three storage backends for a feature that is purely operator-facing.world;x;y;zentries inconfig.ymlgive the same capability with zero migration risk and no way for a player to register one. - The void roll happens at enqueue, not per strategy attempt. An item's fate should be
decided once; rolling inside
DespawnProcesswould re-roll at every candidate location and silently multiply the effective chance. - Screenshots are non-blocking and NOT a required check. They are a deliverable, not a
correctness gate — a renderer hiccup must never hold a good release. This is also why the
clientbackend falls back toviewerinstead of failing. - Honesty about particles is encoded in the artifact, not just the docs. Every frame
records the backend that produced it in
manifest.json, and the gallery prints it. Aviewerframe of the landing effect captures the moment the effect fires, not the particle sprites; only theclientbackend photographs real particles. - Declared loaders stop at the Paper family.
paper · purpur · spigot · bukkit. Listing fabric/neoforge on Modrinth would generate bug reports we cannot reproduce. - Purpur got a real smoke job. "It's a Paper fork so it works" is exactly the kind of claim
that should be proven;
server-smoke.shnow acceptspurpur-<version>and boots a real Purpur server fromapi.purpurmc.org(verified the download URL resolves, 57 MB, 1.21.11).
The screenshots are blank — read this before touching the harness
Four CI cycles took the harness from "doesn't install" to "runs green, captures eight frames, all of them bare sky". The full rule-out table and the two remaining hypotheses (each with its next probe) are in the mandate ledger's not-done list.
The single most useful next step is ten lines: page.evaluate the browser scene's child
count. That one number splits "the viewer never got world data" from "it has data and isn't
drawing it", and every further attempt is guesswork until it is known.
Two things worth internalising from this:
- "The job is green" and "the feature works" are different claims. The first run that
captured eight files reported success, and the files were empty. The blank-frame guard now
in
screenshots.mjsexists so that can never be mistaken again — and it is why the screenshots job is currently, correctly, red. - Every fix this session came from an observation, not a hunch. The three that landed
(
canvas,Vec3, viewer ordering) were each named by a log line. The remaining ones are unresolved precisely because the log does not yet name them — hence adding the probe rather than trying a fourth guess.
Rough edges
- The PowerShell MCP tool times out around two minutes, so long Gradle builds and
gh run watchhad to be run to a log file and polled instead of watched. Worth remembering for future sessions:cmd /c "gradlew.bat … > log 2>&1"thenSelect-Stringthe log. mc-publishhas moved fromKir-Antipov/mc-publishtoKira-NT/mc-publish. The v3.3 tag SHA was read from the live API rather than guessed — pinning a fabricated SHA would have broken the release workflow silently until the first publish.
Ship-contract readings (2026-07-22)
- OpenSSF Scorecard: 7.6 (was 7.1) — above the ≥ 7.0 floor.
- Open PR backlog: empty — nothing to triage or close.
- Tech debt noted, not fixed: the Paper API deprecation warnings in
DespawnBlockIntoAir,DespawnIntoCookerandDespawnIntoVoid(setOwningPlayer,Sign.lines(),CookingRecipe.input,ItemStack.type) are pre-existing and still present. They violate the "no deprecation warnings left to rot" clause of the ship contract and should be cleared before v1.5.0 is tagged.