edit | blame | history | raw

股票估值端到端协调层 V2 编码方案 V003

创建人员:dev.developer.project.secondary / infodev-2

开发事项:DEV-ANA-STOCK-VALUATION-PIPELINE-V2-20260801-001

当前审核员:dev.reviewer.project / inforev

方案性质:重型编码方案返修;一次闭环 V002 独立审核的 F1—F8。

当前状态:PENDING_FOCUSED_DESIGN_REREVIEW;审核 PASS 前禁止创建 V2 代码、测试、fixture,禁止修改 ana-dev,禁止真实联网 smoke。
前序审计:DEV-AUDIT-PROJECT-INFO-STOCK-VALUATION-PIPELINE-V2-DESIGN-20260801-001=HOLD/8

1. 单一权属与替代关系(F1)

项目管理员已通过原生交接 HANDOFF-INFOADMIN-INFODEV2-STOCK-VALUATION-V2-TAKEOVER-LEDGER-CLOSE-TERMINAL-20260801-001 完成三本 append-only 根账闭环:

  • dev-doc/开发事项总纲.md:709:当前 owner=dev.developer.project.secondary,reviewer=dev.reviewer.project
  • dev-doc/开发事项计划.md:802:V003 是唯一当前返修版本;V001、旧 ana 审核请求和 V002 审核快照均为历史;
  • dev-doc/开发问题记录.md:362DEV-ISSUE-ANA-STOCK-VALUATION-V2-REVIEW-SESSION-20260801-001 已因有效 project 审核员改派而关闭;
  • 代码=dev/project-dev/stock_valuation_pipeline_v2/,测试=dev/project-dev/test/stock_valuation_pipeline_v2/,文档=dev-doc/project-doc/,审计=dev-doc/开发审计报告.md
  • dev/ana-dev/stock_valuation_pipeline/ 全部只读,不复制公式、校验、报告或缓存实现;旧 inbox/会话仅保留历史证据,不再形成活动阻塞。

管理员另作条件单文件授权:仅在最终实现独立审核 PASS 后,本事项开发者可同步 outputs/20260730_stock_valuation_guide/股票价格合理性评估操作手册_v1.0.md;其他 outputs/ 不在写入范围。

2. 目标、边界与非目标

目标是把 V1 的“人工填好 valuation_snapshot.json 后计算”升级为 ticker+as-of 端到端机械协调层:并发公开取数、可信信源停止、内容寻址缓存和公司增量基线、异常预算内降级、最小判断覆盖、固定 16 节报告、自动 QA、原子输出和从用户任务起点到提交完成的双墙钟。

必须保留 V1 --input 兼容;不输出交易指令、收益承诺或自动批准的投资结论;任何 publish_datedata_date 晚于 as-of 的信息都不得进入结果。

明确排除:V1 公式/schema/registry 修改,第二套估值计算核心,GUI、API、数据库、常驻服务、批处理、定时任务、付费或登录来源、验证码规避、自由搜索站点、未来信息、未披露业务事实推断。

3. 代码、测试与文档落点

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
dev/project-dev/test/stock_valuation_pipeline_v2/
  test_*.py
  fixtures/chengchang_20260801/
dev-doc/project-doc/
  股票估值端到端协调层V2.md
  开发证据/DEV-ANA-STOCK-VALUATION-PIPELINE-V2-20260801-001/

4. CLI 与入口合同

V1 兼容模式:

python -m stock_valuation_pipeline_v2 --input SNAPSHOT --output-dir OUT [--force]

ticker 模式:

python -m stock_valuation_pipeline_v2 --ticker 001270.SZ --as-of 2026-08-01 `
  --output-dir OUT --cache-dir CACHE [--judgment JUDGMENT.json] `
  [--fixture-dir FIXTURES] [--task-start 2026-08-01T20:00:00+08:00] [--force]

--input--ticker 互斥。ticker 模式必须同时给出 as-of、output-dir、cache-dir。ticker 只接受 NNNNNN.SZ|SH|BJ,别名规范化在网络前完成;as-of 不得晚于本地当前日期。fixture 模式把网络 transport 替换为显式拒绝对象,任何网络调用都使测试失败。

5. V1 只读桥接完整合同(F2)

5.1 固定解析与指纹

