Stop a stalling bot deferring its own thinking forever - #263
Conversation
The other half of #257, and it is a livelock rather than the goal starvation the issue title claimed. Stall recovery clears the goal and pushes ar_nextai out 1.5 s so the bot wanders before re-planning. It re-armed that deferral on EVERY stall. A bot stalling more often than every 1.5 s therefore pushes its own AI tick permanently out of reach: it never re-picks a goal, never routes, and the wander meant to free it is the thing keeping it blind. The edict dump named it. Romero on dm2, motionless at '2352.5 -103.1 56.0' for 65 s, sampled twice 28 s apart: ar_goalstart 13.9 -> 13.9 PickGoal had not run since t13.9 ar_nextai 27.2 -> 55.6 advancing, but from deferrals only ar_stalls 15.0 -> 53.0 38 stalls in 28 s, 1.4 a second ar_wanderturn 26.9 -> 55.8 the wander was running the whole time ar_goal, ar_node, ar_mode, ar_enemy, ar_failstreak, ar_traptime all absent, so all default Every branch that could have re-goaled him was reachable. None ran, because the tick they sit inside never fired. One condition: only defer if we are not already waiting. One stall buys one 1.5 s pause, later stalls inside that window cannot extend it, so the tick always lands. LADDER, dm2, three pairs. Goals is the metric the mechanism predicts, and every fix tape beats every control tape: goals 78, 86, 89 -> 100, 96, 91 worst freeze 22.3s -> 8.2s cells 120,124,114 -> 122,124,123 stalls 77, 57, 67 -> 41, 69, 78 dm4 66 cells, 6 stalls, 152 goals, no freezes. e1m2 co-op 45 cells, no freezes, no water pin. This is the shared stall path, not co-op gated, so it touches every bot on every map. Hence the wider net. METHOD NOTE. Two conclusions in this hunt were drawn from a field list that head -40 had silently truncated; ar_traptime and ar_failstreak were absent rather than unchecked, and only an explicit grep settled it. When the dump is the evidence, read all of it. Refs #257 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3770454c6f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (time > self.ar_nextai) | ||
| self.ar_nextai = time + 1.5; |
There was a problem hiding this comment.
Preserve the initial stall-recovery delay
Whenever a second consecutive stall reaches this branch, this condition can never be true: earlier in the same Argus_AI invocation, the periodic-maintenance block either observes time > self.ar_nextai and resets it to time + 0.2, or leaves an existing future deadline unchanged. Consequently, the new assignment is unreachable, so every cleared goal can be reconsidered within 0.2 seconds instead of receiving the intended one-time 1.5-second wander period, restoring the corner-wedging behavior described immediately above. Distinguishing a normal AI deadline from an already-active recovery pause requires separate state or a comparison that accounts for the normal 0.2-second deadline.
Useful? React with 👍 / 👎.
The other half of #257, and it is a livelock rather than the goal starvation the issue title claimed.
Stall recovery clears the goal and pushes
ar_nextaiout 1.5 s so the bot wanders before re-planning. It re-armed that deferral on every stall. A bot stalling more often than every 1.5 s therefore pushes its own AI tick permanently out of reach: it never re-picks a goal, never routes, and the wander meant to free it is the thing keeping it blind.The edict dump named it
Romero on dm2, motionless at
2352.5 -103.1 56.0for 65 s, sampled twice 28 seconds apart:ar_goalstartar_nextaiar_stallsar_wanderturnar_goal,ar_node,ar_mode,ar_enemy,ar_failstreakandar_traptimeall absent, so all default. Every branch that could have re-goaled him was reachable. None ran, because the tick they sit inside never fired.The fix
One condition: only defer if we are not already waiting. One stall buys one 1.5 s pause; later stalls inside that window cannot extend it, so the tick always lands.
Ladder, dm2, three pairs
Goals is the metric the mechanism predicts, and every fix tape beats every control tape:
dm4: 66 cells, 6 stalls, 152 goals, no freezes. e1m2 co-op: 45 cells, no freezes, no water pin.
This is the shared stall path, not co-op gated, so it touches every bot on every map. Hence the wider net.
Method note
Two conclusions in this hunt were drawn from a field list that
head -40had silently truncated.ar_traptimeandar_failstreakwere absent rather than unchecked, and only an explicit grep settled it. When the dump is the evidence, read all of it.Refs #257
🤖 Generated with Claude Code