创建人员:dev.developer.project.secondary / infodev-2
文件职责:在不修改、不复制 ana-dev V1 计算内核的前提下,冻结 project 级股票估值端到端协调层的接口、证据、缓存、失败、报告、性能和验收合同。
关联事项:DEV-ANA-STOCK-VALUATION-PIPELINE-V2-20260801-001。
上游依据:用户关于日常开发员接手 V2 的原生任务委派;dev-doc/ana-doc/开发方案/CODE-DESIGN-ANA-STOCK-VALUATION-PIPELINE-V2-V001.md;股票价格合理性评估操作手册;V1 流水线与铖昌科技既有结果。
管理规范/模板:../../../common/dev-doc/编码规范.md;../../编码规范.md;../../开发审计规范.md。
引用文件:../开发工作区说明.md;../../../dev/ana-dev/stock_valuation_pipeline/README.md;../../../outputs/20260730_stock_valuation_guide/股票价格合理性评估操作手册_v1.0.md。
记录方式:重型编码方案;dev.reviewer.project 在 dev-doc/开发审计报告.md 给出方案 PASS 前不得实施重型代码。
dev/ana-dev/stock_valuation_pipeline/,负责人和审核员分别是 dev.developer.ana.cai、dev.reviewer.ana.cai;后者会话失效,未产生独立 PASS。dev.developer.project.secondary。合法实现落点改为 dev/project-dev/stock_valuation_pipeline_v2/,测试落点为 dev/project-dev/test/stock_valuation_pipeline_v2/,审核员改为共享 dev.reviewer.project。dev/ana-dev/stock_valuation_pipeline/ 及其测试、Schema、注册表和 README 在本事项中全部只读。V2 通过稳定 Python 入口调用 V1,不复制公式、校验或报告计算逻辑。project.admin 申请一事项范围调整;未获调整前不得写 ana-dev。V1 只能在人工准备好 valuation_snapshot.json 后执行毫秒级计算。用户从提出 ticker/as-of 请求到收到完整报告的主要时间仍消耗在资料取得、来源校验、快照构建、报告扩写和人工终检,现有引擎耗时不能代表总墙钟。
--input 兼容入口。dev/project-dev/
stock_valuation_pipeline_v2/
__init__.py
__main__.py
cli.py
telemetry.py
http_client.py
cache.py
providers.py
acquisition.py
snapshot_builder.py
judgment.py
v1_bridge.py
full_report.py
report_qa.py
workflow.py
provider_registry.json
judgment_overlay.schema.json
README.md
test/stock_valuation_pipeline_v2/
test_*.py
fixtures/chengchang_20260801/
dev-doc/project-doc/
股票估值端到端协调层V2.md
开发方案/CODE-DESIGN-PROJECT-INFO-STOCK-VALUATION-PIPELINE-V2-V002.md
现有操作手册位于角色常规写入范围之外。实现和审核期间先在 project 文档中维护 V2 使用说明;正式修改原操作手册前需由 project.admin 明确授予该单文件写入范围,或由其根据本事项证据代为同步。不得用“用户委派”静默扩大目录权限。
python -m stock_valuation_pipeline_v2 `
--input <valuation_snapshot.json> `
--output-dir <output-dir> `
[--force]
该模式只做参数校验和 V1 桥接,调用 V1 run_pipeline,保留 GENERATED/REUSED、退出码和三件套产物语义。不得改变传入快照或追加 V2 结论。
python -m stock_valuation_pipeline_v2 `
--ticker 001270.SZ `
--as-of 2026-08-01 `
--output-dir <output-dir> `
--cache-dir <cache-dir> `
[--judgment <judgment_overlay.json>] `
[--fixture-dir <fixture-dir>] `
[--task-start <ISO-8601>] `
[--force]
硬合同:
--input 与 --ticker 互斥;ticker 模式必须给 as-of、output-dir、cache-dir。NNNNNN.SZ/SH/BJ;无法确定市场时在网络前失败。runtime.log。V1 的 valuation.scenarios 必须非空且必须包含唯一基准情景。因此 V2 不得在无 judgment 时捏造机械场景来强行调用 V1。
data_snapshot.json、snapshot_build_report.json、16 节数据就绪报告、QA、gap、遥测和 manifest。GAP:需要人工判断覆盖层,不得出现方向性价格结论。DATA_READY_NEEDS_JUDGMENT;不生成伪 V1 valuation_snapshot.json 或 valuation_results.json。judgment_overlay.schema.json 仅允许业务摘要、归一化调整、三情景、主模型、交叉验证、风险、上下调触发器、持有期和结论边界。E_JUDGMENT_CONFLICT。valuation_snapshot.json,通过 v1_bridge.py 调用 V1 load_snapshot 和 compute_valuation。四类适配器统一返回:
{
"provider_id": "market",
"adapter_version": "1.0.0",
"status": "OK|GAP|BLOCKED",
"fetched_at": "ISO-8601",
"as_of_date": "YYYY-MM-DD",
"records": [],
"sources": [],
"gaps": [],
"warnings": [],
"raw_artifact_hashes": []
}
取得交易所或巨潮公开公告索引,登记证券代码、标题、公告日期、报告期、公告 ID、原文 URL、修订状态和支持字段。财务核心字段必须能回链至 A1 原文;公告索引不负责凭叙事直接填利润。
取得不晚于 as-of 的最近交易日收盘价、价格时间、总股本和平台市值。自动检查 价格×股本 与平台市值差异;当前股本晚于历史 as-of 时不得回填历史快照。
取得最近完整年度、本期累计、上年同期累计、资产负债和现金流字段;每个记录带报告期、公告日期、单位、币种和 A1 公告 ID。结构化字段无法回链 A1 时为 gap;与 A1 明示数值超容差时阻断受影响字段。
保存汇总机构数和可见明细两套记录。汇总 4 家、明细 3 家只形成一个 W_FORECAST_COVERAGE gap;最多查询两个登记来源,不为未知第四家无限搜索。明细日期晚于 as-of 的记录排除。
provider_registry.json 登记的 HTTPS 域名;巨潮如需 HTTP 回退必须在注册表明确标识并只用于公开公告查询。ThreadPoolExecutor(max_workers=4) 并发运行四类适配器。单个失败不取消其他来源,异常统一转 gap 或 blocked。同一数字满足以下全部条件即停止搜索:
价格×股本、EPS×股本 等数量关系无异常;任何 publish_date > as_of、data_date > as_of、历史 as-of 使用当前不可历史化字段的行为均为 E_ASOF_VIOLATION,不得仅警告后继续。
<cache-dir>/
blobs/<sha256>.bin
requests/<provider>/<request_fingerprint>.json
companies/<market-code>/baseline.json
companies/<market-code>/source_index.json
请求索引至少包含规范化请求、provider、ticker、as-of、请求/响应时间、状态、内容类型、字节数、SHA-256、适配器版本、来源发布日期和 complete=true。
复用必须同时通过请求指纹、blob 哈希、适配器版本、as-of 安全和完成标记;任一失败只废弃逻辑索引并重取,不删除其他 blob。fixture 响应也走同一缓存路径,以便机械验证缓存合同。
公司基线只在核心采集完成且基线自身哈希正确后原子提交。新 as-of 只刷新价格、最新公告状态、机构预测、股本、现金债务和公司行动;未重述历史报告按内容哈希复用。
snapshot_builder.py 从统一提供者结果建立唯一数据主记录,不直接读取网页模板字段。snapshot_build_report.json 对每个 V1 字段记录来源 provider、source_id、raw_hash、转换、as-of 判断和状态。BLOCKED_CORE_INPUT;机构、辅助说明或单一非核心来源缺失允许 COMPLETE_WITH_GAPS。固定章节顺序:
所有数值表格读取数据主记录或 V1 结果对象。无 judgment 的判断章节写明确 GAP 和需要的覆盖层字段,不得出现 TODO、TBD、待计算、默认倍数、默认方向性评级或伪价格区间。
硬 gate:
valuation_results.json 一致。外部 URL 在线可达性是警告,不因临时网络抖动改写已经生成的正式结果。
| 终态/错误 | 处理 |
|---|---|
COMPLETE |
judgment、V1 计算、报告和 QA 全部完成 |
COMPLETE_WITH_GAPS |
非核心数据缺口已披露,硬 gate 通过 |
DATA_READY_NEEDS_JUDGMENT |
数据和证据就绪,无方向性结论 |
BLOCKED_CORE_INPUT |
价格、股本、核心财务或 A1 回链不足 |
E_INPUT_CONTRACT |
网络前 fail-fast |
E_ASOF_VIOLATION |
阻断并保留失败证据 |
E_SOURCE_CONFLICT |
阻断受影响核心字段 |
E_JUDGMENT_CONFLICT |
覆盖层越权,阻断 |
FAILED |
内部异常或提交失败 |
非核心提供者失败转换为一个有预算记录的 gap;不得 silent fallback,不得无限换站搜索。
complete=true。--force 先形成完整新目录,再以备份交换,失败时恢复旧目录。<output>.failed-<run_id>,只含 failure.json、runtime.log 和已形成的诊断产物;不得存在 COMPLETE manifest。runtime_metrics.json 必须包含:run_id、task_start、process_start、commit_ready_at、每阶段 started_at/finished_at/elapsed_seconds/status、provider 请求/缓存命中计数、task_wall_seconds 和 process_wall_seconds。
性能验收:
<5 s;相同缓存复跑 <2 s。<90 s;外站异常也必须在预算内结束并形成 gap。--input 桥接输出关键结果与直接调用一致。全包 py_compile/import、JSON Schema/注册表解析、V1 10/10 回归。
覆盖 HTTP 超时/4xx/5xx/超大响应、fixture 禁网、缓存哈希篡改/版本变化/未完成标记/as-of 不安全、判断层禁写字段、报告结构和原子写。
DATA_READY_NEEDS_JUDGMENT,不生成方向性价格区间。<5 s、缓存 <2 s。未来来源阻断;A1 与结构化财务冲突阻断;缓存篡改重取;无预测允许 gap;输出冲突、强制替换失败和中断不留下伪 COMPLETE;V1 --input 直接与桥接结果一致。
使用 001270.SZ 或另一只深市股票受控运行一次,核对请求索引、官方公告链接、价格日期、股本、市值、财务期间、机构日期、A1 回链和 90 秒预算。第二次运行证明历史 blob/公司基线复用;真实网络缺口如实记录,不把临时站点故障升级成伪成功。
v1_bridge.py 解析并调用既有公共函数,测试比较直接与桥接结果。本方案状态为 PENDING_DEV_REVIEWER_PROJECT_DESIGN_REVIEW。只有 dev.reviewer.project 在 dev-doc/开发审计报告.md 给出明确 PASS 后,才能创建 V2 代码、测试和 fixture。开发者不自审。