- sBiome, floating biomes and publishNaturalMetadata no longer write MatterBiomeInject; nothing reads it
- stack metadata clearing only runs for dimension stacks
- Version is 4.1.2-26.2 across platform builds
- Plugin builds use shared automatic jar selection
- Native adapters remain bundled in selected artifacts
- Plugin export tasks copy the selected artifact
- The previous plugin packer is removed
- The agent tracks primary storage closure during Spigot shutdown
- Limit terrain cleanup to affected columns and batch cave boundary reads.
- Reuse offline generation workers and native air states.
- Gather history writes and defer unpublished append synchronization until atomic publication.
- Cover terrain parity, worker lifecycle, history durability, and publication failures.
- Startup holds generation admission through recovery and runtime attachment
- Prepared startup state removes the second recovery scan before generator readiness
- Recovery batches allocated chunks by region with reusable snapshot buffers
- Region decoding uses up to four workers within processor and heap limits
- Oversized regions and external chunks use bounded direct reads
- Status parsing validates chunk coordinates without constructing the full NBT tree
- Region snapshots reject changed files, allocation headers and truncated payloads
- Native zlib decompression uses jlibdeflate with a Java inflater fallback
- Chunk readers reuse region handles and decompression buffers during recovery and boundary capture
- Semantic shards reuse validated summaries with invalidation on mutation
- Semantic key validation avoids regular expression allocation
- Saved biome indexes use buffered sequential reads with reusable CRC state
- Pack inspection reads validated manifest and pack state without opening terrain indexes
- Datapack compilation reuses pack inspection within each operation
- Kernel staging avoids duplicate pack hashing when no activation is pending
- Pack copying and directory synchronization use up to four available processors
- Boundary publication batches directory synchronization around durable catalog publication
- Configured world reconciliation reuses ready runtimes after identity and saved-state checks
- Explicit world loads retain the full validation path
- Regression tests cover startup admission, recovery, malformed data, resource limits, publication and reconciliation
- ItemsAdder API resolves from Maven Central
- Integration repositories only resolve their assigned groups and modules
- Shared VolmLib classes and packaging use the same pinned revision
- JitPack builds and publishes with remote dependencies
- Local Maven publication uses art.arcane:iris with the configured version
- API generation tracks the final archive filename lazily
- API jars retain signatures and metadata with valid throwing method stubs
- Publication tests verify metadata, bytecode, and consumer compilation
- Packages regrouped by domain: generation, world, pack, studio, structure, platform, command, localization, diagnostics
- Forked VolmLib utilities dropped for the shared library: noise, stream, interpolation, hunk, matter
- Engine-coupled stream decorators moved to generation.stream.GenerationStreams
- Hunk section splits now run on the Iris burst pool through HunkBurst
- Artifact entry lists, purity allowlists and shrink rules follow the new paths
Surface hydrology policy split, native terrain height cache, watched-edit
hotload cancellation, world-save requestSave with tracked ownership flush,
background-task drain that follows saves admitted mid-drain, peaceful spawn
guard, cached-completion terminal state, IO drains off the owner thread.
Studio pregen at scale: detached historical runtimes keep the configured
noise cache instead of the Studio-wide cache; retired runtimes are no longer
pinned by the volumetric fragment filter's per-thread scratch; pregen mantle
cleanup and native region flushes run on per-run threads instead of the
server thread and the shared Iris IO pool (the flush on the IO pool starved
tectonic plate loads and wedged every Paper worker in Mantle.getChunks);
background-task cancellation claims tasks atomically.
- Resolve IrisTerrainNormalActuator by keeping master's primitive riverWaterSurfaceStream lookup and primarySurfaceLayerOrNull accessors while retaining the terrain column, span, layer surface and ceiling locals that write air through terrain3D gaps
- Resolve HydrologyFootprintCompiler by keeping the MaterializedSurface planned-surface record with terrain ownership beside master's package-private SurfaceRasterIndex, which retains its ownsTerrain override
- Resolve HydrologyCaveContainmentPlanner by dropping the nested RecordingCaveVoxelView, SurfaceObservations and ViewObservations types that master promoted to their own files
- Port the surface-observation ownership check into CaveSurfaceObservations so cached cave validations replay both height and ownership observations through Observation.matches
- Resolve PackExportClosureTest by keeping master's retirement of the source-text packager guard while retaining the snippet export tests, and restore the Files and Path imports those tests use
- Resolve IrisBiomeLayerSlopeSourceTest by folding the lower-ledge slope palette case into master's lockLayers parameterization
- Recapture the studio schema digest for the terrain3D biome property, its IrisTerrain3D definition, the terrain-3d snippet enumeration and the reworded upperDimensionCarving description, verified by reconstructing the previous digest from the stripped schema
- Add an optional per-biome `terrain3D` profile with density and fissure noise styles, amplitude, horizontal and vertical feature scales, crack depth, width and scale, slope and fluid-clearance gates, and a seed offset, each range-checked before use
- Add a terrain runtime that samples the signed density and fissure fields on a four-block lattice around the biome's generated height and resolves each column into solid spans, so surfaces gain projecting rock, undercuts, ledges and narrow cracks that fade out on flat ground and near the fluid line
- Remove unsupported rock by flood-filling span components across neighbouring columns and dropping any fragment of 512 blocks or fewer, while larger connected masses are kept
- Report the shaped column top as the natural terrain height, keep the unshaped generator height available as a separate stream, and measure surface slope between neighbouring ledge floors instead of the flat heightmap
- Write air through the gaps in the normal terrain actuator, generate a fresh surface palette for every ledge floor, and paint ceiling layers beneath undercuts
- Carry each layer's own column through the dimension stack and upper dimension so stack top heights, solidity and surface lookups follow the spans, and each exposed face draws its palette from its own source height and slope
- Sample a layer's slope condition once per column at the surface being generated, and gate surface decorators on the slope of the ledge they sit on rather than the column heightmap
- Decorate every exposed ledge floor and the ceiling above it during the decorant pass
- Treat shaped openings as surface rather than cave when resolving biomes, skip them during cave carving, suppress cave zone markers inside them, and resolve their boundary biome from the surface biome stream
- Include shaped openings in mantle carve queries and carved columns, fall back to terrain solidity for surface-solid checks across stack, upper and normal terrain, and answer both queries from the island mask when placing objects on floating islands
- Let the hydrology planned surface report whether it owns a column, so the cave voxel view consults natural terrain solidity where hydrology does not own the terrain, and split replayed plan observations into height and ownership records
- Validate `terrain3D` on biomes and `snippet/terrain-3d` snippets as a blocking pack error, rejecting unknown fields, wrong types, out-of-range numbers, unknown noise styles, style nesting past 32 levels and snippet references that escape the pack
- Copy the whole snippet tree during modded studio pack export through one shared routine instead of only `snippet/style`, so terrain and nested style snippets survive export
- Add a terrain probe and Gradle task that generates real pack chunks, compares predicted column geometry against the actual blocks, requires retained overhang coverage for named biomes, reports detached-component topology, and writes cross-section images with a JSON summary
- Enumerate image-mapped regions and skip compat-excluded ones when collecting biomes for stacked and upper dimension terrain
- Remove the accessor allocation comparison whose per-call byte counts depend on escape analysis timing and failed under load, keeping the three behavioral accessor tests
- Make IrisInterpolation extend the VolmLib IrisInterpolation and delete the nine numerically identical statics it duplicated: hermite, cubic, bicubic, bihermite, trihermite, tricubic, lerp, blerp and trilerp
- Keep the Iris rangeScale because the VolmLib copy short-circuits bmax == bmin and generation output must not move
- Ship the VolmLib IrisInterpolation and InterpolationMethod by removing their unusedVolmLibClasses entries
- Make StorageHunk, ArrayHunk, AtomicHunk, SynchronizedArrayHunk, AtomicDoubleHunk, AtomicIntegerHunk and AtomicLongHunk extend their VolmLib counterparts and only bind the Iris Hunk interface
- Drop the Lombok data, equals and hashCode generation the duplicated storage hunks carried
- Ship the VolmLib storage hunks by removing their unusedVolmLibClasses entries
- Delete unused board BoardSettings and ScoreDirection wrappers around the VolmLib board types
- Delete unused inventorygui UIStaticDecorator, Window and WindowResolution wrappers around the VolmLib inventorygui types
- Delete unused VectorMath subclass of the VolmLib VectorMath
- Delete unused InterpolationType enum and the IrisInterpolation blerp overload that keyed on it
- Delete HunkFace and point Hunk.viewFace and Hunk.cropFace at the VolmLib HunkFace
- Drop the iris board and inventorygui excludes from supersededVolmLibPackages and the VectorMath entry from unusedVolmLibClasses
- Drop the deleted inventorygui files from the Bukkit purity allowlist
- Remove VectorNoiseKernels2D from requiredBukkitArtifactEntries; the class was deleted with the unwired 2D kernels and verifyBukkitArtifact failed on every build
- Move world registration and shutdown quiescing into JigsawStudioRegistry
- Move save, export and close arbitration into JigsawStudioSaveLifecycle
- Move autosave scheduling, drains and undo into JigsawStudioAutosaveScheduler
- Move variant creation, duplication and deletion into JigsawStudioVariantEditor
- Move variant metadata and resize edits into JigsawStudioVariantProperties
- Move workcell capacity, labels and connector blocks into JigsawStudioWorkcellEditor
- Move graph mutation and live relayout into JigsawStudioGraphMutations
- Move dynamic graph evaluation into JigsawStudioEvaluator
- Move menu state, studio tools and deferred duplication into JigsawStudioToolbelt
- Move the studio world event handlers into JigsawStudioProtectionListener
- Move ownership and mutation guards into JigsawStudioProtection
- Move variant materialization and hydration into JigsawStudioMaterializer
- Move dirty marking into JigsawStudioDirtyTracker
- Move workcell capture scheduling into JigsawStudioCaptureScheduler
- Move chunk capture and connector aggregation into JigsawStudioCapture
- Move materialized and rendered chunk writing into JigsawStudioChunkWriter
- Move jigsaw marker NBT watching into JigsawStudioTileWatcher
- Move particle preview rendering into JigsawStudioVisualization
- Move player workcell context into JigsawStudioPlayerContext
- Point the studio service tests at the relocated collaborators
- Record the split studio sources in the Bukkit purity allowlist
- Move each jigsaw menu kind into its own renderer class
- Move workcell capacity staging into JigsawStudioWorkcellMenu
- Move menu presentation helpers and adjustment math into JigsawStudioMenuFormat
- Promote the menu action contract to JigsawStudioMenuActions
- Point the menu controller test at the relocated menu types
- Move planar object resize geometry into JigsawStudioObjectResizer
- Move owned graph JSON document transforms into JigsawStudioGraphDocuments
- Move owned graph reference checks into JigsawStudioGraphInspector
- Point the graph editor resize test at the relocated resizer
- Add a scripted studio persistence session digest test over project and history bytes
- Move each jigsaw subgroup executor into its own top-level command class
- Move the adoption plan store, handlers and helpers into CommandJigsawAdopt
- Move the vanilla export lease and reporting helpers into CommandJigsawExports
- Move the studio open lifecycle into CommandJigsawOpen
- Point the jigsaw contract test at the relocated command types
- Exclude the new jigsaw command sources from the generation revision scope
- Move segment rasterisation and channel shaping out of HydrologyFootprintCompiler into HydrologyFootprintRasterizer and HydrologyChannelGeometry
- Move chamber, throat and pool construction out of HydrologyCaveContainmentPlanner into HydrologyCaveChamberPlanner
- Promote the candidate span, candidate builder, stencil, column and cave observation types out of the three compilers to top level
- Return the Minecraft version lookups to DatapackIngestService so no new file couples to org.bukkit
- Drop the redundant self imports of the service's own nested types
- Keep planner state, caches, cross-tile entry points and terrain sampling in HydrologyPlanner and move tile planning into ten collaborators for cross-tile resolution, outlets, sources, route geometry, route paths, surface courses, tributaries, underground courses, hydraulic segments and feature sites
- Promote the shared planning records to top level so the collaborators address routes, grids, drafts and course paths directly
- Pin a full four-tile plan digest for two seeds in HydrologyPlanHashTest
- Requalify the reflective and package-private planner call sites in the hydrology tests onto the new owners
- Keep ingest orchestration and the public entry points in DatapackIngestService and move startup validation, staging reapply, removal, install planning, ownership, manifests, transactions and recovery into dedicated package classes
- Promote the shared ingest data types to top level so every collaborator addresses them directly
- Report the managed metadata IO failures on the reapply path instead of logging them at debug
- Requalify DatapackIngestServiceTest call sites onto the new owners without changing any test
- Move registry catalogs, enum definitions and block-state groups out of SchemaBuilder into SchemaRegistryCatalog, SchemaEnums and SchemaBlockStates
- Decompose buildProperty into SchemaPropertyBuilder per-type handlers with SchemaRegistryProperties owning the per-annotation registry chains
- Report the font enumeration, registry list function and default value probe failures instead of swallowing them
- Pin the generated studio schema digest for fifteen pack roots in SchemaBuilderIdentityTest
- Add a test source set to spi with bind, service registry and platform value contracts
- Prove the DataType probe contract, the ExternalDataProvider defaults and the string-only provider namespace claims
- Prove Identifier parsing and rendering
- Cover the data version, primitive and vector director handlers
- Cover the vanilla export identifier, block state, orientation, request and settings values
- Cover the structure adoption limits, diagnostics and result invariants
- Cover the pregen mantle backpressure, heap reclaim urgency, empty cache, listener defaults and diagnostic descriptions
- Split PackValidatorCustomBiomeSpawnTest into parameterized accepted and rejected suites plus the resolver-failure case
- Drive IrisCarveWallPaletteScopeTest from its four generation-scope modes
- Parameterize the legacy bilerp parity samples in IrisComplexGridBoundsCacheTest behind Enclosed
- Parameterize the resolved bounds in IrisStructureYBandTest
- Parameterize the entity key normalization in IrisBiomeCustomSpawnTest
- Parameterize the platform identity in IrisWorldIdentityTest
- Parameterize the layer lock in IrisBiomeLayerSlopeSourceTest
- Replace GenerationHistoryRuntimeRouterTest with promotion, routing and lifecycle classes
- Add GenerationHistoryRuntimeRouterSupport on top of GenerationHistorySupport for the shared fakes and helpers
- Drop the router-local copies of createPack, createHistory, stage, contract, signature and writeRegion
- Move art.arcane.iris.testsupport into core/src/testFixtures and apply java-test-fixtures to core
- Consume core test fixtures from the bukkit plugin, nms, probe and the three loader adapters
- Delete the duplicate ProjectPaths copies in the bukkit-plugin and modded-common test trees
- Point ModdedMessageContributorTest at the shared ProjectPaths
- Guard CommandPackCompatTest, NativeTransitionColumnTest and StubPlatformStateTest with PlatformLeakGuard
- Release the probe runtime state after DimensionStackSuperflatProbeTest opens a workspace
- Keep core main classes ahead of the core jar on the test classpath so the bytecode gates still scan a directory
- Remove the Javadoc and inline comment blocks the three runtime-safety commits added under src/main
- Keep the GPL file header on the new spi type, matching every other file in that module
- Leave the superseded stale-temp ordering comment deleted rather than restoring text the new boot path contradicts
- Add RuntimeInjection so the Java agent attach and the server-code injection run once, on demand, instead of during every enable
- Install the injection when a world Iris created is about to be built and when Bukkit asks for the generator of a world configured outside Iris
- Lock the runtime with the same reason a boot-time injection failure used to raise when the deferred install fails
- Add general.eagerRuntimeInjection to keep boot-time injection and its startup verification
- Re-read the startup lock after a deferred install so a failed install refuses the world instead of generating it
- Move the stale cache/temp sweep off the boot thread and make every pack import wait it out
- Move the default-pack presence warning off the boot thread; it walks the whole pack tree to pick a warning
- Build the wand and dust templates on the first tick instead of during service enable
- Report enable duration, per-phase timings and the three slowest services on every boot
- Drop the wand and dust templates on service disable
- Null Iris.instance, the console sender, the Multiverse link, the compat set and the chunk tickets at the end of teardownRuntime
- Bind the host bridge suppliers to the constructing plugin instead of reading the instance static on every call
- State that Iris is disabled when service, getTemp or getSender is reached after teardown instead of raising a bare NullPointerException
- Add IrisRuntimeStatics so a disable drops the service registry, both capability singletons, the loaded datapack runtime and the localization roots
- Add WorldLifecycleService.reset and WorldRuntimeControlService.reset so the next boot snapshots the server it is running on
- Add ServerConfigurator.resetLoadedDatapackRuntime so an enable revalidates instead of trusting the previous boot's fingerprint
- Clear the localization data folder and plain-text memo on shutdown
- Add BukkitPlatform.releaseHost and call it last in terminal cleanup so the disabled plugin, console sender and log bridge stop being reachable from a static
- Add art.arcane.iris.spi.CapabilityProbe so an absent optional API is recorded at debug with the failure class and message instead of a bare ignored catch
- Route runtime day-time reads, clock pushes and the noon time lock through IrisLogging.reportError with the world name and the full trace
- Report a level storage access that will not close, so a retained world session lock names its cause
- Report a failed iris.json rewrite with the file path instead of dropping the IOException
- Report Iris world registry and dimension read failures during Multiverse reconciliation instead of logging one debug line
- Report a failed pack compatibility summary and a failed vanilla-slot capture with their traces
- Report a superseded generation semantics shard that cannot be deleted, once, with its path
- Restore the interrupt flag when the global cache trimmer join is interrupted
- Replace ValueWithDiagnostics with CheckResult so a startup check carries the runtime lock reason it raises
- Give every startup check an explicit advisory or critical severity and lock the runtime on any Danger result, replacing the catch that recognised the injection check by id
- Lock the runtime when general.disableNMS holds a no-op binding or the NMS binding is unbound, instead of marking the runtime ready
- Match incompatible plugin names against every registered plugin without regard to case
- Name the JVM maximum heap in the memory check output
- Print the lock reason and what it blocks when Iris enables into a locked runtime
- Carry the per-check safeguard modes and diagnostic lines in /iris debugdump
- Delete NoiseKernels2D, ScalarNoiseKernels2D and VectorNoiseKernels2D after measuring the vector kernel at 0.07x scalar on 2-lane NEON with no production call site
- Delete the 2D noise parity test and the SimdSupport plumbing that selected between the two kernel sets
- State in the simd-bench README that its 2D noise classes are a candidate Iris does not ship
- Replace the six per-voxel IrisPosition probes in MantleWriter neighborhood hollowing with an origin-relative primitive key set
- Look mask membership up through the same primitive key set instead of allocating an IrisPosition per candidate voxel
- Give the squared-distance helper a fixed arity so ballooning no longer depends on escape analysis to drop its varargs array
- Resolve each Matter slice once per write instead of paying a hasSlice probe and a getSlice lookup for the same class
- Read the river water surface through the primitive stream accessor instead of boxing a Double per column
- Add nullable primary surface layer accessors so the terrain actuator stops building two Optionals per column
- Add MantleWriterNeighborhoodTest, MantleWriterNeighborhoodBenchmarkTest and HydrologyColumnSampleAccessorTest
- Replace the pregen cache global monitor with atomic per-plate and per-region state and a lock-free resident-plate memo
- Serialize plate eviction and its disk write under the residency lock so a reloaded plate can never lose a concurrent bit
- Retry a chunk or region cache write whose plate was retired mid-write
- Delete SynchronizedCache and the isThreadSafe wrapper it existed for
- Replace the AsyncPregenMethod semaphore and permit monitor with PregenAdmissionGate, one condition that signals on release, adaptive-limit change and cancellation
- Attribute the adaptive and permit waits separately from the single gate wait
- Wait on a progress signal instead of sleeping 25ms in PregenMantleBackpressure, signalled by chunk completion
- Wait on a state signal instead of sleeping 50ms and 150ms in IrisPregenerator pause, heap pressure and tectonic reclaim loops
- Restore the burst pool parallelism when the last pregen job finishes
- Add PregenCacheConcurrencyTest, PregenAdmissionGateTest and PregenWaitPolicyContractTest
- Add PregenDiagnostics.probeFailed so capability probes log their name, class and message at debug instead of vanishing
- Report the moonrise worker pool, mantle radius, engine access and Folia submit probe failures through that helper
- Report async pregen mantle cleanup failures through IrisLogging.reportError with the trace instead of dropping them
- Report a stranded plugin chunk ticket through IrisLogging.reportError so the leaked pin is visible
- Emit the chunk load failure trace before the metrics snapshot so a failing snapshot can no longer silence it
- Report the pregen cancellation and mantle handle probe failures in PregenMantleBackpressure
- Report the Medieval engine resolution probe failure
- Record the real Vector API initialization failure in SimdSupport and print the accurate kernel selection reason
- Add PregenDiagnosticsTest, PregenSilentFailureContractTest and SimdSupportStatusTest
- Complete the async route close on the worker executor so the cross-thread assertion no longer depends on whether the first stage finished before the handler was attached
- Require the core source tree alongside the settings file when walking up for the repository root, so modded-common tests built inside a loader adapter no longer stop at that adapter's own settings file
- Assert the spawn failure report through the bound platform instead of a thread-confined static mock, so the report is seen whichever thread wins the reporting race
- Guard WorldEntitySpawnerLifecycleTest against a leaked platform binding
- Unbind the stub platform after the probe module's platform state test
- Add the Await test helper that polls a condition every ten milliseconds under a bounded timeout
- Replace every Thread.sleep in the fourteen polling test classes with a condition wait, a latch wait or a bounded quiet window
- Keep the crash-consistency fsync interception in GenerationHistoryAdmissionTest and SavedBiomeStoreBatchTest on real barriers
- Add the ProjectPaths test helper that derives the module root from the test class code source and the repository root from the settings file above it
- Replace the working-directory-relative source and resource literals in thirty-five test classes with module and repository lookups
- Drop the bespoke source-root walk in PregenMantleCleanupContractTest
- Add the PlatformBinding rule that binds a mock platform for a class or method, unbinds on teardown and restores the previous binding
- Add the PlatformLeakGuard rule that fails a class when a platform is still bound or a service is still registered at class start or end
- Add IrisRuntimeState so the guard reads the registered services without adding a test-only method to the SPI
- Replace the inline mock-platform setup and teardown of twenty test classes with the rule
- Guard the remaining sixty-four platform and service touching core test classes
- Rename the pack-compat pool fixtures to PackCompatFixtures so the two CompatFixtures names cannot collide
- Scope BukkitTestServer branding to a ServerBranding rule that restores the shared mock after each test
- Add Durability, a process-wide fsync policy defaulting to real barriers and switchable to relaxed through the iris.durability system property
- Route the history, studio, journal, structure and datapack fsync barriers through Durability so relaxed mode skips both the force and the channel open
- Add the DurabilityMode test rule and enable relaxed durability on the twenty slowest core stores tests
- Split GenerationHistoryTest into epoch, legacy adoption and recovery classes over a shared GenerationHistorySupport base
- Delete 22 test classes whose assertions only read production .java text and check call ordering or literal presence
- Remove 77 source-text assertion methods from 34 test classes that keep real behavioural coverage
- Replace the core process-stream source grep with an ASM gate over compiled core classes in CoreProcessStreamPurityGateTest
- Replace the packs-root source grep in PacksFolderContractTest with an ASM call-site gate over compiled core classes
- Replace the IrisData registered-root regex in PackTypeBukkitPurityGateTest with an ASM scan of the registerLoader class constants
- Trim six mixed tests down to their behavioural assertions and drop their source-text tails
- Drop the eight iris.*Source and three iris.moddedCommonSources test system properties now that nothing reads them
- Add a root moddedTest that runs adapters/modded-common through the Fabric build
- Make check depend on moddedTest, ordered ahead of the loader jars
- Gate the buildSrc jar on the buildSrc tests so they stop being skipped
- Drop an unreachable classpath guard from SchemaBuilderPlatformIsolationTest
- Delete stale jars through an injected FileSystemOperations in the root build
- Delete stale loader jars through an injected FileSystemOperations in each adapter
- Resolve stale-jar file trees and copy sources at configuration time
- Expand the loader metadata templates from the configured version string
- Read the modded bukkit-supertype baseline from core/purity-allowlist.txt
- Match nested classes against their top-level source entry
- Exempt VolmLib classes, which Iris' core ratchet does not govern
- Delete the hand-frozen knownBukkitSupertypeClasses inventory
- Drop outputs.upToDateWhen and outputs.cacheIf from the loader jar Exec tasks
- Declare lombok.config, core/agent and both revision scripts as modded inputs
- Add gradle/runtime-relocations.gradle as the one runtime-download relocation map
- Read the slimJar relocations and shrinkRelocations from that map
- Pass the derived relocation prefixes into BukkitArtifactVerifier
- Drop the duplicate jar size check the packaging audit already enforces
- Add minecraftPurityRatchet over core/minecraft-purity-allowlist.txt, wired into check
- Register both purity ratchets from one closure instead of duplicating the scan
- Prune WorldCreationProgressReporter from core/purity-allowlist.txt
- Wire the ProGuard shrink pass into the Bukkit artifact with the core, Bukkit plugin and NMS compile classpaths as library jars
- Map the fourteen SlimJar relocations so runtime-downloaded libraries resolve under their relocated names
- Add packaging/shrink.pro keeping the public API, Iris events, platform SPI, VolmLib integration contract and Bukkit event handler lists
- Lower maximumBukkitArtifactBytes to 7,600,000 so verifyBukkitArtifact enforces the same budget as the packaging gate
- Build VolmitSender.name() from the sender name instead of the relocated CommandSender.name() reference, which cannot resolve on Paper 26.2
- Replaced the nine static final PlatformBlockState fields in IrisDimensionStackActuator, IrisTerrainNormalActuator, IrisPerfectionModifier, IrisPostModifier, IrisBiomeLayerGenerator, BiomeBuffetGenerator, ChunkDataHunkHolder and EngineMantle with BoundBlockState holders that re-resolve when a different platform binds, costing one volatile read of the cached binding, one of the bound platform and a reference compare per read
- Turned the IrisPerfectionModifier ore-hiding table into a Map of BoundBlockState so the four base states follow the bound platform instead of the first one loaded
- Kept the last resolution in BoundBlockState while nothing is bound so in-flight generation on an unbinding server reads the same states it did before, matching what B.registries already does
- Added IrisPlatforms.getOrNull so the block-state holders read the binding once without an exception on a bare JVM
- Added PlatformStateRebindTest, which fails on the old code: it binds two mock platforms in turn and asserts ChunkDataHunkHolder and EngineMantle serve the second one, and rejects any static PlatformBlockState field left on the converted classes
- Indexed the .iob write palette by key so palette lookup is a hash probe rather than a scan of the palette list, cutting the 32767-state IrisObjectIoWriteLimitsTest from 4.9s to 0.7s while writing byte-identical files
- Built the palette once per write instead of once in validateWritable and again in the writer, and shared it between the plain and progress-reporting write paths
- Added IrisObjectIoPaletteTest, which pins the SHA-256 of a 30000-block, 3011-state object written by the previous implementation and asserts the palette keeps first-seen insertion order
- Added BukkitTestServer, a single mock Bukkit server installed once per JVM under a lock, stubbing logger, name, version, plugin manager and both createBlockData overloads, and failing loudly if the install does not take
- Moved IrisRuntimeSchedulerModeRoutingTest, WorldRuntimeControlServiceTimeLockTest, PreObjectMatterTest, CNGInjectorParityTest, BukkitSpiConformanceTest, MantleWriterPreObjectJournalTest, IrisFloatingChildBiomesCarvingResolutionTest and IrisDimensionCarvingResolverParityTest onto it, so whichever class runs first no longer decides whether createBlockData or getPluginManager is stubbed
- Extracted the KeyedBlockState test double out of IrisObjectIoWriteLimitsTest so the palette test can reuse it
- Replaced the IrisServices.clear() teardowns in nine test classes with a targeted remove of the PreservationRegistry each one registers, so a teardown no longer wipes a binding it did not install
- Registered a PreservationRegistry in PackDownloaderTest and StudioSVCWorldPackPublishTest, which reach IrisData.get and openRuntime and were silently getting loaderless IrisData whenever no other class had leaked one
- Removed the core processResources skip that fired on test-only invocations, which packaged a core jar with no generation kernel catalog and made all 10 probe and bukkit-plugin tests that reach GenerationKernelRegistry fail on every ./gradlew test
- Set maxParallelForks on :core:test to half the available processors, overridable with -PtestForks, and left the small modules single-forked so they do not re-pay the Minecraft bootstrap per fork or steal worker leases from core
- Resolved B.registries() per bound platform instead of latching the first one for the JVM lifetime, keeping the previous unbound behaviour, so a test that binds its own platform no longer reads a foreign platform's block states
- Resolved IrisObject.States per bound platform through accessors instead of static finals fixed at class-init, removing the NoClassDefFoundError and null material-key failures that appeared whenever class partitioning changed
- Bound an explicit platform in EngineMantleCoverageTest and IrisDimensionStackActuatorMetadataTest so they no longer depend on another class leaking a binding first
- Gated BukkitSpiConformanceTest registry probes on a live RegistryAccess and restored the IrisPlatforms binding it leaked, which was silently swallowing the stderr two SettingsHotloadWatchTest assertions read
- Initialised org.bukkit.Registry and Biome inside the RegistryAccess mock scope in ObjectStudioGeometryTest so Mockito no longer instruments Registry mid-clinit
- Replaced the SettingsHotloadWatchTest fixed 1200ms diagnostic window with a 10ms condition poll bounded at 4s
- Replaced the IrisCaveCarver3DNearParityTest wall-clock speedup benchmark with a deterministic density-sample count, cutting 28 carves to 2
- Cut HydrologyPlannerTest cold-owner parity from 12 tile plans to 4 and shared the immutable baseline plan across the early-owner tests
- Built one prototype project or staged history per class in the jigsaw studio and world replacement tests and copied it per test, replacing repeated fsync-bound fixture construction
- Replaced Mockito block-state fixtures with concrete implementations in the object IO, deposit modifier and nearest-block-index tests, removing about 2.5 million interceptions
- Replaced Thread.sleep with bounded condition polling in HydrologyTileCacheTest
- Deleted 19 test classes and 60 further test methods that asserted on production .java source text rather than behaviour, and removed the 19 now-unread iris.*Source system properties that fed them
- Terrain and cave scans skip repeated work
- River and structure lookups reuse cached results
- Chunk history saves share disk writes
- History lookups continue during disk writes
- Failed saves retain their original errors
- Deposit failures stop incomplete chunks
- Tests check output and save safety
- Saved biome records use one durable append with shorter lock ownership
- Terrain receipts buffer field writes before compression
- Native cache retirement follows the current index
- Server shutdown drains native chunk tasks before world close
- Shutdown flushes retain native save ownership
- Regression coverage checks persistence and shutdown races
- Server shutdown advances native chunk tasks while waiting for pregeneration
- Native world close owns chunk saves during server shutdown
- Pending plugin flushes stop waiting when native shutdown begins
- Late eviction completion cannot schedule another shutdown flush
- Regression tests cover owner waits and shutdown save ownership
- Biome encoding runs outside the region write lock
- Appends use one framed write before durable publication
- Concurrent claims preserve conflict checks and rollback behavior