# 简报系统运行手册（cron 代理照此执行）

时区：新加坡时间（UTC+8，与北京时间一致）。仅 A 股交易日发布；周末 cron 不触发，
节假日由下面的交易日判断跳过。

## 数据位置
- `data/kline/<code>.csv`：K线库（列序 date,open,close,high,low,vol,amt，与 snapshot.py 一致）
- `data/seed/`：用户上传的种子文件（不动）
- `data/valuation/gate_state.json`：估值闸当前状态（000685/931743）
- `data/scores.json`：附件C 三层评分（有效期至 valid_until）
- `data/holdings.json`：附件A 持仓；`data/ledger.json`：附件B 已执行档
- `data/briefings/<YYYY-MM-DD>.json`：当日简报；`site/`：渲染输出

## 行情抓取（浏览器任务，走东财 push2his 接口）
URL 模板与 secid 对照见 data/FETCH_NOTES.md。增量抓取：beg=库中最新日期+1天，end=今天。
klines 行格式"日期,开盘,收盘,最高,最低,成交量,成交额,..." → 用 scripts/append_bar.py 追加。

## 交易日判断
- 早盘（9:00）：读 589100 页面，若"最新交易日" < 今天且今天是工作日 → 节假日休市，
  不生成、不发布，记日志退出。若最新交易日 == 上一工作日 → 正常（用最新 bar 即昨日收盘）。
- 收盘（15:30）：若 589100 页面"最新交易日" != 今天 → 休市，跳过。否则把今日 bar
  （date,open,close,high,low,amount）追加进各 kline CSV（去重），再往下走。

## 早盘流程（9:00）
1. 交易日判断（上）。
2. `python3 scripts/build_briefing.py --date <今天> --session morning --asof "<最新bar日期>收盘"`
3. `python3 scripts/render.py`
4. `python3 scripts/render_data.py`（历史数据页，全量重渲染即"增补"）
5. `python3 scripts/deploy.py`（推 Cloudflare Pages；token/account 由 Secure Vault 注入环境变量，
   不落地；project 名 ai-langchao-briefings，免费子域名形如 https://ai-langchao-briefings.pages.dev）

## 收盘流程（15:30）
1. 浏览器任务取今日行情 → 追加 bar（交易日判断）。
2. `python3 scripts/build_briefing.py --date <今天> --session afternoon --asof "<今天>收盘"`
3. `python3 scripts/render.py`
4. `python3 scripts/render_data.py`（历史数据页，全量重渲染即"增补"）
5. `python3 scripts/deploy.py`

## 估值闸刷新（每月一次，第1档临近时随日K）
浏览器任务读中证指数官网 000685、931743 的市盈率（中证口径）与历史分位，
更新 `data/valuation/gate_state.json`（status 开放/关闭，记录 pe/pct/asof/source）。

## 评分到期
scores.json 的 valid_until 到期、或出现 skill 决定的"决定性事件"时，不自动评分：
在简报 notes 中标注"方向/利润层评分已过期，待重评"，并提醒用户。

## 每季评分程序（V205 盲评，2026-10-03 起）
1. 先评方向层、利润层并落盘（scores.json），**再读**价格/K线/盈亏——顺序不可对调。
2. 每项须附：数据来源、日期、**反方一句**（该项得更低分的最强理由与来源；写不出记"无"）。
3. scores.json 标注 `"blind": true/false`；2026-09-24 那次记为非盲评。
4. 趋势预警：任一项连续两季各降 1 分即标记预警，下季必须重核该项并写明依据。
5. 简报程序只读 scores.json，不现场打分——"结论由矩阵给出"，外部技能只供数据与事实。

## 12个月后复核（V205）
附件B（ledger.json）每一笔"已执行"与每一次"触档未触发"，12 个月后回看一次：
当时方向层的判断是否成立、估值闸是帮了还是误了，记入该条目的复核栏。
ledger 条目用 `review_date` / `review_note` 记录。首条：589100 第1档 2026-09-28 未触发，复核日 2027-09-28。

## 第1档触发定义（V206，2026-10-03）
第1档触发＝当日收盘≤档位价 **且** 当日估值闸开放（跟踪指数中证口径 PE 历史分位≤P70，当日视角）。
同一周期内（锚重置为界）首次同时满足即触发，次日开盘买；闸关闭日的触档只记为"未触发"
（ledger.json 的 `untriggered`），**不消耗档位、不产生"补买"**；日后闸开放而收盘仍≤第1档，当日即触发。
早盘检查即两条件核对（昨收≤档位价、昨日分位≤P70），同时成立才出"今日开盘买入…第1档"。
程序实现：build_briefing.py 的 `gate_status_asof()` 从估值 CSV 按当日视角算分位（<750日回退 gate_state.json）。
同日收盘跨越多个未执行档位：各档均触发，次日开盘各买一次（信号格式"买入第1、2档"）。

## 财报排雷接法（V206，2026-10-03 用户拍板）
minesweeper 的风险评分保留——它是排除公司的数据产品，性质同"审计意见是否标准无保留"。
接法写死两条：
1. 门槛层（Layer 0）FAIL（审计意见非标、年报逾期）→ 对长鑫视为例外清单命中，暂停执行并复盘。
   程序：build_briefing.py 早盘横幅读 `data/minesweeper_status.json`（`{"688825":{"layer0":"PASS"/"FAIL",...}}`），
   FAIL 即命中。该文件在每次跑排雷 skill（年报/半年报后）后手工更新。
2. 其余各层 FAIL 不自动改分，只作为下次评分时 P2 的"反方一句"素材，分仍由人打。

## 长鑫档位维护（V205）
每份半年报、年报后重算利润基数与三档，并在 skill 规则卡记"基数更新日期"。
当前基数：2026年上半年归母 776.05 亿（年化 1,552.1 亿），三档 3.1042／2.4834／1.8625 万亿，
股本 678.84 亿股 → 45.73／36.58／27.44 元。基数更新日期 2026-10-03。
config.json 的 mcap_rungs/shares 与 skill 脚本 --mcap 默认值保持一致。

## 技能库页面（/skills/，2026-10-03 新增）
供三方同步：Claude.ai（.skill 包）、Fable 5.1 / Marley（原始文本链接核对版本）。
`python3 scripts/render_skills.py` 生成 site/skills/（raw/ 下放 .skill 二进制、SKILL.md、
罗盘行业模式 / 排雷规则 / 九节框架三个方法论 .md、RUNBOOK.md）。
**skill 有新版本时必须重跑此脚本再 deploy**，日常早盘/收盘流程不自动跑它。

## 禁止事项
- 不编造行情/估值数据；取不到就跳过并记录，不发布残缺简报。
- 不改 skill 参数（档位、闸阈值）；只读 skill，不写 skill。
- 结论只按决策矩阵输出；不预测、不建议仓位。
