# Harbor 精读路线图 v1

> 目标：4 周内从「会用 Harbor」到「能拆解架构、能改造、能产出评测研究」。
> 快照：2026-10-25，全部路径基于 `repos/harbor` @ `6099b8c`（v0.24.0）。
> 用法：三种模式任选 (§1)；每阶段有必读清单、设计问题、练习与验收标准；进度记在 [notes/reading-log.md](notes/reading-log.md)。

---

## 0. 30 秒版本

- **只读一条主干**：`models` → `trial` → `agents` → `verifier`，其余模块按需展开。
- **代码回答问题**：每阶段挂 2–3 个「为什么这样设计」的问题，读完必须能答（§7 有完整清单）。
- **大量跳过**：85 个 benchmark adapter、48 个已注册 agent、34 个沙箱后端里，只需要精读各 2 个（§8）。
- **读完不是终点**：§9 给了 5 张研究选题卡，每张都有最小实验与预期产出。

| 模式 | 时长 | 范围 | 适合 |
|---|---|---|---|
| 速通 | 1 天 | P0 + P3 主线 + P6 验证器 + 跑通 `hello-world` | 先建立判断力 |
| 主线 | ~9 天 | P0–P9 全部 | 能吃透框架 |
| 研究 | 3 周 | P0/P1/P3/P5/P6 + P10 选一张卡 | 出研究产出 |

---

## 1. 三种读法

### 1.1 速通（1 天）
1. 读 `README.md` + `docs-mintlify/core-concepts/index.mdx`（30 min）
2. 读 `src/harbor/trial/trial.py` 的 `run()`/`_prepare()`/`_run_agent_phase()` 三段（2 h）
3. 读 `src/harbor/verifier/verifier.py` 全文（1 h）
4. 跑一个 `examples/tasks/hello-world`（1 h，需要 docker 或 modal）
5. 写出「一次 trial 的时序图」，能在 5 分钟内讲清楚

### 1.2 主线（9 天）
按 §6 顺序执行 P0→P9。每阶段产出 `notes/0X-*.md`，验收标准写在每阶段末尾。

### 1.3 研究（3 周）
P0 → P1 → P3 → P5 → P6（可跳过 P4/P7/P8 细节），然后从 §9 选一张选题卡执行 P10。
P2 遇到任务格式问题时回查；P9 用 `notes/inspect-ai-map.md` / `notes/pier-diff-map.md` 做对照。

---

## 2. 版本快照与工作区

代码已下载到 `repos/`（浅克隆，`--depth 1`，`git log` 只有 1 条记录）：

| 仓库 | commit | 日期 | 体积 | 用途 | 读 or 跳 |
|---|---|---|---|---|---|
| `repos/harbor` | `6099b8c` | 2026-10-23 | 145 MB | 主体框架 v0.24.0 | **精读** |
| `repos/pier` | `4d3c14d` | 2026-09-28 | 4.6 MB | DataCurve fork（DeepSWE） | 只读差异（P9） |
| `repos/inspect_ai` | `641b871` | 2026-10-24 | 79 MB | 跨领域通用评测框架 | 对照（P9） |
| `repos/terminal-bench` | `e67a2cb` | 2026-10-22 | 981 MB | 156 个真实 benchmark 任务 | 抽 2–3 个任务读 |
| `repos/harbor-index` | `5399ea1` | 2026-08-03 | 158 MB | 80 题高信号 benchmark + 榜单 | 读治理流程 |
| `repos/harbor-cookbook` | `e093c9a` | 2026-04-22 | 1.5 MB | 10 个端到端 recipe（含 RL） | 当练习手册 |

**版本纪律**：`CHANGELOG.md` 的 `Unreleased` 段显示 breaking change 非常频繁（agent auth、网络策略、verifier 默认模式、skills 目录都在改）。所有笔记要写清 commit，升级后先读 CHANGELOG。

### 环境现状（已实测）

| 项 | 要求 | 现状 | 影响 |
|---|---|---|---|
| uv | `>=0.13.5`（`pyproject.toml:48`） | 0.12.22 | `uv sync --locked` 会失败，先 `uv self update` 或重装 |
| Python | `>=3.12`（`.python-version` = 3.13） | 系统 3.9.6 | 由 uv 代管，不要用系统 python |
| Docker | 本地沙箱默认后端 | **未安装**（`docker` exit 127） | 速通练习改用 `--env modal`，或先装 Docker Desktop |
| 模型 API key | 跑 agent 必需 | 需自备 | `oracle` agent 不需要 key，可用于验证任务本身 |

---

## 3. 架构总图

