# Ritfit Contract Maker

> RitFit Contract Maker

- Skill: `nana7536/ritfit-contract-maker` (Agent Skill, multi-file: 11 files)
- Install (CLI): `npx skillmds@latest add nana7536/ritfit-contract-maker`
- Raw SKILL.md: https://api.skillmd.com/api/skills/nana7536/ritfit-contract-maker/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: nana7536 (https://skillmd.com/u/nana7536)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/nana7536/ritfit-contract-maker

---


# RitFit Contract Maker

> **v2.0 (2026-08-12) — department-shared rebuild.** 本技能从"仅所有者"改为品牌部部门共用版：名册内启用成员均可发起；合同存到飞书云盘共享文件夹下每位成员自己的子文件夹；运营者邮箱从名册解析当前用户；任何合同生成后仅置 `Pending Review`，必须人工审核后才可发送/签署，绝不自动发送。

使用本技能从已批准的模板生成 RitFit KOL 合同，并强制执行合同工作流。

合同由模板驱动。请勿发明、重写或协商法律条款。选择正确的模板，验证必填字段，填写批准的占位符，存储生成的文件，并在发送或签署前要求人工审核。

## ⚠️ Identity resolution — 每次运行第一步（v2.0，部门共用版）

本技能从 v2.0 起改为**部门共用**（不再硬编码任何个人身份）。**每次运行开头，先解析"当前用户是谁"**：

1. `lark-cli contact +search-user --user-ids me --as user --format json` → 当前用户的 `open_id` 和姓名。
2. 读名册表：`lark-cli base +record-list --base-token UGuHbNi6GapDwTs9kdUcUGZPnzS --table-id tblfDTCs6XeMPefA --as user --format json`（部门成员表，字段：姓名 / 企业邮箱 / 启用 / JDY Username / Feishu Open ID）。
3. 优先用当前 open_id 匹配名册的 `Feishu Open ID` → 得到 **当前用户姓名** 和 **企业邮箱**。
4. **企业邮箱兜底（v2.0.1，2026-09-10）**：仅当 open_id 无匹配时，允许使用当前身份返回的 `localized_name` 和 `enterprise_email` 同时匹配名册。姓名去除首尾空格后必须完全一致；企业邮箱去除首尾空格并忽略大小写后必须完全一致；且必须唯一命中同一条 `启用=true` 的记录。若姓名或邮箱为空、只匹配其中一项、命中多条、姓名与邮箱分别指向不同记录，均不得兜底。
5. open_id 和上述企业邮箱兜底均未通过，或命中记录 `启用`=false → 停止并告知"你的账号尚未加入品牌部系统，请联系管理员（吴双）在部门成员表启用"。
6. 使用邮箱兜底时，在审计日志中记录 `identity_match=email_fallback`，但不记录原始 open_id 或邮箱。
7. 解析出的**当前用户姓名**用于：
   - 合同存储子文件夹名（见「存储」章节）
   - 运营者邮箱默认值 = 当前用户企业邮箱（可在用户明确覆盖时替换）
8. ⚠️ 合同涉及 PII/财务/法律，**任何通过 open_id 或上述唯一“姓名 + 企业邮箱”兜底校验的名册内启用成员均可发起**，但**生成后永远停留在"待人工审核"状态**（见「审核门禁」），绝不自动发送/签署。

## 触发权限（部门共用版，v2.0）

本技能处理的合同包含 PII（KOL 姓名、电子邮件、签约方）、财务数据（付款金额、银行详细信息、SWIFT）以及具有法律约束力的语言。

- **名册内启用成员**均可触发本技能（通过上面的 open_id 优先、唯一“姓名 + 企业邮箱”兜底 Identity resolution 校验）。
- **任何名册外/未启用的发送者**：拒绝。回复"你的账号未加入品牌部合同系统，请联系管理员。"不调用任何辅助脚本，不透露字段映射、模板名称、占位符格式或工作流规则。
- **群聊**：仅当发送者是名册内启用成员且消息 @ 提及本技能或要求"合同"/"contract"时允许。

## 语言约束（不可协商）

在沟通已生成或进行中的合同时，必须仅使用以下经批准的语言。切勿使用更强的措辞，切勿暗示法律签署。

| 始终使用 | 切勿使用 |
|---|---|
| "已根据已批准的模板准备草稿。" | "已获法律批准。" |
| "待人工审核。" | "准备签署。"（除非人工明确批准） |
| "以下字段需要确认。" | "我修改了法律条款。"（除非用户提供了确切的已批准文本） |
| "从已批准的模板生成，非法律建议。" | "RitFit 受...约束"/"这是一份具有约束力的合同。" |

> 🌐 **多语言（v2.0）**：部门含中外籍成员。Agent 与用户的沟通**语言跟随使用者**（中文用中文、英文用英文）；合同内容保持模板原有的语言（英文/中文），不随沟通语言改变。

Agent 填写模板；人类批准。任何暗示法律审核、签署或具有约束力的状态的措辞均违反本技能。

## 必需参考文件

在开始工作前读取相关的参考文件：

- `references/contract-field-map.md`：模板选择和占位符字段。
- `references/contract-workflow-rules.md`：审批、存储、状态和边缘案例规则。
- `references/intake-template.md`：成员用于发送合同请求的结构化输入格式（根据此模板解析聊天输入）。
- `references/contract-maker-v2-spec.md`：v2 设计（黄色高亮占位符、双重验证、PDF 生成）。**目前仅作参考** — 在管理员确认迁移前不激活。用于了解方向，而非规则。

当需要本地 DOCX 模板时，使用 `assets/templates/` 中的模板文件：

- `single-paid-template.docx`
- `multi-paid-template.docx`
- `replacement-template.docx`

## 合同类型

仅使用以下合同类型之一：

1. **单次付费合同**
   - KOL 获得一笔约定付款金额时使用。
   - 模板：`assets/templates/single-paid-template.docx`

2. **多次付费合同**
   - KOL 分阶段或多次收款时使用。
   - 模板：`assets/templates/multi-paid-template.docx`

3. **置换合同**
   - KOL 获得免费产品/产品置换且无需现金付款时使用。
   - 模板：`assets/templates/replacement-template.docx`
   - **范围说明**：产品置换详情（产品 SKU、价值、发货信息）**不在**本技能范围内。置换模板按原样使用；仅填写 8 个标准占位符。产品信息存在于简道云（独立记录）中，不嵌入合同。

如果合同类型缺失或不明确，停止并请求确认。如果资金/产品条款不清楚，不要从上下文中推断付费与置换。

## 模板格式和占位符

### 当前状态（活跃）

3 个活动模板使用 **widget-id 占位符**，格式为：

```
${中文名#_widget_数字}
```

示例：`${签约方#_widget_1755054904603}`、`${合同开始时间#_widget_1750749006932}`。参见 `references/contract-field-map.md` 获取完整清单。

`fill_docx.py` 通过运行分段安全替换处理这些占位符。

> ⚠️ **已知坑：占位符提取/匹配请优先用纯字符串操作，不要用正则**（2026-08-12 实测教训）。
>
> **背景**：此前一次运行中，agent 在"提取模板占位符"时用 `re.search(r'\$\{', text)` 得到 `None`，误判为"Python 正则引擎异常"，实际是 **bash/终端多层转义导致正则模式串被改写**（例如 bash 双引号内 `\$` 被 shell 处理后再传给 Python，正则就匹配不到 `${`）。当前环境 Python 正则本身**完全正常**（已复现验证：`re.search(r'\$\{')` 和 `re.sub(rb"<dc:creator>[^<]*</dc:creator>", ...)` 均正常匹配）。
>
> **规则**：
> 1. **提取占位符**（打开 docx 找 `${...}`）：用纯字符串 `t.find('${')` + `t.find('}')` 分段扫描，**不要用正则**——纯字符串最稳，不受转义层级影响。
> 2. **如果正则匹配突然失败**：先怀疑是 shell/引号转义问题（尤其 `\$`、`${`），把正则模式放进脚本文件或单引号 heredoc 里再测，**不要立即断定"环境正则坏了"**。
> 3. `fill_docx.py` 内部用 `in` + `str.replace` 做占位符替换（纯字符串），`strip_metadata` 用 `re.sub(rb"...")` 处理字节 XML——这些都是脚本内部固定模式，无 shell 转义问题，**正常可用，无需改动**。
> 4. 避免在 bash 命令行 `-c "..."` 里内联复杂正则给 Python；优先写临时 `.py` 文件再运行。

### 未来状态（计划中）

v2 迁移计划将模板切换到**黄色高亮占位符**（`<w:shd w:fill="fff2cc"/>` 或 `ffe599` + 纯英文文本），详见 `references/contract-maker-v2-spec.md`。

**状态**：尚未开始。在编辑任何模板前需要管理员确认。

## 字段默认值（v2.0 起动态解析）

以下默认值在 v2.0 起按**当前用户**解析（Identity resolution），除非用户在特定合同中明确覆盖：

- **运营者邮箱**（适用于所有合同）：默认 = **当前用户的企业邮箱**（从名册表解析，不再硬编码任何固定邮箱）。用户明确指定其他运营邮箱时以其为准。
- **公司实体**：`RITFITNESS INC`（品牌方固定）
- **合同结束日期**：由 Agent 根据 `start_date + duration_months` 自动计算（保留月份中的日期）。
- **内容使用权**：默认为模板的标准范围（活动期内、渠道内、非独家）。
- **今天日期**（生效/签署日期）：生成时自动填充为 `YYYY-MM-DD`。
- **日期输入格式**：接受 `YYYY/M/D`（如 `2026/6/12`）和 `YYYY-MM-DD`（如 `2026-06-12`）。写入合同前标准化为 ISO 格式。

## 排除字段（管理员决定，2026-06-12）

以下字段**永久不在**输入模板和合同生成流程范围内：

- 置换合同的产品置换详情（SKU/价值/发货）
- FTC 披露指导
- 可选输入部分（代理机构、平台详情、平台 URL、近期帖子参考、自由格式备注）

## 存储

所有生成的合同必须保存到飞书云空间中的 RitFit KOL Contracts 文件夹：

- **文件夹 URL**：<https://ritfitsports.feishu.cn/drive/folder/TEVbfSRDWlOCvIdRmdmc1CcUnFf>
- **文件夹 ID**：`TEVbfSRDWlOCvIdRmdmc1CcUnFf`
- **租户**：`ritfitsports`

### 文件命名约定（2026-06-12 更新）

**必需格式（向前适用，适用于从 2026-06-12 起的所有新合同）：**

```
{YYYYMMDD}_{KOL Name}_RitFit Agreement.docx
```

- **段 1**：`YYYYMMDD` = **生成日期**（`fill_docx.py` 运行的日期）
- **段 2**：`KOL Name` = KOL 的签署/显示名称，**允许并保留空格**
- **段 3**：`RitFit Agreement` = 静态后缀，不含合同类型或合同 ID

**本地草稿文件夹路径**（v2.0：相对当前 agent workspace，不写死任何人路径）：

```
<当前 agent workspace>\_outputs\ritfit-contract-maker-outputs\drafts\{YYYYMMDD}_{KOL Name}_RitFit Agreement.docx
```

**Payload JSON（侧车文件）**：

```
<当前 agent workspace>\_outputs\ritfit-contract-maker-outputs\drafts\{YYYYMMDD}_{KOL Name}_RitFit Agreement_payload.json
```

## 存储（v2.0，部门共用版）

**合同统一存到飞书云盘部门共享文件夹，每人名下独立子文件夹（以成员姓名命名）。**

- **共享根文件夹**（部门合同共享）：需要吴双在飞书云盘先建好，并把 token 写入本文件下方「共享文件夹 token」处。建议结构：
  ```
  RITFIT 品牌部合同（共享）
    ├── 吴双/
    ├── 曹一麟/
    ├── Angeline Prasetio/
    ├── Diego Isaac Rojo Molina/
    └── ...（每个成员一个，以名册姓名为准）
  ```
- **子文件夹命名**：**以 Identity resolution 解析出的当前用户姓名为准**（跟名册表一致，如 `Diego Isaac Rojo Molina`、`Angeline Prasetio`）。
- **上传目标**：当前用户对应的子文件夹。`upload_drive.py` 上传时 `--folder-token` 传该成员子文件夹的 token。
- **子文件夹不存在** → 用 `lark-cli drive` 在共享根下创建，或以名册姓名为准。
- **访问权限**：共享文件夹对所有品牌部成员可读写（由吴双在飞书云盘配置）。

