# dsh-dd-forge — 尽调资料审查(DeepSeek Harness 插件) [English](./README.md) | 中文 **文档 → 规则库 → 风险报告**:把一份企业尽调资料包(工商/股权/财务/合同/章程/劳动合同)交给确定性规则引擎,产出带依据的风险审查报告。为 [DeepSeek Harness (dsh)](https://github.com/DeepSeek-AI/deepseek-harness) 打造,引擎(opcore)本身零 dsh 依赖,可独立使用。 ``` ┌────────────────────────────────────────────────┐ │ dsh 会话(模型 + 判断力) │ │ skills: dsh-dd-forge-review / -report │ ← 判断层(提示词技能) │ tools: dd_review / dd_rules │ ← 确定层(注册进 dsh 的工具) ├────────────────────────────────────────────────┤ │ opcore 引擎(engine/,零 dsh 依赖) │ │ loader(文档→事实) → 规则执行 → 报告渲染 │ ├────────────────────────────────────────────────┤ │ packs/(YAML 规则库——数据,不是代码) │ │ general-company 12 · contract-basics 8 │ │ trade-contract 8 · trade-bulk 10 │ │ logistics 8 · labour 8 · credit-financials 8 │ │ guarantee 5 · corporate-charter 5 │ └────────────────────────────────────────────────┘ ``` ## 安装 ```bash dsh plugin --profile add dsh-dd-forge ``` 或本地开发:`dsh plugin --profile add /path/to/dsh-dd-forge`(pnpm `link:` 安装不会自动装依赖,需先在本目录 `npm install`)。 ## 使用 在 dsh 会话里把资料目录交给模型("用尽调审查跑一下 ./target-company"),或直接调用工具: - **`dd_review`** — 对资料目录跑全部规则包(`packs` 参数可选规则包子集),返回风险清单并把报告写进工作区(`reportPath` 可改报告路径);`format` 参数可选 `md` / `docx` / `xlsx`(逗号分隔多选,默认 `md`);补料闭环参数 `saveRun`(把本轮序列化为可复跑快照 review.json)与 `baseline`(与旧快照对比,见「补料复跑闭环」);多目录批量用 `targets` 数组(见「批量审查」) - **`dd_rules`** — 列出规则包与每条规则的等级、类别、公开依据 技能:`dsh-dd-forge-review`(资料组织约定 + 高风险项人工核实纪律)、`dsh-dd-forge-report`(在引擎输出之上撰写完整尽调报告的结构与纪律)。 ### 批量审查(多目录) 一次会话审查多个对象时,`dd_review` 接受 `targets` 数组(与 `target` 二选一):`targets=["./公司甲","./公司乙"]`。逐目录各出一份报告(按 `format` 导出到 `<工作区>/dd-review-report-<企业名>.`;无工商信息时用目录名命名;重名对象自动加 `-2`/`-3` 后缀),并额外生成一份**汇总索引** `<工作区>/dd-review-index.md`(`indexPath` 参数可改路径):各对象结论与统计表、跨对象的高风险项速览、合计行与每份报告的相对链接,末尾同样带免责声明。 批量前逐目录校验(任一目录无法访问整体报错,不产出半成品)。`reportPath` / `saveRun` / `baseline` 是单次审查参数,与 `targets` 同传会明确报错——需要对某个目录走补料复跑闭环时,用 `target` 单独调用它。 ### 资料包约定 引擎按文件名模式识别,缺什么就少查什么(对应规则记为"数据缺失"): | 资料 | 文件 | 格式 | | --- | --- | --- | | 工商信息 | `工商信息.json`(或文件名含"工商"/"registry"的 json) | 企业名称、登记状态、成立日期、注册资本(万元)、实收资本(万元)、经营范围 | | 股权结构 | `股权结构.csv` 或 `.xlsx`(文件名/表名含"股权/股东") | 表头:股东,认缴出资(万元),实缴出资(万元),持股比例(%),备注 | | 财务报表 | `*资产负债*.csv`、`*利润*.csv`、`*现金流量*.csv`(或 xlsx 中同名 sheet) | 科目为行、年份为列(`科目,2024,2023`),金额单位万元 | | 合同 | `contracts/*.md` / `.txt` / `.docx` | 每份一个文件,可选 frontmatter:标题、签订日期 | | 公司章程 | 文件名含"章程"的 `.md` / `.txt` / `.docx` | 提取公司名称、注册资本、股东名册行、必备事项与股权转让条款 | | 劳动合同 | 文件名含"劳动合同",或正文含"劳动合同期限"的 `.md` / `.txt` / `.docx` | 提取合同期限、试用期月数与分档上限、试用期/约定工资、竞业限制期限与补偿、服务期与培训费用/违约金、必备条款与规章制度依据 | docx(合同/章程)与 xlsx(报表/股权)为**原生解析**(mammoth/exceljs,按需懒加载,无此类文件零开销);仅扫描件/图片请先在会话中转成上述文本格式。 装载器从合同正文额外提取条款事实(供专项规则使用):**定金金额与占比**(「定金…N 元/万元」)、**预付款金额与占比**(金额式「预付款 N 元」与比例式「预付 N%」,供大宗贸易专项使用)、**付款账期**(「N 日内付清/支付」,支付定金/预付款的期限不计入,贸易与物流专项共用)、**日违约金率**(「万分之X/日」自动折算年化百分比)、**贸易类合同识别**(购销/买卖/采购/销售/供货/大宗商品/贸易,非贸易类合同上大宗贸易规则记为不适用)、**物流类合同识别**(货物运输/运输服务/承运/仓储/配送等,非物流类合同上物流专项规则记为不适用;主体名称含"物流"不作为识别依据),以及风险转移、不可抗力、通知送达、验收检验、排他独家、第三方检验、价格调整/点价、定金违约金择一、货权凭证、自动续期、履约保函、结算开票、涉外与争议解决机构、货物毁损灭失赔偿、保价/货运险、装卸责任、转委托限制、回单对账、货损索赔、车辆司机资质等 36 项条款有无探测。 劳动合同文档走独立解析(不进入商业合同候选):**合同期限年数**(日期式「劳动合同期限自 X 起至 Y 止」优先,显式年限兜底;无固定期限单独识别)、**试用期月数与法定分档上限**(按《劳动合同法》19 条分档自动折算:<3 月 0 / 3 月-1 年 1 / 1-3 年 2 / ≥3 年与无固定期限 6)、**试用期工资与约定工资**(自动折算 80% 线比例)、**竞业限制期限**(月/年折月)**与经济补偿条款**(「无需支付经济补偿」的明示排除不算已约定)、**服务期、培训费用与服务期违约金**,以及第 17 条必备条款(用人单位/期限/工作内容与地点/劳动报酬/社保)与规章制度依据探测。 ## 规则包 内置 9 包 72 条规则,全部注明公开依据(法规条文或显式标注的惯例阈值): | 包 | 规则数 | 覆盖 | | --- | --- | --- | | `general-company` | 12 | 工商登记状态、实缴比例、股权结构勾稽、财务恒等式与偿债指标、对外担保决议 | | `contract-basics` | 8 | 合同要件完备性、金额大小写一致、签署日期与签章栏 | | `trade-contract` | 8 | 定金上限(民法典 586 条 20% 线)、付款账期(90 日惯例线)、风险转移、不可抗力、日违约金率折年化 | | `trade-bulk` | 10 | 大宗贸易专项:预付款比例(30% 惯例线)、第三方检验、价格调整/点价、定金与违约金并用(民法典 588 条)、不可抗力排除市场波动、货权凭证(仓单/提单)、自动续期、履约保函、结算开票、涉外争议解决 | | `logistics` | 8 | 物流运输专项:货物毁损灭失赔偿责任(民法典 832 条)、保价/货运险、运费账期(60 日惯例线,与 TC-002 的 90 日线读同一账期事实、口径分层)、装卸责任划分、转委托限制(参照民法典 923 条)、回单对账、货损索赔程序时限、车辆司机资质 | | `labour` | 8 | 劳动用工专项:必备条款(劳动合同法 17 条)、试用期分档上限与工资 80% 线(19/20 条)、竞业限制补偿与期限(23/24 条)、服务期违约金(22 条)、社保缴纳(社会保险法 58 条)、规章制度依据(4 条);仅对劳动合同文档生效 | | `guarantee` | 5 | 保证方式、保证期间、抵押登记、担保范围、反担保 | | `credit-financials` | 8 | 流动/速动比率、有息负债率、经营现金流连续为负、盈利现金流背离、现金流勾稽、资产质量 | | `corporate-charter` | 5 | 章程与工商勾稽(名称/注册资本/股东名册)、公司法第 46 条必备事项、股权转让条款 | ## 规则 DSL 规则是 YAML 数据,装载时编译校验,绝不执行任意代码: ```yaml - id: FIN-001 name: 资产负债表恒等式不成立 severity: high # high | medium | low category: 财务勾稽 target: case # case=每案一次;contract/charter/labour=每份文档一次(绑定 contract.*/charter.*/labour.*) when: financials.balanceSheetGap != null assert: financials.balanceSheetGap <= 0.01 message: '差额 {financials.balanceSheetGap} 万元' # {路径} 插值 reference: 《企业会计准则——基本准则》会计恒等式 # 公开依据 remediation: 复核报表数据录入是否错漏 # 建议动作 ``` 表达式是安全子集(数字/字符串/布尔/null、点路径、`+ - * /`、`== != > < >= <=`、`and or not`、括号),递归下降求值,无 `eval`。**空值语义**:判等可与 null 比较(`x != null` 守卫),其余运算遇 null 传播为 null——`assert: null` 记为"数据缺失"而不是通过:尽调里没有证据不等于没有风险。 结果四态:`finding`(断言为假)/ `pass` / `missing_data`(数据不足)/ `inapplicable`(when 为假,规则不适用)。 ## 证据链(provenance) 每条 finding 附 0-3 条证据引用,报告从"结论"升级为"可核查证据链": - 装载器提取每个关键事实时经 `note()` 记录来源(`CaseData.provenance`:factPath → `{file, line, excerpt}`)。文本类记**物理行号**(docx 无行号,mammoth 输出每段一行,行号即段落序号);csv 行反查回原文件行号;xlsx 记 `sheet!A6` 式定位;摘录取原文 ≤80 字符。 - 规则命中时按其 `when`/`assert` 里引用的事实路径反查 provenance;比率、勾稽差等派生值经 `DERIVED_INPUTS` 映射回输入科目行(如 CF-001 流动比率 → 「流动资产合计」「流动负债合计」两行原文)。对任意规则包通用,无需为每条规则单独配置。 - 条款缺失类 finding(要引用的文字不存在)退化为文件级引用;合同/章程类规则天然绑定文件。 - `missing_data` 规则在报告"数据缺失"表中列出**缺了哪些输入**(标注应来自哪类文档),补料后复检。 - CLI `--json` 与 `dd_review` 工具返回的每条 finding 均带 `evidence` 数组;`missingData` 带 `missingInputs`。 报告中的渲染样式: ```markdown - **[CF-001] 流动比率低于 1**(流动性) - 发现:流动比率 0.81(流动资产/流动负债,提示线 1) - 证据: > 财务/资产负债表.csv L3:「流动资产合计,1330,1180」 > 财务/资产负债表.csv L8:「流动负债合计,1650,1420」 ``` ## 报告交付格式(md / docx / xlsx) 同一轮审查可导出三种格式,共享同一报告编号与免责声明(编号 = `OPC-日期-短校验和`,同一天内同一资料重复导出编号一致,三种格式可互为附件): - **md**(默认):会话内引用的锚点格式,即上文渲染样式 - **docx**(`docx` npm 包,MIT,纯 JS):交付版 Word 报告——封面(企业名/报告编号/日期/引擎版本/免责声明摘要)、目录(静态大纲,跨 Word/WPS/Pages 无需刷新域)、总体结论、风险汇总表(等级/编号/风险/位置/公开依据)、逐项明细(含证据引用)、通过项与数据缺口、签发栏(审查/复核/签发日期,留空待填)与完整免责声明 - **xlsx**(exceljs):三 sheet 风险台账——`风险明细`(每条 finding 一行:编号/等级/风险/位置/发现/证据/建议/依据,等级配色,表尾报告编号+免责声明)、`数据缺失清单`(待补规则与缺哪些输入;无缺失时明示"无数据缺失项")、`规则清单`(全部装载规则与公开依据,可核查"查了什么、依据什么") CLI:`--format md,docx,xlsx`(逗号分隔多选;`-o` 给出报告基名,各格式按扩展名落盘;不给 `-o` 时默认 `dd-review-report.`)。工具 `dd_review` 加 `format` 参数(透传给引擎导出,报告路径按格式替换扩展名,返回 `reportPaths` 数组)。 ```bash node engine/cli.js review fixtures/demo-company -o 报告 --format md,docx,xlsx # → 报告.md / 报告.docx / 报告.xlsx ``` `npm test` 含往返测试:mammoth 读回生成的 docx 断言封面/目录/汇总表/证据/签发栏关键内容,exceljs 读回 xlsx 断言三 sheet 与行数(45 条风险、72 条规则、缺数据清单)。 ## 补料复跑闭环(两轮 diff) 尽调是多轮补料的过程。引擎把每轮审查序列化为可复跑快照,复跑时与上轮对比: ```bash # 第一轮:审查并把快照存为 review.json(findings / missingData / stats) node engine/cli.js review <资料目录> --save-run review.json # ……用户按报告「数据缺失」表补充材料(文件名保持稳定)…… # 第二轮:对当前目录复跑并与旧快照对比 node engine/cli.js diff review.json <资料目录> # 三分类 + 缺数据关闭率 node engine/cli.js diff review.json <资料目录> --json # 机器可读 node engine/cli.js diff review.json <资料目录> -o 报告.md # 报告内置「与上轮对比」节 node engine/cli.js review <资料目录> --baseline review.json # 或:review 直接带 baseline ``` - **对比口径**:finding 以「规则@文件」识别(案例级规则为 `规则@case`),消息里的数值变化不改变分类;**文件改名会表现为"消除+新增"**,不是同一条。 - **三分类**:消除(上轮有、本轮无)/ 新增(本轮新出现,重点核实)/ 残留(两轮均有,推动解决或明确接受)。 - **数据缺失关闭率** = 上轮待补项中本轮已可判定的比例。一条缺口"关闭"后该规则可能变为通过,也可能变为发现(数据到位但触发规则)——后者会同时出现在「新增」里。 - **报告**:有 baseline 时 md/docx 在「总体结论」下渲染「与上轮对比(补料复跑)」小节(上轮/本轮统计、三分类表、关闭率),新增 finding 在明细中标注「— 本轮新增」;xlsx 追加第四个 sheet「与上轮对比」(逐条消除/新增、残留汇总、缺口清单与关闭率行)。无 baseline 时三种格式与之前完全一致。 - **工具**:`dd_review` 对应参数 `saveRun`(写快照)与 `baseline`(对比并渲染),返回值带 `comparison`(三分类与关闭率)。 ## 独立使用(不装 dsh) ```bash node engine/cli.js review <资料目录> [-o 报告.md] [--json] [--format md,docx,xlsx] [--save-run review.json] [--baseline review.json] node engine/cli.js diff <旧快照.json> [资料目录] [--json] [-o 报告.md] [--save-run review.json] [--format md,docx,xlsx] node engine/cli.js rules node engine/cli.js review <目录> --packs <规则包目录> ``` 多目录批量(`targets`)是 dsh 工具侧能力;CLI 场景对每个目录循环执行 `review` 即可。 引擎 API:`import { runReview, loadPacks, renderReport, renderBatchIndex, renderDocxReport, renderXlsxReport, snapshotFromResult, readSnapshot, diffRuns } from 'dsh-dd-forge/opcore'`(docx/xlsx 渲染为懒加载,不导出该格式零开销;`renderBatchIndex` 渲染批量汇总索引)。 `fixtures/demo-company/` 是一份**全合成**演示资料(公司/人物/号码均虚构),`npm test` 以它断言端到端结果:45 项发现(高 10 / 中 24 / 低 11)、通过 78 项、不适用 69 项(含非贸易类合同上的大宗贸易规则、非物流类合同上的物流专项规则、无服务期约定劳动合同上的服务期规则);并断言 10 条代表性 finding 的证据引用(文件/行号/原文摘录)、xlsx 证据定位、缺数据规则的缺输入清单,docx/xlsx 交付格式的往返内容(见「报告交付格式」),补料场景的两轮 diff(复制 fixtures 到临时目录、补股权表/撤合同/改账期制造差异,断言消除/新增/残留与关闭率,及 CLI `--save-run`/`diff`/`--baseline` 端到端,见「补料复跑闭环」),以及 `dd_review` 工具层(`targets` 批量:逐目录报告命名与重名后缀、汇总索引内容与相对链接、多格式导出、参数互斥,及单目标返回形状回归)。 ## License 分层 - **代码**(`engine/`、`src/`):MIT - **示例规则包**(`packs/`):CC-BY-NC-4.0 —— 规则库是知识资产,商用授权另议;这也是"引擎开源、行业规则库收费"模式的法律基础 规则依据公开法律法规与尽调惯例编写(每条规则 `reference` 注明),不包含任何特定机构的内部标准。 ## Roadmap - [x] 证据链:每条 finding 附原文摘录/文件/行号 - [x] 行业规则包:大宗贸易专项(`trade-bulk`,10 条)、物流运输专项(`logistics`,8 条)、劳动用工专项(`labour`,8 条) - [x] 报告交付层:docx 报告与 xlsx 风险清单直出(`--format md,docx,xlsx`) - [x] 补料复跑闭环:两轮 diff(`--save-run` 快照、`diff` 三分类与缺数据关闭率、报告「与上轮对比」节) - [x] dsh 集成加深:`dd_review` 多目录批量(`targets` 数组:逐目录报告 + 汇总索引 `dd-review-index.md`) - [ ] 规则阈值可配置(pack 级 overrides) - [ ] opcore 独立 npm 包发布 ## 免责声明 本工具输出由确定性规则依据所提供资料生成,仅作信息整理与风险提示参考,不构成法律意见、审计意见或投资建议。