Lisp layer survives hostile brains: panic recovery, recursion limit, arity guards (Closes #121) #132

Merged
robertismo merged 1 commit from 121-panic into master 2026-10-01 15:48:05 +00:00
Owner

Three defenses so a malformed brain can never kill the game process:

  • callHook wraps hook execution in a recover: a residual panic becomes an ordinary hook error and the bank faults (#91) instead of exiting the whole process and destroying every game in a bench run.
  • The interpreter enforces its own recursion limit (maxEvalDepth 2000): Go stack overflow is uncatchable, so eval counts depth and returns an ordinary error before reaching it.
  • Every arg-indexing builtin (set-deposit-rate, bid-loan, take-bonds, bid-acquisition) guards its arity.

Verified with three hostile brains — (-) with no args, unbounded recursion, (bid-loan) with no args: each run exits 0 with the error surfaced and the game completing to a final ranking. Full suite + vet clean.

Three defenses so a malformed brain can never kill the game process: - callHook wraps hook execution in a recover: a residual panic becomes an ordinary hook error and the bank faults (#91) instead of exiting the whole process and destroying every game in a bench run. - The interpreter enforces its own recursion limit (maxEvalDepth 2000): Go stack overflow is uncatchable, so eval counts depth and returns an ordinary error before reaching it. - Every arg-indexing builtin (set-deposit-rate, bid-loan, take-bonds, bid-acquisition) guards its arity. Verified with three hostile brains — `(-)` with no args, unbounded recursion, `(bid-loan)` with no args: each run exits 0 with the error surfaced and the game completing to a final ranking. Full suite + vet clean.
Three defenses so a malformed brain can never kill the game process:

- callHook wraps the hook execution in a recover: any residual panic
  is converted to an ordinary hook error and the bank is faulted
  (#91), like a non-finite output. Previously a panic inside a
  builtin exited the whole process, destroying every game in a bench
  run.
- The interpreter enforces its own recursion limit (maxEvalDepth
  2000): Go stack overflow is uncatchable, so eval counts its depth
  and returns an ordinary error instead of reaching it.
- Every arg-indexing builtin (set-deposit-rate, bid-loan, take-bonds,
  bid-acquisition) guards its arity and returns a hook error.

Verified with three hostile brains - (-) with no args, unbounded
recursion, and (bid-loan) with no args: each run exits 0 with the
error surfaced and the game completing to a final ranking.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Winnie/bankwars!132
No description provided.