```mermaid
flowchart TB
  CLI["harbor run / job start<br/>src/harbor/cli/main.py:171"] --> Job["Job<br/>src/harbor/job.py:64<br/>配置、计划、并发、结果聚合"]
  Job --> Queue["TrialQueue<br/>src/harbor/trial/queue.py:19<br/>信号量限流"]
  Queue --> Trial["Trial（一次尝试）<br/>src/harbor/trial/trial.py:152"]
  Trial --> S1["SingleStepTrial<br/>trial/single_step.py"]
  Trial --> S2["MultiStepTrial<br/>trial/multi_step.py:24"]
  Trial --> Env["Environment 沙箱<br/>environments/base.py:114<br/>docker / modal / daytona ..."]
  Trial --> Agent["Agent<br/>agents/base.py:34<br/>installed CLI / API / oracle"]
  Agent --> Traj["ATIF trajectory<br/>models/trajectories/trajectory.py:12"]
  Trial --> Verifier["Verifier<br/>verifier/verifier.py:42<br/>tests/ → reward.txt / reward.json"]
  Verifier --> Metric["Metrics 聚合<br/>metrics/ + models/metric"]
  Metric --> Result["JobResult<br/>models/job/result.py:236"]
  Traj --> Result
```

**三条数据流**（后面每个 phase 都会回到这里）：
1. **任务包流**：registry/Hub → 下载 → `Task` 对象 → 挂载进沙箱 → verifier 用 `tests/` 打分。
2. **轨迹流**：agent 原生日志 → `sync_trajectory` → ATIF → 落盘 `trajectory.json` → 可回放/可分析/可喂训练。
3. **reward 流**：`/logs/verifier/reward.json` → `VerifierResult` → 多维 metrics 聚合 → 榜单/RL。

---

## 4. 七个核心概念速查（先背下来）

| 概念 | 代码入口 | 一句话 | 研究价值 |
|---|---|---|---|
| **Task** | `models/task/task.py:34`、`models/task/config.py:853` | 目录包：instruction + task.toml + environment/ + tests/ + solution/ | 评测的「单元」定义权 |
| **Trial** | `trial/trial.py:152` | 一个 agent 在一个 task 上的一次尝试 | 可复现性的真正边界 |
| **Job** | `job.py:64`（配置 `models/job/config.py:399`） | 一批 trial 的集合，负责并发、重试、聚合 | 成本与统计口径 |
| **Agent** | `agents/base.py:34` | `setup()` + `run(instruction, environment, context)` | harness 差异的来源 |
| **Environment** | `environments/base.py:114` | 沙箱抽象：start/exec/upload/download/healthcheck | 隔离与保真度 |
| **Verifier** | `verifier/verifier.py:42` | 跑 `tests/`，解析 reward（单值或多维） | 评测信号的质量命门 |
| **Trajectory** | `models/trajectories/trajectory.py:12` | ATIF v1.7：steps / tool_calls / metrics | 可比性与训练数据 |
| **Metric** | `metrics/base.py`、`models/metric/` | 跨 task 聚合方式（mean 默认，可自定义） | 统计口径即结论 |

---

## 5. 精读方法

**三遍法（每个模块）**
1. **地图遍**（15 min）：只看目录 + `class`/`def` 骨架（`grep -nE '^(class |    async def |    def )'`），画出模块边界。
2. **主线遍**（60–90 min）：跟着一条真实路径走（如一次 trial 的 `run()`），忽略分支。
3. **问题遍**（30 min）：带着 §7 的设计问题找答案，读相关分支与测试。

**五条规则**
- **一个时间盒一个产出**：90 分钟 = 10–15 行笔记 + 1 张图 + 1 个问题；写在 `notes/0X-*.md`。
- **测试当规格**：不确定行为时读 `tests/unit/...`，比读文档可靠（540 个测试文件）。
- **先猜后验**：读代码前先写下「我猜它怎么实现」，再验证；偏差最大的地方就是设计洞见。
- **看演化**：`git log`/`git blame` 需要 `git fetch --unshallow`（浅克隆只有 1 条历史），对关键文件值得做一次。
- **命名陷阱**：仓库里有同名类（`TaskConfig` 在 `models/task/config.py:853` 与 `models/trial/config.py:398` 各一个；`AgentConfig` 也是两处）。**每次先看 import 来源**，否则 debug 时会被 Pydantic 类型搞晕。

**每阶段验收标准（通用）**
- 能不看代码画出该模块的数据流图；
- 能回答该阶段的 3 个设计问题；
- 写出一段「如果我来重写会怎么改」的 3 句话评论；
- 产出笔记文件，且引用的路径/行号通过 `python3 scripts/check_refs.py`。

---

## 6. 主干：十个 Phase

> 路径约定：未加前缀的路径都相对 `repos/harbor/`。`L` 前缀行号已核对（commit `6099b8c`）。

### P0 — 定位与环境（0.5 天）

**必读**

| 位置 | 重点 |
|---|---|
| `README.md`、`pyproject.toml` | 定位、依赖组、`required-version` |
| `docs-mintlify/index.mdx`、`docs-mintlify/core-concepts/index.mdx` | 官方概念框架 |
| `CHANGELOG.md`（前 40 行） | 当前 breaking change 范围 |
| `CONTRIBUTING.md`、`rfcs/`（0001/0002/0003） | 治理规则 + 三个已接受设计 |
| `docs-mintlify/docs.json` | 文档全章节导览 |
| `src/harbor/cli/main.py` | 命令树（`run` 是 `job start` 的别名，L171） |

**设计问题**：为什么 Harbor 把 task 定义成「自包含目录包」而不是 Python API？为什么 CLI 命令按 `task/dataset/job/trial/agent` 组织？

**练习**：跑 `git -C repos/harbor log -1`、统计 `adapters/` 数量（85）、`ls docs-mintlify/**/*.mdx` 数量，填进 `notes/00-orientation.md`。

**验收**：能说出「Task/Trial/Job」三者的边界，以及 Harbor 与 Terminal-Bench、Harbor Hub 的关系。

---

### P1 — 数据模型（1 天）

**为什么先读**：整个框架的合同都在 Pydantic 模型里；`task.toml` 的每个字段在这里有唯一定义。

**必读**

| 位置 | 行数 | 重点符号 |
|---|---|---|
| `models/task/config.py` | 1060 | `NetworkMode`(L40)、`NetworkPolicy`(L70)、`EnvironmentConfig`(L435)、`VerifierConfig`(L580)、`StepConfig`(L812)、`TaskConfig`(L853) |
| `models/task/task.py` / `paths.py` / `verifier_mode.py` | 273/243/143 | `Task`(L34)、`TaskPaths`(L14)、shared/separate 解析 |
| `models/trial/config.py` | 588 | `AgentConfig`(L65)、`TaskConfig`(L398)、`TrialConfig`(L488) |
| `models/trial/result.py` | 169 | `StepResult`(L66)、`TrialResult`(L75) |
| `models/job/config.py` / `result.py` / `lock.py` | 560/298/760 | `JobConfig`(L399)、`JobResult`(L236)、`TaskLock`(L66) |
| `models/trajectories/*.py` | ~1000 | `Trajectory`(L12)、`Step`(L14)、`Metrics`、`FinalMetrics` |
| `models/dataset/manifest.py` | 291 | `DatasetManifest`(L161)、content hash |

**配套**：`docs-mintlify/tasks/configuration.mdx`、`docs-mintlify/datasets/datasets.mdx`、`examples/tasks/hello-world/task.toml`。

**设计问题**
1. 为什么同时存在 `models/task/config.py::TaskConfig` 和 `models/trial/config.py::TaskConfig`？两者职责差在哪？
2. `models/job/lock.py` 760 行在「锁」什么？为什么需要内容哈希 + 下载解析（`TaskDownloadResolution` L39）？
3. 多维 reward（`reward.json`）在模型层如何表达？missing dimension 如何处理？

**练习**：用 `python3 -c` 读 `registry.json`（13.6 MB，流式/`jq` 均可）统计 dataset 数量与任务数；画 `TaskConfig → TrialConfig → JobConfig` 的转换链。

**验收**：能回答「`task.toml` 里哪些字段会改变沙箱行为、哪些会改变打分行为」。

---

### P2 — 任务规格与打包（0.5 天）

**必读**

| 位置 | 重点 |
|---|---|
| `tasks/client.py:63`（667 行） | `TaskClient`、`TaskDownloadResult`、dataset spec 解析 |
| `publisher/packager.py:25` | `Packager.collect_files` / `compute_content_hash`（内容哈希 = 可复现的锚点） |
| `registry/client/*`（base/git_repo/package/json/harbor） | registry 来源类型 |
| `models/package/*`、`models/dataset/manifest.py` | `org/name@version` 引用与 manifest |
| `lint/`（`harbor lint` 实现） | 任务质量规则（比文档更全） |
| `examples/tasks/`：`hello-world`、`hello-multi-step-simple`、`separate-verifier-environment`、`network-policy-matrix`、`reward-hacking` | 五类任务形态 |
| `adapters/aider_polyglot/` | 一个 adapter = uv 包 + `adapter.py` + `parity_experiment.json` + `adapter_metadata.json` |

**配套文档**：`docs-mintlify/tasks/{environment,verifier,solution,artifacts,network-policies,separate-verifier,multi-step,lint}.mdx`；`docs-mintlify/datasets/{create-a-dataset,registries,metrics}.mdx`。

**设计问题**：任务包为什么刻意「不依赖 Harbor」？content hash 覆盖哪些文件、不覆盖哪些（`.harborignore` 的作用）？`lint` 能挡住哪类坏任务、挡不住哪类？

**练习**：给 `hello-world` 加一个多维 reward（`reward.json`：correctness + style），说明 verifier 需要改哪几行。

**验收**：能画出「init → lint → run → publish → registry → download」的生命周期图，并指出每步的产物。

---

### P3 — Trial 执行生命周期 ★ 核心（1.5 天）

**为什么最重要**：2100 行的 `trial/trial.py` 是整个框架最贵的一段代码，理解了它就理解了「评测可复现性」的实际含义。

**必读（按函数顺序读，不要从头到尾）**

| 位置 | 行号 | 重点 |
|---|---|---|
| `trial/trial.py` | L152 `class Trial` | 构造、`add_hook` |
| 同上 | L469 `create()` | 装配环境/agent/verifier |
| 同上 | L532 `_load_task()` | 任务下载与缓存 |
| 同上 | L601 `run()` | 状态机入口（START → prepare → run → finalize） |
| 同上 | L641 `_prepare()` | 环境启动、healthcheck、skills 上传、agent setup |
| 同上 | L700 `_run_agent_phase()` | 网络相位、user-agent bridge、超时、轨迹同步 |
| 同上 | L982 / L1013 / L1084 | shared verifier / separate verifier / 独立 verifier 环境 |
| 同上 | L1313 `_init_agent()`、L1342 `_resolve_load_trajectory()` | agent 初始化与「加载历史轨迹续跑」 |
| `trial/single_step.py` | 全文 110 行 | 单步 trial 的 `_run()` 顺序 |
| `trial/multi_step.py` | L24 起 | 多步 trial 的步间 archive/resume/load |
| `trial/{queue,hooks,errors,network_policy,simulated_user,artifact_handler,regrade,sync_trajectory}.py` | 260/77/17/185/151/458/876/158 | 并发、事件、网络相位、模拟用户、产物、重放 |

**配套文档**：`docs-mintlify/jobs/*`、`tasks/verifier.mdx`、`tasks/multi-step.mdx`、`news/separate-verifier-sandboxes.mdx`、`news/multi-step-tasks.mdx`、`rfcs/0002-simulated-users.md`。

**设计问题**
1. `run()` 里异常被吞掉并记录到 `exception_info`，这对「失败样本进入统计」意味着什么？
2. 网络策略分「基线相位 / agent 相位 / verifier 相位」，为什么需要相位切换（`_phase_network_policy` L451）？
3. `separate verifier` 模式在生产上多花多少成本，换来什么（agent 无法污染 grader）？
4. `regrade.py`（876 行）为什么要重放而不是重跑？重放能保住哪些、保不住哪些？

**练习**：画一张 mermaid 时序图：`env start → upload → agent run → logs → artifacts → verifier → reward → result.json`，标出 6 个 hook 事件（`trial/hooks.py`）与所有超时/取消路径。

**验收**：能在 5 分钟内讲清「一次 trial 从开始到出分」；能回答 agent 超时、verifier 超时、环境构建失败分别留下什么产物。

---

### P4 — Agent 适配层（1 天）

**必读**

| 位置 | 行数 | 重点 |
|---|---|---|
| `agents/base.py` | 487 | `BaseAgent`(L34)：`setup`/`run`/`capabilities`/`preflight`/options |
| `agents/capabilities.py`、`agents/factory.py:61` | 小/328 | 能力声明、按名字/import path 造 agent |
| `agents/installed/base.py` | 1295 | 安装型 CLI agent 的公共管线（安装脚本、环境、日志、trajectory） |
| `agents/installed/claude_code.py` | 2233 | 最完整的生产级 adapter（流式 JSON、auth、skills） |
| `agents/installed/codex.py` | 2115 | 第二套 CLI 协议对照 |
| `agents/protocols/acp.py` + `agents/installed/acp.py` | 1721 | ACP 通用协议（不用为每个 CLI 重写） |
| `agents/agent_auth_resolution.py` | 1275 | 模型凭据/base URL 的解析与路由 |
| `agents/terminus_2/terminus_2.py` | 2191 | 沙箱内 API 型 agent（对照 installed 型） |
| `agents/{oracle,nop}.py` | 小 | 最小 agent 示例，先读这两个 |

**配套文档**：`docs-mintlify/agents/{pre-integrated-agents,custom-agents,atif,agent-auth-resolution,base-url-management,acp}.mdx`；`examples/agents/marker_agent.py`（最小自定义示例）。

**设计问题**：接入一个新 CLI agent 最少要实现什么？为什么 installed agent 的「安装」也必须走沙箱网络策略？模型凭据从 `--model`/环境变量/`--ak` 三层解析，优先级是谁定的（`agent_auth_resolution.py`）？

**练习**：写一份「接入我们自己的 harness」checklist：5 个必须实现的钩子 + 在 `claude_code.py` 里对应的代码位置 + 一个最容易被忽略的细节（如 session id / 错误退出码 / 流式日志）。

**验收**：能解释「installed agent vs API agent」在沙箱内外的执行差异，以及 ACP 协议省掉了什么。

---

### P5 — 轨迹格式 ATIF（1 天）

**必读**

| 位置 | 重点 |
|---|---|
| `rfcs/0001-trajectory-format.md` | 规范本体（先读这个） |
| `rfcs/0001-trajectory-format/`（3 个真实样例：gemini-cli / mini-swe-agent / openhands） | 字段级对照 |
| `models/trajectories/{trajectory,step,content,tool_call,observation,metrics,final_metrics,subagent_trajectory_ref}.py` | Pydantic 实现（`Trajectory` L12、`Step` L14） |
| `trial/sync_trajectory.py` | 原生日志 → ATIF 的同步点 |
| `mappers/`、`packages/harbor-atif2otel/` | 外部格式映射与 OTel 导出 |
| `examples/tasks/hello-load-atif-trajectory-{task,run}-level`、`hello-load-native-trajectory` | 轨迹回灌 |
| `docs-mintlify/agents/atif.mdx`、`jobs/loading-trajectories.mdx` | 官方说明 |

**设计问题**：ATIF 有意丢失了哪些 agent 原生信息？`peak_context_tokens` / `llm_call_count` 这类计量字段为什么重要？「一个 API turn = 一个 step」在 streaming 下如何保证？

**练习**：把三个真实样例做字段对比表（有的字段/缺的字段/可能被伪造的字段）；写 10 行脚本用 `Trajectory` 模型校验样例可解析（需 `uv sync`）。

**验收**：能画「native log → ATIF → OTel/训练数据」的映射图，并指出跨 harness 比较会踩的坑。

---

### P6 — 验证器、RewardKit、Metrics ★ 核心（1 天）

**必读**

| 位置 | 重点 |
|---|---|
| `verifier/verifier.py`（310 行） | `Verifier`(L42)、`verify()`(L198)、`reward.txt/json` 解析（L69/L91） |
| `verifier/{base,factory}.py`、`models/verifier/result.py` | 抽象与结果结构 |
| `packages/rewardkit/src/rewardkit/`：`runner.py`、`isolation.py`、`judges.py`、`criteria/`、`sandbox.py`、`session.py`、`trajectory.py`、`compare.py` | RewardKit 实现 |
| `rfcs/0003-secure-rewardkit-workers.md` | 不可信代码评分的安全边界 |
| `metrics/`（base/factory/mean/sum/min/max/uv_script）、`examples/metrics/mean.py` | 聚合与自定义 metric |
| `examples/tasks/{reward-kit-example,secure-python-worker,reward-hacking,verifier-mode-matrix,llm-judge-example}` | 五个关键案例 |
| `docs-mintlify/rewardkit/*`、`tasks/verifier.mdx`（custom-verifiers） | 官方设计说明 |

**设计问题**：verifier 的威胁模型是什么（agent 能看到 tests 吗？能改 reward 吗？能联网吗？）？LLM judge 的偏差如何被隔离（多 judge ensemble？）？为什么 reward 是「协议」（文件路径）而不是「函数调用」？

**练习**：画出「验证器攻击面」清单：代码执行位置、用户权限、网络、文件可见性、reward 写入路径各 1 行；对照 `secure-python-worker` 说明防护点。

**验收**：能评估一个新 benchmark 的 verifier 是否容易 reward hack；能设计一个多维 reward + 自定义 metric。

---

### P7 — Job 编排、并发与沙箱（1 天）

**必读**

| 位置 | 重点 |
|---|---|
| `job.py`（1345 行） | `Job`(L64)、`create`(L171)、trial 配置构建（L459 standard / L464 diff / L518 regrade）、结果聚合 |
| `job_plan.py`(412)、`job_diff.py`(404) | 任务计划与差分实验 |
| `trial/queue.py:19` | `TrialQueue`：信号量模型与并发上限 |
| `environments/base.py`(1616) | `BaseEnvironment`(L114) 抽象方法：`start`(L1108)/`exec`(L1359)/`upload_dir`(L1134)/`download_dir`(L1154)/`run_healthcheck`(L1560) |
| `environments/docker/docker.py`(1517)、`environments/modal.py`(1700)、`environments/factory.py:232` | 本地 vs 云沙箱两套实现 |
| `telemetry.py`(1011)、`hosted/` | 遥测与托管执行 |
| `examples/configs/` | job 配置形态 |

**配套文档**：`docs-mintlify/jobs/{run-a-job,configs,error-classification,regrade,artifact-collection,handoff}.mdx`、`docs-mintlify/sandboxes/*`。

**设计问题**：并发上限在哪一层生效（job / queue / provider）？重试与幂等如何保证（`models/job/lock.py` 与 trial 目录）？云沙箱与本地 Docker 的语义差异（主机挂载、网络、时钟、日志抓取）？

**练习**：统计超时配置的传播链（JobConfig → TrialConfig → env/agent/verifier），画出 3 个最容易被误解的默认值；对比 docker/modal 对 `BaseEnvironment` 的实现差异（可只读方法签名与关键注释）。

