fix(loop): deliver recovered tool-panic message to the LLM + review cleanups#26
Conversation
…leanups A panicking tool's recovered error message was discarded: the goroutine returned before results[idx] was assigned, so the LLM received an empty tool result and the consecutive-error tracker never counted the failure. Drop the early return so the panic message flows through like any other tool error. The existing TestToolPanic_DoesNotKillAgent never exercised this path (its message-count trigger never matched with no system prompt); switch it to a call counter and assert the panic message reaches the LLM. Review cleanups from the #25 follow-up: - loop: name the thrice-repeated anonymous interface as trustAllSetter - telegram: parse ODEK_TELEGRAM_ALLOW_ALL with strconv.ParseBool for a consistent truthy grammar (malformed values fail closed) - telegram: add TelegramConfig.HasAllowlist() and use it in both ValidateConfig and the open-bot startup warning - telegram: correct HandlerConfig allowlist comments (AllowAllUsers is only consulted when BOTH lists are empty) and document on HandleUpdate that every routed handler must enforce isAllowed Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
odek | fb9a98b | Commit Preview URL Branch Preview URL |
Jun 10 2026, 11:28 AM |
Verification-protocol remediation for #26: the claim that malformed or extended truthy values ("yes", "on", "junk") fail closed had no corresponding test, and HasAllowlist had no direct unit test. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Verification Certificate(per the AI Verification Protocol v5.2.7, applied within a single-session pipeline — see honesty caveats below) PR: #26 — fix(loop): deliver recovered tool-panic message to the LLM + review cleanupsClassification: GeneratedCode (correlated-failure risk: code, tests, and review produced by the same model instance) Axes Summary
Evidence
Remediations applied during this run
Unverified Gaps
Verdict
Rationale: all nine axes pass or carry only low-risk gaps, but this pipeline cannot attest independence from its own generator — the human auditor's review of this PR is the required independent check. 🤖 Generated with Claude Code |
Summary
Follow-up to #25: applies the findings from the code review of that branch. One real bug fix plus five small cleanups.
Bug fix
Panicking tool's error message was discarded (
internal/loop/loop.go). The tool-execution goroutine recovered the panic and builterror: tool "x" panicked: ..., but then hit an earlyreturnbeforeresults[idx]was assigned. Consequences:error:prefix check, so the consecutive-tool-error circuit breaker never counted the failure — a repeatedly panicking tool could loop tomaxIterwith no error signal.The early return is removed so the recovered message flows through like any other tool error.
The existing
TestToolPanic_DoesNotKillAgentwas a false positive: itslen(body.Messages) == 2trigger never matched (no system prompt → first request has 1 message), so the mock returned the final answer immediately and the panic path never ran. It now uses a call counter and asserts the panic message actually reaches the LLM — it fails against the old code.Cleanups
internal/loop/loop.go: the anonymousinterface{ SetTrustAll(bool) }repeated in three places is now a namedtrustAllSettertype.internal/telegram/config.go:ODEK_TELEGRAM_ALLOW_ALLis parsed withstrconv.ParseBoolinstead of a customparseBoolthat acceptedyes/on— consistent truthy grammar with the rest of the config surface; malformed values fail closed. (The extended grammar shipped only in fix(security): audit remediation — Telegram path traversal + approval-grant leak #25 and was never documented; all docs use=true.)internal/telegram/config.go+cmd/odek/telegram.go: newTelegramConfig.HasAllowlist()helper replaces the fail-closed condition duplicated betweenValidateConfigand the open-bot startup warning.internal/telegram/handler.go: corrected misleadingAllowedChats/AllowedUserscomments (AllowAllUsersis only consulted when both lists are empty), and added a SECURITY note onHandleUpdatethat every routed handler must enforceisAllowed— the pattern whose omission caused the callback-query bypass fixed in fix(security): audit remediation — Telegram path traversal + approval-grant leak #25.Test plan
go vet ./...cleango test ./...passesTestToolPanic_DoesNotKillAgentstrengthened into a regression test for the panic-output drop🤖 Generated with Claude Code