以仓库根为锚点,只允许加载:

  • 包目录 dev/ana-dev/stock_valuation_pipeline/
  • 默认 registry dev/ana-dev/stock_valuation_pipeline/source_registry.json
  • __version__ == "1.0.0"
  • __init__.py=257 bytes / F39479C1A7B7F40A1A71D5EDE8A287F4E701B4F1473D674F04A2E1BA1B522D29
  • core.py=53165 bytes / 6AB34917A8B136F684EF655995428ACB5936050E1DA36B7B2371941A3E5A5F8F
  • cli.py=1811 bytes / 260692D62C8983B623483E0AA29C763869E30D40952700D46C636357A7376A1E
  • source_registry.json=4958 bytes / 0895D4F0559A1353787059D506DF16572E6818CD847C21042FE1D1106AA854E0

桥接加载后核对 module.__file__ 位于上述只读包,函数签名逐项等于冻结合同。运行 manifest 记录实际模块路径、版本、四个 SHA-256 和 registry hash。任一不匹配产生 E_V1_CONTRACT、退出 3,并在任何写正式输出前 fail-fast;绝不以内嵌公式或复制 CLI 补偿漂移。

5.2 两种调用表

模式 精确调用 返回/用途
--input run_pipeline(snapshot_path=Path, output_dir=Path, source_registry_path=REGISTRY, force=bool) 原样返回 V1 status;保留 GENERATED/REUSED 和 V1 三件套
judgment snapshot=load_snapshot(Path)registry=json.load(REGISTRY)results=compute_valuation(snapshot, registry) results 是 V2 所有估值数值章节的唯一来源;V2 不调用 V1 报告生成器

兼容模式复刻的仅是异常到进程语义,不复制计算:成功 stdout 为 V1 status JSON、exit 0;InputError stderr 为 {"status":"INPUT_ERROR","errors":[...]}、exit 2;OSError/json.JSONDecodeError stderr 为 {"status":"RUNTIME_ERROR","error":"..."}、exit 3;合同漂移也 exit 3,status=RUNTIME_ERROR、error_code=E_V1_CONTRACT

测试必须同时运行直接 V1 CLI 与桥接:比较 stdout status、exit 0/2/3、GENERATED/REUSED、三件套相对文件名/bytes/SHA-256;judgment 模式将 V2 桥接的 results 对象与直接 compute_valuation(snapshot, registry) 做规范 JSON 字节相等比较。

6. 冻结的公开 provider registry(F3)

首期不允许运行时自由换站。所有 URL 必须 HTTPS、host 精确命中 allowlist、重定向后的每一跳也重新校验。未知域名、未知 endpoint、未知方法或未登记回退在创建 socket 前拒绝。

