feat(runtime): early-game survival curriculum + stone/craft skills (Phase 3) (#15)

Phase 3 of plans/autonomous-survival-bot-prd.md. Gives the bot a
deterministic path from empty inventory through stone-tier tools and
basic storage, without an LLM call per tick.

New:
- runtime/curriculum.js: ordered milestone chooser
  (wood.16 → wood.planks-and-sticks → wood.tools → stone.32 →
   stone.tools → food.basic → storage.chest → shelter.torch). Each
  milestone exposes isDone(inventory, snapshot) and suggest() returning
  a { skillId } plan the scheduler can dispatch via runSkill. isDone
  uses "stage reached" escapes so progress is monotonic — crafting
  planks doesn't bounce the chooser back to "gather 16 logs".
- runtime/skills/gather-stone.js: gather.stone with pickaxe-required
  precondition, blacklist on failed paths, registry-aware matching
  (stone / cobblestone / deepslate / cobbled_deepslate / andesite /
  diorite / granite).
- runtime/skills/craft.js: factory + concrete skills for craft.planks,
  craft.sticks, craft.wooden-axe/-pickaxe/-sword, craft.stone-axe/
  -pickaxe/-sword, craft.furnace, craft.chest, craft.torch (torch
  requires coal or charcoal preflight).

Tests:
- runtime/curriculum.test.js: 14 tests covering chooser ordering,
  per-milestone skill suggestion, inventoryFull threshold, monotonic
  advancement across stage transitions.
- npm test now runs the full suite: 28/28 passing.

Wiring:
- runtime/bot.js: lastSnapshot.curriculum carries the next milestone
  + suggested skill on every tick; lastSnapshot.currentMilestone
  prefers the curriculum title over the planner.md line.
- tui/tui.tsx: milestone line shows the curriculum's suggested skill
  and an [inventory full] flag when isInventoryFull fires.

Reflex.js still calls actions.js directly; wiring the scheduler to
runSkill(plan.skillId, …) lands in Phase 4.

Co-authored-by: Yuriy Mayatnikov <mayatnikov@me.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit was merged in pull request #15.
This commit is contained in:
Yuriy Mayatnikov
2026-05-25 22:23:33 +03:00
committed by GitHub
co-authored by mayatnikov Claude Opus 4.7
parent 4b7541435d
commit ae7b4d89cb
9 changed files with 785 additions and 3 deletions
+29 -1
View File
@@ -204,12 +204,40 @@ Reference skills shipped today: `gather.logs`, `survive.eat`,
`runtime/actions.js` primitives directly — porting more behaviours to
skills lands in later phases.
Run the contract + groups tests:
Run the contract + groups + curriculum tests:
```bash
npm test
```
### Survival curriculum (Phase 3)
`runtime/curriculum.js` exposes a deterministic early-game progression:
```
wood.16 → wood.planks-and-sticks → wood.tools →
stone.32 → stone.tools → food.basic → storage.chest → shelter.torch
```
Each milestone has an `isDone(inventory, snapshot)` predicate and a
`suggest(inventory, snapshot)` function that names the next skill to
dispatch. `isDone` is stateful in the sense that reaching a later tier
implies all earlier "gather" milestones are complete (so the bot
doesn't loop back to "gather 16 logs" after crafting them into
planks).
The current curriculum result is on every snapshot as
`snapshot.curriculum = { milestone, plan, inventoryFull }` so the TUI
can show what the bot is working on and which skill should drive it.
Wiring the scheduler to actually call `runSkill(plan.skillId, …)` in
the reflex loop is a Phase 4 task; today the reflex still uses
`actions.js` directly.
Inventory pressure: `isInventoryFull(snapshot)` is exposed on every
curriculum result; the TUI surfaces `[inventory full]` next to the
milestone label so the operator can see when a deposit step is needed
before progress continues.
### Optional: prismarine-viewer
Set `VIEWER_PORT=<port>` in `.env` to launch