C0b: address verified gadfly findings (panic-safety + test honesty)
executus CI / test (pull_request) Failing after 58s
executus CI / test (pull_request) Failing after 58s
From PR #9 (minimax + deepseek): - Run now has a top-level recover() — the "never propagates a panic" promise was unenforced; a panicking host Port (Critic/Audit/Palette) on the run goroutine now becomes Result.Err instead of unwinding into the caller. - The critic deadline-watch goroutine recovers panics from a host Deadline() (it's a separate goroutine, so Run's recover can't catch it) — a buggy CriticHandle can't crash the process. - CriticHandle interface documents its concurrency contract (Record*/Steer on the run goroutine vs Deadline()/Stop() from the watch goroutine — impls must be concurrent-safe; the critic battery already is). - startCritic's dead `soft <= 0 -> noop` guard (withFallbacks already coerces to 90s) replaced with a defensive inline 90s default, so a bypass of withFallbacks still gets a working critic instead of silently none. - Delivery tests made honest: the old "error path" test only checked the early-return (no delivery); added TestDeliverErrorOnRunFailure (in-loop model error -> DeliverError to the target) + renamed the early-return test. Graded all #9 findings in the gadfly MCP. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+12
-3
@@ -104,10 +104,19 @@ type Result struct {
|
||||
}
|
||||
|
||||
// Run executes ra with the given invocation + input and returns the Result. It
|
||||
// never propagates a panic; failures surface in Result.Err.
|
||||
func (e *Executor) Run(ctx context.Context, ra RunnableAgent, inv tool.Invocation, input string) Result {
|
||||
// never propagates a panic; failures surface in Result.Err (a top-level recover
|
||||
// converts any panic — including from a host Port — into a run error).
|
||||
func (e *Executor) Run(ctx context.Context, ra RunnableAgent, inv tool.Invocation, input string) (res Result) {
|
||||
started := time.Now()
|
||||
res := Result{RunID: inv.RunID}
|
||||
res = Result{RunID: inv.RunID}
|
||||
// Enforce the no-panic contract: a panic anywhere in the run (incl. a host
|
||||
// Critic/Audit/Palette callback on the main goroutine) becomes Result.Err
|
||||
// rather than unwinding into the caller.
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
res.Err = fmt.Errorf("run.Executor: recovered panic: %v", r)
|
||||
}
|
||||
}()
|
||||
|
||||
tier := ra.ModelTier
|
||||
if tier == "" {
|
||||
|
||||
Reference in New Issue
Block a user