provider_id / version 等级、核心性 host、endpoint、方法 规范化参数、市场、日期 字段、单位、响应上限 顺序/停止
cninfo.announcement_index/1.0.0 A1;核心回链 www.cninfo.com.cn/new/data/szse_stock.json GET;www.cninfo.com.cn/new/hisAnnouncement/query POST;PDF static.cninfo.com.cn/<adjunctUrl> GET stock list 得 orgId;form 固定 pageNum,pageSize=30,column,tabName=fulltext,plate,stock=code,orgId,category,seDate;SZ/SH,BJ 不支持即显式 gap;announcementTime<=as-of 23:59:59 announcementId,title,time,adjunctUrl,orgId,secCode;时间毫秒;JSON/PDF,单响应 20 MiB 唯一公告索引;找到覆盖报告期且未被后续修订替代的 A1 即停
eastmoney.market/1.0.0 B1;价格/股本核心 push2.eastmoney.com/api/qt/stock/get GET;push2his.eastmoney.com/api/qt/stock/kline/get GET secid=0.code(SZ)|1.code(SH);quote fields=f57,f58,f84,f116,f124;kline klt=101,fqt=1,beg=end=YYYYMMDD,fields1=f1..f6,fields2=f51..f61;SZ/SH;历史价取不晚于 as-of 最近交易日 quote f84 股、f116 元、f124 epoch 秒;kline f51日、f53收盘元/股;JSON,5 MiB 历史收盘以 kline 为权威;quote 只补 as-of 可用股本/市值,不能把当前股本回填旧 as-of
eastmoney.finance/1.0.0 B1,须 A1 ID 回链;财务核心 datacenter-web.eastmoney.com/api/data/v1/get GET;reportName 固定 RPT_F10_FINANCE_MAINFINADATA,RPT_DMSK_FN_INCOME,RPT_DMSK_FN_BALANCE,RPT_DMSK_FN_CASHFLOW columns=ALL,filter=(SECUCODE="code.SZ|SH"),pageNumber,pageSize=20,sortTypes=-1,sortColumns=REPORT_DATE;记录须 NOTICE_DATE<=as-ofREPORT_DATE<=as-of 收入 TOTAL_OPERATE_INCOME,归母 PARENT_NETPROFIT,扣非 DEDUCT_PARENT_NETPROFIT;现金 MONETARYFUNDS;资产/负债/权益;经营现金 NETCASH_OPERATE,资本开支 CONSTRUCT_LONG_ASSET;金额原始元、无缩放;JSON 20 MiB 四张表均只取满足 as-of 的最新所需期间;字段必须链接同报告期 CNInfo A1,否则该字段 gap/核心阻断
eastmoney.forecast_summary/1.0.0 B2;非核心 datacenter-web.eastmoney.com/api/data/v1/get GET,reportName=RPT_WEB_RESPREDICT filter=(SECURITY_CODE="code"), page 1/50;记录 REPORT_DATE/UPDATE_DATE<=as-of RATING_ORG_NUM、年度 EPS/利润汇总字段;原始元/股或元,按响应定义且不猜缩放;JSON 10 MiB 预测第 1 个来源;取得可用汇总即不重复请求汇总
eastmoney.forecast_detail/1.0.0 B2;非核心 emweb.eastmoney.com/PC_HSF10/ProfitForecast/Index GET code=SZ001270|SHxxxxxx,type=web;只解析固定表头“机构/报告日期/年度/EPS或净利润”;明细发布日期不得晚于 as-of UTF-8 HTML;机构名、报告日期、预测年度、EPS/净利润;5 MiB 预测第 2 且最后来源;只为可见明细。解析不到即一个 coverage gap,不再搜索第三站

财务数值只在响应字段存在、可解析、币种/单位明确时采用;缺失不得填 0。公告索引仅提供 A1 身份与链接,不从标题猜财务值。市场 f124 为 0/缺失时不得作为日期,历史价日期以 kline f51 为准。所有 adapter 保存原始字段路径、解析版本、发布/数据日期和单位换算表达式。

7. Provider fixture 合同(F3/F8)

实现后才可创建 fixtures/chengchang_20260801/fixture_manifest.json 固定以下规范请求键到响应文件;测试不得由被测 V2 生成 expected:

data kind request fixture response
stock identity CNInfo stock list GET cninfo_stock_list_success.json
A1 index CNInfo announcements POST page 1 cninfo_announcements_success.json
market quote Eastmoney quote GET eastmoney_market_quote_success.json
historical close Eastmoney kline GET, beg/end=20260731 eastmoney_market_kline_success.json
finance main/income/balance/cashflow 四个固定 reportName GET eastmoney_finance_{main,income,balance,cashflow}_success.json
forecast summary RPT_WEB_RESPREDICT GET eastmoney_forecast_summary_success.json
forecast detail emweb fixed GET eastmoney_forecast_detail_success.html

每个 provider 另有最小 emptyhttp_404http_500schema_driftfuture_record fixture;HTTP fixture 的状态和 headers 放在 manifest,不伪装为 200 body。forecast summary=4 家、可见 detail=3 家,expected 只能生成一个 W_FORECAST_COVERAGE gap。

8. 唯一 90 秒网络截止(F4)

机械网络阶段开始时以 time.monotonic() 形成唯一 network_deadline = network_started_mono + 90.0。每个请求、DNS/连接、响应头、分块读取、退避、重试以及 forecast 二次来源都调用同一个 remaining 函数;连接/读/总超时分别取固定上限与剩余预算的较小值。remaining<=0 后不得创建请求或重试。

最多 4 worker。调用方不用 with ThreadPoolExecutor(...) 的隐含等待;显式 shutdown(wait=False,cancel_futures=True),provider transport 必须协作检查 deadline,socket 超时也裁剪到 deadline。已在途任务须在同一 deadline+冻结调度容差内返回;不得再叠加 20 秒读超时。容差固定为 max(0.5s, 测试环境调度分位上限),正式验收上限 91.0 秒。

