自检判据按基座二批新制度重写
- 旧判据全废(cap30/quiet12 启发式,07-27 实测 6/7 条假阳性) - 保留 mkt_trade_date 检查(07-27 实测有效:自动降级污染日) - 新增:members_total>600(大主题闸值)=基座制度回退 tripwire; 不变量 n_quiet_stored=members_total−moved(旧制度日告警属预期) - config: UPSTREAM_MEMBER_CAP 30→600(语义=闸值),UPSTREAM_QUIET_CAP 废弃
This commit is contained in:
parent
856372a0bb
commit
1232619525
|
|
@ -104,5 +104,6 @@ FROZEN_ROOT = os.environ.get("FROZEN_ROOT", "/app/data/frozen")
|
||||||
# 基座 graph_store.topic_context 的 Cypher 是 `LIMIT $cap`(默认 30)且无 ORDER BY;
|
# 基座 graph_store.topic_context 的 Cypher 是 `LIMIT $cap`(默认 30)且无 ORDER BY;
|
||||||
# transmission.scan 落库时又有 `quiet[:12]`。命中这两个数就说明上游被截断了,
|
# transmission.scan 落库时又有 `quiet[:12]`。命中这两个数就说明上游被截断了,
|
||||||
# 该行的 moved_ratio 建立在任意抽样上、覆盖也被展示逻辑锁住。
|
# 该行的 moved_ratio 建立在任意抽样上、覆盖也被展示逻辑锁住。
|
||||||
UPSTREAM_MEMBER_CAP = int(os.environ.get("UPSTREAM_MEMBER_CAP", "30"))
|
# 07-28 语义更新:基座二批后 topic_context cap=1000、scan 大主题闸=600、quiet 全量落库。
|
||||||
UPSTREAM_QUIET_CAP = int(os.environ.get("UPSTREAM_QUIET_CAP", "12"))
|
# 本值对齐基座"大主题闸":members_total 超过它 = 基座制度回退,桥侧告警(factors.py)。
|
||||||
|
UPSTREAM_MEMBER_CAP = int(os.environ.get("UPSTREAM_MEMBER_CAP", "600"))
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,58 @@ backend/worker/worker-interactive/beat;赶不上则明天跑同一清单)。
|
||||||
6. 桥机 18:45+:`ls data/frozen/`(应有 2026-07-27/)+ `tail data/cron_build.log`
|
6. 桥机 18:45+:`ls data/frozen/`(应有 2026-07-27/)+ `tail data/cron_build.log`
|
||||||
(service not running 则 exec→run --rm)
|
(service not running 则 exec→run --rm)
|
||||||
7. 顺手:07-24 的 17:30 sync 日志(受污染日根因)
|
7. 顺手:07-24 的 17:30 sync 日志(受污染日根因)
|
||||||
|
|
||||||
|
**六节判收结果(07-27 晚实测)**:0✅新码三真|2✅quiet_rows **410**(旧制 93/102,
|
||||||
|
约 4.4×),不变量 12/12 全 t,mkt_trade_date=07-24 如实打标,max_m=99 未触闸
|
||||||
|
(整机制造 217 图成员中上市仅 99,改1 的上市优先排序本就保住了它)|4✅钉死
|
||||||
|
07-23=(07-23,1675 行),movers 按日分明(479 vs 75)|5✅asof=07-17 写 1388 行、
|
||||||
|
live 无扰、核销=0(闸生效;1388≫邻近 live 行=当前池口径回填的预期形态)
|
||||||
|
⇒ **改1~4 机制层全部判收通过,二批关账**。
|
||||||
|
|
||||||
|
**新仪表首夜逮住的两起事故(待办)**:
|
||||||
|
A. **07-27 当日 mkt 无数据 → 定性=源侧迟到**(07-27 晚二读):源 `MAX(timestamp)`
|
||||||
|
19:50 时已=2026-07-27,而 17:30 sync 只见到 07-24(顺手把它 727→2389 修复、
|
||||||
|
三 kind 补齐——sync 本身没坏,取"源侧最新"照章办事)。当晚修复链已给
|
||||||
|
(sync 手动重拍→hotspot→transmission 同日重扫→桥补建,命令在对话)。
|
||||||
|
**结构性建议待拍板**:beat 加"第二拍"sync-market(如 09:55 UTC=17:55 CST,
|
||||||
|
幂等删后插,首拍已有当日则等效空操作),基座 workers/tasks.py 一行。
|
||||||
|
佐证:`akg.sync_market_snapshot` 路由 **interactive 队列**(tasks.py:43)
|
||||||
|
⇒ 快照/传导的运行日志在 **worker-interactive** 容器,不在 worker——
|
||||||
|
六-3 的 grep 落空即此因。
|
||||||
|
B. **桥 cron 首夜失败(两层)**:①`data/` 为容器 root 属主,宿主重定向
|
||||||
|
Permission denied——日志已改 `$HOME` 路径;②**cron 时刻的宿主时区未定**:
|
||||||
|
若桥机宿主是 UTC,`40 18` 实为凌晨 02:40 CST(我给错,已认领)——
|
||||||
|
跑 `date` 判定后改 `40 10`(UTC)或保持 `40 18`(CST)。
|
||||||
|
③**桥容器 date.today()=2026-07-28**(run.py daily 裸取 today → 空跑出
|
||||||
|
2026-07-28 垃圾目录、四路 0 行)——容器时钟/TZ 待测;治本=cron 行加显式
|
||||||
|
`--date $(date +\%F)`(宿主取日,两种宿主时区下均正确),已并入修复命令。
|
||||||
|
遗留小项:consensus 历史 07-16/07-22 空日(低优先)。
|
||||||
|
probe 三张读数提醒已钉 **07-30 周四 19:00**。
|
||||||
|
**工作规约(07-27 用户令):所有命令必须标注运行机器**——
|
||||||
|
【基座机 tlai4090·astock-kg】/【桥机 factorevaluation·akg-factor-bridge】。
|
||||||
|
|
||||||
|
**07-28 晨复盘(事故收口)**:
|
||||||
|
- **A 关闭**:修复链完成——07-27 mkt 三 kind 补齐(2389/386/90);根因=源迟到实锤
|
||||||
|
(次晨重拍即得完整当日)。**第二拍已落码**(beat 表 sync-market-2nd,17:55 CST,
|
||||||
|
beat 配置本就是 Asia/Shanghai 时区,直接写 17:55)——部署=基座 pull 后
|
||||||
|
force-recreate **beat**。**拍板记录:07-27 传导台账不重扫**,保持 mkt_trade_date=07-24
|
||||||
|
的降级标记(重扫=今日图谱套昨日,成员性前视;降级标记正是采信规则的输入)。
|
||||||
|
- **B 关闭**:桥宿主=UTC 实锤 → cron 已改 `40 10`(=18:40 CST)+ 显式
|
||||||
|
`--date $(date +\%F)`;"容器 07-28 之谜"消解——那批命令实际在次晨 UTC 零点后执行,
|
||||||
|
容器 UTC 无时钟病。frozen=07-24+07-27(垃圾 07-28 已清)。桥代码为卷挂载
|
||||||
|
(compose `.:/app`),**pull 即生效无需 rebuild**。
|
||||||
|
- **C(新,已修)**:桥自检两条旧制度判据假阳性(">=30 撞 cap30" 6 条误报、
|
||||||
|
"quiet 存满 12" 7 条误报)——已重写:mkt_trade_date 检查保留(07-27 实测有效,
|
||||||
|
桥打出"该日传导项不可信"=链路端到端贯通的实证);members_total>600(大主题闸值)
|
||||||
|
才告警=制度回退 tripwire;新增不变量检查 n_quiet_stored=members_total−moved。
|
||||||
|
config.UPSTREAM_MEMBER_CAP 默认 30→600,UPSTREAM_QUIET_CAP 废弃。
|
||||||
|
- 07-27 补建因子读数:transmission 302 行(旧制 83)/ heat 2387 / upside 992 /
|
||||||
|
event 531;segment_members/edges 0 行=投影表未建,预期内(三批-4)。
|
||||||
|
- 07-28 晨间占位台账(hotspot 32 候选 / transmission 12 候选 quiet 218,09:25 建)
|
||||||
|
今晚 18:00/18:15 beat 删后插自然覆盖,无需处理。
|
||||||
|
- **今晚(07-28)=首个全自动夜**,明晨验:①mkt_daily 07-28 三 kind(第二拍是否兜住)
|
||||||
|
②传导台账 mkt_trade_date=07-28 ③桥 cron 10:40 UTC 首次正点(frozen/2026-07-28
|
||||||
|
重新出现 + 因子行数非 0 + 新自检无假阳性)。
|
||||||
7. ✅(07-27 已回) mkt_daily stock 按日行数:52/52/131/81/1674/1674/1675/1675/727
|
7. ✅(07-27 已回) mkt_daily stock 按日行数:52/52/131/81/1674/1674/1675/1675/727
|
||||||
(07-10~07-24,缺 07-16、07-21)。四个结论:
|
(07-10~07-24,缺 07-16、07-21)。四个结论:
|
||||||
① stock 快照 = **池内快照非全市场**(1674≈当时池规模)——probe"有现价 727"
|
① stock 快照 = **池内快照非全市场**(1674≈当时池规模)——probe"有现价 727"
|
||||||
|
|
|
||||||
34
factors.py
34
factors.py
|
|
@ -242,7 +242,7 @@ def build_transmission(start, end):
|
||||||
改用 distinct source 数,也更贴合传导模块自述的语义「多源汇聚 = 传导逻辑更硬」。
|
改用 distinct source 数,也更贴合传导模块自述的语义「多源汇聚 = 传导逻辑更硬」。
|
||||||
"""
|
"""
|
||||||
cols_new = ("scan_date, target, ts_code, n_sources, n_paths, moved_ratio, "
|
cols_new = ("scan_date, target, ts_code, n_sources, n_paths, moved_ratio, "
|
||||||
"members_total, n_quiet_stored, mkt_trade_date")
|
"members_total, moved, n_quiet_stored, mkt_trade_date")
|
||||||
try:
|
try:
|
||||||
tr = db.read_pg(
|
tr = db.read_pg(
|
||||||
f"SELECT {cols_new} FROM v_factor_transmission "
|
f"SELECT {cols_new} FROM v_factor_transmission "
|
||||||
|
|
@ -273,9 +273,12 @@ def build_transmission(start, end):
|
||||||
|
|
||||||
|
|
||||||
def _warn_upstream_truncation(tr: pd.DataFrame) -> None:
|
def _warn_upstream_truncation(tr: pd.DataFrame) -> None:
|
||||||
"""把三个上游「静默失真」变成显式告警(评审 硬伤1、§6.2)。
|
"""把上游「静默失真」变成显式告警——07-28 按基座二批后的新制度重写判据。
|
||||||
|
|
||||||
这些是基座侧的问题,桥修不了,但**必须看得见**——否则第一权重项在悄悄失真。
|
基座二批后:topic_context cap=1000、scan 大主题闸=600、quiet 全量落库、
|
||||||
|
mkt_trade_date 落库。旧判据(members_total>=30 撞 cap30 / n_quiet_stored>=12
|
||||||
|
撞截断)在新制度下全是假阳性(07-27 实测 6/7 条误报),废弃。
|
||||||
|
采信规则(stale 剔除/打折/标记)待三批-5 拍板,当前全量采信、只告警。
|
||||||
"""
|
"""
|
||||||
if "mkt_trade_date" in tr.columns and tr["mkt_trade_date"].notna().any():
|
if "mkt_trade_date" in tr.columns and tr["mkt_trade_date"].notna().any():
|
||||||
bad = tr[tr["mkt_trade_date"].astype(str) != tr["scan_date"].astype(str)]
|
bad = tr[tr["mkt_trade_date"].astype(str) != tr["scan_date"].astype(str)]
|
||||||
|
|
@ -284,20 +287,21 @@ def _warn_upstream_truncation(tr: pd.DataFrame) -> None:
|
||||||
f"scan_date 不符(17:30 sync_market 晚点)——这些日的传导项不可信")
|
f"scan_date 不符(17:30 sync_market 晚点)——这些日的传导项不可信")
|
||||||
if "members_total" in tr.columns:
|
if "members_total" in tr.columns:
|
||||||
hit = tr[pd.to_numeric(tr["members_total"], errors="coerce")
|
hit = tr[pd.to_numeric(tr["members_total"], errors="coerce")
|
||||||
>= config.UPSTREAM_MEMBER_CAP]
|
> config.UPSTREAM_MEMBER_CAP]
|
||||||
if not hit.empty:
|
if not hit.empty:
|
||||||
n = hit["target"].nunique() if "target" in hit else len(hit)
|
n = hit["target"].nunique() if "target" in hit else len(hit)
|
||||||
print(f" ⚠️ {n} 个环节 members_total >= {config.UPSTREAM_MEMBER_CAP},"
|
print(f" ⚠️ {n} 个环节 members_total > {config.UPSTREAM_MEMBER_CAP}"
|
||||||
f"撞上游 topic_context 的 LIMIT cap —— moved_ratio 建立在**任意顺序**的"
|
f"(基座大主题闸值)——基座制度回退或闸失效,查 transmission.scan")
|
||||||
f"抽样上(Cypher 无 ORDER BY),先修基座再放量")
|
if {"n_quiet_stored", "members_total", "moved"} <= set(tr.columns):
|
||||||
if "n_quiet_stored" in tr.columns:
|
mt = pd.to_numeric(tr["members_total"], errors="coerce")
|
||||||
hit = tr[pd.to_numeric(tr["n_quiet_stored"], errors="coerce")
|
mv = pd.to_numeric(tr["moved"], errors="coerce")
|
||||||
>= config.UPSTREAM_QUIET_CAP]
|
nq = pd.to_numeric(tr["n_quiet_stored"], errors="coerce")
|
||||||
if not hit.empty:
|
bad = tr[(mt - mv) != nq]
|
||||||
n = hit["target"].nunique() if "target" in hit else len(hit)
|
if not bad.empty:
|
||||||
print(f" ⚠️ {n} 个环节 quiet 存满 {config.UPSTREAM_QUIET_CAP} 条,"
|
n = bad["target"].nunique() if "target" in bad else len(bad)
|
||||||
f"撞 transmission.py 的 quiet[:12] 截断 —— 真实未动成员更多,"
|
print(f" ⚠️ {n} 个候选 n_quiet_stored ≠ members_total − moved ——"
|
||||||
f"因子覆盖被展示逻辑锁住")
|
f"quiet 截断复活或台账/视图不一致(07-27 新制度起不该发生;"
|
||||||
|
f"若构建窗口含 07-24 及更早的旧制度日,此告警对旧日属预期)")
|
||||||
|
|
||||||
|
|
||||||
BUILDERS = {
|
BUILDERS = {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue