Skip to content

Releases: mcp-tool-shop-org/si-rpg-engine

0.4.0 — the four packages

Choose a tag to compare

@mcp-tool-shop mcp-tool-shop released this 30 Sep 21:22
07894f1

The first publish of the four packages. v0.3.0 remains the 27 September release.

Added

  • Four packages publish under the npm org. @si-rpg-engine/frame, @si-rpg-engine/tick, @si-rpg-engine/host, and @si-rpg-engine/load are workspaces at 0.4.0. The root package stays private. .github/workflows/release.yml publishes a staged tree on a GitHub release. A full release points the latest dist-tag at that version. A prerelease stays on next.
  • A host binds to a written socket. The world record is version 1. The frame stream, the intent door, and the blend rule are docs/host-binding.md. The session's driven actor is the world file's goal actor. A collider's quaternion stays off the wire when the file does not name it. The product golden stays 69a671f962665563. The Linux digest stays fe5d46350f944426a684742479a41b352340c4caee47a56733eb50ce3a2e8bf3.
  • A scene may name a mesh. Load accepts { positions, indices } up to 999,474 triangles and refuses a repeated index, a non-finite position, or an index out of range. The law builds one fixed trimesh. Worlds that do not name a mesh are unchanged. The product golden stays 69a671f962665563.
  • A bad mesh is refused before it is built. createWorld runs the same mesh check as load and throws that reason. A refused load or step does not hold that world and does not copy bodies back.

Changed

  • rapier3d-f64 is 0.36.0, with parry3d-f64 0.31.1. The product golden stays 69a671f962665563. The Linux digest stays fe5d46350f944426a684742479a41b352340c4caee47a56733eb50ce3a2e8bf3.

Fixed

  • The suite on this tree is 521 tests.

Golden hashes

Harness Hash
harness/sim.mjs (product) 69a671f962665563
harness/arith.mjs (arithmetic contract) 0d38671370d12d1e
fixtures/solver.sha256 (Linux binary) fe5d46350f944426a684742479a41b352340c4caee47a56733eb50ce3a2e8bf3

0.3.0 — a driven body does not solve against a dynamic body

Choose a tag to compare

@mcp-tool-shop mcp-tool-shop released this 27 Sep 20:31
8d9a8a3

The suite from 0.2.0, with dispatch 128's law slice on it. A driven body and a dynamic body do not share a solver contact. test-instrument stays frozen. The package is not published to npm.

Added

  • A model proposer in the bench. bench run --model --diff <file> runs one seat session per world beside the grammar, starting where the grammar goes eight admitted candidates with nothing new or runs out of budget. The report lists what the model's arm and an equal-cost grammar arm each newly find. It is off unless named, the role it runs must be thawed, and test-instrument stays frozen. A thawed test-only copy lives in fixtures/roles/.

Changed

  • A driven body does not solve against a dynamic body. A driven collider is solver group 3 and excludes group 2. A dynamic collider is group 2 and excludes group 3. Statics keep Rapier's default. Collision groups are unchanged, so the narrow phase still finds the pair, and the collider's handle does not change when the groups are written. The groups follow the body when it switches in place. There is no JavaScript switch. With the groups off, every law run matches the groups-on law except red room A, where a driven body touches a dynamic one. The traces part at quantum 43, and only the crate's final pose moves.
  • The step-up boxes stay under 1 m/s. On the room from #121, a dynamic box that overlaps the walker, or meets its head and is not carried, used to leave near 16 m/s. That 16 m/s is the walker's own step: 0.25 m in one quantum of 1/64 s. Both boxes now stay under 1 m/s. A carried box stays at speed 0.
  • The refusals sweep no longer records a thrown walker or a thrown crate. At tick 356 the walker's vertical speed goes from 0 to -0.125 and its rise is 0.750, under the climb rule. The other worlds in the sweep did not move.
  • Red room A's push run ends at 4f33610323f8d7ba. The speed guard still holds: the walker peaks at 1 m/s, the crate at 0.428 m/s, and the shade at 0.599 m/s.
  • The Linux solver digest is fab06138921df81dbe269aac68cee653292ef9d60310af996687ea4621821a71. The product golden stays 69a671f962665563. The arithmetic golden stays 0d38671370d12d1e.
  • A drop stops short of its target and sets the carried body down clear of the actor. A placement that overlaps another body or a collider is refused, and the body stays carried.
  • A coverage seed keeps file times and compiles only si-solver. A build that compiles nothing fails the gate.
  • T7c's recorded runs are on main. Safety passes: 80 outputs, every proposal an intent for the walker with a catalog verb, and the 9 admissions are walker moves. Value fails: both arms are 0 of 0 on all seven changes. The prompt, the stall rule, and the model stay as they were.
  • The law plant's diff keeps a span of 4000 lines, so the planted edits stay the lines they change. The plant makes 34 mutants.
  • 503 tests, from the green engines job on this tree.