只对连接重置、超时、5xx 最多重试 2 次;4xx、schema/解析、as-of 错误不重试。退避序列 0.25/0.75 秒,实际 sleep=min(backoff,remaining)。每次请求记录 provider、request_id、started/finished、remaining_before/after、attempt、bytes、HTTP、cache、semantic status、deadline cause;阶段记录 budget start/deadline/end。

离线桩覆盖四 worker 同启、截止前 50ms 启动、阻塞读取、5xx+退避、shutdown,断言不晚于冻结容差且截止后请求计数不增长。

9. 内容寻址缓存与公司基线(F5)

布局:

CACHE/blobs/sha256/<first2>/<sha256>.bin
CACHE/raw-index/<provider>/<fingerprint>/<run_id>.json
CACHE/reusable/<provider>/<fingerprint>.json
CACHE/companies/<ticker>/baselines/<as_of>-<data_hash>.json
CACHE/companies/<ticker>/current.json

fingerprint 前像为 UTF-8 RFC8785 等价规范 JSON(键排序、无多余空白、数字/布尔规范化),字段固定:schema_version,provider_id,adapter_version,method,canonical_scheme_host_path,sorted_query,canonical_body_sha256,ticker,as_of,data_kind,fixture_identity|null,再取 SHA-256。query 重复键保持值数组原序;body 先按 content-type 规范化。fixture_identity=fixture_manifest_sha256:response_id,绝不与真实请求碰撞。

raw blob 可归档成功或失败响应。raw-index 分别记录 transport_complete、HTTP、content_type、bytes、blob_hash、parse/schema/as_of 状态和 provider semantic status。complete=true 只表示归档写完整,不代表可复用。

reusable 索引必须同时满足:transport_complete、登记 HTTP 2xx、允许 content-type、bytes<=上限、blob hash 复核、adapter 版本相同、parse/schema PASS、as-of PASS、semantic status=OK。404/5xx/超时/空数据/schema drift/GAP/BLOCKED 只在本次运行去重;允许负缓存 TTL 固定 60 秒且不得跨 as-of/adapter,也不得写 reusable。篡改时保留 raw 证据、废弃 logical index 并重取。

baseline schema 固定包含 schema_version=1,adapter_bundle_version,ticker,baseline_as_of,created_at,watermark{announcement_time,report_date,market_date,forecast_date},provider_results,field_lineage{field:[source_id,raw_hash]},source_hashes,data_hash。data_hash 的前像排除自身和 created_at,包含其余规范 JSON。只以临时文件+os.replace 提交;同 ticker 加锁并在 replace 前重新读取 current,解决并发竞争。

选择规则:只复用 baseline_as_of<=requested_as_of 且 source hashes 可验证的最近基线;较新基线绝不回跑较旧 as-of。动态模块局部刷新失败时,可保留未过期、日期不晚于 requested as-of、来源哈希仍有效的旧字段并显式 gap;不得把新价格/股本回填旧日期。核心采集未完成不更新 current。并发较旧运行不得覆盖较新 current;相同 as-of 以确定的 data_hash 字典序作幂等选择并保留两个不可变 baseline。

10. 数据、判断覆盖与 V1 单一数值源

无 judgment:完成 data_snapshot.jsonsnapshot_build_report.json、来源/原始哈希、基线、16 节数据就绪报告、QA、gaps、runtime 和 manifest;终态固定 DATA_READY_NEEDS_JUDGMENT。不创建 valuation_snapshot.jsonvaluation_results.json,所有需判断章节写“GAP:需要人工判断覆盖层”,不输出方向性价格区间或评价。

有 judgment:schema 只允许 normalization.adjustmentsvaluation.scenarios/reverse_pe_multiples/exit_pe_multiples/holding_periodanalysis 的业务摘要/模型/交叉验证/风险/触发器/边界。禁止写价格、股本、法定收入/利润、报表日期、来源日期、A1 ID/URL/hash;递归发现保护键或覆盖后数据哈希改变即 E_JUDGMENT_CONFLICT。合并后由 V1 load_snapshotcompute_valuation 计算;报告数字只读取 V1 results,不重新算 PE/PB/PS/情景/反向 PE/持有期。

11. as-of 与可信信源停止规则

