SKW-1 — the fourth Alpaca client has no request deadline: the skew-capture cron can still hang forever
status: open · raised panel run 15 (2026-08-31) · class: moat / loudness (capture path) · judgement: YES · effort ~0.1 pd · horizon: any delayed/stalled 19:00Z snapshot run — the outage-correlated class
Plain-language summary. PR #120 (finding 2) injected a 30-second request
deadline at the HTTP session of the three trading-path Alpaca clients, so a
broker stall now raises instead of hanging until the CI job is killed. There
is a fourth client the fix does not reach:
src/thales/data/options_skew.py:383-386 constructs its own
OptionHistoricalDataClient bare — no _apply_default_timeout — and it is
live on the 19:00Z skew-snapshot cron (cli snapshot-skew,
.github/workflows/skew-snapshot.yml:48). A stall there hangs the capture run
until the job kill. Capture-cron stalls are precisely the outage-correlated
class the STAMP-1/STAMP-2 record documents, and a hung capture run loses a
permanent, un-backfillable day of the B4-pinned stream. This row completes an
owner-shipped fix; it is not new scope.
Fix shape (propose-only)
Wrap the client via the existing _apply_default_timeout
(execution/alpaca_broker.py:69-77). The helper is already fail-loud if a
future SDK drops ._session, so the pattern transfers unchanged: one import,
one line.
Test design + kill criterion (pre-registered, negative-controlled)
A test asserting every Alpaca SDK client construction site in src/ applies
the deadline wrap (negative control: remove the wrap at the skew site → the
test reds; the three #120 sites are already covered by their own tests).
Falsifier: if the wrapped client breaks the skew capture within 5 shadow
trading days (any capture failure attributable to the timeout on a
normally-paced run), revert and record the exposure as accepted — do not tune
the 30s value after seeing failures.
Built — recorded 2026-09-05
Shipped 2026-08-31 in PR #125 (commit 29c6f23, "SKW-1 deadline").
options_skew.py:398 wraps the skew-capture client's HTTP session in
_apply_default_timeout, the same 30-second deadline PR #120 gave the three
trading-path clients; all four Alpaca clients now carry it
(alpaca_broker.py:102, :352; vrp_daily.py:165; options_skew.py:398).
Outcome: shipped.
Route — recorded honestly: built on the owner's direct instruction in the
2026-09-01 interactive session (RESEARCH.md's 09-01 banner already reads
"SKW-1 built"), NOT via queue/approved/. The row itself was never moved and
sat in open/ for five days, still asserting "can still hang forever", until
the 2026-09-05 external design review (finding 6, retire-stale-docs) caught
the disagreement between the notebook and the queue. Moved by the maintainer
in the review-response PR; the guard denies the open→built rename, so a
human merges.