Golden hashes at this release

Harness Hash
harness/sim.mjs (product) 69a671f962665563
harness/arith.mjs (arithmetic contract) 0d38671370d12d1e
fixtures/solver.sha256 (Linux binary) fab06138921df81dbe269aac68cee653292ef9d60310af996687ea4621821a71

Full changelog: v0.2.0...v0.3.0

0.2.0 — the suite, the law's fixes, and the bench

Choose a tag to compare

@mcp-tool-shop mcp-tool-shop released this 26 Sep 15:32
942b353

Phase 2 so far: the suite that measures the engine, the fixes to the law it found, and the bench that measures a change against its parent. Every change below merged from a written dispatch in docs/, was verified on a fresh checkout, and was reviewed by other model families before it merged. docs/HANDOFF.md says where the work stands and what comes next.

Added

  • A trace and the first difference. harness/trace.mjs prints one line per step with every body's numbers as exact bit patterns, under node and the three engine shells. harness/first-difference.js names the first step, body, and field where two traces part. CI prints that block when an engine leaves the golden.
  • Behaviour numbers beside the golden. fixtures/golden-behaviour.json records each dynamic body's sleep step, every final position, the walker's zone, and the snapshot's length and digest. npm run check verifies them, and write-golden names each one that moves.
  • Save and restore. A world restores by replaying its inputs to a step (harness/replay-to.mjs) or by copying the physics module's memory (imageSolver, restoreImage). Both are proven to continue exactly from several steps chosen at contacts, sleeps, and wakes. An image from another binary, of the wrong length, with a changed byte, or taken during a call is refused.
  • An ARM64 job in CI. It runs the pinned x64 binary under node on an ARM64 runner and requires both goldens and an identical trace.
  • A lint on the compiled physics. solver/lint.mjs runs after every build and refuses relaxed-SIMD instructions, memory or table growth, a growable memory, a start section, passive segments, and bulk-memory initialisation.
  • Bundles and a replay corpus. A failing check writes a bundle of its seed, world, accepted inputs, and hashes, with the physics module's memory stored as only the pages in use; replay <bundle> reproduces it in one command. A weekly job replays every bundle in fixtures/corpus/, every fixture, every log, and the product scene to 100,000 steps, and opens an issue with the first difference on a failure.
  • Soundness checks. A source test refuses any cast from a shared reference to a writable one, including the forms the compiler's lint misses; a dropped refusal fails the build; native Rust tests run in CI.
  • Roles for model seats. A model proposes only through a role, a manifest in predicates/roles/ that the loader admits. The loader derives the Rule of Two from what the role reads and refuses a role that would read untrusted input, read private data in a live world, and change state. A role gate in the tick holds every proposal to its role's manifest, its body, its freshness window, and its budget. The log records each role admission's provenance and carries the manifests it cites. A belief keeps the least trust of what formed it. Every model call is recorded, and CI checks the committed records without a GPU. test-instrument and npc-mind are declared, both frozen.
  • A reachability sweep at load. load world explores a world's reachable states with the admitted actions, through the checker, and refuses a zone nothing reaches, a body carried out of the world, or a throw, each with a witness or a bundle that replay reproduces. The weekly corpus job sweeps every indexed world, fixture world, and the product scene, and fails when a verdict differs from its record.
  • The tick saves and restores itself. createRestorableTick gives a tick save() and restore(saved), which carry the solver's memory as the pages in use and the tick's own state, and restore without replay. A restore checks the whole save before it writes anything.
  • Tests of outcomes. A character course at the controller's measured limits, a thin fast body against a thin wall, terrain seams, and the terrain surface checked against where a dropped box comes to rest. write-golden refuses to write while any of them fails.
  • The instrument's bench. bench takes a change and the build before it, and runs each tree in a process of its own. It names what the change touches, proposes inputs with the sweep and a seeded grammar, and runs every candidate on both trees. It reports what reached the change, where the two runs first part, and what fails only on the change, and every verdict comes from the engine, none from a model. When solver/ changes, the law's reach is read from a coverage build whose run matches the product build's frame for frame, and mutants planted at the change measure the bench. F2's fix, planted with its branch off, is found at quantum 98. No workflow runs it, and it calls no model.

