CI / Tool tests and sync-check (push) Successful in 16s
CI / Verify references (all modules, Rust and TS) (push) Successful in 2m4s
CI / Verify Expansion Drop solutions (all modules, Rust and TS) (push) Successful in 2m1s
CI / Coupling audit on references (push) Successful in 5s
CI / Differential fuzzing of the Rust and TS references (300 seeds) (push) Successful in 53s
CI / Mutation check (tools/mutants.json against the highest TS reference) (push) Successful in 34s
CI / Verify the SpellGrid level proofs (solver) (push) Successful in 5m25s
CI / Site build (push) Successful in 15s
CI / Naive engine tests (Module 0) (push) Successful in 20s
I1: run-scenario and both SpellGrid CLIs check moves first and treat any other engine error as fatal (same text in both tracks); trigger blocks close on error (try/finally, catch_unwind in Rust); unknown summons rejected. I2, I3, M1-M7, T3, T9a-c, T10a-b. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Module 8 reference engine (TypeScript)
The course's own engine as of the end of Module 8. Part I's card engine is unchanged, and all of its tests still pass. The Part II engine in src/engine/puzzle/ now moves objects: each YOU object's move is planned in full, push chain and all, and only then committed. Module 7's reference was the starting point, so a diff between the two shows what this module adds.
cards/(at the package root; not in this directory): Part I's card data, a copy ofcourse/cards/staged bytools/verify-references.mjs. Part II doesn't read it.src/engine/puzzle/: the Part II engine. It names no noun: the engine's own words are the operatorsIS,AND,NOT, the meta-nounTEXT, the propertyPUSHof the base ruleTEXT IS PUSH, and from Module 8 the propertyYOU, which picks the objects that move.grid.ts: the level format, object kinds and the board. Module 8 addsBoard.find,Board.remove,Board.shift,Board.atandKind.format(the kind as placed, forkindsAt).movement.ts(new): validate, then commit.Planner(tryMove,stayingAt,destroy,has),Step,Plan,ResponseandDir. The planner reads the board and plans one step at a time; for each step it runs content's movement responses in order, and rolls back everything a step added if a response blocks it. The edge of the level blocks every step, and an object that has already stepped in the same move can't step again.level.ts: a level in play. Module 8 addsLevel.moveYou: theYOUobjects move one at a time, furthest ahead first, each planned and then committed, and an object steps at most once per move (aYOUobject that an earlier move carried along doesn't start its own); the rules are reparsed once at the end.hasPropertyisfalsefor a destroyed object.word.ts,parse.ts,resolve.ts: unchanged.index.ts: the module's exports.
- The rest of
src/engine/: Part I, unchanged. src/content/movement.ts(new) andsrc/content/index.ts: the movement responses, in the order the engine runs them:OPEN/SHUT,PUSH,STOP. What a property does when something moves is content, not engine.src/content/words.json: Module 8 addsOPENandSHUT.src/harness.ts: the adapter the course tests call. Module 8 addsmove,posOf,kindsAtandstackAtonBaba.
Run it with the module's tests: node tools/verify-references.mjs 08 from the course repository.