RecessionAlert RFD — exploratory public-proxy campaign

The checked-in RecessionAlert page documents a fifteen-model diffusion, a 0–15 range, and an RFD > 5 warning, but does not include the observation series, component formulas, publication clock, or portfolio rule. This notebook reruns only the explicitly inferred public FRED proxy campaign from the local read-only cache. It does not request the live site or modify a canonical database.

In [1]:
from pathlib import Path
import json
import runpy
root = Path.cwd()
while root != root.parent and not (root / 'data' / 'market.sqlite').exists():
    root = root.parent
builder = runpy.run_path(str(root / 'research/experiments/1346-publication.py'))
campaign = builder['write_publication_inputs']()
print('campaign:', campaign['campaign_id'], campaign['status'])
print('source SHA256:', campaign['source']['sha256'])
print('native span:', campaign['source']['native_span'])
print('proxy inputs:', campaign['provenance']['proxy_sources'])
campaign: recessionalert-rfd published
source SHA256: sha256:e705e5996621202e0e72744fdf229c4a15a8d85d1de3eff8427c7ac76bd99066
native span: Narrative page snapshot only; no source-linked RFD observation span
proxy inputs: ['FRED INDPRO', 'FRED UNRATE', 'FRED DGS10', 'FRED DGS3MO', 'FRED HOUST', 'cached SPY', 'cached IEF', 'cached BIL']

Source rule versus inferred rule

The source rule remains a documented reference only: count fifteen model states and warn above five. The executable campaign counts four transparent public recession states (industrial production growth, unemployment change, 10-year/3-month curve inversion, and housing-starts growth), scales that count to 0–15, and labels every result inferred. A one available-month lag plus one execution bar is the causal baseline; lag 0 is a research-only sensitivity.

In [2]:
state = json.loads((root / 'research/campaigns/recessionalert-rfd/state-space.json').read_text())
print('feature window:', state['window']['macro_feature_window'])
print('primary overlay:', state['window']['primary_overlay'])
for trial in state['variants']:
    metrics = trial['metrics_spy_ief']
    print(trial['id'], 'events=', trial['risk_off_events'], 'IEF=', round(metrics['total_return'], 4), 'SPY=', round(metrics['benchmark_total_return'], 4), 'lag=', trial['availability_lag_months'])
feature window: 1982-09-30/2026-06-30
primary overlay: SPY versus IEF on their 2002-07/2026-07 overlap
recessionalert.1346.public_diffusion.lb1.avail1.t5p0 events= 25 IEF= 4.1741 SPY= 11.3974 lag= 1
recessionalert.1346.public_diffusion.lb3.avail1.t5p0 events= 11 IEF= 4.8138 SPY= 11.3974 lag= 1
recessionalert.1346.public_diffusion.lb6.avail1.t6p0 events= 7 IEF= 5.1588 SPY= 11.3974 lag= 1
recessionalert.1346.public_diffusion.lb12.avail2.t4p0 events= 7 IEF= 3.2668 SPY= 11.3974 lag= 2
recessionalert.1346.public_diffusion.lb6.avail0.t5p0 events= 8 IEF= 5.7128 SPY= 11.3974 lag= 0
recessionalert.1346.public_diffusion.lb21.avail1.t5p0 events= 5 IEF= 4.6227 SPY= 11.3974 lag= 1

Interpretation

All tested public-proxy defensive overlays trail aligned SPY in this snapshot. That is an exploratory negative result, not a rejection of native RFD: the proprietary component series and point-in-time publication behavior are unavailable. No official indicator is registered and no market recommendation is made.