# CreditReportPubulic **Repository Path**: COangean/CreditReportPubulic ## Basic Information - **Project Name**: CreditReportPubulic - **Description**: No description available - **Primary Language**: Python - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-06 - **Last Updated**: 2026-10-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 授信报告生成器(公开演示副本) 面向 A 股上市公司授信研究的本地 Streamlit 演示项目。它把可回查的来源材料和经过资格核对的 财务事实送入写作、逐句核对和独立审阅流程,并展示报告草稿及其问题。 **这是面试演示,不是生产授信审批系统;草稿不能代替人工判断。** > **关于本副本。** 这是一个**代码副本**,从内部工作仓库复制而来,用于公开和本地复现。 > 内部的历史运行结果、上传的真实材料、数据库、日志和一次性探针产物**都没有包含在内**。 > 本副本附带**本案例的六份输入文件**(三份电子 PDF + 三份财务 XLSX),它们**不**随内部仓库 > 分发,是本批次为本副本单独附上的;来源与权利状态见第六节。三份 PDF 已核实与法定披露平台 > 提供的下载件**逐字节相同**,三份 XLSX 是**人工整理**的工作簿、并做过元数据清理。 > **没有任何一份被核实为获得再分发许可**,版权与数据权利归原权利人所有。 > 本副本**不对应内部仓库的任何一次提交**(见第九节「代码状态」)。 --- ## 一、已验证环境与安装 本次交付实测环境:**Windows 11 Home China / CPython 3.12.7 / 全新隔离虚拟环境**。 按锁定清单安装后解析到的关键版本:`streamlit 1.65.0`、`pandas 3.0.6`、`torch 2.14.1+cpu`。 ```bash python -m venv .venv .venv/Scripts/python.exe -m pip install -r requirements.lock.txt ``` - **本文档记录的所有读数都是用这条命令装出来的环境测的**(165 个包)。锁定清单里 `pypdf` 钉在 `6.19.0`;下面第三节的 block 数、第四节的套件读数都以这个版本为准。 - 安装约 **1.9 GB**(含 `torch`)。这些是 `retrieval/embedding.py` 的懒加载依赖: 实测演示页面跑起来时 `torch` / `chromadb` / `sentence_transformers` / `transformers` **一个都没有被 import**。但依赖清单保留完整声明,以便真实运行和研究侧检索可用。 - [requirements.lock.txt](./requirements.lock.txt) 是一份**解析快照**,不是最低版本要求。 若你想按不带钉版本的 [requirements.txt](./requirements.txt) 安装,请注意它只写 `pypdf>=5.0.0`,不同版本会改变三份 PDF 的解析 block 数(见第二节警示)。 - 两个清单都是 **ASCII-only** 的:pip 按控制台区域编码解码依赖清单, 在 GBK/cp936 的 Windows 控制台上,含中文注释的清单会在安装前直接 `UnicodeDecodeError`。 --- ## 二、从空副本准备输入权威(必须先做一次) `data/evidence.db` 与 `data/financial_v2.db` 是**运行期产物**,不随副本分发——它们必须由本副本 携带的六份输入在**你的机器上重建**。重建用一条命令完成: ```bash # 只校验六份文件的 SHA-256 并打印将要执行的步骤,不写任何文件 .venv/Scripts/python.exe -m scripts.prepare_case_inputs --check # 校验通过后真的执行:登记三份 PDF 建 evidence 库 + 由三份 XLSX 建财务快照 .venv/Scripts/python.exe -m scripts.prepare_case_inputs ``` 身份参数(每份 PDF 的 `document_id` / `source_type` / `material_group`、财务的工作簿顺序 / `scope` / `currency` / 声明公司名)写在 [data/samples/300750/case_inputs.yaml](./data/samples/300750/case_inputs.yaml), 本副本专有;该文件同时声明了**期望产出**,供你核对。实测本次重建得到: | 产出 | 值 | |---|---| | `evidence_set_version` | `set-501395a7ad5a` | | 三份 PDF 的 block 数 | `288 / 301 / 177`(**随 `pypdf` 版本变化**,见下方警示) | | 财务 `snapshot_id` | `snap-5c912da539bc643fe3fad7e54735553e`(112 项指标 / 432 条读数 / 期末 `2026-03-31`) | > **警示:`evidence_set_version` 不覆盖 PDF 解析库版本。** 同一批 PDF 字节、同一份解析 > 代码,只因 `pypdf` 版本不同,三份 PDF 被切成 **288 / 301 / 177**(`pypdf 6.19.0`) > 或 **292 / 300 / 177**(`pypdf 6.11.0`)个 block。`requirements.txt` 只写 `pypdf>=5.0.0`, > 所以**每次全新安装解析到的版本可能不同**,block 数也会跟着变;`evidence_set_version` > 在这一变化下**不变**。因此上表第二行是「本机实测」,不是可跨环境断言的不变量。 > 要复现本文记录的读数,请按 [requirements.lock.txt](./requirements.lock.txt) 钉版本 > (该文件里是 `pypdf==6.19.0`)。 > > **据此,本副本不承诺「跨 `pypdf` 版本得到相同的解析产物」。** block 切分、以及任何按 > block 计数的读数(例如三份文档的 block 数)都可能随版本不同而变化;而 > `evidence_set_version` 因为不含库版本,**不会**跟着变——也就是说,同一个 > `evidence_set_version` 底下可能对应两套不同的 block 切分。不要拿 `evidence_set_version` > 相等去推断「解析结果逐条相同」,也不要拿 block 数去跨环境比对。 > 财务 `snapshot_id` 只由三份 XLSX 的**字节**派生,与 `pypdf` 版本无关。 要点: - 真正执行(不加 `--check`)时,目标库已存在就**默认拒绝**(这两个库是运行期权威,静默重建会让 「本次基于哪份输入」不可追溯)。要重建请先移走旧库。`--check` 不写盘,因此库在不在都能跑。 - 它**不联网、不调用大模型、不读任何历史数据库**,只调用两个既有入口 (`python -m evidence.builder`、`python -m scripts.prepare_financial_snapshot`)。 - 生成的两个 `.db` 是运行期产物,已被 `.gitignore` 排除,**不属于**拟公开内容。 --- ## 三、跑通离线替身演示(不需要模型密钥) 这一节只说明**流程接线能跑通**。它**不**证明正文质量、选材质量或真实 Writer 的表现。 ### 1. 启动页面 ```bash .venv/Scripts/python.exe -m streamlit run scripts/cited_demo_app.py --server.headless true --browser.gatherUsageStats false ``` 浏览器打开 。页面有四屏: | 屏 | 内容 | |---|---| | ① 上传材料 | 选**六份**文件(三份电子 PDF + 三份财务 XLSX),逐字节核对后点「开始生成」 | | ② 生成过程 | 本次运行**真实落盘**的阶段事件(不推算百分比、不假装「正在调用模型」) | | ③ 报告与审核 | 本次运行的公司 A1、财务 A1、财务 A2,以及四条互相独立的状态轴 | | 历史对照 · 非本次生成 | 上批的并列展示基线,**明确标注不是本次生成**,不参与 ②③ 的任何读数 | ### 2. 操作顺序 1. 第 ① 屏选主体、模式保持 `offline`,上传三份 PDF 与三份 XLSX。 2. 页面逐字节核对,出现三条成功提示后「开始生成」按钮才可点。 3. 点「开始生成」会**新建一次运行**(create-only 的 run-id),把本次上传的字节交给同一条 正式 CLI,并且**只**展示这一次运行的产物。它不会回落到任何历史 run。 4. 第 ② 屏可翻看本次运行的每个阶段事件;第 ③ 屏读本次运行的正文、引用、缺口、机械核对与 审阅结果。 ### 3. 本次实测看到的状态(离线替身,run `m930_3_cited_upload_20261006T100930Z`) 下表是**本批清洗后**六份文件在**全新空环境**里重新跑出的一次运行(不是复用上批的 run)。 读数逐条取自该 run 自己的产物:第 ② 屏读 `run_progress.jsonl`,第 ③ 屏读该 run 的各产物文件。 | 读数 | 值 | |---|---| | 整轮结果 | `run_outcome=completed`(读自**调用账本**,不由进度条推断) | | 上传绑定 | 业务 PDF 清单指纹 `ea3d1e9c50472091…`;财务绑定指纹 `517787702b0c346c…` | | 阶段事件 | **25** 条,`resumable` 恒 `false`、`checkpoint_id` 恒空(页面写明「不可恢复」) | | 公司 A1 | 4 句;机械标红 0 / 4;`report_version` `crpv_4eb4dff1fcf519ddeac724d3` | | 财务 A1 | 3 句;机械标红 0 / 3;`report_version` `crpv_209856c6388387ef5b6348e8` | | 财务 A2 | 3 条结构项 / 117 条读数 / **模型调用 0 次**;项目级 typed 缺口 25 条 + notes 缺口注记 1 条 | | 发布资格 | `not_publishable`(两节都是);系统放行 `system_review_not_run`;人工状态 `human_not_reviewed` | | 审阅 | 公司 4 条、财务 3 条意见,产出者是**离线回声**;本 run 账本**无**此次调用 | | 报告级审阅 | **未审**:本 run 没有报告级审阅读数,页面不拿本节意见冒充报告级结论 | | 原 PDF 表格区域 | 12 个只读区域,人工确认 **0 / 12**(每个区域带渲染 SHA-256 与 `pending_human_confirmation`) | 本轮从第一条阶段事件到两节全部落盘约 **17 分钟**(`10:09:36Z → 10:26:28Z`), 产物在末尾统一落盘;中途页面显示的是已落盘事件,不是估算进度。 > 上批报告里的旧读数(run `m930_3_cited_upload_20261006T091547Z`、清单指纹 > `ed70599e22c790bc…`、`report_version crpv_2e079e22…` / `crpv_8ab5d40d…`)对应的**不是** > 本批清洗后的输入,已被上表取代。 > **离线替身的含义。** `offline` 模式下写作、返修、审阅都由**离线替身**产出:它证明的是 > 「接线接通、材料真的进了 Writer 清单、引用真的绑到来源」,**不是**真实写作质量或真实审阅 > 结论。页面自己也这么标注。替身句数(公司 4 句)由替身实现决定,不代表真实模型会写这么多。 ### 4. 这一节是怎么验证的(以及没验证什么) 上表读数取自**本次交付时实际执行**的一次运行,而不是截图或历史 run: - 页面本身用 Streamlit 自带的 [`streamlit.testing.v1.AppTest`](https://docs.streamlit.io/develop/api-reference/app-testing) 驱动**同一个** `scripts/cited_demo_app.py`:真的把六份文件喂给 `st.file_uploader`、真的点 「开始生成」、真的翻第 ②③ 屏读渲染结果。**没有**用浏览器/CDP 会话,也**没有**用 「HTTP 200」或「模块导入成功」代替页面读数。 - 第 ② 屏的 25 条事件、第 ③ 屏的正文、引用、缺口与审阅读数,都逐条记在本批交付报告里。 - 服务器本身另行验证过(本批重跑):`streamlit run` 能起,`/_stcore/health` 返回 `ok`(HTTP 200)、 首页返回 HTTP 200。**勘误**:`streamlit 1.65.0` 下 `/healthz` 返回的是前端单页 HTML, **不是**健康端点——上一版 README 把 `/healthz` 说成健康检查是措辞不准。 但「浏览器里点着走一遍」这一步是用上面那套测试驱动代替的,**不是**真人鼠标操作。 - 本次页面对重库(`torch` / `chromadb` / `sentence_transformers` / `transformers`)的 import 实测为 **0 个**——离线只读路径确实不加载它们。 ### 5. 不联网的确切含义 - `offline` 模式会装上一个**只覆盖大模型调用入口**(`LLMClient.chat_with_usage` / `chat` / `get_client`)的网络守卫;它**不**拦截裸 HTTP,也不阻断其他库自己发起的请求。 - **没有做过断网实测**(没有真的拔网线/断网卡跑一遍)。做过的只是**采样观测**:上批在 一次等价的 `offline` 运行窗口内按 20 秒间隔读本机 TCP 表,共 **58** 个采样点覆盖 `09:15:41Z → 09:34:53Z`,属于 Python 进程的非环回套接字里**已连接数为 0**;唯一反复出现的 是一个 Python 进程 `LISTENING` 在 `0.0.0.0:8765`(本机另一个常驻服务,不是本演示链, 也不是本链发起的连接)。**本批这次新运行没有重复做 TCP 采样**;它自己的网络记录只有 `chain.log`,其中**没有**任何联网行(全文见交付报告)。 - 上面那段采样与本次的 `chain.log` 加起来仍只是一段窗口、一类观测,**不能**据此说「整条链 不联网」。若你在意绝对无外联,请在容器或防火墙层阻断。 --- ## 四、离线评测套件:本副本的实际读数 ```bash # 从本副本根目录运行 .venv/Scripts/python.exe -m evals.run_evals ``` 本次在**清洗后的副本**上、用一个**全新隔离环境**实测(新副本目录 + 新 venv,按 [requirements.lock.txt](./requirements.lock.txt) 装 165 个包;无数据库、无历史产物、无 `.env`、 无授权、无模型 key): **22180 passed / 141 failed / 53 skipped(411.0 秒),退出码 1**,297 个登记模块全部跑到 (242 PASS + 19 SKIP + 36 FAIL)。原始输出整份留档,未做管道过滤,也未重跑。 > **与清洗前那份副本的读数逐项相同。** 清洗前一轮是同样三个总数、同样 **36 个**红模块、 > 同样 **19 个**跳过模块;把两轮的模块名单**按名字逐个求差集**,结果为空——**没有新增红项、 > 没有消失的红项**。也就是说 XLSX 元数据清理与随之变化的哈希/快照 id,没有改变套件里任何 > 一个模块的通过/失败归属。耗时从 369.8 秒变为 411.0 秒只是机器负载差异,不是内容差异。 > > 这是**一次**运行的结果,没有自动重跑;141 条红项的原因分类见下,本批**没有**改动它们、 > 也**没有**改断言制造全绿。 **六个与本次输入改动/修复直接相关的模块**在上批已单独复验过(下表是当时的聚焦读数; 本轮全量里它们同样没有被清洗改动带红): | 模块 | 聚焦读数 | 本轮全量里的归属 | |---|---|---| | `evals.test_intermediate_preview` | 11 passed / 0 failed / 0 skipped | SKIP(~1:需要有已建库的样例) | | `evals.test_financial_v2_snapshot_admission` | 46 / 0 / 0 | PASS | | `evals.test_financial_v2_store` | 100 / 0 / 0 | PASS | | `evals.test_metrics_db` | 24 / 0 / 0 | PASS | | `evals.test_m930_5_upload_run` | Ran 57 tests … OK | FAIL(整轮才出现,见下(三);该模块自报的 `passed` 计数会印成负数,是它自己的汇总口径问题) | | `evals.test_m930_5_cited_demo_ui` | Ran 0 tests … OK | SKIP(~2:本机没有已存真实双节演示 run,用例**拒绝伪造**真实产物) | 这 141 条失败来自 **36 个模块**,按原因分三类: **(一)依赖本副本**按设计**不包含的资产/环境——33 个模块** | 缺什么 | 受影响模块 | |---|---| | `evaluation/datasets/v1_baseline.jsonl` 等评测数据集 | `test_contracts`、`test_retrieval_v2_runner`、`test_split_manifest`、`test_router_eval`、`test_section_eval_runner` | | `.env` 里的真实 provider key | `test_llm_call_budget`、`test_demo_preflight` | | `data/evidence.db`(需先按第二节重建) | `test_tree_span_*`、`test_tree_table_*`、`test_tree_final_material` 等 13 个模块 | | `evaluation/results/` 下的历史冻结 run | `test_tree_span_*`、`test_tree_table_*`、`test_m930_4_*`、`test_m930_5_display_binding` 等 12 个模块 | | 由上面这些派生出的 live evidence-set 版本 | `test_m930_3_table_object_release` | 这些是**输入依赖**,不是代码回归:它们的失败信息都是「某路径不存在」或「key 未配置」。 按第二节重建 `data/evidence.db` 之后,其中一部分会转为可运行(`test_tree_*` 还需要历史冻结 run, 本副本**没有也不会有**)。 > 本副本**保留了** `evaluation/datasets/baseline_contract_mapping.jsonl`:它不是评测语料, > 而是**生产代码的运行期依赖**(`harness/aspects.py` 与 `contracts/review.py` 按固定路径读它, > 用来把 `case_id` 映射到契约主题)。它只有 case_id/question_id/覆盖角色的对应关系, > 不含公司名、页码或任何案例正文。真正的评测语料(`v1_baseline.jsonl` 等)**按设计没有附带**。 **(二)本副本范围内、与缺失资产无关的红项——1 个** - `test_m930_3_writer_face`:一条断言失败(「歧义的扫描必须在扫描处以自己的诊断 fail-closed: 未拒绝」)。逐字节比对证明**被测试的模块与本测试文件都和内部工作仓库完全一致**,即这是 **上游既存缺陷**,不是本副本引入的,也**不是**缺资产导致的。按纪律**没有**放宽断言或绕过它。 > 另有一个曾经属于本类的缺陷**已经修好,现在不再是红项**:`test_metrics_db` 原先在一个函数内 > 有一句 `import os` 遮蔽了同名模块级导入,使「样本缺失」那条提前返回路径抛 `UnboundLocalError` > 而不是按设计 SKIP。上批已在副本内做**最小修复**(只删掉那句多余 import,不动任何断言), > 本轮全量里它是 **PASS**(聚焦复测同样 24 / 0 / 0)。 **(三)整轮跑才出现、单跑正常的两个模块——1 + 1 个** - `test_m930_3_numeric_channel`:整轮里崩在 `NoneType is not iterable`;**单独运行同一模块 退出码 0**。原因是套件在同一进程内跑完前面的模块后,证据库句柄留在了别的临时路径上, 于是这条「未初始化先报错」的断言拿到了另一种返回形状。属于**套件内跨模块状态隔离**问题。 - `test_m930_5_upload_run`:整轮里失败在 `candidates_come_from_the_real_financial_db_when_present`。 该用例本意是「本机没有财务库就 SKIP」;但套件前面的模块会在 `data/financial_v2.db` 留下一份**只有表结构、没有内容**的库,于是它不再 SKIP、读到空主体集。同样是**套件自身的副作用**。 > **三点提醒。** > > ① **这套「离线」评估套件并不等于断网运行——它确实发起过真实外联。** 本轮原始输出里可以 > 读到:有模块经项目自带的 `external/akshare_client.py` 调用 `akshare`,向**东方财富行情接口** > `push2.eastmoney.com:443` 发出 `GET /api/qt/stock/get?…&secid=0.300750` 请求。本机该请求 > **全部失败**——`requests` 走系统代理(`trust_env`)后拿到 > `ProxyError('Unable to connect to proxy', RemoteDisconnected(...))`,**没有任何一次成功返回**。 > 异常在函数内被捕获(日志里是 `get_company_info failed for 300750`),涉及的模块本轮**没有** > 因此变红。**不要**把本节读成「断网测试」;要绝对无外联请在容器/防火墙层阻断。 > > ② 套件和演示页都会在 `data/` 下创建运行期产物(`financial_v2.db`、`chroma/`、`run_inputs/` > 等),它们是缓存与操作记录,不是交付内容,也都被 `.gitignore` 排除。 > > ③ 要单独跑某个模块用 `python -m evals.<模块名>`(例如 > `python -m evals.test_m930_3_numeric_channel`),直接 `python evals/test_x.py` 不成立。 --- ## 五、真实双节运行(本批**未验证**) 下面这一节**没有**在本副本上执行过,写出来是为了说明边界,**不是**使用说明。 | 条件 | 说明 | |---|---| | 六份有权使用的输入 | 三份电子 PDF + 三份财务 XLSX(本副本已附带本案例的六份,见第六节) | | 模型凭据 | 你自己的 `DEEPSEEK_API_KEY`;复制 `.env.example` 为 `.env` 后填入 | | 逐次运行授权 | 一次性授权凭据;**本副本不含、也不会创建或消费任何授权** | `real` 模式只会替换写作、返修与审阅三步的模型调用方;研究侧仍按现行设计走离线装配。 真实运行的产出**不保证**与任何历史运行逐字相同:模型输出本身不确定,材料版本、提示词版本、 期间口径与调用预算都会影响结果。演示结果**不等于**可发布的授信报告。 **三点必须分清:** 1. **本副本验证过的只有 `offline` 替身**(第三节)。它证明的是**接线接通**——材料真的进了 Writer 清单、引用真的绑到来源、逐句硬核对真的跑得动。它**不**证明写作质量。 2. **真实模式的写作质量,本副本一次都没有验证过。** 本副本从未为真实模式跑过一次运行, 因此对真实模式产出的可读性、事实正确性、选材质量**没有任何实测结论**。README 不提供 真实模式的读数。 3. **真实模式需要你自己的模型凭据,且每一次运行都要单独授权。** 凭据放在你本机 `.env` 里(复制 `.env.example` 后填自己的 key),不随本副本分发;一次性运行授权凭据 **本副本不含、也不会创建或消费**。缺少这两样中任何一样,真实模式都**不会**启动—— 这不是可以绕过的开关,也不应被绕过。 --- ## 六、随附输入:来源与权利状态 六份文件位于 `data/samples/300750/`,逐份复核过大小与 SHA-256(`scripts/prepare_case_inputs.py --check` 每次都会重新核对)。**以下说法刻意保守**: | 文件 | 大小 | SHA-256(前 16 位) | 性质 | |---|---|---|---| | `announcements/NDSD_2024_year.pdf`(229 页) | 2 070 073 | `b4f1713d7b821eb0` | 发行人公开披露文件的下载副本(2024 年年度报告) | | `announcements/NDSD_2025_year.pdf`(232 页) | 2 043 710 | `c15272977147dee7` | 同上(2025 年年度报告) | | `announcements/NDSD_KCZ_2026.pdf`(141 页) | 1 558 483 | `2b3a1fb3de97f23c` | 同上(发行人 2026 年度第二期绿色科技创新债券募集说明书) | | `financial/NDSD_BALANCESHEET_2023-2026Q1.xlsx` | 12 898 | `906034ec0b40b89b` | **人工整理的工作簿**(`openpyxl` 生成),已做元数据清理 | | `financial/NDSD_EFFORT_2023-2026Q1.xlsx` | 10 990 | `f5e43889262f2aee` | 同上 | | `financial/NDSD_CASH_2023-2026Q1.xlsx` | 11 590 | `a2e7096303faa7f5` | 同上 | - 三份 PDF 是**法定披露平台上发布文件的下载件**,本副本里的字节与平台返回的字节**逐字节相同** (SHA-256 一致,见上表),本批**未对 PDF 作任何改动**: | 文件 | 完整/节选 | 下载 URL | |---|---|---| | 2024 年年度报告(229 页) | 完整全文(首页为发行人封面与「2024 年年度报告」,末页为报告末节) | `http://static.cninfo.com.cn/finalpage/2025-03-15/1222806982.PDF` | | 2025 年年度报告(232 页) | 完整全文 | `http://static.cninfo.com.cn/finalpage/2026-03-10/1225002214.PDF` | | 债券募集说明书(141 页) | 完整全文(首页为发行人封面与注册金额/发行金额,末页为落款) | `https://www.chinamoney.com.cn/dqs/cm-s-notice-query/fileDownLoad.do?contentId=3326437&priority=0&mode=save` | 三份都是**完整报告**,不是节选,也没有被我们处理过——「完整」与「未被处理」两点的依据是 同一份字节:本地文件与平台下载件的 SHA-256 相同(下载件另存于本副本之外用于比对)。 > **这三条 URL 的核实程度不一样,如实说明:** 2025 年年度报告与募集说明书这两条,是**从平台 > 发布页上直接读取**的。**2024 年年度报告的 URL 不是**——它是通过探测同一披露区间内的相邻 > 静态 ID 得到、再以**下载件 SHA-256 与本副本文件精确相符**来确认的;**没有**该页面的列表页 > 证据。也就是说,这一条的凭据是「哈希对上」,**不是**「页面标注对上」。如果需要一个列表页 > 级别的来源记录,这仍然是一个待补的项。 - 逐份通读正文、文档属性、首页与末页,**未在文件内发现版权声明或再分发限制**(也没有发现 绝对路径、凭据形状串或嵌入对象)。**本副本不声称**已获得任何再分发许可;版权与数据权利 归原权利人所有。 - **两处未改动的属性残迹**(因为它们都在平台发布的那份文件里,改了就不再逐字节相同): ① 募集说明书那份的 PDF `title` 元数据写着**另一家公司**的名字,而正文封面、页眉与目录都是 发行人的这份募集说明书——模板残留,与内容无关;② 三份 PDF 的文档属性里各留有**具名的个人 署名**(其中两份带事务所代号,一份为编制者个人名),本 README 不复述姓名。 正因为元数据不可信,本副本**不**拿文件名或元数据当作身份依据——链上一切按内容哈希命中。 - 三份 XLSX 是**按公开披露内容人工整理**的工作簿:单张可见工作表、0 个公式、无外部链接、 无 VBA/批注/嵌入对象/图表,文件属性显示由 `openpyxl` 生成。它们**不是**官方发布文件。 - 这三份工作簿做过**元数据清理**:只从 `docProps/core.xml` 移除了整理者的个人显示名。 除此之外,每个 OOXML 成员的**解压后内容逐字节相同**(工作表、单元格原值与公式、定义名称、 单位与格式均未变),财务导入读数也逐项相同。因此它们**不是**清洗前文件的逐字节副本; 清洗前的大小为 `14 494 / 12 268 / 12 930` 字节——**这组旧哈希已不适用**, 校验一律以本表当前值为准。 - 三份 PDF 与本批**未做任何改动**,仍与公开披露平台下载件逐字节相同。 - 三份 PDF 与三份 XLSX 是**两条独立的输入轴**:PDF 进公司节材料,XLSX 进财务权威快照; 两者之间没有内容勾稽,谁都不冒充谁。 - **没有 LICENSE 文件**是刻意的:本副本**不声称**项目已按某个开源许可证授权。第三方材料 (上面六份文件以及任何你自备的材料)的权利不在代码许可范围内。 --- ## 七、系统如何工作 ```text 电子 PDF / Excel → 来源定位、Evidence 与研究 Pack;财务事实另走权威数据通道 → Writer 依据当前材料和合格事实写自然正文,每句标注引用 → 确定性逐句检查引用、期间及高风险数字等硬底线 → 独立、只读的语义审阅指出遗漏、越界和矛盾 → 带逐句问题的预览;系统放行与人工接受分别记账 ``` 当前写作主线是 **Pack 之后直接生成带引用的正文**,不是先批准原子 `ClaimCandidate` 再逐字拼句。 研究 Harness、Pack 来源、事实资格和财务权威各自保持边界;Writer 不能自行检索、计算或批准自己的事实。 历史 Claim 链保留供兼容和审计,不是当前演示的必经写作链。 主营业务的原表以已登记电子 PDF 的**原件区域**供人工回查。它不是结构化 `TableObject`、 Pack/Writer 材料或数字权威;图片可见不等于正文可引用其中金额和比率。正文使用的营收、成本、 毛利等数字仍须另做格级资格核对,跨期计算由 Python/Decimal 完成。财务指标表则由权威财务事实 确定性生成,不能用原 PDF 截图替代。 本副本支持可提取文本的电子 PDF,以及财务 PDF/Excel 输入;**不**把扫描件 OCR、图片、PPT 或 Word 当作首版输入。外部搜索有单独的来源获取、快照和资格要求;**打开只读演示页不需要** 外部搜索或模型密钥。 ## 八、边界与状态声明 - 本副本展示了流程与界面,**不代表** M930-3 内容质量、M930-4 审阅、M930-5 界面、 正式树结构/TS5 门或任何正式阶段已经关闭。 - 流程完成、预览可看、逐句硬核对、独立审阅、系统放行、人工接受和正式阶段关闭是**不同**状态。 - 发现硬错误或必要证据缺口时仍可保留清楚标记的**不可发布预览**;不能把问题隐藏成整节「通过」。 - 「在本次搜索范围内未取得」**不等于**「来源不存在」。 - 所有输出仅供演示与研究辅助。使用前应人工核查来源、适用期间、计量单位、口径、遗漏和结论。 公开资料的版权及数据权利归原权利人所有。 ## 九、代码状态(重要) 本副本的代码来自内部工作仓库的**工作区快照**: - 其中相当一部分文件在该仓库里处于「已跟踪但已修改」或「从未提交」状态, 也就是说 **代码本副本不对应任何一次提交**,不应被当作「已经过评审」的版本; - 本批次在副本内做的改动只有四项:新增六份输入及 `data/samples/300750/case_inputs.yaml`、 新增 `scripts/prepare_case_inputs.py`、补入生产代码依赖的 `evaluation/datasets/baseline_contract_mapping.jsonl`(见第四节)、以及 `test_metrics_db.py` 的最小修复(见第四节),外加 `.gitignore` 对 `data/samples/300750/` 的再包含例外; - 后续清理批次另改了 **7 个文件**,全部与「三份 XLSX 的元数据清理」这一件事相关:三份 XLSX 本身、 `case_inputs.yaml`(为三份工作簿补上 `sha256`/`size_bytes`,并更新财务快照 id)、 `scripts/prepare_case_inputs.py`(`--check` 现在对六份文件一律核对哈希与字节数,不再只查 工作簿是否存在)、`evals/test_intermediate_preview.py`(快照身份钉子)、本 README。 **三份 PDF 一个字节都没有动。** - **发布准备批次在副本内只改了本 README**(第一节安装命令改为锁定清单、第二节与第五节的措辞、 第四节换成清洗后副本上的整轮实测读数、第六节的来源核实程度说明)。同批还**删除**了两处 `__pycache__` 目录下的 7 个 `.pyc`——它们是更早的验证批次在这个副本里 `import` 时写下的构建 残留,不属于内容,`.gitignore` 本来就排除它们(所以即使留着也不会进入新仓库)。 **六份输入与其余代码在本批一个字节都没有改动。** - 逐文件的状态标注与本次前后差异清单另行记录在交付报告里,该报告**不作为仓库内容**随副本分发。 ## 十、进一步阅读 - [AGENTS.md](./AGENTS.md) —— 项目约束 - [DOCUMENTATION_INDEX.md](./DOCUMENTATION_INDEX.md) —— 文档权威顺序 - [DESIGN_V2.md](./DESIGN_V2.md) —— 现行设计 - [evaluation/README.md](./evaluation/README.md) —— 评测入口说明 - [https://waypointean.com/projects/credit-report] —— 网页端图解说明 这些文档出自内部工作仓库,描述的是**内部**项目的进展与判据;其中引用的历史 run、 `evaluation/results/` 目录和一次性探针路径在本副本中**不存在**。