P0 hardening patch on top of rc.1, addressing four real bugs spotted from
live observation + adding the self-reflection loop the operator asked
for.
Bugs fixed
Pi subprocess opens second MC connection. When the hybrid runtime
spawns pi -p \"...\" for banter / coach / planner, the loaded extensions/mineflayer-bridge.ts calls connect(\"startup\") and
races for the nickname. PEPA_HEADLESS=1 env (set by runtime/pi-bridge.js) now makes the bridge skip its connect.
Tests poison live state.runtime/log.js, scenario-memory.js, world-journal.js, and knowledge/store.js all key off config.stateDir. Under npm test that resolved to the live state/<host>/, so test rows ended up in real scenarios.jsonl. config.js now detects node test context (or PEPA_STATE_DIR
override) and redirects to /tmp/pepa-test-state-<pid>/. ~550
historical test rows cleaned from live state in this commit.
defendReflex marks lesson failed too early. Combat advice override
used to call reportAdviceOutcome({succeeded:false})before the
flee skill returned. The creeper-rule lesson got applied_count=2, succeeded_count=0 not because the lesson is bad
but because we marked it bad pre-emptively. Now dispatchDefendFlee
carries lessonId and reports the actual flee outcome.
Pi-coach mode-name leak. Coach lessons sometimes set prefer_skill: \"night_shelter\" or self_preservation (those are
mode names, not skill ids), so they failed SAFE_OVERRIDES and
silently fell to avoid instead of override. normalisePreferSkill in coach/advice.js translates mode names
and underscore-shapes to canonical skill ids.
New behavior
Self-reflection loop (runtime/coach/reflect.js). Every 30 min
Pi gets asked: "Are you making progress, or in a loop? What should
you do?" Reply parsed into verdict + summary + next-action + new
lessons. Reflection written to state/<host>/reflections/<ts>.md;
lessons land in knowledge.lessons with source=\"pi-reflect\".
Rate-limited 2 calls/hour.
Test plan
npm test — 246/246 green (was 237; +9 advice/reflect coverage).
Verified empirically: after the config fix, npm test adds 0
rows to the live scenarios.jsonl.
extensions/mineflayer-bridge.ts typecheck — diff only adds an
early-return guard.
Followups (rc.3 candidates)
Wedged-pit emergency policy: at low HP + no food + no movement, force village.choose-base or survive.sleep instead of explore.far.
Promote village.choose-base early in the curriculum when bot's been
stuck in same chunk > N minutes.
Tool-progression auto-craft: if gather.stone returns missing_tool,
curriculum should auto-dispatch craft.wooden-pickaxe.
## Summary
P0 hardening patch on top of rc.1, addressing four real bugs spotted from
live observation + adding the self-reflection loop the operator asked
for.
### Bugs fixed
1. **Pi subprocess opens second MC connection.** When the hybrid runtime
spawns `pi -p \"...\"` for banter / coach / planner, the loaded
`extensions/mineflayer-bridge.ts` calls `connect(\"startup\")` and
races for the nickname. `PEPA_HEADLESS=1` env (set by
`runtime/pi-bridge.js`) now makes the bridge skip its connect.
2. **Tests poison live state.** `runtime/log.js`, `scenario-memory.js`,
`world-journal.js`, and `knowledge/store.js` all key off
`config.stateDir`. Under `npm test` that resolved to the live
`state/<host>/`, so test rows ended up in real `scenarios.jsonl`.
`config.js` now detects node test context (or `PEPA_STATE_DIR`
override) and redirects to `/tmp/pepa-test-state-<pid>/`. ~550
historical test rows cleaned from live state in this commit.
3. **defendReflex marks lesson failed too early.** Combat advice override
used to call `reportAdviceOutcome({succeeded:false})` *before* the
flee skill returned. The creeper-rule lesson got
`applied_count=2, succeeded_count=0` not because the lesson is bad
but because we marked it bad pre-emptively. Now `dispatchDefendFlee`
carries `lessonId` and reports the actual flee outcome.
4. **Pi-coach mode-name leak.** Coach lessons sometimes set
`prefer_skill: \"night_shelter\"` or `self_preservation` (those are
mode names, not skill ids), so they failed `SAFE_OVERRIDES` and
silently fell to `avoid` instead of `override`.
`normalisePreferSkill` in `coach/advice.js` translates mode names
and underscore-shapes to canonical skill ids.
### New behavior
5. **Self-reflection loop** (`runtime/coach/reflect.js`). Every 30 min
Pi gets asked: \"Are you making progress, or in a loop? What should
you do?\" Reply parsed into verdict + summary + next-action + new
lessons. Reflection written to `state/<host>/reflections/<ts>.md`;
lessons land in `knowledge.lessons` with `source=\"pi-reflect\"`.
Rate-limited 2 calls/hour.
## Test plan
- [x] `npm test` — 246/246 green (was 237; +9 advice/reflect coverage).
- [x] Verified empirically: after the config fix, `npm test` adds 0
rows to the live `scenarios.jsonl`.
- [x] `extensions/mineflayer-bridge.ts` typecheck — diff only adds an
early-return guard.
## Followups (rc.3 candidates)
- Wedged-pit emergency policy: at low HP + no food + no movement, force
`village.choose-base` or `survive.sleep` instead of `explore.far`.
- Promote `village.choose-base` early in the curriculum when bot's been
stuck in same chunk > N minutes.
- Tool-progression auto-craft: if `gather.stone` returns `missing_tool`,
curriculum should auto-dispatch `craft.wooden-pickaxe`.
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.
Summary
P0 hardening patch on top of rc.1, addressing four real bugs spotted from
live observation + adding the self-reflection loop the operator asked
for.
Bugs fixed
Pi subprocess opens second MC connection. When the hybrid runtime
spawns
pi -p \"...\"for banter / coach / planner, the loadedextensions/mineflayer-bridge.tscallsconnect(\"startup\")andraces for the nickname.
PEPA_HEADLESS=1env (set byruntime/pi-bridge.js) now makes the bridge skip its connect.Tests poison live state.
runtime/log.js,scenario-memory.js,world-journal.js, andknowledge/store.jsall key offconfig.stateDir. Undernpm testthat resolved to the livestate/<host>/, so test rows ended up in realscenarios.jsonl.config.jsnow detects node test context (orPEPA_STATE_DIRoverride) and redirects to
/tmp/pepa-test-state-<pid>/. ~550historical test rows cleaned from live state in this commit.
defendReflex marks lesson failed too early. Combat advice override
used to call
reportAdviceOutcome({succeeded:false})before theflee skill returned. The creeper-rule lesson got
applied_count=2, succeeded_count=0not because the lesson is badbut because we marked it bad pre-emptively. Now
dispatchDefendFleecarries
lessonIdand reports the actual flee outcome.Pi-coach mode-name leak. Coach lessons sometimes set
prefer_skill: \"night_shelter\"orself_preservation(those aremode names, not skill ids), so they failed
SAFE_OVERRIDESandsilently fell to
avoidinstead ofoverride.normalisePreferSkillincoach/advice.jstranslates mode namesand underscore-shapes to canonical skill ids.
New behavior
runtime/coach/reflect.js). Every 30 minPi gets asked: "Are you making progress, or in a loop? What should
you do?" Reply parsed into verdict + summary + next-action + new
lessons. Reflection written to
state/<host>/reflections/<ts>.md;lessons land in
knowledge.lessonswithsource=\"pi-reflect\".Rate-limited 2 calls/hour.
Test plan
npm test— 246/246 green (was 237; +9 advice/reflect coverage).npm testadds 0rows to the live
scenarios.jsonl.extensions/mineflayer-bridge.tstypecheck — diff only adds anearly-return guard.
Followups (rc.3 candidates)
village.choose-baseorsurvive.sleepinstead ofexplore.far.village.choose-baseearly in the curriculum when bot's beenstuck in same chunk > N minutes.
gather.stonereturnsmissing_tool,curriculum should auto-dispatch
craft.wooden-pickaxe.