Skip to content

daily_append: hard-fail on missing macro keys + verify writes landed#37

Merged
cipher813 merged 1 commit into
mainfrom
fix/daily-append-verify-macro-freshness
Apr 15, 2026
Merged

daily_append: hard-fail on missing macro keys + verify writes landed#37
cipher813 merged 1 commit into
mainfrom
fix/daily-append-verify-macro-freshness

Conversation

@cipher813
Copy link
Copy Markdown
Owner

Summary

Root-cause fix for the silent-fail that let 2026-04-15 weekday pipeline runs report SUCCEEDED while macro/SPY sat 5 days stale (4/10 → 4/15) — the scenario that today's deploy canary finally surfaced after 5 days of silent daily failures.

Before: If `closes.get(key)` returned None for a macro ticker, `daily_append` silently skipped the update. Combined with "all stocks skipped because backfill wrote today's row," the pipeline could produce ZERO writes and still return status="ok".

After:

  1. Track every macro/sector-ETF key missing from `closes` — raise with the full missing-keys list at end of macro loop.
  2. Sector ETFs iterate an explicit `["XLB",...]` list (not `startswith("XL")` filter) so missing keys surface instead of silently-not-iterating.
  3. After update() calls, readback every updated key and verify its last date == today. Belt-and-suspenders against silent no-ops in ArcticDB's commit layer.
  4. Summary log includes `macro_updated + sector_updated` counts so "ok with zero writes" is visible in logs.

Test plan

  • Full suite: 46 passed (+3 new source-level regressions).
  • After merge: next weekday pipeline run either succeeds cleanly (macro updated + verified) or fails loudly with named missing keys. No more silent "ok with stale data."
  • Follow-up investigation: WHY was upstream daily_closes missing macro keys on the 4/15 08:39 rerun despite 920-ticker load including SPY? (Scope for a separate PR in alpha-engine-data/collectors/daily_closes.py.)

Related

🤖 Generated with Claude Code

Root-cause fix for the silent-fail that let 2026-04-15 weekday
pipeline runs report SUCCEEDED while macro/SPY sat 5 days stale
(4/10 → 4/15) until the inference Lambda preflight finally caught
it via the PR #28 deploy canary.

## The silent-fail

Old macro update loop:

    for key in macro_keys:
        bar = closes.get(key)
        if bar and not np.isnan(...):
            macro_lib.update(key, new_row)

If `closes.get(key)` returned None (upstream daily_closes collection
gap for that ticker), the update silently skipped. No log. No raise.
daily_append returned status="ok". weekly_collector returned status="ok".
Python exited 0. Step Function marked SUCCEEDED. macro never updated.

Combined with the "all stocks skipped because backfill wrote today's
row" case, an entire daily_append invocation could produce ZERO writes
and still report success.

## The fix

1. Track macro_missing_from_closes list. Any key absent from closes
   (or with NaN Close) goes in the list instead of being silently
   skipped.

2. After both loops, if the list is non-empty, raise RuntimeError
   naming the missing keys. Macro inputs are not optional — SPY feeds
   return_vs_spy_5d, VIX feeds vix_level, sector ETFs feed
   sector-relative features. Upstream collection must produce them.

3. Sector ETF iteration now uses an explicit ["XLB","XLC",...] list
   rather than filtering closes.keys() with startswith("XL"). Missing
   sector ETFs now surface as rejects instead of silently-not-iterating.

4. After update() calls complete, read back every updated key and
   verify its last date matches today. A pure belt-and-suspenders check
   — update() has no return value to confirm success, so a silent
   no-op in ArcticDB's commit layer could still slip through the
   no-exception path without this readback. If verification fails,
   raise with the specific (key, reason) tuples.

5. Summary log line now surfaces macro_updated + sector_updated counts
   alongside the stock counts, so "ok with zero writes" is visible in
   the logs instead of hidden behind stock-only metrics.

## Test plan

tests/test_daily_append_semantics.py — 3 new source-level regression
tests locking the hard-fail semantics:
- Missing macro keys raise
- Verification readback exists
- Sector ETFs iterate explicit list

Full suite: 46 passed (was 43 + 3 new).

## Follow-up

Investigate WHY the upstream daily_closes collector was missing macro
keys in the 2026-04-15 08:39 PT rerun despite loading 920 tickers
with SPY/VIX/etc verified present in the parquet. The missing-keys
branch should not trigger in a healthy run — its purpose is to
loudly halt the pipeline when upstream collection is broken, so we
find out and fix it instead of running on stale data.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@cipher813 cipher813 merged commit a948066 into main Apr 15, 2026
1 check passed
@cipher813 cipher813 deleted the fix/daily-append-verify-macro-freshness branch April 15, 2026 21:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant