# CLAUDE.md — FacereDataset

项目级 Claude Code 指令。与 `~/.claude/CLAUDE.md` 全局指令合并使用，本文件覆盖冲突项。

## 项目性质

数据集仓库。产出代码 + 元数据 + （通过 LFS 或外链引用的）原始资产。不要把几百 MB 的 Gerber / STEP 直接塞进 git。

## 核心工作流

1. **每次重要动作结束后**：追加一条到 `log.md`（时间倒序，顶部最新），格式：
   ```
   ## YYYY-MM-DD HH:MM  <一句话概括>
   - 做了什么
   - 为什么（如果非显然）
   - 下一步建议
   ```
2. **计划有调整时**：更新 `plan.md`，不要新建 `plan_v2.md`。
3. **新增爬虫**：放到 `crawlers/<site>/`，至少包含 `__init__.py` 入口、`README.md`（目标站点调研），遵循 `schemas/project.schema.json`。
4. **数据输出位置**：`data/raw/<site>/<date>/` 存原始响应（JSON/HTML），`data/processed/<site>/` 存清洗后的 jsonl。两者都在 `.gitignore` 里，不入库。

## 爬虫规约

- **速率**：默认 QPS ≤ 1/site，并发 ≤ 3。可配置但不得默认贪婪。
- **缓存**：所有 HTTP 响应落盘（`data/raw/...` + `requests-cache` 或 httpx + diskcache），重跑不要重新打目标站。
- **UA**：声明为 `FacereDataset/<version> (+<repo-url>; contact:<email>)`，不要伪造浏览器。**例外**：目标站主动封标识 UA、且内容属公开静态资源时，允许切 lightpanda/web-access 真浏览器模式，并在 commit message 说明原因。
- **robots.txt**：每个爬虫 **必须** 先查 `robots.txt`；命中 Disallow 的路径直接跳过，不要"绕过"。
- **登录态**：本项目**不**抓需要登录的内容。
- **失败重试**：指数退避 + jitter；连续 5xx / 429 超过阈值要停爬、提醒人介入，不要傻重试。
- **断点续跑**：state 记到 `data/state/<site>.json`（游标、已处理 ID 集合）。

## 数据 schema

统一以 `schemas/project.schema.json` 为准。每条项目记录至少包含：
`source`, `source_url`, `project_id`, `title`, `description`, `author`, `license`, `created_at`, `updated_at`, `crawled_at`, `tags`, `files[]`（每个文件 `type` / `path` / `size` / `sha256`）。

## 合规红线

- 不抓登录墙后的内容。
- 不绕过付费墙、不破解 DRM。
- 遇到站点明确声明"禁止抓取/训练"的内容，跳过并记录到 `data/state/<site>_excluded.jsonl`。
- 每条记录**必须**保留 `license` 字段；无法判定的标 `license: "unknown"` 并在下游过滤时默认剔除。

## 约定（项目内部）

- 语言：代码/注释/commit 英文；文档（README / plan / log）中文。
- Python：3.11+，`uv` 管理依赖，`ruff` 做 lint/format，`pytest` 测试。
- 不要为"以防万一"添加抽象或配置项；多爬虫共享需求再抽共用代码。
- commit message 说清楚 **why**，尤其是涉及数据过滤、许可证判定逻辑的改动。

## Claude 行为提醒

- 启动任何爬虫前，先跑 dry-run（`--limit 1 --no-write`），确认 schema 和速率正确。
- 一次只推进 `plan.md` 的一个阶段，推进后更新 `log.md`。
- 涉及数据删除（`rm` `data/`）必须先跟 Charles 确认。
- 新发现的反爬/法律坑录入 `docs/pitfalls.md`，不要只放在 log。