**验收**：能解释「一次 job 为什么慢/为什么贵/为什么有 trial 丢结果」，并给出 3 个调优点。

---

### P8 — 分发、平台与生态（0.5 天）

**必读**：`registry/client/*`、`models/package/*`、`download/`、`upload/`、`publisher/*`、`hub/{client,leaderboards,agent_catalog}.py`、`hosted/`、`storage/`、`db/`、`viewer/`、`apps/viewer/`（扫一眼）、`docs-mintlify/harbor-hub/*`、`hosted-harbor/*`。

**设计问题**：`harbor run -d terminal-bench/terminal-bench@latest` 从字符串到本地任务目录经过哪些层？开源核心与托管服务（Hub）的边界在哪？榜单的可信度靠什么保证（提交 CI + trial 链接）？

**练习**：追踪一条 dataset spec 的完整解析路径；列出「本地目录 / registry / Hub」三种来源的差异表。

**验收**：能画出平台架构图，并指出哪些 part 是商业服务（做研究/内网部署时要知道）。

---

### P9 — 横向对照（0.5 天，依赖并行笔记）

**输入**（已由并行任务产出并由 Lead 抽查，见 `notes/`）：
- `notes/inspect-ai-map.md` — Inspect AI 架构与读法（209 行，路径逐条核对）
- `notes/pier-diff-map.md` — Pier fork 差异分类（159 行，路径逐条核对）

**结论速览（已复核，可直接引用）**

*Pier（4 个卖点的实际含量）*
- `critique run`：**仍然独有**（Harbor 0 命中，1,592 LOC 独立功能）——唯一值得整块读的东西。
- air-gapped CLI agent 安装：**部分上游化**——机制独有（构建期装进镜像 + squid 推理代理），但 Harbor 用任务级相位网络策略解决了同一场景，且 allowlist 更丰富；Pier 反而**拒绝** Harbor 的 `allowlist` 任务。
- ATIF 增强：**部分上游化**——数据模型是 Harbor 逐行 copy（Harbor 已到 v1.8），只有 `peak_context_tokens` / `summarization_count` 两个指标仍独有。
- viewer：**部分上游化**——README 说的「chat 式轨迹查看器」实为 **task-definition chat**，属描述夸大。
- 兼容性硬伤：Pier 基于 `harbor>=0.5.0`（比上游 0.24 落后约 19 个 minor），拒收 Harbor 1.3/1.4 任务字段。

*Inspect AI（可迁移的设计）*
- 五条：协议+注册表替代子类/名字映射；Scorer 与 Metric 分离并带不确定性指标（stderr/ci/bootstrap/pass@k）；log 作为可版本化、可重放的一等产物（retry/rescore/edit）；agent 可组合（`as_solver`/`as_tool`/`handoff`）；limit & approval 作为策略对象。
- Harbor 领先处：34 个沙箱后端（Inspect 仅 2 个内置）、声明式任务包可分发、环境内验证 + 多步部分奖励。
- Harbor 明确缺：token/turn/cost 级 limit、工具调用审批、epoch reducer（√ 统计口径）。

**动作**：抽查两份笔记里的关键结论（各 30 min，Lead 已抽查数字与锚点），对照 §7 的设计问题，产出一页对比：抽象层 / 可复现性 / 可扩展性 / 评测治理 四个维度。

**验收**：能回答「Harbor 缺什么、Inspect 强在哪、Pier 的哪条经验值得反向贡献」，并据此定下自己的研究方向。

---

### P10 — 研究开题（3–5 天）

从 §9 的选题卡选一张，产出：问题陈述 → 相关工作 5 篇 → 最小实验 → 结果 → 2 页 memo（或 workshop 短文骨架）。

---

## 7. 设计问题清单（读代码时始终带着）

| # | 问题 | 去哪找答案 | 我的暂定假设（读完再修正） |
|---|---|---|---|
| 1 | 为什么 task 是目录包而不是 Python API？ | `docs-mintlify/tasks/overview.mdx`、`publisher/packager.py` | 让任务可独立版本化/复用，解耦 runner 与题目 |
| 2 | 为什么 verifier 输出是文件（`reward.txt/json`）而不是进程返回值？ | `verifier/verifier.py:198` | 跨容器/跨进程边界，reward 必须落盘可审计 |
| 3 | 为什么需要 separate verifier 沙箱？ | `trial/trial.py:1013`、`rfcs/0003` | agent 可以改 tests/reward，必须隔离打分侧 |
| 4 | 为什么 2100 行都放在一个 `Trial` 类里？ | `trial/trial.py` 全貌 | 状态机 + 大量可选分支，拆分反而增加跨模块耦合 |
| 5 | 为什么 single/multi step 用继承而不是策略模式？ | `trial/single_step.py`、`multi_step.py` | 生命周期骨架相同、步骤控制差异大 |
| 6 | 为什么 ATIF 定义在 models 而不是各 agent 里？ | `rfcs/0001`、`sync_trajectory.py` | 跨 harness 可比性是核心产品价值 |
| 7 | 为什么 job lock 要 760 行？ | `models/job/lock.py:66` | 可复现需要锁定任务内容哈希与下载解析结果 |
| 8 | 网络策略为什么要按相位切换？ | `trial/network_policy.py`、`tasks/network-policies.mdx` | agent 需要网、verifier 不该有网（防作弊） |
| 9 | 并发控制在 queue 还是 job？ | `trial/queue.py:19`、`job.py` | 全局信号量 + provider 配额双层 |
| 10 | regrade 为什么不重跑而重放？ | `trial/regrade.py`(876 行) | 证据不可复得（模型非确定），只能重放已记录产物 |