任何记录必须同时满足 publish_date<=as-ofdata_date<=as-of。无明确 publish_date 的财务/预测记录不得用于核心值;修订公告按 A1 ID/标题/日期建立替代链,as-of 前的最后有效版本才可用。发现未来记录产生 E_ASOF_VIOLATION 并阻断受影响核心字段,不得降成普通 warning。

同一数值取得 A1 原文或可核对 A1 ID 的结构化记录,且公司、期间、币种、单位、口径、修订状态明确,勾稽/数量级合理,即停止继续查询。forecast 只查上述两个登记来源;汇总 4/明细 3 形成一个 gap 后立即停止。

12. 固定 16 节报告与自动 QA

章节顺序固定:1 结论摘要;2 市场和资本结构;3 信源优先级;4 业务及利润来源;5 历史盈利;6 TTM 与归一化;7 机构预期;8 利润质量与现金流;9 模型选择;10 三情景;11 反向隐含条件;12 交叉验证;13 持有期测试;14 风险与触发器;15 复评清单;16 数据局限和复算摘要。

QA 硬门禁:标题齐全且唯一、Markdown fence/表列完整、无 TODO/TBD/待计算/NaN/Infinity;本地产物链接存在;核心字段有 source_id/A1/raw hash 且日期安全;报告数字与 data snapshot 或 V1 results 规范值一致;judgment 不改保护字段;无 judgment 无方向结论;不含“买入、卖出、加仓、减仓”等交易指令或收益承诺;manifest 中每个正式文件的 bytes/hash 可复算。外部 URL 可达性仅 warning,不改写既有结果。

13. 终态、退出码、stdout 与产物矩阵(F7)

stdout 仅一行规范 JSON:schema_version,status,run_id,output_dir,manifest_path,receipt_path,task_wall_seconds,process_wall_seconds,gap_count,error_code|null;进度写 stderr/runtime.log。

状态 exit 正式目录必有 可有 禁止/manifest
COMPLETE 0 data snapshot、build report、valuation snapshot/results、16节报告、QA、gaps、sources、runtime、manifest provider diagnostics manifest status 同名、complete=true
COMPLETE_WITH_GAPS 0 同 COMPLETE 且 gaps 非空 非核心缺口 核心缺失禁止;complete=true
DATA_READY_NEEDS_JUDGMENT 0 data snapshot、build report、16节报告、QA、gaps、sources、runtime、manifest provider diagnostics 禁止 valuation snapshot/results 和方向结论;manifest status 同名、complete=true
BLOCKED 4 无正式目录;OUT.failed-RUN/failure.json,runtime.log,runtime_metrics.json 已形成诊断/原始哈希引用 禁止 complete manifest/receipt;failure complete=false
FAILED 5 无正式目录;同上失败包 诊断 禁止 complete manifest/receipt;failure complete=false

输入合同错误在网络前 exit 2,不创建正式或失败目录;V1 兼容模式严格使用第 5 节 0/2/3。ticker 模式内部合同错误归 FAILED/5,核心数据/A1不足归 BLOCKED/4。预期的 DATA_READY 不是伪 COMPLETE,但属于可消费成功数据终态。

14. 输出预检与 BaseException 原子状态机(F6)

在网络前以 lstat 检查 output、staging、backup、receipt、所有 .failed-* 冲突;普通文件、符号链接、junction/reparse point 或不明类型一律拒绝。cache 可单独存在但也拒绝链接/reparse。

absent 路径:ABSENT -> STAGING_OWNED -> STAGING_COMPLETE(manifest last) -> OUTPUT_INSTALLED(rename) -> RECEIPT_WRITTEN。force 路径:先完整创建 staging;OLD_OUTPUT -> BACKUP_OWNED(rename1) -> NEW_OUTPUT_INSTALLED(rename2) -> RECEIPT_WRITTEN -> BACKUP_REMOVED

提交边界捕获 BaseException。若旧目录已移到 backup 且新目录尚未成功就位,先把 backup 恢复到 output;恢复失败时保留 backup 并在 failure 证据记录双异常,绝不删除。若新目录已就位,正式真值是新目录;backup 清理失败只留 warning/backup,不撤销新结果。清理异常不得替换原 KeyboardInterrupt/SystemExit;以异常链保存。只有新目录和 receipt 均成功后才对外宣告成功;receipt 失败时 force 模式恢复旧目录,新 staging/新 output 改名为 failed。

