feat(pipeline): typed per-run source outcomes with doctor-aligned failure states (#797)

* feat(pipeline): typed per-run source outcomes in the report

* fix: address self-review findings

* fix: propagate failure capture to nested pools, surface authed GitHub failures, classify wrapped timeouts, opt-in strict exit

* fix: pick the most specific captured failure, not the last-appended one

---------

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
This commit is contained in:
Matt Van Horn
2026-07-12 07:14:00 -07:00
committed by GitHub
parent 06b68a883a
commit 021bdbf60e
19 changed files with 1280 additions and 71 deletions
+10
View File
@@ -355,6 +355,16 @@ Every live run writes its JSON result to `~/.config/last30days/doctor-cache.json
Web search has **no** env pin — pin it per-run with `--web-backend=<name>` only (see [Web search backend priority](#web-search-backend-priority)).
### Strict exit for degraded runs
By default a research run exits `0` even when a source failed mid-run (rate-limited, auth-failed, unreachable, timeout, schema-drift) — the report still renders, with the failure annotated in the per-source footer and a partial-coverage warning. Wrappers that need to distinguish degraded coverage from success (cron briefs, CI, downstream agents) can opt in:
| Var | Effect |
| --- | --- |
| `LAST30DAYS_STRICT_EXIT` | Truthy (`1`/`true`/`yes`/`on`): the engine exits `3` when any source outcome is neither `ok`, `no-results`, nor `skipped-unconfigured`. A one-line `strict-exit: degraded sources: ...` note goes to stderr. Default (unset): exit `0`, unchanged behavior. |
Exit codes with the flag on: `0` clean run, `3` completed-but-degraded (report was produced), non-zero others unchanged (hard failures). Same hybrid pattern as `LAST30DAYS_DEBUG` — works shell-exported or in `.env`.
---
## Trend monitoring (`--store` + watchlist + briefings)