药材谷自动化运转的顶层设计:Agent 团队 + 蜂群调度。王先生只做甩手掌柜——看结果、拍板;其余(行情录入、详情页、情报、竞品、营销)全部交给蜂群自动跑。
/api/fund_gate:登记 → 待人工确认 → 拍板 → SHA256 上链;下游凭 require_approved 放行),总面板 ⑥ 拍板台一屏拍板,只写闸门台账、绝不碰业务库;③ 治理告警自动推送已上线(#195-③,2026-10-07)——把 工位熔断 + 调度日志 error/warn + 预警巡检高危 + 审核蜂问题 汇总成站内信推给管理员(/api/gov_alert,总面板 ⑦ 一屏推送 + 守护巡检),④ 审计中风险处置流转闭环已上线(#195-④,2026-10-07)——Agent 任务审计中心把「写类动作」标为中风险却只列不改,本台补上 审阅 → 处置 → 销号 人工闭环(/api/audit_disp,总面板 ⑧ 一屏处置,误报可一步销号、支持同质条目批量闭环);清单实时派生自审计底座(只读切面),台账只记处置状态 + SHA256 链式留痕,原始审计底座严格只读(既不写也不改——审计者不自记于被审日志);自动推送默认关(开不开由王先生拍板)、跨日去重(业务键指纹)、只写推送台账(不重启工位 / 不自动处置 / 不自动发布);审计留痕——Agent 任务审计库 562 条 / 25 个 Agent / 42 个模块(风险分布 高 0 · 中 184 · 低 378);人工闸门——auto_push 默认关、待复核队列全部待人工、32 味处置「保存结论→预演→执行」三步闸;异常熔断——同工位连续失败 3 次熔断 + 冷却自动恢复(当前 16 工位 0 熔断)。投放物料/ 与 引流落地页/。新增前端「投放蜂工坊」页(KPI / 选品种选类型一键生成 / 物料墙 iframe 预览 / 三级闸门批量操作);编排层新增 投放蜂 职能(executor=swarm_ads,human_gate=True)。守住口径:去外部厂商名、不碰金融板块。collect.pool_auto / pool_batch 可调。采集调度台数据源区新增自动补建状态标(读流水线配置显示「每日 06:30 自动补建 20 味 / 已配置未开启 / 关闭」)。/api/swarm/pool 已返回 real auto_build{on,batch,enabled,run_at};流水线采集步新增 ctx.collect.pool 明细并在步骤消息里追加「品种池自动补建 +N 味」。口径不变:补建只换 ID、不抓详情,抓取仍只入待复核队列intel_rivals.json 快照台账、端点 /api/intel/rivals + /rivals/scan,且并入每日流水线情报步 + 情报日报。ads_schedule.json,仅「已审核通过」物料可排期,状态 待投放→已投放→已完成/已取消)+ 投放回收台账(ads_recycle.json,人工回填真实曝光/点击/转化/花费,自动派生 CTR/CPC/CVR/CPA)+ ROI 看板(/api/ads/roi,总体 + 按渠道 + Top 物料)。投放蜂工坊新增排期表 / ROI 概览 / 回收登记表单。build_rivals 新增 extremes 极值字段(在完整压力榜上取,不用截断值当极值),晨报推送站内信时同步带上竞品明细。due_reminders() 扫「待投放」且已填计划时间的排期,plan_time − now ≤ 提前量(默认 60 分钟,含已到点)即推站内信内部提醒;同一排期只提醒一次(写 reminded_at 去重),落 ads_reminders.json 台账。端点 /api/ads/reminders + /remind_check;流水线守护线程每轮顺带检查(与总闸解耦,总闸关也照常提醒)。投放蜂工坊新增「投放到点提醒」区块(24h 内待投放 / 提醒台账 / 立即检查 / 仅预览)。reminded_at 去重生效(重跑 count=0);预览命中 2 条(三七 1911 分钟后到点)。离线单测 32/32、UI 17/17。口径:提醒只是内部通知,系统绝不自动投放,真实外投须人工执行;未填时间的排期不猜、跳过build_rival_trend(limit) 把最近 N 份快照按时间排成序列,输出 ① 市场活跃度变化榜(报价条数 首→末,态势 上升/下降/新进/退出)② 报价压力漂移榜(avg_dev 变化,更低价/更高价)③ 争抢品种进出(首末两期集合差)④ 极值市场漂移(采购/销售窗口是否换人 + pt 变化)⑤ 汇总结论句。端点 GET /api/intel/rivals/trend;analyze(task="trend") 已接入调度中枢。情报蜂中心新增「竞品趋势(跨期对比)」区块。scope 里显式标注;快照 <2 份如实提示「样本不足」,绝不编造趋势recycle_import(text, channel, date, dry) 解析粘贴文本(英文/中文逗号、制表符、分号、竖线均可),表头行与 # 注释自动跳过,空列保留占位(三七,,1200,48,6,80);未给物料ID 时按品种自动关联已审核物料并在备注留痕 [自动关联物料]。端点 POST /api/ads/recycle/import(dry=true 先预览不落盘)。投放蜂工坊回收区新增「批量导入」文本框 + 粘贴示例 + 预览解析。build_rival_trend() 结论写入 KPI(rivals_trend_snaps / mkt_up / mkt_down / mkt_new / mkt_out / quotes_delta / hot_delta / hot_enter / hot_exit),晨报 headline 自动生成趋势句,推送站内信正文同步带趋势段。蜂群自动化底座晨报区新增竞品趋势行。recycle_export() 把真台账导出为 CSV(带 BOM,Excel 中文友好;支持日期区间 + 渠道筛选),落盘到「回收导出/」;② 对账 recycle_reconcile() 核对「排期 vs 回收」,四类问题逐条列出——投放未回收(已投放/已完成却无回收数据)、未投先收(还没投放就有回收)、游离回收(回收未关联任何排期)、指标待补(缺曝光/点击/花费)。端点 GET /api/ads/recycle/export、GET /api/ads/reconcile;投放蜂工坊新增「台账导出 · 排期对账」区块(日期/渠道筛选 + 预览 + 导出 + 一键对账)。reconcile_fix() 针对投放未回收的缺口,按排期预填「回收补录骨架」——品种 / 渠道 / 物料ID / 日期取真值,曝光 / 点击 / 转化 / 花费一律留空,骨架入台账后自然归入「指标待补」等人工核实填写;② 一键催办 reconcile_dispatch() 汇总四类缺口推一条站内信给运营管理员。未投先收 / 游离回收 / 指标待补 一律只催办、不改数据。端点 POST /api/ads/reconcile/fix、POST /api/ads/reconcile/remind、GET /api/ads/reconcile/log;投放蜂工坊对账区块新增「🩹 一键回填骨架 / 📣 一键催办」与处置留痕。None、缺口 1→0 转入指标待补 1、重复回填幂等、早投/游离不改数据。离线单测 33/33、UI 16/16 零控制台错误。纪律:系统只搬运排期已知事实,绝不编造回收数字;数据修正一律人工执行build_alerts() 在全量压力榜 / 争抢榜上按阈值产出三类预警——低价方(采购窗口)报价偏离同品种中位价 ≤ -15%、高价方(销售窗口)≥ +15%、争抢品种价差 ≥ 50%;达阈值 2 倍记高危。① 落账 scan_alerts() 写 intel_alerts.json,同日内 (类型,对象) 去重防重复告警;② 并入流水线:情报步扫完自动挂 rivals_alerts,晨报 KPI 落 6 个预警字段 + headline 预警句 + 推送正文【竞品预警】段。端点 GET /api/intel/alerts、POST /api/intel/alerts/scan;情报蜂中心新增「竞品多市场预警」区块(当前命中 + 台账留痕)。alert_config() / save_alert_config() 读写 intel_alert_cfg.json——报价偏离阈值(1–90%)、争抢价差阈值(5–300%)、自动推送开关、推送级别(仅高危 / 高危+达标)、接收人五项;坏值一律夹到合法区间并如实回显(不静默吞掉)。阈值解析优先级:显式传参 → 配置 → 默认(传 0/None 视为用配置)。端点 GET/POST /api/intel/alerts/config(reset:true 回默认);情报蜂中心「竞品多市场预警」新增配置行(保持数值 + 保存 / 恢复默认)。reset 回 15%/50% 且 customized 归位。离线单测 44/44 覆盖默认 / 持久化 / 夹取 / reset / 传参优先 / 传 0 用法。修一处真实缺口:customized 原以「文件是否存在」判定,reset 后仍误报已自定义 → 改为文件内显式标记(修实现不改断言)push_alerts() 把达级别预警汇总成一条站内信推给指定受众(默认运营管理员),正文含级别筛选口径、逐条明细、阈值口径,并声明「系统仅告警,不自动调价、不自动投放」。跨日去重按 (日期, 级别口径, 命中集合指纹) 判定,同日同批只推一次。受配置 auto_push 控制:开则 scan_alerts() 与流水线情报步顺带推,关则如实返回「未开启」。端点 POST /api/intel/alerts/push、GET /api/intel/alerts/push/log;情报蜂中心新增「📣 推送站内信」按钮 + 推送台账状态条;晨报 KPI 落推送条数 / 去重标记 + 正文推送句。rivals_alert_push.pushed=True + KPI 落条数 + 正文「已推站内信 8 条(跨日去重)」;配置关 → disabled 如实留痕、KPI 不写推送字段。离线单测 44/44、UI 23/23 零控制台错误。交付后配置已 reset 回默认(自动推送关)——不替王先生开自动推送recycle_export_xlsx()(openpyxl)产出 首表「总览」(导出时间/筛选条件/记录数/全量合计 CTR·CPC·CVR·CPA + 按渠道的汇总分布)+ 每个渠道一个分页签列明细(含表头冻结、列宽、暗金表头)。端点 /api/ads/recycle/export?fmt=xlsx(csv 走原路);投放蜂工坊新增「📊 导出 Excel 多表」按钮 + 结果面板(分页签 / 渠道分布 / 合计 / 可下载链接)。口径与 CSV 完全一致:空值一律留空不填 0;汇总比率为各列求和后重算(非逐行比率求平均),分母为 0 时留空;分页签名按 Excel 规则净化(去非法字符、截断、防撞名)。环境缺 openpyxl 时自动降级 CSV 并如实标注,绝不假成功。['总览','公众号长文']、总览第 9 行真值 公众号长文 1200/48/6/80/CTR 4%/CPC 1.6667/CVR 12.5%/CPA 13.3333、明细备注空值读回 None(留空不填 0)、冻结窗格 A2。离线单测 55/55(含纯空值渠道汇总全留空、降级路径、sheet 名净化)、UI 28/28 零控制台错误alert_patrol() 按配置 patrol_min(默认 30 分钟,区间 5–1440)判到点则 scan_alerts() 落账(同日 (类型,对象) 幂等去重),auto_push 开时顺带推站内信。守护线程 _loop() 新增 _intel_alert_tick(),与流水线总闸解耦(总闸关也照常巡检,与 #125 到点提醒同哲学)。纪律:巡检只做「扫描入台账 + 受开关约束的可选推送」,绝不改任何业务数据、绝不自动调价/投放;推送仍由 auto_push 单独把关(默认关)。端点 POST /api/intel/alerts/patrol(force/dry)、GET /api/intel/alerts/patrol/log;情报蜂中心新增「⏱ 定时巡检」配置行(开关 + 间隔 + ⚡ 立即巡检 + 下次时刻状态标)+ 巡检台账表。recycle_export_xlsx(include_recon=True) 落「对账」分页签 —— 四类缺口(投放未回收 / 未投先收 / 游离回收 / 指标待补)各一区块(区块标题 + 暗金表头 + 逐条明细),首部有汇总行(排期 / 回收 / 已闭环 / 缺口合计)与对账结论句;无缺口的区块显式写「(无)」。口径:对账页走全量口径(不受上方日期/渠道筛选影响,因为对账是「排期 vs 回收」的账账核对),页内 A3 明示;导出是可开可关的(include_recon=0)。端点 GET /api/ads/recycle/export?fmt=xlsx&include_recon=1;投放蜂工坊导出区新增「带对账页」勾选框(默认勾选)+ 结果面板对账摘要。回收台账_多表_20261007_020008.xlsx(分页签 总览 / 公众号长文 / 对账),openpyxl 读回对账页 —— A1 标题、A3 全量口径声明、A4「排期 3 / 回收 1 / 已闭环 1 / 缺口合计 0」、A5「账账相符」,四个区块按四类缺口逐块列出。离线单测 36/36(含 dry 也带对账页、渠道筛选下对账仍全量、include_recon=False 关闭、全闭环 4 个「(无)」)、UI 全绿。空值一律留空、不编造缺口patrol_log() 台账留痕,抽取「累计巡检 N 次 / 今日 M 次 / 最近一次命中 X 条(高危 Y)/ 下次巡检时刻 / 巡检开关态」并入晨报 —— KPI 落 7 个 rivals_patrol_* 字段 + headline 出「预警巡检」句 + 人工推送正文出【预警巡检】段。口径:今日次数按台账 date 比对当日,跨日不混算;无巡检记录时整段不写、绝不编造(B4 已验证)。rivals_patrol_total=5 / today=5 / last_total=10 / last_high=7 / next=2026-10-07 02:23:12;headline「预警巡检:今日已巡检 5 次(累计 5 次),最近一次命中 10 条(高危 7),下次 …(每 30 分钟)」。离线单测 36/36(含无记录不写、巡检关时明示「未开启」)、UI 全绿。蜂群自动化底座新增巡检行dev_overrides 按市场覆盖报价偏离阈值、spread_overrides 按品种覆盖争抢价差阈值 —— 不同品种/市场可各设各的(如黄芪价差阈值 30%、陇西药市偏离 8%)。逐条解析:命中覆盖用覆盖值(标 thr_src=override),否则回全局(global);写入走增量合并 + 定向删除(dev_override_del / spread_override_del),reset 一并清空;坏键 / 坏值一律丢弃(绝不臆造),越界值夹取。页面 datalist 提供真实市场 / 品种候选(取自当前压力榜 / 争抢榜,不编造)。端点 POST /api/intel/alerts/config(带 overrides 字段);情报蜂中心新增「🎯 分级覆盖」区(市场 / 品种两行 + 添加覆盖 + 逐项 × 移除)。{};reset 后两张表清空、auto_push 仍为关。离线单测 45/45(含坏值丢弃 / 越界夹取 / 非 dict 容错 / 分级改变命中档位)、UI 取证 16/16 零控制台错误;回归 168 全绿回收台账_多表_20261007_020658.xlsx,读回分页签 ['总览','公众号长文','对账'];对账页「处置建议」表头出现 4 次、四区块建议文案齐备,A6 处置入口指路落地;当前真库账账相符(缺口 0)时四区块写「(无)」+ 建议列写「(无需处置)」,recon.advice_col=true。离线单测 45/45(含全闭环场景)、UI 取证 16/16;回归 168 全绿POST /api/intel/alerts/config/import(scope=market/herb 选表、mode=merge 增量合并 / replace 整表替换)+ GET /api/intel/alerts/overrides/export(导出当前覆盖为 CSV,含注释首行,可直接编辑后回导)。解析层 _parse_override_text 支持逗号 / 等号 / 制表符 / 冒号 / 空格五种分隔与 # 注释行。口径铁律:坏行丢弃并如实回显行号与原因、越界夹取、未知 scope 明确报错——绝不臆造。情报蜂中心新增「⇅ 批量」行(导入 / 导出市场 / 导出品种 + 示例填充 + 确认导入)。{"甘肃兰州市场":6,"陇西首阳市场":8,"陇西药市":25,"越界市场":90};覆盖真生效——thr_src=override 三条:甘肃兰州 thr=6→高危、陇西首阳 thr=8→高危、陇西药市 thr=25→关注;导出市场块 count=4、CSV 带注释行与真值;replace 整表替换 deleted=3;导出 CSV 回导幂等;未知 scope 如实 ok=False。离线单测 56/56(含五分隔解析 / 注释行 / 坏行 / 别名 / replace / 坏值 / 空文本)、UI 取证 16/16(含 CSV 真下载捕获)零控制台错误;回归 213 全绿patrol_trend(days=7) 按日期聚合台账(次数 / 命中 / 高危 / 新增 / 推送),产出 7 个日桶 + headline;无记录的日期如实留空(runs=0),绝不插值;days 参数 None→默认 7、0/负→夹到 1、>30→夹到 30(不把 0 当默认,语义更诚实)。接线:patrol_log() / alert_board() 内嵌 trend;端点 GET /api/intel/alerts/patrol/trend;流水线 _step_intel 写 rivals_patrol_trend → _step_brief 落 6 个 KPI + headline 句 + 人工推送正文段。前端情报蜂中心巡检区加柱状趋势条(红=含高危 / 金=仅关注 / 灰=无巡检),底座晨报区加趋势 KPI 行。days=7 → total_runs=5、active_days=1、total_hits=50、today_runs=5、today_hits=50、max_hits=50;7 个日桶中 10-01~10-06 如实 0、10-07 = 5 次 / 命中 50 / 高危 35。流水线 intel+brief 2/2 全绿;KPI 落 rivals_patrol_trend_days=7 / _runs=5 / _hits=50 / _active_days=1 / _today_hits=50 / _max_hits=50;headline「预警巡检趋势:近 7 日共 5 次(覆盖 1 天),累计命中 50 条,单日峰值 50 条。」。离线单测 56/56(含空台账 / 按日期聚合 / days 夹取 / 非 dict 台账容错)、UI 取证 16/16;回归 213 全绿push_min_level —— force=该目标的预警无条件纳入推送(哪怕全局只推高危、它只是达标);silent=该目标预警永久排除推送(哪怕它是高危);未配=default 跟随全局。落 intel_alert_cfg.json 的 dev_push_overrides(按市场)/ spread_push_overrides(按品种),值域严格限定 force/silent、坏值一律丢弃。解析 _push_level_for(key, ov),build_alerts 每条标 push_level;push_alerts 先按全局 min_level 取基线,再 force 补推 / silent 剔除,指纹含联动口径 #fN#sM(联动变化不会被同日去重误拦);端点 POST /api/intel/alerts/push/link(level=default 删除该项)。前端情报蜂中心每条覆盖项右侧加推送级别下拉(跟随全局 / 强制推 / 静默)。push_level 分别回显 silent/force;真推 min_level=high → pushes_forced=1 / pushes_silenced=1,推送集 7 条中 甘肃兰州市场被排除、连翘被补推;导出 market_push/herb_push 块 CSV「键,级别」;非法 level / 未知 scope 如实报错。离线单测 54/54(含 force 补推、silent 高危剔除、指纹联动、端点三态)、UI 取证 12/12 零控制台错误;回归 269 全绿。交付后配置 reset 回默认(两张推送级别表空 / customized false)patrol_trend 增加 dod(今日 vs 昨日:巡检次数 / 命中 / 高危三项 prev/cur/diff/dir)与 dod_text,按真值做差、方向由 diff 符号决定(0 记 flat)、绝不插值;无昨日桶(如 days=1)如实按 0 比对。接线:_step_brief 落 7 个环比 KPI(dod_text + 三项 diff/dir)+ headline 句尾追加 + 推送正文行。前端情报蜂中心趋势区加「⚖ 环比昨日」行(红升=变多、绿降=变少、灰=持平,带「昨 X → 今 Y」真值),底座晨报区加环比 KPI 行。days=7 → dod = 次数 ↑5(昨 0→今 5)/ 命中 ↑50(昨 0→今 50)/ 高危 ↑35(昨 0→今 35);dod_text「环比昨日:次数 ↑5 / 命中 ↑50 / 高危 ↑35」;流水线 intel+brief 2/2,KPI 落 rivals_patrol_dod_text + _runs/_hits/_high_diff·dir 共 7 项;headline 尾追加「…单日峰值 50 条;环比昨日:次数 ↑5 / 命中 ↑50 / 高危 ↑35。」。离线单测 54/54(含 up/down/flat 三向、days=1 无昨日桶、空台账 flat)、UI 取证 12/12;回归 269 全绿suggest_overrides(scope, obs_min, obs_max, thr, top_n) 先扫全量观测池(_obs_pool 取 pressure_all / hot_all,不截断,否则真实极值会漏),再按 |观测值| 区间筛选 + TopN 取前 N;只出建议、绝不落库(确认后走 #140 导入)。阈值未指定时自动 = 本批最小 |观测值| 向下取整 −1(确保本批全部仍触发);未给任何筛选条件时默认聚焦「已达全局阈值的对象」——否则全量池里的微小偏离(如 0.0x%)会把建议值一路拉到区间下限,建议失去意义;该默认行为如实回显 default_focus + thr_basis。返回 candidates(带当前阈值 / 是否已覆盖)+ 可直接导入的 text。端点 POST /api/intel/alerts/overrides/suggest;前端「🔎 按区间生成」行(观测区间 / TopN / 建议阈值)+「✔ 采用为导入内容」一键填入导入框。obs_min=30 → 4 项 / thr=30.0;品种 top_n=3 → 池 7 选中 3 / thr=115.0,text 走 #140 导入后 3 条 thr_src=override 生效(黄芪 240 / 百合 152.17 / 当归 116.41 仍触发);空池如实「无可生成对象」、未知 scope 报错。离线单测 52/52(含区间 / TopN / 自动阈值 / 夹取 / 只出建议不落库 / 默认聚焦)、UI 取证 22/22 零控制台错误;回归 323 全绿bulk_push_level(scope, level, keys, from_alerts, obs_min, obs_max, mode),取键三来源并集(显式 keys / 当前命中预警 / 观测区间),mode 分 merge(增量合并)/ replace(整表重设),level=default 等价清除;只写推送级别表,不动阈值覆盖表、不动业务数据;未选中任何目标时不改配置并如实返回。端点 POST /api/intel/alerts/push/bulk;前端「⚡ 批量设级别」行(scope / 级别 / 三来源 / 模式 / 执行)。default 清除 4 项(表内剩 山西市场);交叉校验:批量设级别后品种阈值覆盖表原样保留(黄芪/百合/当归 115.0);非法 level / 未知 scope / 空来源三态如实。流水线 intel+brief 2/2。离线单测 52/52、UI 取证 22/22;交付后 reset 回默认(覆盖与级别双清空 / auto_push 仍关)patrol_trend 增 avg3——近 3 日(含今日)vs 前 3 日各自按「有记录天数」摊平后做差(无记录日不参与平均、不插值);两侧都要有样本才判 comparable,否则 dir=na 并如实标注「无法对比」。单日环比易被一次抖动带偏,3 日均更稳。返回 avg3(recent / prev / diff / dir / 窗口区间)+ avg3_text;流水线写 rivals_patrol_avg3_* KPI 并在晨报正文落「预警巡检均值对比」句。前端情报蜂中心趋势区 + 底座 KPI 区同步渲染。comparable=False、dir=na、文案「前 3 日无巡检记录,无法对比(如实标注,不臆造)」;dod 与 avg3 并存互不影响(环比 ↑7 次 / ↑73 命中 / ↑50 高危)。构造样本验证:近 3 日 18 条/3 天=6.0 vs 前 3 日 6 条/2 天=3.0 → diff +3.0 up;仅 1 天有记录时 日均按 1 天算(9.0)而非按 3 天摊;days=3 窗口不足 → prev 空、如实不可比。离线单测 38/38(含 8 组 avg3 用例)、UI 13/13;流水线 intel+brief 已带 KPI + 正文句suggest_overrides(..., quantile) 按 |观测值| 升序取 q 分位值为筛选下界(如 0.8 → 约保留前 20%);与 obs_min 同时给时取更严者(max)。仅接受 0<q≤1,坏值忽略并如实回显 quantile_error(不静默);分位下界高于显式上限时如实标注「筛选区间为空」(quantile_empty_note)。仍只出建议不落库,确认后走 #140 导入。返回 quantile / quantile_value / quantile_basis;前端「🔎 按区间生成」行加分位输入框(0~1)。text 走 #140 导入后 8 条 thr_src=override 生效;obs_min=30 + q=0.5 → 取更严者 下界 30 → 4 项;q=1.5 → 忽略 + 如实回显 + 回落默认聚焦 5 项;q=0.8 + obs_max=1 → 0 项 + 文案「分位下界 10.24% 已高于上限 1.00%,筛选区间为空」。离线单测 38/38、UI 13/13;回归 413 全绿;交付后 reset 归位(覆盖清空 / auto_push 仍关)patrol_trend(days, wins) 支持任意窗口列表(默认 (3,7,30)),每窗口为「近 n 日 vs 前 n 日」,分母仍只算有记录天数;台账不足 2n 天 → 该窗口 comparable=False 并如实标注 need_days(绝不臆造对比)。days 上限由 30 提到 90(30 日窗口的对比需 60 天台账,原上限根本喂不满)。返回 wins / avgs(逐窗口 recent/prev/diff/dir/text)+ avgN_text(仅在 ≥2 个可比窗口时非空,否则留空,免得与 #146 单窗口句在晨报里重复);avg3 保留为 avgs["3"] 向后兼容。端点支持 ?wins=3,7,30;pipeline 写 7/30 日 KPI(只写可比窗口,不可比绝不编造)+ 多窗口正文句;前端趋势区逐窗口渲染(可比显示箭头与日均、不可比如实显示「台账不足 N 天」)。days=7 → wins=[3,7,30] 全渲染;台账仅 1 天有记录 → 三窗口 comparable=False,文案分别为「前 3 日无巡检记录,无法对比」「对比需 ≥14 天台账,当前仅 7 天」「对比需 ≥60 天台账,当前仅 7 天」;days=999 夹到 90;wins=5 → avgs 只含 '5'。构造样本(14 天台账)验证:近 7 日 10/日 vs 前 7 日 4/日 → diff +6.0 up、avgN_text 汇总两窗口;单窗口时 avgN_text 留空(晨报只出 #146 句,不重复)。离线单测 48/48、UI 13/13 零控制台错误bulk_push_level(..., types) 支持 price_low 低价方(采购窗口)/ price_high 高价方(销售窗口)/ spread 争抢价差,兼容别名(low / high / 低价 / 高价 / 价差 / 采购 / 销售…,大小写无关);勾选类型即等价于开启「当前命中」并按类型筛。类型与 scope 不匹配时(如按市场却选「价差」)→ 取交集为空,如实提示「类型 spread 与 scope 不匹配(该 scope 只认 低价/高价)」而非静默返回空;无法识别的类型单独回显 types_bad 并忽略。仍只写推送级别表、不动阈值覆盖表。端点 types 支持数组或逗号串;前端「⚡ 批量设级别」行加低价 / 高价 / 价差三个复选。types=["low"] → 2 家(甘肃兰州 / 山西市场)force;["high"] → 3 家(陇西首阳 / 陇西药市 / 岷县药市)silent;按品种 + 别名 ["价差"] → 5 个(黄芪 / 百合 / 当归 / 连翘 / 金银花);按市场 + ["spread"] → 0 项 + 明确提示不匹配;["低价","乱七八糟"] → 生效 2 家 + types_bad 回显。交叉校验:设级别后阈值覆盖表原样保留(陇西药市 8.0 / 岷县药市 6.0)。离线单测 48/48、UI 13/13;回归 461 全绿;交付后 reset 归位patrol_trend().week 给出「本周至今(周一~今日)vs 上周同期(上周一~上周同一个星期几)」,分母只算有记录天数;另附「今日 vs 上周同一星期几」点对点对比(same_dow)。为能回溯上周,把按日聚合提为全量 by_date(不受 days 窗口限制,桶结构与原实现完全一致)。上周同期无记录 → comparable=false 并如实标注不可比,绝不臆造对比。流水线写 rivals_patrol_week_* KPI 并在晨报落「预警巡检周同比」句。days=3 时窗口只有 3 天但周同比仍可比(全量回溯生效)。流水线 intel+brief 7/7,KPI 带 rivals_patrol_week_cur/dow、晨报含周同比句。离线单测 50/50、UI 11/11bulk_push_level(..., dirs):market 取市场活跃榜的涨跌家数(up>down 走高 / down>up 走低 / 相等持平);herb 取跨市场平均涨跌幅 avg_trend。无涨跌数据的对象计入 dir_unknown 如实回显、绝不当持平;build_rivals 新增 market_activity_all 全量榜(截断会漏市场,沿用 #131 pressure_all 范式)。dirs 与 types 取并集;仍只写推送级别表、不动阈值覆盖表。前端「⚡ 批量设级别」行加走高 / 走低 / 持平三个复选。["up","down"] → 6 个;坏方向 xyz → 0 项 + dirs_bad 回显。dir_basis 回带真实涨跌家数(如「涨 2 / 跌 0 / 平 2」)。交叉校验:设级别后阈值覆盖表原样保留(陇西药市 8.0)。离线单测 50/50、UI 11/11(零控制台错误)quantile_hi 上界分位:取 q_hi 分位值为上界,剔除最高端 1−q_hi 的极端值;两者同给即成 双向分位区间 [q_lo_val, q_hi_val]。与显式 obs_min / obs_max 各取更严者(下界 max、上界 min)。单给上界也算给了筛选条件(不再回落默认聚焦)。分位与区间冲突(实际下界 > 实际上界)→ 0 项 + 如实说明并点名是哪一侧,绝不静默返回空。坏值单侧忽略不影响另一侧。quantile_mode 回显 分位 / 分位上界 / 双向分位区间。前端「🔎 按区间生成」行由单框扩为「分位区间 下界~上界」双框。q=0.5 兼容旧行为(quantile_hi=None);单上界 q_hi=0.6 → 候选全 ≤ 上界值;双向 0.3~0.85 → 0.00%~12.50% 命中 31/36 项(严格窄于全池)、quantile_basis 回显「约保留中段 55%」;obs_min=5 与分位下界取更严 → 下界 5.0;冲突 0.8 > 0.2 → 0 项 + 如实说明;坏值 1.9 → 忽略回显且下界仍生效;导入后 31 条 thr_src=override 生效。离线单测 44/44、UI 16/16(零控制台错误)month = 本月至今(本月 1 号~今日)vs 上月同期(上月 1 号~上月同日),分母只算有记录天数;另附「今日 vs 上月同日」点对点对比。今日日号超上月天数时(如 3-31 → 2 月仅 28 天)夹到上月月末并回显 clamped、文案如实标注「已夹到月末」,绝不越界取到再上月的数据。复用 _range_stat 区间统计,by_date 全量回溯不受 days 窗口限制。顺带修掉 #150 就存在的晨报词重复(原拼出「预警巡检月同比:月同比:…」)——四类对比句统一只加「预警巡检」前缀。diff +16.0 ↑、点对点 30 vs 4 → +26 ↑,days=3 窄窗口下仍可比(全量回溯生效),台账即时复原零污染。流水线 intel+brief 7/7,KPI 带 rivals_patrol_month_*、晨报含月同比句且无词重复。离线单测 44/44、UI 16/16;回归 555 全绿types 时台账 targets 同步按类型筛(意图一致:本周推送过的低价方)。与 keys / 当前命中 / 观测区间 / 方向五路取并集。周期内无推送记录 → period_info.empty 如实标注「取 0 项」并说明区间,绝不臆造;坏别名(如「明天」)period_bad 回显且配置不动。period_bad 回显。离线单测 41/41(含 types×period 组合、五路并集、别名大小写)src(quantile_lo/hi=分位值 / obs_min/max=显式区间 / default_focus=自动聚焦 / pool),前端候选 pill 直接展示并放 title;text 头部加「# 来源」注释行(scope + 分位 + thr_basis + 池/选中数 + 生成时间)——#140 解析器本就跳过 # 注释 → 带来源备档、可直接回导两不误。default_focus 是自动聚焦不是显式 obs_min → 单独标注不伪装。quantile_lo=10.24;text 头注释含 scope+分位+时间 → 直接喂 #140 导入 8 项 / 跳过 0 / 零报错,thr_src=override 全生效;默认聚焦 → 逐条 default_focus。UI 7/7(零控制台错误);回归 13 文件 596 全绿;交付后 reset 归位(四表空、auto_push 仍关)grep -c 单行 HTML 误判空壳);翻页是 URL 参数 ?pageNum=N(点下一页=location.href 跳转,共 56 页,第 2 页与第 1 页品种零重叠)→ http 直翻更稳;②browser_paginate 引擎点击翻页在该站不生效(pages=1)→ 引擎保留给真无 URL 翻页站备用。落地:源级 page_tpl({page} 占位)+ max_pages(上限 60)+ _fetch_paged()(总页数截断 / 页间去重同品种+规格+市场+同价 / 首页失败=整源失败、后续页失败如实记录不炸)+ results 带 pages 元信息;升级合并给存量同名源补缺失新字段(不覆盖用户已改);前端源卡「URL翻页 N 页」标签。_fetch_paged✅ 已落地实测P11-0-0-{page}.html / 8-0-0-{page}.html,真实 href、分页条「1 / 122」格式)→ 市场源 + 产地源都接 page_tpl + max_pages=5;_total_pages() 扩展兼容天地网「<span>1 / 122</span>」格式(康美「共 56 页」不回退);升级合并改「空值即未配置」——历史 setdefault 写盘的空串/1 占位也要被内置默认补齐(live 抓到 page_tpl="" 空键骗过合并的真 bug)。_HERB_ALIAS(只写有把握的常用别名/炮制品基原映射,如 当归身→当归、生地炭→生地黄、紫芝/赤芝→灵芝、棕榈炭→棕榈/棕板;保护动物类/食品杂类/矿物类不硬凑);新端点 POST /pool/retry_miss:对仍无 ID 的品种依次试别名,别名全败再试一次原名兜底(应对上次跑批网络抖动假阴性);命中写入 name_map 扩池,仍搜不到如实留空;dry 试跑不写盘;前端采集调度台加「🔍 别名补搜」按钮带结果明细。len(tried) 计数器真 bug 修复{level, via, ts}——via 为渠道摘要(keys/当前命中/观测区间/趋势方向/周期 + 类型·方向·周期·replace 参数);save_alert_config 加 dev_push_meta / spread_push_meta 增量合并(None 删);alert_config() 读取透传(**真 bug:重建 dict 丢未知键,meta 写进盘读出来就没了**);default 回落删值同步删 meta;reset 一并清空。export_overrides 推送级别块 CSV 头带「# 来源标注」头行 + 逐键「# 键 ← 渠道·级别 @ 时间」注释行(**# 注释行回导自动跳过,备档/回导两不误**);来源未记录项如实标注(#162 之前设置或回导导入);前端导出 toast 带来源标注统计。1-{id}-0.html)分页条恒 1/1、上一页/下一页全 disabled(javascript:void(0))——全部报价(多规格×多市场 + 周/月/年涨跌)单页服务端渲染;页内 5 列涨跌榜小表是全站排行非该品种数据,不进主解析属合理设计。9 列主表解析器覆盖零漏抓(黄芪 6 规格×市场行全吃到、价格/趋势/涨跌全对)。结论:池源的「翻页」语义即多品种轮转(pool 机制已覆盖),_fetch_paged 不适用;结论固化进池源 note。/alerts/push/log?limit=20;无推送如实显示空(台账只留真实记录)。last_pages,真实采集才落盘(dry 试抓零污染不动 last_got/last_pages),无翻页源如实显示「—」。/pending 端点加 source 参数(source_id 精确匹配,空=全部);采集台状态 tab 旁加「全部来源」下拉(选项随 /sources 自动填充、保留当前选中、change 即筛),1164 条存量人工复核可按源分批审。pool_total/pool_built/pool_ids/pool_coverage(读真实池台账,读不到如实不加键)。实现坑:_step_brief 内无 swarm_collect 引用 → 直用 sc 会 NameError 被 try 吞成静默失效(假通过)→ 改 try 双路 import _sc。last_runs(近5次 时间/状态/抓到,真实采集才记录、dry 不入),健康度表新增「近5次成功率」列(全绿金色、有败红色);#182 /pending/export 与 #174 同套筛选(status+source)导出 CSV,带来源标注注释行 + BOM(Excel 中文直开),采集台一键「⬇ 导出台账」按当前视图导出。POST /collect/run 全源真跑:新行情入待复核队列(人工闸门内)、last_pages/last_runs 真值首次落盘。此前 122 页全量仅 dry 验证过,本轮为首次真跑入队。/pending/stats(按来源统计条数、降序)+ /pending/decide_filter(按状态+来源批量采纳/驳回,确认弹窗展示筛选与条数=人工闸门,服务端硬顶 2000 防误伤);采集台新增各源条数 chips(点击即筛选)与「⚡✓ 按筛选采纳 / ⚡✕ 按筛选驳回」按钮——5395 条存量不必再一页页勾。#184 修真坑:_step_brief dry 也写晨报台账(零污染违规)→ dry 改预演不落盘、msg 标注。/pending/stats 升级三态:by_source 各源带 pending/committed/rejected 计数(三态按全队列口径、count 按当前筛选视图)+ by_status 汇总;采集台 chips 加已采纳(金)/已驳回(红)占比条与队列汇总。_step_review 增全队列三态统计(须在 auto 改写前采样);晨报 KPI 加 review_committed/review_rejected/review_queued_total 三键,正文加复核进度句(零处置不占篇幅)。#188 审阅处置台加「⬇ 导出结论 CSV」(七列:分类/品名/背景预判/处置/补搜别名/备注/结论时间,带 BOM + 来源标注注释行 + 引号转义)+ 结论统计条(不建池/手动补ID/维持留空/未填)。#189 内容蜂工坊加「📈 档案库铺开进度」看板:全库 728 味覆盖进度条 + 剩余数 + 活跃日均速 + 按速 ETA(活跃日不足 2 天不给估算,如实显示 —)+ 近 N 日速率柱 + 未铺品类缺口 chips;后端 /api/content/spread。_rbar(pct,n=10) 纯文本进度条(非零进度至少 1 格,避免 0.1% 渲染全空、看起来像「一条都没处置」;None/非法值按 0、夹取 0~100、未满 100% 不显示全满),复核进度句升级为「已采纳…已驳回…待复核…(队列共 N)|█░░░░░░░░░ 已处置 3/5398(0.1%)」,KPI 落 review_done / review_done_pct / review_bar 三键;推送正文 = "\n".join(headline),站内信正文同步带进度条;零处置仍不占篇幅(保持 #187 口径)。前端底座晨报区加可视化进度条行(宽度=已处置占比,>0 时最小 1.5% 可见)。#191 ①审阅处置台加「🧩 批量填别名」:贴多行「品名=挂牌名」(宽容分隔符 = : : , , 制表符,空格兜底;# 注释行跳过),一键填入各卡片并自动切「手动补 ID」,清单外/格式未识别行如实报出(结果区汇总 + 明细 + 底部提示),可折叠;②工坊铺开看板未铺品类 chip 加「→生成」直达(点即按该品类建草稿,单次 ≤100,草稿非对外发布故不涉人工闸门,已生成默认跳过)。POST /api/pipeline/run {"steps":["review","brief"]} → KPI review_done=3 / review_done_pct=0.1 / review_bar=█░░░░░░░░░,晨报台账 35→36 条,推送正文抽检含「已处置 3/5398(0.1%)」且零重复前缀;POST /api/content/generate {"cat":"动物类","limit":3} → created=3,spread 覆盖 160→163 味、剩余 568→565、动物类缺口 65→62(真值闭环)。单测新增 29/29(_test_reviewbar.py);UI 取证 19/19 零控制台错误;全量回归 28 文件 rc 全 0 累计 969 断言全绿/api/swarm/pending/stats by_status=5395/3/0、全队列 5398、已处置 0%;串行队列 其他类/菌藻类/根及根茎类 各 limit=1 → created 各 1,spread 覆盖 163→166、剩余 565→562、三类缺口各 -1(真值闭环)。UI 取证 19/19(Playwright 真机:弹窗文案 / dismiss 零改动 / accept 生效 / 覆盖清单现值 / 队列取消不启动 / 进度条可见)零控制台错误;单测新增 40/40(_test_round21.py,含 C5 抓到的「极小占比整条不可见」真缺陷 → 已修 数量>0 保底 1% 可见);全量回归 29 文件 rc 全 0 累计 1009 断言全绿POST /api/swarm/pool/alias_candidates:传品种名清单 → 返回内置别名表 _HERB_ALIAS(35 条)里有候选的映射,每味附池状态(has_id / excluded / no_id);表内没有的一律不返回(无候选=留空,绝不硬凑)。审阅页加「🎯 一键填内置候选名」:一键把命中味切「手动补 ID」并填首候选,结果区如实报「命中 N 味 · 无候选 M 味」+ 状态标注 + 无候选清单;填完仍需「保存结论」才落盘(人工闸门未改)。② 工坊队列加「每类上限」输入框(1~100,越界 clamp),值以 localStorage(ygg_q_cap) 记忆、进页面回填,替代原先生成台的 fLimit。③ 情报蜂中心推送台账区加复核进度条(与采集调度台 / 底座晨报同源 /api/swarm/pending/stats,金=已采纳 / 红=已驳回,数量>0 保底 1% 可见)。alias_candidates 传审阅页 32 味真清单 → 命中 7 味(芫荽 / 松子仁 / 木芙蓉花 / 木芙蓉叶 / 石楠 / 天竺子 / 枸橘,与页面 hint 的「内置别名已试未中」完全一致)、25 味如实无候选、坏入参(names 非数组)返回 ok=False 防护。UI 取证 20/20(真机 Playwright:一键填 7 味切手动 / 别名值对 / 无候选如实 / 统计条同步;上限 999→100、0→1 clamp + localStorage 写入 + reload 回填;情报蜂中心进度条三态 + 金红段)零控制台错误;单测新增 50/50(_test_round22.py:A 后端接口 16 条含确定性假池三态 + 真池冒烟,B/C/D 契约 27 条,E/F 语法与配平 6 条);全量回归 30 文件 rc 全 0 累计 1059 断言全绿pool_alias_candidates 新增 states(对每个非空请求名据池给出 has_id / excluded / no_id,别名候选仍只取 _HERB_ALIAS 真表),前端加筛选下拉(全部 / 池内无 ID / 已有 ID / 已标不建池),只隐藏显示不动结论(统计与保存范围不变),取状态失败如实提示不静默。② 工坊队列加「指定品类」输入:逗号/顿号分隔、保序去重,只对填入品类排队(按您输入顺序)、未匹配项(已铺完或名称不符)如实报出跳过,留空则回退全量缺口升序;闸门弹窗标明清单来源与排队品类。③ 情报蜂中心复核进度条加「按来源分解」折叠面板:复用 by_source 三态,每源一行显示待复核/已采纳/已驳回 + 迷你金红占比条(数量>0 保底 1% 可见)。alias_candidates 传 32 味 → states 32/32 全返回(分布 no_id=32,与「32 味均为池内空缺」一致)、候选仍 7 味未变。UI 取证 30/30(真机 Playwright:筛「池内无 ID」可见=真值计数 32、「已有 ID」「已标不建池」可见=0、统计条筛选前后文本一致、显示全部还原 32;工坊指定「动物类,菌藻类」闸门文案含「指定品类 2 个 · 按您指定顺序」+ 品类缺口、取消零生成、未匹配品类如实 toast、留空回退全量缺口升序;情报蜂中心折叠展开行数=5 源且每行三态)零控制台错误;单测 52/52(_test_round23.py:A 后端 states 假池三态 + 真池冒烟,B/C/D 契约 32 条,E 语法与配平 6 条);全量回归 31 文件 rc 全 0 累计 1111 断言全绿。重构 queueGen 后同步修 _test_round21 两条锚旧文案的断言(B6/B11),非实现错_PERIOD_LABEL 查表(新增周期不再漏改文案);坏周期提示更新为四周期;无推送记录如实 empty;前端周期复选加本月/上月、互斥提示同步。range_from/range_to + 可选基期(缺省自动等长前移并回显 auto_base);坏日期/起止倒序/基期倒序/无记录一律如实回显绝不臆造;两参全空 → 空壳不校验不误报(单测 B5 抓到「空参被当坏日期」真 bug)。week/month 原路径文本一字未动(#152 规矩)。前端趋势区加季同比行 + 区间对比表单(日期四框 + 对比按钮)。🏷 当前可见 N 味→不建池:范围严格等于当前筛选可见集合(与 applyFilter 同判定 (!f)||(s===f)),被隐藏的味一律不动;走人工闸门(confirm 列出范围 + 条数 + 会被覆盖的逐味清单与当前处置),取消即零改动,改完仍需点「保存结论」才落盘;空可见集不弹窗、如实提示。② 工坊「指定品类」加 localStorage 记忆(同 #qCap 范式):change 即按排队解析同一口径(保序去重)规范化回写并落本地,进页面自动回填,清空即删记忆,全程 try/catch 兜底。③ 情报蜂中心「按来源分解」每源加「→ 查看该源」:跳采集调度台 ?src=<源ID>,调度台在源清单加载完成后自动选中该源并筛选;源 ID 不在清单时如实提示并回落「全部来源」(不静默失败)。?src= 命中选中 / 未命中如实回落。未落盘取证:审阅页批量置不建池仅改页面状态,真库(swarm_herb_pool.json / swarm_pool_review.json)未被写入按品种清单依次抓取国内、国外行情站实时报价,带限速与重试
去重、价格离群值剔除、单位归一(元/公斤)、来源标记;抓不到的数据如实留空
AI 复核 → 异常项挂起待人工抽检 → 合格数据批量落仓,自动触发大屏刷新
价格异动归因、竞品动向、供需缺口,写成日报;同步产出可发布的详情页/资讯草稿
王先生一睁眼看到:昨天抓到多少条、入库多少条、哪些品种异动、哪些要拍板
抓不到就留空、数据不足就拒出结论。预测门槛(≥3 个不同日期)由后端裁决,蜂群无权绕过。
已定项不得换载体回流,Agent 不得重复提交已驳回产物。
任何新能力上线前必须有真机跑出的证据,不接受"应该可以"。
对外发布、资金动作、口径变更三类,蜂群只能准备材料,必须王先生拍板才能落地。