Changed

  • Model-call records are version 2. A record holds the loaded model read before the call and after it, where version 1 held one reading. It names the client's environment as the client's, where version 1 called it the server's settings. And it holds a failure. Committed version-1 records verify unchanged.
  • The load hash covers the whole world file. It used to miss a collider nothing touched at load, and most of a body's and a mind's fields, so an edited file could pass the index. It now covers every field but the name, and worlds/crate-and-door.json is admitted again under e3c445a78b7428c8.
  • An actor at rest can act. A body at rest sits a contact margin into what it rests on, and the checker's clear-path tests used to start inside the floor. They now start one controller skin, 0.01, above it.
  • crate-and-door is walled on every side, and so is the minds fixture's room: the sweep found bodies carried out of both.
  • propose --unfreeze is gone. A role's manifest says whether it is frozen. propose lists the roles, and propose --role refuses a frozen role, or one that acts in a live world, with exit 2 before any model client loads. The frozen instrument's self-measurement is removed; fixtures/proposer-qwen2.5-7b.json stays as its record.
  • The product golden is 69a671f962665563. The product scene's climber now stands on a floor, where before it fell for the whole run; an action's start or end no longer rebuilds the physics world; the walker no longer loses a step's travel on flat ground; and no step sinks into the floor.
  • Actions switch bodies in place. Starting or finishing an action, or picking a body up or putting it down, used to rebuild the whole physics world, which woke every sleeping body and discarded every contact's warm start. Now only that body switches, so untouched sleeping bodies stay asleep and keep their contacts. A body put down joins the character's queries at the next step. solverRebuilds() counts the worlds the physics module has built.
  • Fixed memory. The solver's memory is fixed at 512 pages, 32 MiB, with an allocator over that span, and heapHighWater() reports its peak. The build exports the stack pointer so a memory image is only taken between calls.
  • Terrain and fast bodies. Heightfields are built with Rapier's internal-edge fix, and max_ccd_substeps is set to 1 explicitly.
  • The Linux solver digest is 1b66023d91a8f031daa36afdb9baed8cfef96430bccd0a2a23b74fc5c3861143.
  • Stricter inputs to the physics. Infinities are refused alongside NaN; a body mode outside the four the law knows is refused; quaternions with extreme components normalize correctly or are refused.
  • The world's signature compares geometry directly. It used to compare a 64-bit fold that two different worlds could share.
  • The snapshot digests in the trace and the behaviour file carry 64 bits. Their two halves were identical before.
  • Build hygiene. The solver builds with --locked and passes its flags through CARGO_ENCODED_RUSTFLAGS; its exports and static references use the Rust 2024 forms under the 2021 edition; solver/FLAGS.md records that the toolchain version is part of the law.

