Pre-v0.3.0, the bot had no internal hierarchy of needs. The curriculum
produced a single "next milestone" but no priority structure. So when
the bot was wedged with no pickaxe, it kept dispatching explore.far
instead of recognising "I need wood → planks → pickaxe first". Pi could see this in reflection logs but had no internal-state language to
express "L2 tools_wood is unmet".
This rc gives the bot an explicit 11-level Maslow-like needs ladder:
L0 alive HP>5, food>0, not lava, not panic-near hostile
L1 food ≥6 food items in inventory
L2 tools_wood wooden_pickaxe + wooden_axe + wooden_sword
L3 shelter_basic bed placed nearby or in inventory
L4 tools_stone stone-tier triplet
L5 armor_basic any chestplate (pursue=null for now)
L6 food_security ≥16 food items
L7 tools_iron iron-tier triplet
L8 armor_iron iron chestplate (pursue=null for now)
L9 village_seed bed + chest nearby
L10 village_full global goal (always falls through)
Each reflex tick picks the lowest unsatisfied pursuable need and
dispatches a concrete skill toward it. Needs whose pursue() returns null (armour, currently — no craft.leather-* skills yet) gracefully
skip without stalling the bot.
Changes
runtime/manifesto/needs.js (new) — 11-need catalogue with detect(snapshot) and pursue(snapshot) per need.
runtime/manifesto/state.js (new) — pickActiveNeed(snapshot) walks
the ladder, returns {need, skillId, args, blockedNeeds}. 3s cache. Validates skillId against the live registry (rc.1 plumbing) — the
manifesto literally cannot ship a hallucinated skill name.
runtime/reflex.js — curriculumReflex consults manifesto first.
Curriculum plan becomes the fallback. Tests can pass ctx.disableManifesto = true to exercise the curriculum branch
in isolation (existing tests do that; new tests exercise manifesto-on).
runtime/coach/reflect.js — Pi self-reflection prompt now includes "activeNeed: L2 tools_wood → gather.logs (Деревянные орудия)" so Pi
advises at the right level.
Behavioural diff (illustrative)
Situation
v0.2.x dispatch
v0.3.0-rc.2 dispatch
food=20, no inventory, curriculum=logs
gather.logs
survive.acquire-food (L1)
Full wood tools, no bed, no stone
gather.logs (loop)
gather.wool (L3)
Full wood + stone tools, no chestplate
curriculum plan
armor skipped → L6 food
HP=4, creeper@3m, has tools, has bread
curriculum plan
survive.flee (L0)
Test plan
npm test — 315 green (was 279 on rc.1, +36 new):
24 unit tests in manifesto/needs.test.js (per-need)
10 unit tests in manifesto/state.test.js (ladder walk, L0 takeover,
skip-on-null, caching)
2 integration tests in reflex.test.js
Post-merge: deploy, watch
sqlite3 state/.../knowledge.db \
"SELECT applied_count, source, text FROM lessons
WHERE applied_count > 0 ORDER BY applied_count DESC LIMIT 20;"
Expect Pi-coach/Pi-reflect applied_count to start growing as the
bot makes ladder progress (each progression generates valid
prefer_skill suggestions Pi can build on).
AbortSignal plumbing through long skills (gather.logs, explore.far,
recovery.tunnel-out, survive.pillar-up) so they preempt within
~100ms instead of waiting for a tick boundary
Wire fast-advisor (rc.1 scaffold) into the awareness layer
## What and why
Pre-v0.3.0, the bot had no internal hierarchy of needs. The curriculum
produced a single "next milestone" but no priority structure. So when
the bot was wedged with no pickaxe, it kept dispatching `explore.far`
instead of recognising "I need wood → planks → pickaxe first". Pi could
*see* this in reflection logs but had no internal-state language to
express "L2 tools_wood is unmet".
This rc gives the bot an explicit 11-level Maslow-like needs ladder:
```
L0 alive HP>5, food>0, not lava, not panic-near hostile
L1 food ≥6 food items in inventory
L2 tools_wood wooden_pickaxe + wooden_axe + wooden_sword
L3 shelter_basic bed placed nearby or in inventory
L4 tools_stone stone-tier triplet
L5 armor_basic any chestplate (pursue=null for now)
L6 food_security ≥16 food items
L7 tools_iron iron-tier triplet
L8 armor_iron iron chestplate (pursue=null for now)
L9 village_seed bed + chest nearby
L10 village_full global goal (always falls through)
```
Each reflex tick picks the **lowest unsatisfied pursuable** need and
dispatches a concrete skill toward it. Needs whose `pursue()` returns
`null` (armour, currently — no `craft.leather-*` skills yet) gracefully
skip without stalling the bot.
## Changes
- `runtime/manifesto/needs.js` (new) — 11-need catalogue with
`detect(snapshot)` and `pursue(snapshot)` per need.
- `runtime/manifesto/state.js` (new) — `pickActiveNeed(snapshot)` walks
the ladder, returns `{need, skillId, args, blockedNeeds}`. 3s cache.
**Validates skillId against the live registry** (rc.1 plumbing) — the
manifesto literally cannot ship a hallucinated skill name.
- `runtime/reflex.js` — `curriculumReflex` consults manifesto first.
Curriculum plan becomes the fallback. Tests can pass
`ctx.disableManifesto = true` to exercise the curriculum branch
in isolation (existing tests do that; new tests exercise manifesto-on).
- `runtime/coach/reflect.js` — Pi self-reflection prompt now includes
`"activeNeed: L2 tools_wood → gather.logs (Деревянные орудия)"` so Pi
advises at the right level.
## Behavioural diff (illustrative)
| Situation | v0.2.x dispatch | v0.3.0-rc.2 dispatch |
|---------------------------------------------|------------------------|-----------------------------|
| food=20, no inventory, curriculum=logs | `gather.logs` | `survive.acquire-food` (L1) |
| Full wood tools, no bed, no stone | `gather.logs` (loop) | `gather.wool` (L3) |
| Full wood + stone tools, no chestplate | curriculum plan | armor skipped → L6 food |
| HP=4, creeper@3m, has tools, has bread | curriculum plan | `survive.flee` (L0) |
## Test plan
- [x] `npm test` — 315 green (was 279 on rc.1, +36 new):
- 24 unit tests in `manifesto/needs.test.js` (per-need)
- 10 unit tests in `manifesto/state.test.js` (ladder walk, L0 takeover,
skip-on-null, caching)
- 2 integration tests in `reflex.test.js`
- [ ] Post-merge: deploy, watch
```
sqlite3 state/.../knowledge.db \
"SELECT applied_count, source, text FROM lessons
WHERE applied_count > 0 ORDER BY applied_count DESC LIMIT 20;"
```
Expect Pi-coach/Pi-reflect `applied_count` to start growing as the
bot makes ladder progress (each progression generates valid
prefer_skill suggestions Pi can build on).
## Followup (rc.3)
- Event-driven awareness layer: `bot.on('move')` jump-detect,
`bot.on('health')` plunge-detect, `bot.on('entitySpawn')` hostile-add
- AbortSignal plumbing through long skills (gather.logs, explore.far,
recovery.tunnel-out, survive.pillar-up) so they preempt within
~100ms instead of waiting for a tick boundary
- Wire fast-advisor (rc.1 scaffold) into the awareness layer
See [`dev/v0.3.0/PLAN.md`](dev/v0.3.0/PLAN.md) for the full v0.3.0 design.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What and why
Pre-v0.3.0, the bot had no internal hierarchy of needs. The curriculum
produced a single "next milestone" but no priority structure. So when
the bot was wedged with no pickaxe, it kept dispatching
explore.farinstead of recognising "I need wood → planks → pickaxe first". Pi could
see this in reflection logs but had no internal-state language to
express "L2 tools_wood is unmet".
This rc gives the bot an explicit 11-level Maslow-like needs ladder:
Each reflex tick picks the lowest unsatisfied pursuable need and
dispatches a concrete skill toward it. Needs whose
pursue()returnsnull(armour, currently — nocraft.leather-*skills yet) gracefullyskip without stalling the bot.
Changes
runtime/manifesto/needs.js(new) — 11-need catalogue withdetect(snapshot)andpursue(snapshot)per need.runtime/manifesto/state.js(new) —pickActiveNeed(snapshot)walksthe ladder, returns
{need, skillId, args, blockedNeeds}. 3s cache.Validates skillId against the live registry (rc.1 plumbing) — the
manifesto literally cannot ship a hallucinated skill name.
runtime/reflex.js—curriculumReflexconsults manifesto first.Curriculum plan becomes the fallback. Tests can pass
ctx.disableManifesto = trueto exercise the curriculum branchin isolation (existing tests do that; new tests exercise manifesto-on).
runtime/coach/reflect.js— Pi self-reflection prompt now includes"activeNeed: L2 tools_wood → gather.logs (Деревянные орудия)"so Piadvises at the right level.
Behavioural diff (illustrative)
gather.logssurvive.acquire-food(L1)gather.logs(loop)gather.wool(L3)survive.flee(L0)Test plan
npm test— 315 green (was 279 on rc.1, +36 new):manifesto/needs.test.js(per-need)manifesto/state.test.js(ladder walk, L0 takeover,skip-on-null, caching)
reflex.test.jsapplied_countto start growing as thebot makes ladder progress (each progression generates valid
prefer_skill suggestions Pi can build on).
Followup (rc.3)
bot.on('move')jump-detect,bot.on('health')plunge-detect,bot.on('entitySpawn')hostile-addrecovery.tunnel-out, survive.pillar-up) so they preempt within
~100ms instead of waiting for a tick boundary
See
dev/v0.3.0/PLAN.mdfor the full v0.3.0 design.🤖 Generated with Claude Code
Superseded by single v0.3.0 PR
Pull request closed