---

## 8. 跳过清单（省 60% 时间）

| 不读 | 理由 | 例外 |
|---|---|---|
| `adapters/*` 的 85 个中 83 个 | 结构同构，读 2 个即可 | 读 `aider_polyglot`（最规范）+ 一个 SWE 类（如 `swebench_multilingual`） |
| 48 个已注册 agent（`models/agent/name.py`） | 只有 3 类模式 | `oracle`/`nop`（最小）→ `claude_code`（installed）→ `terminus_2`（API/沙箱内） |
| 34 个沙箱后端中 32 个 | 抽象一致 | `docker` + `modal`（本地/云各一） |
| `apps/viewer/`、`docs/`（Next.js 站） | 纯前端 | 只在需要查 UI 行为时看 |
| `packages/harbor-langsmith` | 产品集成 | 研究 observability 时再看 |
| `registry.json`(13.6 MB) 全文 | 数据文件 | 用 `jq` 统计，别读 |
| `repos/terminal-bench` 全量(981 MB) | 156 个任务，读不完 | 抽 2–3 个 `task.toml` + 对应的 `tests/` 验证脚本 |
| 大部分 `tests/unit/...` | 540 个测试文件 | 只在读某模块时读对应测试（当规格） |

---

## 9. 研究选题卡（P10 备选）

### 卡 A：Verifier 安全与 reward hacking
- **问题**：coding agent 在什么条件下能「伪造通过」？现行防护（隔离沙箱、非特权 worker、LLM judge ensemble）的边界在哪？
- **素材**：`verifier/verifier.py`、`packages/rewardkit/`、`rfcs/0003`、`examples/tasks/{reward-hacking,secure-python-worker,llm-judge-example}`、`harbor-index` 的 reward hacking supervision 流程。
- **最小实验**：在 reward 检查上做 3 类攻击（改测试、伪造日志、利用判分脚本漏洞），统计各防护挡住的比率。
- **产出**：攻击面清单 + 防护矩阵；可写成评测方法论短文/内部规范。
- **风险**：需要能跑沙箱（docker/modal）。

### 卡 B：轨迹客观性与跨 harness 可比性
- **问题**：同一模型在不同 CLI harness 下分数差异，有多少来自 harness 而非模型？ATIF 字段能否区分？
- **素材**：`rfcs/0001` + 3 个真实样例、`sync_trajectory.py`、`models/trajectories/*`、`notes/pier-diff-map.md`（Pier 的 augment 经验）、`hub/agent_catalog.py`。
- **最小实验**：同模型 2–3 个 harness 各跑同一小任务集，比较 token/步数/工具调用模式/成功率的归因。
- **产出**：归因框架 + 数据；研究价值高（业界共识痛点）。
- **风险**：API 成本；需要固定版本与随机种子。

### 卡 C：Benchmark 维护、污染与难度漂移
- **问题**：continuous benchmark（TB 主线）与静态 benchmark 的分数如何可比？80 题蒸馏（6000→80）的筛选是否引入偏差？
- **素材**：`repos/harbor-index`（80 题 + 蒸馏/审计流程文档）、`repos/terminal-bench`（continuous + tagged releases）、`adapters/*/parity_experiment.json`（85 个 benchmark 的 parity 实验）、`job_diff.py`。
- **最小实验**：复现 2 个 adapter 的 parity 实验；统计 parity 报告里的分数偏移分布。
- **产出**：benchmark 治理方法学笔记/清单；可指导自建 benchmark。
- **风险**：parity 实验需要跑大量 trial（成本）；可只做小样本。

### 卡 D：并行调度与评测成本
- **问题**：`n-concurrent` 提高到 500 时，成本/时延/失败率的权衡曲线是什么？哪些失败是基础设施伪失败（会污染指标）？
- **素材**：`trial/queue.py`、`job.py`、`environments/{docker,modal}.py`、`docs-mintlify/jobs/error-classification.mdx`、`telemetry.py`。
- **最小实验**：同一小任务集，2 个并发档 × 2 个 provider，统计 wall-clock/失败分类/伪失败率。
- **产出**：调度参数建议 + 伪失败识别规则（对评测可信度很实用）。
- **风险**：需要云 provider 额度。