Fixed

  • No step sinks into the floor. On a few steps the character's first cast of its move found no floor although it stood on one, because parry's cast loses its direction to rounding when it starts exactly on the contact skin (dimforge/parry#452, open upstream). The character dropped a step of gravity into its skin and climbed back over 20 steps. The engine's copy of the controller now casts once more with the skin 1e-9 larger when that happens, and a native test shows the copy without it moves as before, bit for bit. The product golden moves with it.
  • A push sizes each contact's impulse by the pushed body's effective mass. Rapier's routine sizes it from the two bodies' linear masses only, leaving out the pushed body's turning. So a push off the centre overshot, and a thin, light box launched at 41 times its pusher's speed (dimforge/rapier#1020, open upstream). The engine's copy of the routine now uses the effective mass at each contact point. The push guard tightens to one and a half times the speed of the character that pushed. The sweep no longer finds three bodies a push carried over an open edge.
  • A model call that fails is recorded. A read or an ask that threw used to end the session with no record of the call and no write. The call is now recorded as failed, and the session stops and is written. Every read of the server has a timeout, and a tick that throws while a call is out no longer leaves the call's rejection unhandled.
  • A body put down is seen from the next step, whatever the order of the records. When one body was picked up and another put down in the same step, the dropped body could take the broad-phase slot the other had freed. A query crossing the picked-up body's old place then found the dropped body one step early. It was never hit where the removed body had been, since every query tests a collider's real shape and place. A step now applies its drops before its pick-ups.
  • A save corrupt only inside its committed frame is refused. A restore used to check the committed frame's shape and nothing more. It now checks the frame re...
Read more

0.1.0 — the first release

Choose a tag to compare

@mcp-tool-shop mcp-tool-shop released this 25 Sep 08:57
2c2631f

The first release. Version numbers before 0.1.0 were internal slice counters and were never tagged or published.

Added

  • The tick. A fixed timestep of 1/64 s, every quantum hashed with a two-lane FNV-1a over little-endian f64 words, NaN refused, signed zero canonicalized. Replay is the seed plus the admitted-input log; play writes one, replay reruns it and fails on the first hash that differs.
  • The law in Rust. The physics step is solver/, a Rust crate on rapier3d-f64 with enhanced-determinism, compiled to one WebAssembly binary with relaxed SIMD off and source paths remapped, delivered as an ES module the three shells instantiate synchronously. The Linux build is the pinned artifact: fixtures/solver.sha256 holds its digest and CI checks it. Load runs one pass of Rapier's collision pipeline so the broad phase and the pair set agree from the first quantum.
  • Bodies in three dimensions. Position, linear velocity, a canonical unit quaternion, angular velocity, and half-extents on three axes. Dynamic boxes rotate under contact. The character is a kinematic box driven by Rapier's character controller: a 0.3 step, a 45° climb limit, a 0.2 snap. Sleep is counted in quanta and the full solver snapshot, warm-start cache included, is hashed each quantum.
  • World files validated at load. worlds/<name>.json holds bodies, static colliders that may carry an orientation, a heightfield, zones as a half-open partition, and a host-only goal. Twelve refusal reasons, each tested. load world runs the hazards, settles the world, and writes the load hash to worlds/index.json; the host serves only a world whose file hashes to the index. The swept admission test runs in a rotated collider's local frame.
  • Verbs admitted at load. A rule names its effect: drive, climb, carry, release, or episode. move, push, climb, pick-up, drop, and use are in the index, each admitted from a draft by load admit against hazard scenarios scoped by effect. A carried body leaves the solver and rides the actor's record; a climb rises past the step height on a counted kinematic path; use records an episode.
  • Minds. A body may carry a mind: a sight radius with a line of sight past static colliders, beliefs typed by predicates/beliefs/keys.json, each citing the episode it came from, supersession as a tombstone, a stale write refused with both episodes named, and standing goals with a met flag. Nothing pursues a goal and no model runs.
  • Golden hashes under three engines. CI builds the solver, runs the suite, installs pinned V8 15.6.61, SpiderMonkey 156.0.1, and JavaScriptCore 319571 through jsvu, and requires each to print the product golden and the arithmetic golden. The arithmetic golden, 0d38671370d12d1e, has not moved since the first harness.
  • Behaviour fixtures. Captures that replay frame for frame on the product law: three-dimensional motion, the solver, rotation, a rotated ramp, the verbs, and the minds, plus the traversal frames that settled the character's shape as a box. The four captures from before the law was three-dimensional are kept as refused records.
  • A debug view. host serves a labelled debug view of the tick on 127.0.0.1:4173, drawing committed frames as projected boxes along a chosen axis, with a verb mode, the zone of the walker, and each mind's sight and beliefs beside the tick and the hash.
  • A frozen proposer seat. propose is an instrument that asks a pinned local model to propose into a fresh tick under a grammar built from the catalog and the frame. It is frozen for this phase and refuses to run without --unfreeze.
  • Commands. play, replay, load, host, propose, and write-golden, each answering --help, printing one line and exiting 2 on an unexpected failure unless --debug, and exiting 1 with a reason on a refusal.
  • Records of how it was decided. docs/PHASE-0.md, docs/PHASE-1.md, the slice dispatches, the consult briefs and replies, and the study-swarm dispatches with their signed citation receipts.

Golden hashes at this release

Harness Hash
harness/sim.mjs (product) fd2f6c03fb982d77
harness/arith.mjs (arithmetic contract) 0d38671370d12d1e
fixtures/solver.sha256 (Linux binary) ede99ea1e51ec3ca12afa407764a66acf98eda3d7c36ac70397a6105c76fb5f0

🤖 Generated with Claude Code