28 lines
1.7 KiB
Python
28 lines
1.7 KiB
Python
"""Resolver — the SEPARATE forward pass that closes the loop (§6.2, §6.3).
|
|
|
|
ARCHITECTURALLY ISOLATED from the scorers: it has no shared write path with them. Scorers write
|
|
candidate_scores + ledger rows with outcome columns NULL and a FROZEN discourse_metric. The resolver
|
|
runs later (larger as_of), reads ledger rows whose date_logged < as_of_now, and writes ONLY
|
|
resolution_date / discourse_outcome / external_outcome / lead_time_days. It is FORBIDDEN from touching
|
|
discourse_metric — that is the structural reason the ledger can't reward noticing what already happened.
|
|
|
|
Implementation note: real resolutions need forward time (the clock can't be backfilled). For the
|
|
backtest, the discourse leg can be resolved by re-running the discourse metric forward from date_logged;
|
|
the external leg (price/filings/human check, §6.5) is filled as that evidence arrives. Stubbed now to
|
|
lock the architecture; filled out for the forward pilot.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
|
|
def resolve_discourse_leg(conn, sc, cfg, *, as_of_now: str) -> int:
|
|
"""For each ledger row logged before as_of_now without a resolution, re-measure discourse forward
|
|
and set discourse_outcome + lead_time. (Forward-only; never reads/edits discourse_metric.)
|
|
Returns count resolved. STUB — implemented for the forward pilot."""
|
|
rows = conn.execute(
|
|
"SELECT signal_id, date_logged FROM ledger WHERE resolution_date IS NULL AND date_logged < ?",
|
|
(as_of_now,),
|
|
).fetchall()
|
|
# TODO(forward-pilot): re-run windowed independence from date_logged→as_of_now for each row's
|
|
# origin derivative; set discourse_outcome in {up_cross_cluster,up_single_cluster,flat,down}.
|
|
return 0
|