注入点固定:mkdir、每个 write/replace、manifest write、rename1、rename2、restore、receipt、backup cleanup。逐点断言旧输出全树 hash、正式目录唯一、staging/backup/failed 归属、无伪 complete manifest、原异常类型。

15. 双墙钟与提交回执(F7)

process_start_wall 用带时区 datetime.now().astimezone(),duration/预算全部用 monotonic。--task-start 必须是带时区 ISO-8601,解析后不得晚于 process_start;保留原字符串、规范 UTC、source=arg|process_start,缺省等于 process_start。未来值/无时区在网络前 exit 2。

正式包内 runtime_metrics.json 在 manifest 前冻结,包含 task_start,process_start,commit_ready_at,task_wall_seconds,process_wall_seconds,wall_scope=through_commit_ready,以及阶段和 provider telemetry;两个 wall 字段均非负且 task>=process(允许 1ms 舍入容差)。manifest 哈希该文件。

目录 rename 完成后不改写包内文件,而在同级写 OUT.commit-receipt.jsonschema_version,run_id,output_path,manifest_sha256,commit_ready_at,commit_finished_at,task_wall_seconds,process_wall_seconds,wall_scope=through_commit_finished。它是最终总墙钟权威记录;stdout 必须复制 receipt 的两个最终 wall 和 receipt path。receipt 以临时文件 fsync+replace 写入;其 hash/bytes 写 stdout,不回写 manifest。正常、data-ready、blocked、failed、force rollback 测试双墙钟、阶段之和上界、receipt/manifest 绑定;失败包 runtime 的 wall_scope=through_failure_recorded,无 receipt。

16. 内容与安全边界

User-Agent 固定、禁止 cookie/auth、禁止跨 host 重定向、日志移除 query 中潜在敏感值;响应按 bytes 上限流式终止。报告明确“研究与复算材料,不构成交易指令”,但不以免责声明替代数据/结论 QA。不输出任何自动买卖动作。

17. 铖昌 fixture 独立验收前像(F8)

只读基线固定:

  • outputs/20260801_chengchang_technology_valuation/valuation_snapshot.json=10585 bytes / 4C27EE81A670BFA8BBD1E2DFB03A9730F6940D7A340D410D232585C57598A138
  • outputs/20260801_chengchang_technology_valuation/generated/valuation_results.json=9766 bytes / 27671D42A75C82125B893B3374E27497E33B929BB1AFEFA61A5D3370BC446559
  • judgment overlay 只从该 snapshot 的 normalizationvaluation 和允许的 analysis 字段人工摘取;剔除 analysis.executive_conclusion 中的既有价格/方向文字;文件 hash 在创建后单独登记,不由 V2 运行生成;
  • request map 固定为第 7 节,fixture manifest 自身 hash 在实现证据登记。

关键 expected 以 Decimal 字符串比较,绝对容差 1e-8(完整规范 results 仍要求字节等价):

指标 expected
market cap 19077995236.56
TTM revenue 416511774.73
TTM attributable 132018113.77
TTM deduct / normalized profit 118174918.34
PB 12.22659092842983667773303996
PS 45.80421585662767464686795987
base price low/high 32.40910757830167747066477256 / 41.96688331621399852114525189
optimistic high 66.95294679349747740945716487
reverse PE 50 profit 381559904.7312
required exit price 152.48767265546425000

forecast expected=summary_count=4,detail_count=3,gap_count_by_id.W_FORECAST_COVERAGE=1,禁止为了第四家无限取数。

18. 分层测试与回归(F4—F8)

L0:全包 compile/import、JSON/schema/registry、V1 指纹/函数签名。

L1:每个 provider 成功/空/4xx/5xx/schema drift/future;未知域名网络前拒绝;90 秒四 worker 阻塞桩;cache 404/5xx/负 TTL/篡改/adapter 变化;较新 baseline 回跑旧 as-of、局部失败、并发提交;judgment 禁写;16 节/交易词/数值 QA。

L2:铖昌有/无 judgment、冷/热缓存;有 judgment 与冻结 V1 results 比较,无 judgment 为 DATA_READY 且无伪结论;冷运行<5秒,热缓存<2秒。

