创建人员:dev.developer.ana.cai
文件职责:冻结 DEV-ANA-HIBOR-FAST-COLLECTION-20260729-001 的模块边界、接口、额度语义、失败闭合、测试与性能验收方案。
管理规范/模板:common/dev-doc/编码规范.md;common/dev-doc/开发审计规范.md;dev-doc/编码规范.md;dev-doc/开发审计规范.md。
引用文件:ana-doc/研报体系/研报采集角色说明.md 第 4.1–4.3 节;ai-yanbao-collector/工作说明.md 第 6.4–6.5 节;ai-yanbao-collector/worklog/2026-07-29-慧博APP研报自动采集与选取规则.md;HANDOFF-YANBAO-DEV-ANA-HIBOR-FAST-COLLECTION-TOOL-20260729-001。
记录方式:重型开发方案;方案审核通过前不实现、不运行候选工具、不触发慧博下载额度。
DEV-ANA-HIBOR-FAST-COLLECTION-20260729-001dev.developer.ana.caidev.reviewer.ana.caicase_analysis.report_collector本事项不解析研报正文、不生成正文 Markdown、不输出研究结论,不取得、保存或传播认证秘密,不绕过登录、验证码、付费、订阅、权限或其他访问控制。
本事项为有上游任务的重型实现:包含多模块、子进程、缓存监听、额度账本、正式 PDF 原件、重跑恢复和性能 SLA。
固定顺序:
dev.reviewer.ana.cai 独立方案审核;PASS 后实现;dev.reviewer.ana.cai 独立实现/测试复审;case_analysis.report_collector 单次回传终态。普通源码和内部测试产物按语义验收,不做普遍 Base64/逐字节预冻结。外部 PDF 原件、正式 manifest、额度账本、交付 receipt 和正式审计快照继续保持真实消费者所需的字节/哈希不可变边界。
使用 CPython 3.12 标准库为主,避免安装新包;PDF 可打开性优先调用已有 pdfinfo,缺少时可调用项目运行环境已提供的只读 PDF provider。所有可执行文件通过 CLI 参数、配置或 PATH 解析,不在代码中写个人机器绝对路径。
计划代码目录:
dev/ana-dev/hibor_fast_collection/
__init__.py
__main__.py
cli.py
models.py
budget.py
adb.py
ui.py
quota.py
cache.py
archive.py
manifests.py
terminal.py
dev/ana-dev/test/hibor_fast_collection/
fixtures/
fake_adb.py
test_*.py
不得把代码写入 ana-data/ 或 ai-yanbao-collector/。真实运行数据仍由调用方指定到 ana-data/tmp/<task_id>/ 或正式案例容器。
唯一公共入口:
python -m hibor_fast_collection <command> [arguments]
命令:
preflight:只读检查 Python、ADB、唯一设备、MEmu、包名、缓存目录、屏幕尺寸、pdfinfo 与额度账本;不打开研报、不新增额度。dry-run:使用 fake ADB/已有缓存只读快照/合成 PDF 验证选择、额度、缓存差分、归档、manifest、终态和计时;不得向真实设备发送点击。collect-one:单份采集。collect-batch:同查询批量采集,共用一次搜索和候选扫描。resume-postprocess:仅处理已记录且 SHA-256 可确认的既有缓存,不重新打开 APP;若无法证明未产生新触发则拒绝运行。公共必填参数:--project-root、--task-spec、--adb、--pdfinfo、--output-root。真实采集另需 --quota-ledger;路径必须位于项目根目录允许范围内。task-spec 至少包含 capability/version、task/handoff/requester/review_owner、query、quantity、destination、selection filters 和运行模式。
输出终态至少包含:task/handoff、status、started/ended、总耗时、阶段耗时、requested/triggered/success/failed/duplicate/gap、quota summary、有效文件、manifest/delivery/timing 路径、blocker、访问控制声明和 report_collection_terminal payload。
SUCCESSPARTIAL_SUCCESSTIME_BUDGET_STOPPARTIAL_QUOTA_STOPBLOCKED_INPUTBLOCKED_ACCESS_CONTROLBLOCKED_ENVIRONMENTBLOCKED_AMBIGUOUS_MAPPINGVALIDATION_FAILEDINTERNAL_ERROR任何 10 分钟到时、进程超时或状态不确定都不得静默继续;保留有效子集并返回精确阶段、耗时和可行动 blocker。
Budget 只使用 time.monotonic() 做截止判断,wall-clock 仅用于审计时间戳。
remaining() 上限;子进程不得越过剩余预算。计时阶段固定为:preflight、quota、ui_search、ui_scan、detail_and_trigger、cache_wait、copy、validation、manifest、terminal。每阶段记录 monotonic start/end/elapsed 与 wall-clock start/end,写入 timing_manifest.csv。
固定包名:cn.com.hibor。固定缓存目录:/sdcard/Android/data/cn.com.hibor/files/myfile/。
adb devices -l 必须恰有一个已授权、在线且符合 task spec 的本地模拟器;离线、多设备或身份不确定立即停止。dumpsys package 确认包名存在;只读确认前台包、屏幕尺寸和缓存目录可读。优先级:uiautomator dump 的可见文本/边界 → 截图锚点/模板 → 按屏幕比例归一的受限坐标。OCR 作为可插拔只读 provider,仅在显式配置且本机可用时启用;未配置 OCR 不得伪称执行 OCR。
UI 动作只允许白名单:启动/回到慧博、聚焦搜索、清空/输入查询、搜索、纵向翻页、打开候选详情、打开原文、返回。每次动作前验证当前包和页面锚点,漂移或出现登录/验证码/付费/订阅/权限词即停止。
正常截图只保留:开始、结果页、详情页、结束;异常额外保留一张当前页。不得恢复每次点击一张图的高开销模式。
quantity + 2 个合格候选,且最近连续 2 屏 top-K 集合与分值均未改善时早停。在打开原文前记录 reservation 和当前缓存快照。触发后后台轮询目录元数据;只要出现唯一新增候选并连续两次(间隔 1–2 秒)字节数稳定,即进入后处理,不等待阅读器完整渲染。
出现多个新增文件、旧文件变化、远端 stat/hash 不可读或目标映射不唯一时返回 BLOCKED_AMBIGUOUS_MAPPING;不得按缓存文件名猜测标题、机构或日期。
adb pull 到本事项 staging;不得对远端原件做写、删、改名。%PDF-、字节数、SHA-256。pdfinfo 检查可打开性、页数、加密状态;详情页页数与 PDF 页数不一致时失败。<机构>-<主体>-<标题短句>-<YYYYMMDD>.pdf,仅清理 Windows 非法字符。open(..., 'xb') / 等价 CreateNew,写入后 flush+fsync 并只读复核;目标存在时不覆盖。相同 SHA-256 登记 duplicate,不同 SHA-256 报冲突。PDF 与 SHA-256 为权威原件。工具不读取正文文本、不做 OCR 正文、不生成研究内容。
固定账本:ana-data/tmp/report-collection-control/daily_quota_<YYYY-MM-DD>.csv,时区 Asia/Shanghai。
2026-07-29 已知中国中免任务至少触发 3 份不同研报。若当日账本不存在,首次真实测试必须以 append-only BASELINE_ESTIMATE 建立 confirmed_consumed>=3,引用 HIBOR-CHINA-DUTYFREE-20260729-001,不得从 0 开始。若 APP 可见剩余额度推导出更高消耗,用 CORRECTION 追加提高,不改写历史;低于本地保守值时仍取更保守者。
使用单文件互斥锁、append、flush+fsync:
RESERVE,active_reservation_delta=+1。CONSUME_CONFIRMED,confirmed +1、reservation -1。CONSUME_UNCERTAIN,uncertain +1、reservation -1。RELEASE,reservation -1。CORRECTION,必须引用原 event_id。崩溃遗留 reservation 在后续运行中继续占用,除非有可复核证据追加释放或更正。
safe_available=max(0,27-confirmed-uncertain-active_reservations)。正常目标 25,硬停止 27,永久余量 3。第 26–27 份只用于已接收任务收尾/替换/缺口;28–30 禁止自动化使用。任何时点安全可用量不足即返回 ACCEPTED_PARTIAL_QUOTA、QUEUED_NEXT_DAY 或 PARTIAL_QUOTA_STOP。
按角色说明最小字段加慧博专用字段逐行追加;成功、失败、重复、冲突和 STOP 都必须记录。CSV 使用标准转义;append 前加锁,append 后 flush+fsync。正式行必须能复核 task、requester/review_owner、source cache、原件与副本 bytes/hash、PDF magic、openability、page_count、encryption、selection reason 和 quota event。
仅包含元数据、文件链接、选取依据、状态、缺口和额度摘要;禁止写研报正文或研究结论。
工具生成公开能力契约所需 JSON/Markdown payload,由调用方通过 Codex 原生任务单次发送。工具本身不向外部线程发消息;避免把通信权限嵌入采集程序。
resume-postprocess 只能消费已记录 cache identity/remote hash,且明确 reused_without_new_trigger;证据不足则拒绝。.partial/staging,不被视为正式成功。run_id、run_meta.json、timing_manifest.csv 和 terminal;重跑不得复用完成标记冒充新结果。py_compile/import。unittest 覆盖 Budget、候选硬过滤/评分/早停、文件名清理、quota reducer/state machine、CSV quoting、manifest、terminal schema。%PDF-、远端/本地 bytes 与 SHA-256、openability、page count、manifest、quota ledger。INSUFFICIENT_PERFORMANCE_SAMPLES 而非 PASS。方案审核必须确认:
实现审核必须以源码、测试命令、运行日志、真实 PDF/manifest/quota/timing 证据和性能矩阵为准;开发员不得自审。
PENDING_INDEPENDENT_DESIGN_REVIEW。
在 exact dev.reviewer.ana.cai 返回方案 PASS 前,不创建上述候选源码,不启动候选工具,不进行 ADB/APP 真实采集或消耗额度。