[gw6] darwin -- Python 3.12.12 /Users/cao/.pyenv/versions/3.12.12/bin/python3.12
tests/services/test_tide_etf_reasoning.py:3456: in test_no_entry_facts_leaves_the_prompt_byte_identical
    TR.reason_tide_event(date(2026, 7, 15), ev, _timeline(), conf=2, entry_facts=None)
        ev         = {'direction': 'down', 'et': '09:51:00', 'kind': 'rollover_down', 'via': 'km60'}
        monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x1279ccf50>
        seen       = {'prompt': "YESTERDAY'S CHAPTER — your base for reading this morning.\nThree words first, so the rest reads plainly: T...doubt — and only when in doubt: no wave fired AND no fresh break on the tape — NO_TRADE. Return the strict JSON only."}
        without    = "YESTERDAY'S CHAPTER — your base for reading this morning.\nThree words first, so the rest reads plainly: TNA is the f... doubt — and only when in doubt: no wave fired AND no fresh break on the tape — NO_TRADE. Return the strict JSON only."
rtrader/services/tide_etf_reasoning.py:4535: in reason_tide_event
    prefix = _morning_prefix(day, str(event.get("et") or ""))
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        attempts   = 3
        conf       = 2
        day        = datetime.date(2026, 7, 15)
        entry_facts = None
        event      = {'direction': 'down', 'et': '09:51:00', 'kind': 'rollover_down', 'via': 'km60'}
        max_tokens = 5000
        model      = None
        struct_ctx = None
        system_prompt = None
        timeline   = {'day': '2026-07-06', 'fake_up_peak': {'et': '11:03', 'mean_pct': 0.813}, 'gap_down': (False, None, None), 'gap_up': (True, '09:30:00', '11:30:00'), ...}
rtrader/services/tide_etf_reasoning.py:4315: in _morning_prefix
    return morning_prefix_for_consult(day, event_et)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        day        = datetime.date(2026, 7, 15)
        event_et   = '09:51:00'
        morning_prefix_for_consult = <function morning_prefix_for_consult at 0x121ad20c0>
rtrader/services/morning_prior_day.py:336: in morning_prefix_for_consult
    return morning_prior_day_block(day, db_factory=db_factory) + "\n\n"
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        day        = datetime.date(2026, 7, 15)
        db_factory = None
        et         = '09:51'
        event_et   = '09:51:00'