### 卡 E：任务合成与 RL 环境
- **问题**：自动合成任务（SWE-gen / seta-env / endless-terminals）的质量与可验证性如何保证？Harbor 作为 RL environment 的接口是否够用？
- **素材**：`repos/harbor-cookbook/harbor_cookbook/{harbor_rl,sky_rl,prime_rl,tinker_rl,gepa}`、`awesome-harbor` 的训练数据集列表、`examples/training`。
- **最小实验**：用 cookbook 的 RL recipe 跑通一次 rollout→训练接口；检查 ATIF 是否足够做 SFT 数据。
- **产出**：RL 环境接口评估 + 最小闭环 demo。
- **风险**：训练资源需求最高；建议只做接口层实验。

---

## 10. 进度追踪

见 [notes/reading-log.md](notes/reading-log.md)。每次读完一个 phase：更新状态、写产出链接、记录当天日期与 commit。

已产出：

| 文件 | 内容 | 状态 |
|---|---|---|
| `notes/00-orientation.md` | P0 定位笔记（架构图 + 版本 + 环境结论） | 已写 |
| `notes/01-models.md` | P1 数据模型笔记（类关系图 + 转换链 + 3 个设计问题答案 + 失败语义表） | ✅ 已写（2026-10-25） |
| `notes/02-task-format.md` | P2 任务包生命周期笔记（格式/内容哈希/3 种来源/lint 17 规则/adapter 范式） | ✅ 已写（2026-10-25） |
| `notes/03-trial-spine.md` | P3 骨架笔记（单步/多步/网络四相位/并发重试/regrade） | ⏳ 部分（骨架完成） |
| `deck/harbor-eval-framework.html` | 由浅入深 HTML 演示（25 页、L1→L5、键盘导航、可打印 PDF） | ✅ 已交付（2026-10-25） |
| `notes/01-models.md` … | P1+ 阶段笔记 | 待写（用 `notes/_template.md`） |
| `notes/inspect-ai-map.md` | Inspect AI 对照地图（teammate） | 待复核 |
| `notes/pier-diff-map.md` | Pier 差异地图（teammate） | 待复核 |

---

## 11. 风险与坑（已知）

1. **文档漂移**：`AGENTS.md` 里写的 `orchestrators/`、`inspect/`、`dataset/` 目录在 `src/harbor/` 下已不存在（实际是 `job.py`、`trial/`、`tasks/`）。**以代码为准**，路线图里的路径均已核对。
2. **同名类陷阱**：`TaskConfig`、`AgentConfig` 各有两处定义，先看 import 来源。
3. **浅克隆无历史**：`git log` 只有 1 条；要读设计演化需 `git fetch --unshallow`（约几百 MB）。
4. **breaking change 频率高**：`CHANGELOG.md` 的 Unreleased 段就有 10+ 条 breaking；笔记必须带 commit。
5. **体积陷阱**：`registry.json` 13.6 MB、terminal-bench 981 MB；用统计/抽样，不要全文读。
6. **环境门槛**：uv 需 ≥0.13.5（当前 0.12.22）、Docker 未装；先用 `oracle` agent 验证任务，再跑真 agent。
7. **文档版本滞后**：`docs-mintlify/agents/atif.mdx:47` 写「current format is ATIF-v1.7」，而 `models/trajectories/trajectory.py:15-26` 已接受 **ATIF-v1.8**（音频）。同类滞后可能出现在别处，以代码为准。
8. **评测伦理/合规**：跑真 agent 需要 API key；对外发布分数前先确认任务许可（adapters 的 README 有 license 说明）与数据污染风险。

---

## 12. 参考入口

- 文档站：https://harborframework.com/docs （对应源码 `docs-mintlify/`）
- Harbor 仓库：https://github.com/harbor-framework/harbor
- Terminal-Bench（continuous）：https://github.com/harbor-framework/terminal-bench 、https://www.tbench.ai
- Harbor Hub 榜单：https://hub.harborframework.com
- Cookbook：https://github.com/harbor-framework/harbor-cookbook
- 生态清单：https://github.com/harbor-framework/awesome-harbor
- Inspect AI：https://github.com/UKGovernmentBEIS/inspect_ai 、https://inspect.aisi.org.uk
- Pier（fork）：https://github.com/datacurve-ai/pier
- 对照材料：TB3.0 发布 https://labs.scale.com/blog/terminal-bench-harder-tasks-for-better-agents ；SWE-bench Pro https://scale.com/blog/swe-bench-pro

---

## 附录：路径约定与自检

- 路线图中未加前缀的路径均相对 `repos/harbor/`；其他仓库用 `repos/<name>/...`。
- 自检：`python3 scripts/check_refs.py` 会校验本文引用的所有 `path:Lnn` 是否存在、行号是否越界。