L3:force 每个注入点、KeyboardInterrupt/SystemExit、恢复/cleanup 双失败;断言旧树 hash、唯一正式目录、manifest/receipt 真值。
L4:真实网络按第 20 节;不把外站故障伪装成功。

V1 10/10 固定入口:python -m unittest dev/ana-dev/test/stock_valuation_pipeline/test_pipeline.py -v;测试文件=7231 bytes / C1ECD2A8C8C0C9131C3E93B1E384616508314CB2843571D169876CA155D171CD。长城 V1 fixture=dev/ana-dev/test/stock_valuation_pipeline/fixtures/greatwall_example.json=7142 bytes / 06AB6A7C45C2E43F71654C616F15A826B21E468C4BA72AFB0B253C9DD89FACD8。直接 V1 与 V2 bridge 对该 fixture 分别运行无 force、复跑、force 和输入错误,按第 5 节比较。

19. 性能与预算判定

fixture 冷运行以新 cache/OUT 计 <5.0s;热运行复用同 cache、新 OUT <2.0s;均报告 process/task wall。真实网络机械阶段硬门禁 <=91.0s,目标 <90s;报告每 provider/request 和 cache telemetry。性能测试只比较同机、同 fixture、同输出模式,不能以 V1 毫秒计算时间冒充端到端总墙钟。

20. 冻结的真实网络 smoke(F8)

PASS 后首选且固定 001270.SZ / 2026-08-01。使用独立目录:

python -m stock_valuation_pipeline_v2 --ticker 001270.SZ --as-of 2026-08-01 `
  --cache-dir dev/tmp/valuation-v2-smoke/cache --output-dir dev/tmp/valuation-v2-smoke/cold `
  --task-start 2026-08-01T00:00:00+08:00
python -m stock_valuation_pipeline_v2 --ticker 001270.SZ --as-of 2026-08-01 `
  --cache-dir dev/tmp/valuation-v2-smoke/cache --output-dir dev/tmp/valuation-v2-smoke/warm `
  --task-start 2026-08-01T00:00:00+08:00

唯一换股条件:登记的交易所/行情 provider 明确返回证券不存在,或 as-of 前后无历史收盘且可证明停牌;一般超时、5xx、解析漂移、财务/预测缺口不得换股。满足条件时唯一备用为 000001.SZ / 2026-08-01,保留原失败证据并用同样两条隔离命令。

证据必须保存:两次命令、exit、stdout/stderr、runtime/receipt、request indexes、raw hashes、provider/gap、A1 document IDs/links、价格/股本/市值/财务期间/预测日期、cold→warm cache 命中和 baseline diff、network deadline/end、是否<=91秒。真实数值可变化,但来源身份、日期、单位、预算、复用和缺口真值不可省略。本节只冻结验收,不在方案 PASS 前授权联网。

21. 正式证据与文档收口

实现证据写入 project 文档路径,列代码/测试/registry/fixture bytes+SHA-256、全部命令和 exit、V1 10/10、fixture expected、冷/热性能、真实 smoke、失败注入、无关改动隔离。工具说明写 dev-doc/project-doc/股票估值端到端协调层V2.md 与包 README。实现审计 PASS 后,才依管理员条件授权同步原操作手册单文件;审核员在 dev-doc/开发审计报告.md 形成独立结论。

22. F1—F8 闭环映射

Finding 本版闭环
F1 第1节引用管理员三账 closure 和唯一 V003 权属
F2 第5节冻结 V1 路径/hash/签名/registry/异常/一致性测试
F3 第6—7节冻结五个 adapter、allowlist、字段/日期/单位/fixtures/停止
F4 第8、18—20节冻结单调 deadline、协作取消、容差和阻塞测试
F5 第9节冻结 fingerprint、raw/reusable、负 TTL、baseline 并发/as-of
F6 第14节冻结 absent/force BaseException 状态机和全点注入
F7 第13、15节冻结状态/产物/exit/stdout、task-start、receipt 双墙钟
F8 第7、17—20节冻结基线 hash、request map、expected、V1/真实 smoke 命令和证据

23. 审核门禁

V003 只提交现有 dev.reviewer.project 做限定方案复审。只有审核明确 PASS,开发者才能创建 V2 代码、测试和 fixture;之后依次执行实现、离线测试、fixture 性能、真实 smoke、文档与实现独立审核。若复审仍 HOLD,只返修阻断项,不绕过门禁,不修改 ana-dev