Pixelbolt test suite at main d8776d4, run 2026-10-19 with: node --test Windows 11 Pro (build 26200), Node.js v24.19.0 ✔ pose instances flip their grid, anchor and points inside the part (4.8884ms) ✔ mirrored poses reflect parts, points and markers around the origin corner and inherit timing (1.2032ms) ✔ pose origins become recipe or frame anchors and markers become atlas points (0.9092ms) ✔ autotile compiler composes every blob mask from the template pieces its neighbours call for (3.9471ms) ✔ autotile variants become palette-cycled frames with one animation per mask (2.4369ms) ✔ the autotile op draws the quarters a mask selects, exactly like four copies, and the compiler emits one per frame (6.3752ms) ✔ canvas-only overlays survive unrelated base edits but refuse changes to the frames they touch (8.6363ms) ✔ PNG import keeps up to 256 colours as compact, lossless palette grids (4.1157ms) ✔ a compiled mirror placed by its anchor draws exactly what drawFrame draws when flipping the original (2.7134ms) ✔ hex shorthand, alpha and named colors (1.3701ms) ✔ grid dots skip existing pixels, with exact palette colors (2.0351ms) ✔ grid shape and color errors include the exact source path (0.261ms) ✔ non-square stamp rotates clockwise and flips before rotation (0.3512ms) ✔ Bresenham line includes both endpoints in every direction (0.532ms) ✔ outlined ellipse has a transparent center; rectangles can be outlined (0.2393ms) ✔ flood fill respects boundaries and fills the target region exactly (0.224ms) ✔ clear erases alpha and replace matches the full RGBA value (0.1653ms) ✔ layer opacity applies once after the layer is flattened (0.189ms) ✔ frame inheritance copies pixels without mutating the parent (0.2332ms) ✔ animation direction preserves timings and avoids duplicate pingpong endpoints (0.1792ms) ✔ atlas positions include scaled padding and no color interpolation (0.4803ms) ✔ clipping warns once, and invalid fill seeds are rejected (0.2569ms) ✔ invalid references, duplicate names, typos and resource limits fail early (2.3025ms) ✔ prototype-like palette keys are safe and are not inherited (0.2075ms) ✔ integer scaling replicates pixels exactly (0.0811ms) ✔ portable output names reject devices, case collisions and null options (0.2754ms) ✔ dither draws a canvas-anchored ordered pattern, ramps density and respects over/erase (4.6486ms) ✔ noise dither is seeded and non-periodic, and a rising density only ever adds pixels (13.853ms) ✔ value dither grows seeded clumps of a chosen size and keeps density as the share of pixels drawn (100.5585ms) ✔ outline adds inside, middle, width and direction masks (1.8679ms) ✔ rewrite rules grow, clean and decorate deterministically (3.9672ms) ✔ cleanup finds doubled corners and strays without touching filled areas or right-angle corners (0.6568ms) ✔ a cleanup patch proposes corrections with a report, and diagnostics count what it would change (23.0961ms) ✔ rotation keeps colours, turns around the pivot pixel and is exact at right angles (2.2274ms) ✔ easing presets start at 0, end at 1 and keep their character (0.3782ms) ✔ diorama: the committed sources match build.mjs (118.0804ms) ✔ diorama: every scene, lit or re-themed, keeps exactly its palette (495.2473ms) ✔ diorama: the hero is drawn behind the barrel it walks past, and the smear only shows during the strike (76.4755ms) ✔ the studio keeps one draft with its name and time, and forgets it on request (1.018ms) ✔ a draft that cannot be stored or read never breaks the studio (0.35ms) ✔ Emberfall double jump, landing, dash cooldown, pause and restart form a coherent movement cycle (3.7193ms) ✔ Emberfall elemental interactions persist and charged shots consume breakable health (2.1656ms) ✔ Emberfall checkpoint healing, death, retry and portal gating preserve progression (0.4038ms) ✔ Emberfall guided tour traverses gaps, destroys scenery, defeats boss and wins without unbounded effects (115.561ms) ✔ PNG encodes exact RGBA scanlines including transparency (1.7958ms) ✔ APNG contains exact durations, loop flag and source replacement (0.9801ms) ✔ bundle emits CSS for variable duration and multi-row atlas (5.9299ms) ✔ exports are deterministic, including ZIP bytes (4.7716ms) ✔ export refuses overwrite before changing any existing files (37.3972ms) ✔ all bundled examples validate and produce complete exports (17.5397ms) ✔ formatJSON keeps short records on one line and grids one row per line, and parses back to the same value (1.1122ms) ✔ clipping reports each source location and pixel count (4.8464ms) ✔ copy takes rectangles from symbols or earlier frames, with transforms, and validates its source (1.1772ms) ✔ frame copies remap exact colours named by palette key or hex (0.794ms) ✔ outline wraps the current buffer, 4-connected by default or 8-connected with diagonal (0.6452ms) ✔ remap recolors palette characters for one operation only (0.4364ms) ✔ frame palettes recolor declared keys for that frame, including symbols and corrections (1.2399ms) ✔ layer palettes recolor keys for one layer only, on top of the frame palette (2.1846ms) ✔ wrapping translation scrolls pixels around the canvas without clipping (0.2209ms) ✔ anchors and named points reach the atlas in exported pixels with a normalized pivot (0.9524ms) ✔ trimmed atlases pack visible bounds deterministically and keep full-canvas source coordinates (1.1733ms) ✔ tile view repeats frames 3x3 and reports doubled edges and wrap steps instead of edge equality (2.0123ms) ✔ palette file references and astral grid characters fail with actionable paths (0.2681ms) ✔ every fluid example compiles to its golden recipe, using only its palette and grid operations (2464.6022ms) ✔ looping examples close their loop and one-shot examples end empty or at rest (56.5193ms) ✔ the committed fluid GIFs match the examples (107.8479ms) ✔ heat rises and curls, smoke thins, obstacles stay clear and a still pool stays still (19.6504ms) ✔ sparks draw as blocks of their size, with a streak back along their path (5.0396ms) ✔ in a liquid, spray ends where it falls back into the water and a bubble bursts in a ring, then two droplets (12.0096ms) ✔ depth bands stay level under water standing on the surface (0.8514ms) ✔ water under an overhang is as deep as the pool beside it, and a hanging drop keeps its highlight (1.7302ms) ✔ whitewater throws spray where water lands and sheds drops off a fast stream (23.4228ms) ✔ emitters can fall off toward their rim, orbit on an ellipse and lay a smooth trail (9.9924ms) ✔ loops repeat their forcing, blend their seam and wrap sparks round (42.4339ms) ✔ viscosity slows spreading but never falling, and walls hold a viscous liquid unless it slips (652.3368ms) ✔ a yield stress holds a heap up, squashes and springs back, and flows once pushed past it (338.315ms) ✔ adhesion keeps a film under a ledge, APIC keeps a thick liquid turning (307.6212ms) ✔ sharp advection keeps a puff crisp, and a viscous gas calms swirls but not drift (415.6855ms) ✔ nothing passes through a wall one pixel thick, however fast it moves (50.3827ms) ✔ fluid sources fail early with paths an agent can act on (135.7134ms) ✔ limits are reported with the effect path, extreme settings stay finite, and any palette key draws its own colour (265.4395ms) ✔ the fluid schema lists exactly the fields the compiler reads (80.3645ms) ✔ fluid sources compile from the CLI with a shared palette, and preview and sequence accept them (517.5627ms) ✔ MCP pixel_compile builds fluid sources and pixel_help serves their schema (111.7626ms) ✔ the documented fluid example compiles as written (37.5996ms) ✔ the documented live example runs as written (14.8171ms) ✔ the package ships the fluid schema and example sources (6.3183ms) ✔ a live runner steps the simulation compileFluid bakes, frame for frame (1032.7264ms) ✔ live runs are deterministic: the same calls give the same pixels everywhere (207.733ms) ✔ a live push stirs the gas and moves the water from the next step on (44.0738ms) ✔ a live puff adds or takes away smoke and water, and a boost scales an emitter for a while (56.5598ms) ✔ live frames use only palette colours, and keys name each pixel's colour (335.8201ms) ✔ live runs stay inside the limits instead of stopping at them (91.5743ms) ✔ live runners check sources like compileFluid, and their own inputs with paths (475.119ms) ✔ a live runner steps a hero-sized steam plume in milliseconds (687.9173ms) ℹ 128 × 60 steam: 9.04 ms a step, 0.90 ms a render, 101 frames per second ✔ effects compile deterministically into ordinary frames, one animation per effect (10.6924ms) ✔ gravity, floors, trails, variants, remaps and dissolve bake into stamps, grids, lines and pixels (4.2674ms) ✔ looping effects warm up so the first frame continues the last (1.2781ms) ✔ effect sources fail early with paths an agent can act on (2.4733ms) ✔ rotated pose parts bake into editable symbols and carry their points (5.4343ms) ✔ tweened poses interpolate offsets and angles, switch shapes at the eased midpoint and keep attachments (3.8293ms) ✔ scene trajectories ease each segment and still land on whole pixels (4.0457ms) ✔ the CLI compiles effect sources and keeps their shared palette link (454.547ms) ✔ GIF frames, colours, timing and loop flag are read back exactly by a separate decoder (4.118ms) ✔ GIF blends onto a background instead of thresholding, and keeps a sequence's length when rounding delays (0.7363ms) ✔ GIF uses a table per frame when the animation needs more than 256 colours, and never quantizes (24.4079ms) ✔ GIF compression survives dictionary resets and 12-bit codes on noisy frames (66.9327ms) ✔ a busy opaque animation keeps unchanged pixels under a transparent index and stays within 1.5x of ffmpeg, every frame exact (1349.9817ms) ✔ GIF writes the end code as wide as a decoder reads it after the last code fills the table (0.6357ms) ✔ a sprite with transparency is cleared only where a pixel turns transparent, also when the loop restarts (0.6523ms) ✔ GIF keeps unchanged pixels only where a table has room, and stays exact when it has none (2.3134ms) ✔ an animation exports as a GIF with a default scale, notes about what GIF cannot keep, and named errors (43.6665ms) ✔ CLI gif writes only the requested file and refuses to replace it (607.1657ms) ✔ MCP pixel_render writes GIFs on request and leaves nothing behind when one is refused (674.2054ms) ✔ framesGIF times frames on the frame-rate grid, counts plays and keeps every colour of every frame (2.1634ms) ✔ numbered frames are read in number order, with gaps and other files reported and mixed sequences refused (0.5027ms) ✔ CLI gif-frames turns a folder of PNG frames into an exact GIF and writes only --out (1009.9152ms) ✔ grids read pixels back as palette keys, transparency and one shared legend (8.4864ms) ✔ inspection keeps frame order, crops regions and rejects bad options with paths (1.9476ms) ✔ contact sheet scales cells exactly over a checkerboard inside dark gutters (0.6729ms) ✔ automatic layout picks the largest readable scale and enforces size limits (67.6197ms) ✔ a stride picks the A or B frames of a strobe that evenly spaced samples would mix (87.2099ms) ✔ CLI inspect takes --step and --offset (432.9691ms) ✔ the legacy CLI agrees on help, stdin validation, errors and every rendered byte (1482.0486ms) ✔ both CLI names initialize Pixelbolt and expose the same eight MCP tools and schemas (193.1004ms) ✔ CLI help describes its text output and commands for checkout and portable builds (82.4042ms) ✔ CLI consumes stdin, emits machine-readable diagnostics and handles unknown flags (279.3611ms) ✔ CLI init protects an existing recipe with an actionable JSON error and honours --force (260.0478ms) ✔ MCP handshake, discovery, help, errors and render work over stdio (32.226ms) ✔ MCP pixel_inspect returns a contact sheet and ruled grids, saving only its revision (13.5116ms) ✔ MCP revisions let pixel_patch edit, compare and export without resending the recipe (44.2314ms) ✔ MCP revisions from validate, inspect and paint survive process restarts before export (346.1962ms) ✔ MCP render previews every frame or an animation in playback order, with exact timing and cells (217.5909ms) ✔ CLI patch previews by default and writes only the requested recipe and image (424.2067ms) ✔ MCP exports a maximum-length animation with a bounded, explicit sampled preview (432.6089ms) ✔ CLI inspect prints cells and grids, and writes a PNG only when asked (614.3927ms) ✔ studio serves only its assets and exports ZIP over same-origin requests (480.5612ms) ✔ studio returns frames for a video editor as one ZIP, built as the sequence command builds them (106.2395ms) ✔ every sample the studio lists is served, and the sidebar counts the list itself (2.3147ms) ✔ MCP answers an oversized request with an error, recovers its id and keeps serving (68.506ms) ✔ MCP compiles pose sources and autotile templates into revisions it can render and review in scenes (168.1163ms) ✔ MCP imports PNGs, applies overlays, explains topics and resolves palettes only inside its root (67.7729ms) ✔ CLI resolves shared palettes, keeps the link when writing edits, builds autotiles and reports clipping (487.0505ms) ✔ MCP compiles particle effects, explains the fx topic and previews cleanup patches (52.5275ms) ✔ registry source is metadata-only with a short description (286.1496ms) ✔ release workflow guards and assets use the renamed repository (2.1997ms) ✔ MCPB builds are byte-identical, including across CRLF and LF checkouts (137.9629ms) ✔ the standalone verifier runs bundled MCP help, render, import and scene export (400.2356ms) ✔ the verifier reports missing help and scene export assets and cleans up (435.5495ms) ✔ the verifier refuses traversal paths and a manifest/package version mismatch (109.8837ms) ✔ the builder refuses template versions, non-stable versions and different existing artifacts (96.061ms) ✔ registry entry identifies the exact release bundle and preserves source metadata (10.8746ms) ✔ registry entry refuses bad tags, mismatched versions and packages in metadata (34.0048ms) ✔ registry entry cannot replace server.json or the bundle (3.1553ms) ✔ shipped JavaScript and studio resources make no external network calls (62.9153ms) ✔ the network check rejects regressions with the file and line (5.0292ms) ✔ the studio sends a self-only default Content-Security-Policy (51.1182ms) ✔ a generated pass rounds a shape: rims lean outward, the middle faces the viewer, and keys encode their directions (15.7395ms) ✔ the pass lines up with its colour recipe in a scene, and lights each side toward the light (8.476ms) ✔ each separate shape rounds on its own; bevel flattens the top; mirrored frames get mirrored normals (3.2472ms) ✔ detail raises lighter colours, ramps keep materials level, and the canvas border is not an edge unless frames wrap (3.7663ms) ✔ normals sources are validated with paths (1.0191ms) ✔ the normals schema lists exactly the fields the compiler accepts (9.0092ms) ✔ the CLI compiles a normals source whose recipe file sits beside it, keeping the colour palette link out of the pass (317.7139ms) ✔ MCP compiles a normals source from a saved revision and explains the normals topic (35.2106ms) ✔ the bundled spirit normal pass is what its source compiles to, and its night scene lights it (17.6134ms) ✔ patches address items by name, index or end and report what they replaced (8.2696ms) ✔ patch errors name the change that failed (1.7996ms) ✔ canvas painting replaces exact pixels after translated layers, and inherited frames keep the corrections (12.5071ms) ✔ paint rejects wrong targets and invalid pixels without mutating the source (1.3029ms) ✔ comparison reports changed, inherited, added and retimed frames with exact pixels (3.055ms) ✔ comparison crops to the change, summarizes recolors and reports resized canvases (11.6264ms) ✔ native RGBA PNG and atlas roundtrip preserve hidden RGB, alpha, order, timing and once flags (12.5305ms) ✔ scene honors anchors, playback durations, state changes and persistent aftermath (6.6239ms) ✔ material passes align exactly; light direction changes hand-authored normals and unlit pixels remain intact (15.8428ms) ✔ tile repeat exposes a seeded doubled edge line and leaves a clean tile unflagged (1.3635ms) ✔ quality examples validate, preserve source poses and create deterministic scenes (116.4945ms) ✔ PF-EF-001: ZIP32 accepts 65,535 entries and preflights overflow before reading entries (464.3967ms) ✔ PF-EF-003: stamp references have the same string type as the schema (1.2706ms) ✔ PF-EF-002: oversized animation sheets can sample endpoints with honest omission metadata (128.1358ms) ✔ review views preserve pixels; silhouette is solid even for translucent detail (2.0707ms) ✔ layer isolation preserves inherited placement and validates the full source before hiding it (0.7602ms) ✔ onion neighbors follow reverse, sparse, repeated and pingpong positions with once boundaries (1.3159ms) ✔ diagnostics expose deliberate isolated pixels, undeclared colors and a loop jump, without rejecting holds (1.7696ms) ✔ regional grids preserve dots and masks, erase explicitly, and report inherited versus frame scope (8.514ms) ✔ overlapping masked moves carry highlights and recoloring respects exact selected pixels (2.2928ms) ✔ named correction overlays survive identical rebuilds and refuse moved bases atomically (5.3245ms) ✔ large regional batches preflight bounded edit work without changing their source (0.4954ms) ✔ authored part replacements keep held objects attached and export timing in expanded order (1.9635ms) ✔ revisions persist across store instances and concurrent saves do not overwrite snapshots (37.3218ms) ✔ revision reads reject traversal and corruption, and never overwrite damaged files (30.9501ms) ✔ older rendered recipes recover the same revision id without modifying the bundle (50.909ms) ✔ Canvas player respects durations, once/loop behavior, pause/resume and scaled atlas rectangles (6.4265ms) ✔ runtime helpers look up frames by time and draw trimmed, anchored and mirrored frames (2.3088ms) ✔ Canvas player keeps the full source size and draws trimmed frames at their offset (0.8362ms) ✔ placements can start hidden and be hidden again by a cue; named cues write related times once (10.8719ms) ✔ an attached placement follows a named point of another placement's current frame (2.2784ms) ✔ placements sorted by ground draw by the y of their placement point, so a hero passes behind a post (1.3326ms) ✔ tilemap placements expand a character map into frames, variants and animations as one declaration (12.2193ms) ✔ autotile legends pick compiled blob tiles from each cell's neighbours (6.9687ms) ✔ lighting scope "all" darkens plain assets too, and clipping names the placements (1.609ms) ✔ banded lighting keeps a coloured light's hue: channels change band together (0.7545ms) ✔ null legend entries are context cells: matched by neighbours, never drawn (3.9847ms) ✔ scene file and revision references must be resolved before rendering (0.3286ms) ✔ anchor "frame" places each drawn frame by its own anchor, so animated placements follow per-frame anchors (1.3918ms) ✔ every operation field the schema lists is one the renderer accepts, and no others (17.5161ms) ✔ scene fields in the schema match what prepareScene accepts (13.2335ms) ✔ every generated schema defines each definition it references, and carries none it does not (11.8313ms) ✔ frame rates are exact fractions, including the NTSC rates (2.3594ms) ✔ each video frame shows the pose that is active when the frame starts (2.1985ms) ✔ a sprite is enlarged by a whole number and placed on a video-sized canvas (1.4153ms) ✔ a recipe becomes numbered PNG frames with exact pixels, straight alpha, a sidecar and working instructions (7.5208ms) ✔ cover fills the canvas with the sprite and crops what hangs over (2.6267ms) ✔ a background blends the alpha away, and the notes say what the frame grid changed (1.9145ms) ✔ a scene becomes a shot: each frame is the scene at that moment, and still moments share a file (1584.3277ms) ✔ CLI sequence writes a new folder for a recipe, an effects source and a scene, and never half of one (1183.7461ms) ✔ MCP render and scene tools write a sequence on request, beside what they already write (787.8321ms) ✔ validate --fps lists durations off the video frame grid and agrees with the sequence it predicts (291.6701ms) ✔ shade moves each pixel along its own ramp, clamped at the ends, and keeps the palette (29.4532ms) ✔ ramps and shade validate with actionable paths (3.8881ms) ✔ shade placements darken whatever lies beneath along its ramps, so one shadow suits any floor (24.384ms) ✔ ramp lighting moves colours along ramps instead of multiplying them, so a lit scene keeps its palette (2.4213ms) ✔ shared palette files may carry ramps, and themes override palette keys per scene or per asset (27.5168ms) ✔ new environment names take precedence and old names remain fallbacks when unset (1.1443ms) ✔ the build ZIP is deterministic, compressed where it helps and read back exactly (3.7291ms) ✔ the macOS and Linux archive keeps permissions, carries no host details and is read back exactly (167.8433ms) ✔ START HERE is one text with blocks for each system (0.5082ms) ✔ the macOS and Linux builds hold shell launchers marked executable, their own START HERE and the right runtime (648.1057ms) ✔ the build ships exactly the files npm pack ships (1122.6289ms) ✔ every relative README link and image is shipped in the portable package (6.7238ms) ✔ the portable layout holds the package, runtime, launchers and build facts, and nothing from development (193.8169ms) ✔ a release build takes its files from the commit, whatever line endings the working copy holds (528.4622ms) ✔ the launcher is preview with a browser: the usual port, a free one beside it, and a dropped recipe opens (621.4076ms) ✔ the browser is opened by each system's own handler, with no shell to quote for (1.1937ms) ✔ the connect helper prints the same server for four agents and changes nothing (112.5824ms) ✔ the Windows connect helper pauses after failure only when started without arguments (43.5655ms) ✔ an assembled build passes the release checks from a folder with a space and an accent (11658.0119ms) ✔ the built-in font covers printable ASCII, western European letters and common symbols, with tabular digits (10.8888ms) ✔ text is laid out with glyph spacing, line height and alignment (1.0032ms) ✔ the text operation draws exact glyph pixels, placed by align and changed by the usual transforms (5.7808ms) ✔ text errors name the field and the character (1.2196ms) ✔ the schema describes the text operation the renderer accepts (8.3067ms) ✔ every module the browser imports is served by the studio and packed with scene exports (39.3147ms) ✔ Tidewatch: every recipe validates without clipping warnings (156.6204ms) ✔ Tidewatch: compiled recipes and metadata match their authoritative pose, autotile and effect sources (70.0068ms) ✔ Tidewatch: particle effects keep the animations, anchor and hand-drawn frames the game uses (7.397ms) ✔ Tidewatch: exported game atlases match the recipes byte for byte (1356.5042ms) ✔ Tidewatch: material passes stay aligned with their colour recipes (17.5901ms) ✔ Tidewatch: Pixelbolt blob masks give every sand and grass cell a compiled tile (14.9931ms) ✔ Tidewatch: the game places sprites from atlas anchors and reads reach, held items and glyph advances from points (2.7686ms) ✔ Tidewatch: the island can be completed in a deterministic headless run (5.7768ms) ✔ rule tiles choose by the characters around a cell and may draw into a neighbouring cell (6.739ms) ✔ rule chances and variant weights are seeded by position, and unweighted variants keep their old picks (10.4768ms) ✔ tilemap legends and rules fail with paths that name the entry (2.4401ms) ✔ a recipe tilemap composes symbols and autotile templates, and later operations see the composed result (3.8231ms) ✔ autotile variants may redraw the set from their own template (6.5306ms) ℹ tests 256 ℹ suites 0 ℹ pass 256 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0 ℹ duration_ms 12998.9413