// Package safego provides a goroutine launcher that recovers panics instead
// of letting them crash the whole process.
//
// Go's default behavior for a panic in ANY goroutine — not just the one
// serving an HTTP request, which net/http recovers automatically per
// request — is to take down the entire process. This codebase runs several
// long-lived or unattended background goroutines (the nomos auto-
// continuation worker, resumed chat turns, async execution dispatch, the SSE
// event listener) that do real work — JSON parsing of model/tool output,
// map/slice indexing — with no operator watching. Before this package, a
// single edge case in any of them (a malformed tool result, an unexpected
// nil) would crash nomos or the api process outright, taking down every
// concurrently-running task or request, not just the one that hit it.
package safego

import (
	"log/slog"
	"runtime/debug"
)

// Go runs fn in a new goroutine. A panic inside fn is recovered and logged
// (with a stack trace) instead of crashing the process. label identifies the
// goroutine in logs — use something a reader can trace back to the call
// site, e.g. "nomos:continuation-worker" or "mcp:executeApprovedViaAPI".
func Go(label string, fn func()) {
	go func() {
		defer func() {
			if r := recover(); r != nil {
				slog.Error("panic recovered in background goroutine",
					"goroutine", label, "panic", r, "stack", string(debug.Stack()))
			}
		}()
		fn()
	}()
}