rtrader/services/morning_prior_day.py:278: in morning_prior_day_block
    late_turns = load_late_turns(d1)
                 ^^^^^^^^^^^^^^^^^^^
        d1         = datetime.date(2026, 7, 14)
        d1_iso     = '2026-07-14'
        day        = datetime.date(2026, 7, 15)
        db_factory = None
        late_turns = None
        ledger_rows = None
        profile    = {'blocks': [BlockStory(direction='UP', start_et='09:30', end_et='09:31', duration_min=1, size=0.52, share_of_day=0.001...de. One side never got answered — the band goes home loaded on the TNA-below-crowd side.', 'close_stretch': 1.285, ...}
rtrader/services/morning_prior_day.py:82: in load_late_turns
    for o in compute_rollover_onsets(day) or []:
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        after_et   = '14:00'
        compute_rollover_onsets = <function compute_rollover_onsets at 0x121947600>
        day        = datetime.date(2026, 7, 14)
        out        = []
rtrader/services/market_turn_algo_sim.py:459: in compute_rollover_onsets
    km_up = _km60_up(s, anchor, i, km_win=km_win, _cache=_picks_cache)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        _gu_gate   = True
        _km_min_bars = 30
        _picks_cache = {0: None, 1: None, 2: None, 3: None, ...}
        anchor     = datetime.datetime(2026, 7, 14, 9, 32, 36, 204000, tzinfo=zoneinfo.ZoneInfo(key='America/New_York'))
        day        = datetime.date(2026, 7, 14)
        db_factory = None
        direction  = 'down'
        dn         = True
        end        = None
        fires      = {'down': True, 'up': False}
        gap_down_gate = True
        gap_fired  = False
        gap_hi     = None
        gap_lo     = None
        gap_up_gate = True
        gapdn_fired = False
        gapdn_hi   = None
        gapdn_lo   = None
        i          = 101
        in_gap     = False
        in_gapdn   = False
        km_dn      = True
        km_up      = False
        km_win     = None
        mt3_dn_hit = False
        mt3_down_min = set()
        mt3_up_hit = False
        mt3_up_min = set()
        out        = [{'direction': 'down', 'down_vol': 233106907769.0, 'fire_et': '10:46:46', 'fire_ts': datetime.datetime(2026, 7, 14, 14...ire_et': '12:51:24', 'fire_ts': datetime.datetime(2026, 7, 14, 16, 51, 24, 577000, tzinfo=datetime.timezone.utc), ...}]
        prev       = {'down': True, 'up': False}
        regime_gap_up = False
        s          = _Series(T=[datetime.datetime(2026, 7, 14, 9, 32, 36, 204000, tzinfo=zoneinfo.ZoneInfo(key='America/New_York')), dateti...757.0, 255542910546.0, 253997648363.0, 253997648363.0, 254058143364.0, 252842483930.0, 252842483930.0, 257030682624.0])
        t          = datetime.datetime(2026, 7, 14, 12, 52, 11, 828000, tzinfo=zoneinfo.ZoneInfo(key='America/New_York'))
        tmin       = datetime.datetime(2026, 7, 14, 12, 52, tzinfo=zoneinfo.ZoneInfo(key='America/New_York'))
        up         = False
        via        = {'down': 'km60', 'up': 'mt3-accel'}
rtrader/services/market_turn_algo_sim.py:223: in _km60_up
    picks = _km60_picks(s, anchor_ts, i, km_win=km_win, _cache=_cache)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        _cache     = {0: None, 1: None, 2: None, 3: None, ...}
        anchor_ts  = datetime.datetime(2026, 7, 14, 9, 32, 36, 204000, tzinfo=zoneinfo.ZoneInfo(key='America/New_York'))
        i          = 101
        km_win     = None
        s          = _Series(T=[datetime.datetime(2026, 7, 14, 9, 32, 36, 204000, tzinfo=zoneinfo.ZoneInfo(key='America/New_York')), dateti...757.0, 255542910546.0, 253997648363.0, 253997648363.0, 254058143364.0, 252842483930.0, 252842483930.0, 257030682624.0])
rtrader/services/market_turn_algo_sim.py:204: in _km60_picks
    km = KMeans(n_clusters=3, n_init=4, random_state=0).fit(vv)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        KMeans     = <class 'sklearn.cluster._kmeans.KMeans'>
        _cache     = {0: None, 1: None, 2: None, 3: None, ...}
        anchor_ts  = datetime.datetime(2026, 7, 14, 9, 32, 36, 204000, tzinfo=zoneinfo.ZoneInfo(key='America/New_York'))
        i          = 101
        idx        = [56, 57, 58, 59, 60, 61, ...]
        km_win     = None
        lo_t       = datetime.datetime(2026, 7, 14, 11, 22, 11, 828000, tzinfo=zoneinfo.ZoneInfo(key='America/New_York'))
        s          = _Series(T=[datetime.datetime(2026, 7, 14, 9, 32, 36, 204000, tzinfo=zoneinfo.ZoneInfo(key='America/New_York')), dateti...757.0, 255542910546.0, 253997648363.0, 253997648363.0, 254058143364.0, 252842483930.0, 252842483930.0, 257030682624.0])
        vv         = array([[7.66397214e+11],
       [7.66397214e+11],
       [7.65541439e+11],
       [7.33508188e+11],
       [7.33508188... [7.65745887e+11],
       [7.65745887e+11],
       [7.64305774e+11],
       [7.65468629e+11],
       [7.65468629e+11]])
../.pyenv/versions/3.12.12/lib/python3.12/site-packages/sklearn/base.py:1365: in wrapper
    return fit_method(estimator, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        args       = (array([[7.66397214e+11],
       [7.66397214e+11],
       [7.65541439e+11],
       [7.33508188e+11],
       [7.3350818...7.65745887e+11],
       [7.65745887e+11],
       [7.64305774e+11],
       [7.65468629e+11],
       [7.65468629e+11]]),)
        estimator  = KMeans(n_clusters=3, n_init=4, random_state=0)
        fit_method = <function KMeans.fit at 0x11c2a4860>
        global_skip_validation = False
        kwargs     = {}
        partial_fit_and_fitted = False
        prefer_skip_nested_validation = True
../.pyenv/versions/3.12.12/lib/python3.12/site-packages/sklearn/cluster/_kmeans.py:1510: in fit
    labels, inertia, centers, n_iter_ = kmeans_single(
        X          = array([[ 2.64254723e+09],
       [ 2.64254723e+09],
       [ 1.78677284e+09],
       [-3.02464782e+10],
       [-3.024...99122041e+09],
       [ 1.99122041e+09],
       [ 5.51107165e+08],
       [ 1.71396282e+09],
       [ 1.71396282e+09]])
        X_mean     = array([7.63754666e+11])
        best_centers = array([[ 1.63082267e+09],
       [-3.02845435e+10],
       [ 2.45995290e+09]])
        best_inertia = 3.561200582199309e+18
        best_labels = array([2, 2, 0, 1, 1, 1, 2, 2, 0, 2, 2, 0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 2,
       2, 2, 0, 0, 0, 2, 0, 0, 2, 2, 2, 0, 2, 2, 0, 2, 2, 2, 0, 0, 0, 0,
       0, 0], dtype=int32)
        best_n_iter = 2
        centers    = array([[ 1.63082267e+09],
       [-3.02845435e+10],
       [ 2.45995290e+09]])
        centers_init = array([[ 1.63082267e+09],
       [-3.02845435e+10],
       [ 2.45995290e+09]])
        i          = 1
        inertia    = 3.561200582199309e+18
        init       = 'k-means++'
        init_is_array_like = False
        kmeans_single = <function _kmeans_single_lloyd at 0x11c2739c0>
        labels     = array([2, 2, 0, 1, 1, 1, 2, 2, 0, 2, 2, 0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 2,
       2, 2, 0, 0, 0, 2, 0, 0, 2, 2, 2, 0, 2, 2, 0, 2, 2, 2, 0, 0, 0, 0,
       0, 0], dtype=int32)
        n_iter_    = 2
        random_state = RandomState(MT19937) at 0x127B51E40
        sample_weight = array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
       1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
       1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
        self       = KMeans(n_clusters=3, n_init=4, random_state=0)
        x_squared_norms = array([6.98305589e+18, 6.98305589e+18, 3.19255718e+18, 9.14849445e+20,
       9.14849445e+20, 9.21770531e+20, 6.589852...146e+18,
       5.76426610e+17, 3.96495871e+18, 3.96495871e+18, 3.03719107e+17,
       2.93766854e+18, 2.93766854e+18])
        y          = None
../.pyenv/versions/3.12.12/lib/python3.12/site-packages/sklearn/utils/parallel.py:173: in wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
        args       = (array([[ 2.64254723e+09],
       [ 2.64254723e+09],
       [ 1.78677284e+09],
       [-3.02464782e+10],
       [-3.02..., 1., 1., 1., 1., 1., 1., 1., 1., 1.]), array([[ 1.63082267e+09],
       [-3.02845435e+10],
       [ 2.45995290e+09]]))
        controller = <threadpoolctl.ThreadpoolController object at 0x1277889e0>
        func       = <function _kmeans_single_lloyd at 0x11c273920>
        kwargs     = {'max_iter': 300, 'n_threads': 8, 'tol': np.float64(6422127436060998.0), 'verbose': 0}
        limits     = 1
        user_api   = 'blas'
../.pyenv/versions/3.12.12/lib/python3.12/site-packages/sklearn/cluster/_kmeans.py:750: in _kmeans_single_lloyd
    inertia = _inertia(X, sample_weight, centers, labels, n_threads)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E   Failed: Timeout (>60.0s) from pytest-timeout.
        X          = array([[ 2.64254723e+09],
       [ 2.64254723e+09],
       [ 1.78677284e+09],
       [-3.02464782e+10],
       [-3.024...99122041e+09],
       [ 1.99122041e+09],
       [ 5.51107165e+08],
       [ 1.71396282e+09],
       [ 1.71396282e+09]])
        _inertia   = <cyfunction _inertia_dense at 0x11c298520>
        center_shift = array([47991488.46666694,        0.        , 30366552.32173872])
        center_shift_tot = np.float64(3225310465155121.0)
        centers    = array([[ 1.63082267e+09],
       [-3.02845435e+10],
       [ 2.45995290e+09]])
        centers_init = array([[ 1.63082267e+09],
       [-3.02845435e+10],
       [ 2.45995290e+09]])
        centers_new = array([[ 1.67881415e+09],
       [-3.02845435e+10],
       [ 2.49031945e+09]])
        i          = 1
        labels     = array([2, 2, 0, 1, 1, 1, 2, 2, 0, 2, 2, 0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 2,
       2, 2, 0, 0, 0, 2, 0, 0, 2, 2, 2, 0, 2, 2, 0, 2, 2, 2, 0, 0, 0, 0,
       0, 0], dtype=int32)
        labels_old = array([2, 2, 0, 1, 1, 1, 2, 2, 0, 2, 2, 0, 0, 2, 2, 0, 2, 2, 0, 2, 2, 2,
       2, 2, 0, 0, 0, 2, 0, 0, 2, 2, 2, 0, 2, 2, 0, 2, 2, 0, 0, 0, 0, 0,
       0, 0], dtype=int32)
        lloyd_iter = <cyfunction lloyd_iter_chunked_dense at 0x11c299a40>
        max_iter   = 300
        n_clusters = 3
        n_threads  = 8
        sample_weight = array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
       1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
       1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
        strict_convergence = False
        tol        = np.float64(6422127436060998.0)
        verbose    = 0
        weight_in_clusters = array([18.,  3., 25.])
