fabro/lib/crates/fabro-util/src
fabro-sh-0530[bot] 5d6cd48e9e
Replace vague expect/panic messages with invariant-explaining messages (#422)
Production code must not panic without a clear explanation of *why* the
failure is impossible. This PR upgrades panic-adjacent messages across
the codebase to meet that standard, and converts two genuine runtime
panics into proper error handling.

## What changed

**Invariant-explaining `expect` messages** — all existing `expect("short
label")` calls that guarded hard-coded literals, just-inserted map
entries, just-pushed Vec elements, or hard-coded regex/template strings
now carry a sentence explaining *why* the None/Err path cannot be
reached (e.g. `"node was just inserted by ensure_node, so get_mut cannot
return None"`). No behavior changes.

**`assert_eq!` → `panic!` with justification** in `strategy.rs` — the
bare assert is replaced with an explicit `panic!` whose message names
every existing call site that enforces the `CodexDevice ↔ OpenAI`
invariant, making future regressions easier to diagnose.

**Genuine runtime errors converted to `Result`** — `select_backend` /
`select_backend_for_gh_command` in the upgrade command previously called
`.expect()` on `http_client()`, which can fail due to TLS or environment
issues. Both functions now return `Result<Backend>` and propagate the
error to the CLI boundary.

**Signal handler panics degraded to warnings** in `serve.rs` —
`ctrl_c()` and `unix::signal()` failures no longer panic the server;
instead they log a warning and park the future, allowing the server to
keep running without graceful-shutdown support rather than crashing on
startup.

**Telemetry thread spawn failure** in `fabro-telemetry` — instead of
panicking, a failure to spawn the background thread logs a debug message
and silently disables telemetry, which is the correct degradation for an
optional observability feature.

**OS RNG `expect` messages** — three sites (`random_secret`,
`random_auth_code`, `generate_dev_token`) now explain that a failure
means the system RNG is broken and the security of the generated value
would be compromised, justifying the panic boundary.


### Fabro Details

<details>
<summary>Ran 3 stages in 45m 16s for $11.65</summary>

| Stage | Duration | Cost | Retries |
|---|---|---|---|
| start | 0s | – | 0 |
| work | 34m 22s | $9.00 | 0 |
| audit | 10m 35s | $2.65 | 0 |
| **Total** | **45m 16s** | **$11.65** | **0** |

</details>

<details>
<summary>Ran <code>Goal.fabro</code> (4 nodes and 5 edges)</summary>

```dot
digraph Goal {
    graph [
        goal="Complete the user-provided goal",
        rankdir=LR,
        max_node_visits=30
    ]

    start [shape=Mdiamond, label="Start"]
    exit  [shape=Msquare, label="Exit"]

    work [
        label="Work",
        thread_id="goal",
        fidelity="full",
        max_visits=12,
        prompt="@prompts/continue.md"
    ]

    audit [
        label="Completion Audit",
        thread_id="goal",
        fidelity="full",
        goal_gate=true,
        retry_target="work",
        output_schema="routing",
        output_retries=2,
        max_visits=12,
        prompt="@prompts/audit.md"
    ]

    start -> work -> audit

    audit -> exit [label="Done", condition="outcome=succeeded"]
    audit -> work [label="Continue", condition="outcome=failed || preferred_label=Continue"]
    audit -> work [label="No clear verdict"]
}

```

</details>

⚒️ Generated with [Fabro](https://fabro.sh)

---------

Co-authored-by: Fabro <noreply@fabro.sh>
Co-authored-by: Bryan Helmkamp <bryan@brynary.com>
2026-05-27 10:38:20 -04:00
..
backoff.rs refactor(unwrap): clean runtime hotspot call sites 2026-04-19 20:48:44 -04:00
browser.rs refactor(static): centralize env var names 2026-04-24 12:29:51 -04:00
check_report.rs refactor(unwrap): clean runtime hotspot call sites 2026-04-19 20:48:44 -04:00
dev_token.rs Replace vague expect/panic messages with invariant-explaining messages (#422) 2026-05-27 10:38:20 -04:00
env.rs refactor(static): centralize env var names 2026-04-24 12:29:51 -04:00
error.rs feat(errors): add structured failure diagnostics (#277) 2026-05-16 13:25:07 -04:00
exit.rs feat(cli): suggest fabro auth login on auth-required errors 2026-04-22 10:49:22 -04:00
home.rs feat(auth): store dev tokens in auth store 2026-04-24 16:02:36 -04:00
json.rs refactor: remove remaining event json indirection 2026-04-04 13:24:19 -04:00
lib.rs refactor(workflow): share metadata snapshot helpers 2026-04-29 19:43:30 -04:00
path.rs Improve install command output ordering and path display 2026-04-14 15:16:21 -04:00
printer.rs chore(clippy): require reasons on allow attributes 2026-04-19 20:24:24 -04:00
run_log.rs refactor: simplify per-run logs client and handler 2026-04-26 16:06:23 -04:00
session_secret.rs deps: bump rand 0.8 → 0.9 (#163) 2026-04-17 07:57:10 -04:00
terminal.rs fmt: apply nightly rustfmt after merge 2026-04-11 13:43:30 -04:00
text.rs Enable 7 additional pedantic clippy lints 2026-03-29 13:47:08 -04:00
time.rs refactor(workflow): share metadata snapshot helpers 2026-04-29 19:43:30 -04:00
version.rs Move git SHA/build date from fabro-util to fabro-cli build.rs 2026-03-13 15:03:12 -04:00
warnings.rs Replace bare unwrap() with documented expect() across production runtim… (#415) 2026-05-26 17:46:39 -04:00