> ✅ **共享文件夹已创建（2026-08-12）**：
> ```
> 共享根文件夹: RITFIT 品牌部合同
> 根 token: E9DxfXK2blRUhRdzTpccmH7CnS9
> 链接: https://ritfitsports.feishu.cn/drive/folder/E9DxfXK2blRUhRdzTpccmH7CnS9
> ```
>
> **成员子文件夹 token 对照（按名册姓名）：**
> | 成员 | 子文件夹 token |
> |---|---|
> | 吴双 | `S8nJfIuFulH7ADdH3bNczYbRnnf` |
> | 曹一麟 | `RIWofbIEllGJSddeRDXcq7ZWnmb` |
> | Angeline Prasetio | `XiBYfslvXlilwDd4lTHcupBSnYz` |
> | 谭婷 | `K3rbfC851lmd9Fd8MWccjpnhnNP` |
> | 蒋鑫 | `ImNEf80P1le79zdCHRTc36QxnNb` |
> | 李佳蕾 | `XE6JfuF0klGDr2dreI1cS3UQnGX` |
> | 韦小庆 | `Nmpqf3LUSlGUdBdCynoc8sp4nkh` |
> | Diego Isaac Rojo Molina | `D6X3fGLFclOFp4dIcZbc4dSHnjm` |
> | 汪晨 | `MeF3fuaBZl334zdTVEncR77NnoM` |
> | 李仁龙 | `PY3UfB2eElLtAwdOaVOcRFJ1nOb` |
> | 丁露 | `H9CEfEyvglk3DkdOnCQcDWkLnXb` |
> | 林子馨 | `Cq8Hf2ltklti5NdWpdZc6ARnnQZ` |
> | 张羽婕 | `LC7vf9y1olpJs1drkZkcvNI7nrh` |
> | 朱颖 | `XIApfA0Iml1BJsd5L4Oc6KI7nug` |
>
> ⚠️ 子文件夹已建好，运行时按名册解析当前用户 → 用上表对应 token 作为上传目标。若名册新增成员而表里没有 → 用 `lark-cli drive +create-folder --name <姓名> --folder-token E9DxfXK2blRUhRdzTpccmH7CnS9` 创建并回填本表。

上传到对应成员子文件夹后，文件链接必须写回：
- 简道云合同记录
- 飞书多维表格合同记录（附件列）
- 活动/KOL 合作记录（如果分开）

## 核心工作流

> ⚠️ **数据源检索（v2.1，2026-08-12 吴双实测反馈修正）**：合同必填字段必须**优先从简道云「网红信息」表自动带出**，不要只依赖用户输入，更不要先去查飞书 Base「ALL KOLs」。查询一律用**简道云 MCP**（`member_data_list`/`member_data_get`，app_id `685a468345ade02b47318ca9`，entry `685a4688ff01bd47de8c32a7`），**不需要 API Key**。API Key 只在"往简道云写回合同记录"时才需要（见步骤 12）。**绝不能因为"缺 API Key"就放弃检索网红数据——查询走 MCP，不依赖 Key。**

检索网红信息（按网红名称 search `_widget_1750747331717`）后，**自动带出以下字段**，并填充到对应合同占位符：

| 合同字段 | 网红信息表字段 | 说明 |
|---|---|---|
| KOL 名称（签约方） | `_widget_1750747331717`（网红名称） | 自动 |
| KOL 邮箱 | `_widget_1751591561200`（联系邮箱） | 自动 |
| 运营英文名 | `_widget_1754550773137`（运营英文名，如 Christina Wu）| 自动 |
| 收款渠道 | `_widget_1751612132022`（收款渠道，PayPal/银行转账）| 自动 |
| PayPal 账户 | `_widget_1751612955631`（PayPal收款人名字）+ `_widget_1751612955632`（PayPal收款账号）| 自动 |
| 银行账户名/账号 | `_widget_1751592169915`（银行账户名）+ `_widget_1751592169916`（银行账号）| 自动 |
| 银行名称 | `_widget_1750747926379`（银行名称）| 自动 |
| ACH 路由号 | `_widget_1751592169917`（ACH汇款路由号）| 自动 |
| SWIFT | `_widget_1751618631862`（SWIFT号）| 自动 |
| 收款人所在国家 | `_widget_1750747331717` 关联网红国籍 | 参考 |

> ⚠️ 若网红信息表中**收款字段为空**（该网红未填收款信息），如实告知用户"网红信息表未登记收款信息，请提供"，让用户补充——不要编造。运营英文名若为空，用当前用户英文名（从运营信息表 `_widget_1754548083129` 或名册解析）。

**合同 ID 来源**：合同 ID（`_widget_1750748364947`）不是用户输入，是**简道云合同管理表**自动编号（历史格式如 `RF-202607020`、`RF-202607021`）。生成前用 JDY MCP 查合同管理表（app `685a468345ade02b47318ca9`，entry `685a4cab6303c86dd2eed46d`）看最新编号，按同一规则取下一个；无法确定时询问管理员。**不要编造合同 ID。**

