mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-14 23:22:51 +00:00
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>
|
||
|---|---|---|
| .. | ||
| src | ||
| Cargo.toml | ||