feat(runtime): observability + no-progress detector (Phase 1) #13

Merged
halofourteen merged 1 commits from feat/survival-pivot-phase-1 into main 2026-05-25 22:11:13 +03:00
halofourteen commented 2026-05-25 22:11:06 +03:00 (Migrated from github.com)

Summary

Phase 1 of plans/autonomous-survival-bot-prd.md: make the bot able to
answer "what am I doing and why am I not doing more?" without parsing
the log stream.

  • runtime/state.js — pure FSM classifier emitting one of
    emergency / working / recovering / planning / social /
    idle from the current snapshot + reflex context.
  • runtime/no-progress.js — sliding-window detector. When position
    and inventory are both unchanged for 60 s+, emits a stable reason
    code from the REASONS enum (waiting_for_day,
    night_hostile_nearby, no_food_source, inventory_full,
    no_reachable_target, planner_empty, awaiting_action_cooldown).
  • runtime/bot.jstick() now stamps runtimeState,
    activeSkill, currentMilestone (from plan.md, cached 30 s),
    lastResult, noProgressReason, failuresByCode, lastEscalation,
    reflexPaused on every STATUS snapshot. dispatchAction tracks
    lastResult and lastFailureAt for the recovering-state
    classifier.
  • runtime/planner.js — exposes isPlannerBusy(),
    readNextMilestone(), planExists().
  • runtime/viewer.js + VIEWER_PORT — optional
    prismarine-viewer launcher (lazy import; dep stays out of default).
  • TUI — StatusBar gains state badge, current-skill row, milestone
    row, no-progress reason warning, last-result line with ok/fail
    color, failures-by-class summary, last-Pi-escalation age.

Test plan

  • Smoke-tested computeState across all 6 states + disconnected
  • Smoke-tested no-progress detector: still→reason, moved→null,
    night+hostile→night_hostile_nearby, busy→null
  • node --check on every touched module
  • TUI starts (raw-mode stdin warning is expected in headless smoke)
  • Live-server: bot stands still for >60 s with no inventory change
    → TUI displays one concrete noProgressReason
  • Live-server: VIEWER_PORT=3007 npm i prismarine-viewer && npm run bot
    starts the viewer at http://localhost:3007

🤖 Generated with Claude Code

## Summary Phase 1 of `plans/autonomous-survival-bot-prd.md`: make the bot able to answer "what am I doing and why am I not doing more?" without parsing the log stream. - **`runtime/state.js`** — pure FSM classifier emitting one of `emergency` / `working` / `recovering` / `planning` / `social` / `idle` from the current snapshot + reflex context. - **`runtime/no-progress.js`** — sliding-window detector. When position and inventory are both unchanged for 60 s+, emits a stable reason code from the `REASONS` enum (`waiting_for_day`, `night_hostile_nearby`, `no_food_source`, `inventory_full`, `no_reachable_target`, `planner_empty`, `awaiting_action_cooldown`). - **`runtime/bot.js`** — `tick()` now stamps `runtimeState`, `activeSkill`, `currentMilestone` (from `plan.md`, cached 30 s), `lastResult`, `noProgressReason`, `failuresByCode`, `lastEscalation`, `reflexPaused` on every STATUS snapshot. `dispatchAction` tracks `lastResult` and `lastFailureAt` for the recovering-state classifier. - **`runtime/planner.js`** — exposes `isPlannerBusy()`, `readNextMilestone()`, `planExists()`. - **`runtime/viewer.js` + `VIEWER_PORT`** — optional prismarine-viewer launcher (lazy import; dep stays out of default). - **TUI** — StatusBar gains state badge, current-skill row, milestone row, no-progress reason warning, last-result line with ok/fail color, failures-by-class summary, last-Pi-escalation age. ## Test plan - [x] Smoke-tested `computeState` across all 6 states + disconnected - [x] Smoke-tested no-progress detector: still→reason, moved→null, night+hostile→`night_hostile_nearby`, busy→null - [x] `node --check` on every touched module - [x] TUI starts (raw-mode stdin warning is expected in headless smoke) - [ ] Live-server: bot stands still for >60 s with no inventory change → TUI displays one concrete `noProgressReason` - [ ] Live-server: `VIEWER_PORT=3007 npm i prismarine-viewer && npm run bot` starts the viewer at http://localhost:3007 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.