1. 识别 KOL 和活动。
2. 确认合同类型：单次付费、多次付费或置换。
3. **检索网红信息**（见上方数据源检索说明）：用 JDY MCP 查简道云「网红信息」表，自动带出 KOL 名称/邮箱/运营英文名/收款账户等字段。
4. 从 `references/contract-field-map.md` 加载必填字段列表，对照网红信息表带出的值，**标出仍缺失的字段**（如付款金额、交付成果、合同起止日期等需用户提供的）。
5. **预生成验证（步骤 3）**——构建所有数据源（用户输入、简道云网红信息表、合同管理表）的比较表，并在继续前获得用户明确确认。**缺失字段必须让用户补充后确认，不能带着空字段继续。**
6. 验证所有必填字段是否存在。
7. 检查 `references/contract-workflow-rules.md` 中的风险条件。
8. 仅填写已批准的模板占位符。
9. 通过 `fill_docx.py` 生成合同草稿。
10. **生成后验证（步骤 4）**——解包生成的 .docx，提取已填字段，向用户打印验证摘要。验证通过前不上传。
11. **生成 PDF 副本**（计划中）通过 LibreOffice 无头模式。
12. 将最终草稿（+ PDF）存储在共享文件夹对应当前用户的子文件夹中。
13. 将合同链接和状态写回飞书多维表格/简道云合同记录（**这一步如走 Open API 需要 Key，缺失时先写飞书多维表格，简道云侧标注"待补 Key 后回写"**）。
14. 将合同标记为`待审核`。

## 验证（预生成 + 生成后）

为防止合同使用错误字段生成的错误类别，每份合同经历**两个验证阶段**。

### 步骤 3 — 预生成验证（在 `fill_docx.py` 之前）

1. **识别本合同的所有数据源**：用户聊天输入、**简道云网红信息表（自动带出）**、简道云合同管理表、电子邮件线程或上传的文件。
2. **构建比较表**（KOL 基础信息优先来自网红信息表自动带出）：
   ```
   | 字段 | 来源：用户 | 来源：网红信息表 | 待填写 | 匹配？ |
   |-------|--------------|--------------------|--------------|--------|
   | KOL 名称 | Drew Dixon | Drew Dixon | Drew Dixon | OK |
   | KOL 邮箱 | (未提供) | realdadofgenius@gmail.com | realdadofgenius@gmail.com | OK |
   | 运营英文名 | (未提供) | Christina Wu | Christina Wu | OK |
   | 付款金额 | $5,000 | (不适用) | $5,000 | 待定 |
   | 收款账户 | (未提供) | (网红未填) | 待用户补充 | ⚠️ 缺失 |
   ```
3. **标记任何不匹配或缺失字段** — 缺失字段让用户补充后再继续，不带着空字段硬生成。
4. **在生成前获得用户明确确认**。

### 步骤 4 — 生成后验证（在 `fill_docx.py` 之后、上传之前）

1. 解包生成的 .docx（原始 zip → `word/document.xml`）。
2. 从 XML 中提取已填字段。
3. 向用户打印验证摘要。
4. **如果任何字段与源数据不匹配**：停止，修复 `fill_docx.py` 逻辑，重新生成，重新验证。不上传。

## 硬性规则

- 不创建新的法律条款。
- 不更改付款、终止、责任、保密、知识产权、FTC、管辖法律或签署语言，除非人工明确提供已批准的替换文本。
- 不自动向 KOL 发送合同。
- 未经人工确认，不将合同标记为已批准或已签署。
- 如果付款金额或付款方式缺失，不生成付费合同。
- 如果交付物或产品置换详情缺失，不生成置换合同。
- 如果 KOL 身份、电子邮件、公司实体、合同开始日期或合同结束日期缺失，不生成任何合同。
- 如果人工在生成后手动编辑合同，将编辑后的版本视为真相来源。
- 在交付已生成合同前始终剥离模板元数据。
- 将每次合同生成/验证/审核/状态更新记录到审计日志。仅记录元数据，从不记录原始 PII。
- 不完成步骤 3（预生成验证）和步骤 4（生成后验证）就生成合同。
- 当模板迁移到黄色高亮占位符（v2）时，`fill_docx.py` 必须保留每个已填运行的突出显示颜色。

## 文件交付（v2.2，部门共用版）

**所有生成的合同以【原始 .docx 文件】上传到飞书云盘共享文件夹下对应当前用户的子文件夹**（见「存储」章节），使用 `upload_drive.py`（`lark-cli drive +upload`，**不是 +import**）。

> ✅ **v2.2（2026-08-12）关键变更：上传原始 .docx，不再转成飞书在线文档**。
> - 旧逻辑用 `+import --type docx` → 把本地 .docx **转换**成飞书在线文档（云 docx），导致文件夹里是在线文档，需要再导出/下载才能转 PDF，且人工审核不便修改。
> - 新逻辑用 `+upload` → 把本地 .docx 作为**原始文件**上传，文件夹里就是**一个可编辑的 .docx 文件**（Word 可直接打开修改，也方便后续转 PDF）。
> - 好处：人工审核发现问题时能直接在 docx 里改，改完再转 PDF。

> ⚠️ **Windows 上传脚本已知坑（v2.1 修复 + v2.2 更新）**：
> 1. **裸命令问题**：`upload_drive.py` 早期用 `subprocess.run(["lark-cli", ...])`，Windows 上报 `FileNotFoundError (WinError 2)`——npm 装的 lark-cli 是 `lark-cli.cmd`/`.ps1`（无 .exe），Python list-args 不解析 .cmd。已修复：脚本用 `resolve_lark_cli()` 在 Windows 上解析 `lark-cli.cmd`。
> 2. **如果 upload_drive.py 仍报找不到命令**，可直接用 Bash 手动上传原始文件：
> ```bash
> cd <草稿目录> && lark-cli drive +upload --as user --file "<docx名>" --folder-token <成员子文件夹token> --name "<docx名>"
> ```

交付流程：
1. 生成并验证合同（步骤 3/4 通过）。
2. **上传原始 .docx** 到当前用户子文件夹：`python upload_drive.py --file <out.docx> --folder-token <成员子文件夹token> --name <filename> --as user`。
3. 上传后把文件链接写回：简道云合同记录 + 飞书多维表格合同记录。
4. 将合同状态置为 `Pending Review`（待人工审核），**不自动发送给 KOL**。
5. **主动提醒生成者审核（必须执行）**：通过 `mcp__claw__notify` 向当前用户推送一条醒目的通知，内容固定为：
   ```
   📄 合同已生成并进入你的文件夹，请审核
   - 合同：{YYYYMMDD}_{KOL Name}_RitFit Agreement.docx（原始 .docx，可直接编辑）
   - 位置：RITFIT 品牌部合同 / <当前用户名> 子文件夹
   - 状态：待人工审核（Pending Review）
   👉 请审核确认后再发送给 KOL。我不会自动发送。
   ```
   同时也在对话中回复同样内容的提醒。**这一步不可省略**——每个生成者都必须收到"合同已进你的文件夹，请审核"的明确提醒。
6. 若生成者不是 KOL 的负责人/对接人，且另有指定负责人：额外把上述通知转发给该负责人（在对话中说明"已提醒负责人审核"）。
7. **PDF 转换（v2.2 确认：不自动生成 PDF）**：**本技能只交付原始 .docx，不自动转 PDF**（当前未安装 LibreOffice）。审核通过后如需 PDF，由**人工自行转换**（Word 另存为 PDF，或飞书在线导出）。Agent **不要**尝试本地转 PDF，也不要承诺会自动生成 PDF。

> ⚠️ 若子文件夹尚不存在，先在共享根下创建（`lark-cli drive` 建文件夹，以名册姓名为准）。

## 审核门禁（v2.0 强调）

- **生成后永远只置 `Pending Review`**，绝不自动发送给 KOL、绝不标记已批准/已签署。
- **状态流转**：`Draft → Pending Review → [人工] Approved → Sent → Signed → Completed`；`Pending Review → [人工] Rejected`。Agent 只能置 `Pending Review`，其余状态必须人工操作。
- 任何成员生成的合同，由**该成员（生成者）或其指定负责人**人工审核；审核通过前合同不出本部门。

## 输入格式（v2.0）

**所有合同请求应使用** `references/intake-template.md` 中定义的结构化输入格式发送。当成员发送自由文本请求时，根据模板字段解析并运行**字段验证**以显示任何缺失的必填数据。

## PDF 生成（计划中，v2.2 暂缓）

工具：LibreOffice（无头模式）

```bash
soffice --headless --convert-to pdf <out.docx> --outdir <out_dir>
```

**状态**：**暂缓（v2.2，2026-08-12 吴双决定不装 LibreOffice）**。当前未安装 LibreOffice，本技能**不自动生成 PDF**，只交付原始 .docx。PDF 由人工在审核通过后用 Word/飞书自行导出。若未来需要自动 PDF，需先在机器上安装 LibreOffice（`soffice` 加入 PATH），再启用本节逻辑。

