Hao Harness — 第三方软件声明
Third-Party Notices
================================================================================

本文件列出 Hao Harness（下称「本项目」）使用或随其分发的第三方软件，
以及各自的许可条款与合规做法。

This file lists the third-party software used by or distributed with
Hao Harness (the "Project"), together with the applicable licenses and
the compliance measures taken.

**若你只是使用终端界面，第 2 节与你无关**——Qt 只在桌面界面（`harness-gui`）
中被使用，而桌面界面是可选扩展。
**If you only use the terminal interface, Section 2 does not apply to you.**
Qt is used solely by the desktop interface (`harness-gui`), which is an
optional extra.


--------------------------------------------------------------------------------
1. 本项目自身的许可 / The Project's own license
--------------------------------------------------------------------------------

    Copyright 2026 The Hao Harness Authors

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        https://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

许可全文见 `LICENSE`。 / See `LICENSE` for the full text.


--------------------------------------------------------------------------------
2. Qt for Python（PySide6 / shiboken6）—— LGPL v3
   Qt for Python (PySide6 / shiboken6) — LGPL v3
--------------------------------------------------------------------------------

### 2.1 适用范围 / Scope

桌面界面（`harness-gui`，安装形态为可选扩展 `hao-harness[gui]`）依赖
**Qt for Python**。它由 **The Qt Company** 开发，著作权归其所有。

The desktop interface depends on **Qt for Python**, developed and owned by
**The Qt Company**.

| 组件 / Component | 版本 / Version | 许可（取自包元数据）/ License (from package metadata) |
|---|---|---|
| `PySide6-Essentials` | 6.12.0 | `LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only` |
| `shiboken6` | 6.12.0 | `LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only` |

**本项目选取 `LGPL-3.0-only`。** 本项目自身为 Apache-2.0，与 LGPL v3 兼容。

**The Project selects `LGPL-3.0-only`.** The Project itself is Apache-2.0,
which is compatible with LGPL v3.


### 2.2 我们如何满足 LGPL v3 的要求 / How the Project satisfies LGPL v3

LGPL v3 第 4 条允许以「组合作品」（Combined Work）形式分发，但须满足以下条件。
逐条对应如下：

LGPL v3 Section 4 permits distribution of a Combined Work provided the
following conditions are met. Each condition is addressed below.

| LGPL v3 的要求 / Requirement | 本项目的做法 / What the Project does |
|---|---|
| **显著声明**该库被使用且受 LGPL 覆盖<br/>**Prominent notice** that the library is used and is covered by the LGPL | 即本节。本文件随源码仓库与桌面分发产物一并提供。<br/>This section. This file ships with the source repository and with the desktop distribution. |
| **随程序提供许可副本**（LGPL v3 §4(b)）<br/>**Give a copy of the license** (LGPL v3 §4(b)) | `third_party/LGPL-3.0.txt` 与 `third_party/GPL-3.0.txt`（LGPL v3 以 GPL v3 为基础，故两者均需提供），并**随源码仓库、wheel 与桌面产物三处分发**。<br/>`third_party/LGPL-3.0.txt` and `third_party/GPL-3.0.txt` (LGPL v3 builds on GPL v3, so both are required), shipped in all three forms: source repo, wheel, and desktop artifact. |
| **允许用户替换该库**——这是 LGPL 的核心目的，也是使用 LGPL 而非 GPL 的全部意义<br/>**Permit the user to replace the library** — the core purpose of the LGPL | 本项目**动态链接** Qt、**未修改** Qt 的任何源码，也不禁止替换：<br/>• pip 安装：`pip install --upgrade PySide6-Essentials`，或在虚拟环境中替换对应共享库；<br/>• 打包安装：所有 Qt 共享库直接位于程序目录内，用户可用自己构建的版本覆盖。<br/>The Project **dynamically links** Qt, **modifies no Qt source**, and does not prohibit replacement: <br/>• pip install: `pip install --upgrade PySide6-Essentials`, or replace the shared libraries in your environment;<br/>• packaged install: all Qt shared libraries sit directly inside the application directory and may be overwritten with builds of your own. |
| **提供对应源码**（LGPL v3 §4(d)(0)）<br/>**Provide the Corresponding Source** | 见 §2.4。本项目**不分发** Qt 源码，只指向官方来源。<br/>See §2.4. The Project does **not** redistribute Qt source; it points to the official sources only. |
| **不得限制为调试而修改/逆向该库**<br/>**No restriction on modifying/reverse-engineering the library for debugging** | 本项目的许可未施加任何此类限制；Apache-2.0 亦不含此类条款。<br/>The Project's license imposes no such restriction; neither does Apache-2.0. |

> **为什么许可副本由本项目提供，而不是随 Qt 而来**
> 我们核对过 `PySide6-Essentials` 的 wheel：其 `dist-info/licenses/` 下**只有**
> `LicenseRef-Qt-Commercial.txt`（470 字节，商业许可的引用说明），
> **并不包含 LGPL/GPL 全文**。因此「Qt 自己会带」这一假设不成立——许可副本必须
> 由分发方提供，也就是本项目。
>
> **Why the Project provides the license copy rather than Qt**
> We inspected the `PySide6-Essentials` wheel: its `dist-info/licenses/` contains
> **only** `LicenseRef-Qt-Commercial.txt` (470 bytes, a commercial-license
> reference) and **no LGPL/GPL text**. The assumption that "Qt ships it" does not
> hold — the distributor must supply it, i.e. this Project.


### 2.3 许可全文 / Full license texts

随本仓库提供： / Bundled in this repository:

    third_party/LGPL-3.0.txt     GNU Lesser General Public License v3
    third_party/GPL-3.0.txt      GNU General Public License v3

官方地址（如上述文件缺失，可从此处取得）： /
Official locations (if the files above are missing):

    https://www.gnu.org/licenses/lgpl-3.0.txt
    https://www.gnu.org/licenses/gpl-3.0.txt


### 2.4 源码获取途径 / Obtaining the source

本项目分发的是**未修改的** Qt for Python。其源码可通过以下官方途径取得：

The Project distributes **unmodified** Qt for Python. Its source is available
from the following official locations:

| 内容 / What | 地址 / Where |
|---|---|
| Qt 框架源码 / Qt framework source | https://download.qt.io/official_releases/qt/  ·  https://code.qt.io/ |
| PySide6（Qt for Python）源码 / PySide6 source | https://code.qt.io/cgit/pyside/pyside-setup.git/ |
| 与所用版本对应的 sdist / sdist matching the version used | PyPI 上的 `PySide6-Essentials` 源码包 / the `PySide6-Essentials` source distribution on PyPI |
| Qt 的许可与条款 / Qt licensing | https://www.qt.io/licensing/ |

如需本项目所打包的具体 Qt 版本对应的源码，请通过第 6 节的方式联系。

To request the source corresponding to the exact Qt build bundled by the
Project, use the contact route in Section 6.


--------------------------------------------------------------------------------
3. 运行时依赖 / Runtime dependencies
--------------------------------------------------------------------------------

下表由 `packaging/dependency_licenses.py` 从各包的元数据生成
（**已按当前环境求值环境标记、并排除可选 extra**），可随时重算：

    python packaging/dependency_licenses.py --markdown

The table below is generated by `packaging/dependency_licenses.py` from the
packages' own metadata (with environment markers evaluated for the current
environment and optional extras excluded). It can be regenerated at any time.

**表内取值一律照抄元数据，不做人工「修正」。** 元数据本身可能不够精确
（例如 `pyinstaller` 只写 GPLv2，未体现其特别例外，见第 4 节），此时**以各包自带
的 LICENSE 文件为准**——与其由我们猜一个更漂亮的说法，不如让读者清楚该去核对什么。

**Values are copied verbatim from package metadata, never "corrected" by hand.**
Metadata can be imprecise; in that case **each package's own LICENSE file is
authoritative**.

> **版本以「用于构建分发产物的环境」为准，不是开发机上的环境。**
> 两者会不一致——实测中开发机的 `pydantic` 是 2.12.5，而干净虚拟环境解析出
> 2.14.0。合规文档描述的必须是**实际分发出去的东西**，因此下表取自构建环境。
>
> 环境标识 / Environment:
> `Windows 10 (AMD64)` · `Python 3.14.3` · 干净虚拟环境 · 生成日期 2026-10-10
>
> **Versions reflect the environment used to build the distributed artifact,
> not the developer's machine.** The two do differ — measured: 2.12.5 vs 2.14.0
> for `pydantic`. A compliance document must describe what actually ships.

### 3.1 终端界面 / Terminal interface

| 组件 / Component | 版本 / Version | 许可 / License |
|---|---|---|
| `Pygments` | 2.21.0 | BSD-2-Clause |
| `annotated-types` | 0.8.0 | MIT |
| `anyio` | 4.15.1 | MIT |
| `certifi` | 2026.7.22 | MPL-2.0 |
| `h11` | 0.16.0 | MIT |
| `httpcore` | 1.0.9 | BSD-3-Clause |
| `httpcore2` | 2.13.1 | BSD-3-Clause |
| `httpx` | 0.28.1 | BSD-3-Clause |
| `httpx2` | 2.13.1 | BSD-3-Clause |
| `idna` | 3.20 | BSD-3-Clause |
| `jiter` | 0.17.0 | MIT |
| `markdown-it-py` | 4.2.0 | MIT License |
| `mdurl` | 0.1.2 | MIT License |
| `openai` | 3.26.1 | Apache-2.0 |
| `pydantic` | 2.14.0 | MIT |
| `pydantic_core` | 2.50.0 | MIT |
| `rich` | 15.0.0 | MIT |
| `sniffio` | 1.3.1 | MIT OR Apache-2.0 |
| `truststore` | 0.10.4 | MIT |
| `typing-inspection` | 0.4.4 | MIT |
| `typing_extensions` | 4.16.0 | PSF-2.0 |

### 3.2 桌面界面额外依赖 / Additional dependencies for the desktop interface

| 组件 / Component | 版本 / Version | 许可 / License |
|---|---|---|
| `PySide6-Essentials` | 6.12.0 | **LGPL-3.0-only**（见第 2 节 / see Section 2） |
| `shiboken6` | 6.12.0 | **LGPL-3.0-only**（见第 2 节 / see Section 2） |


--------------------------------------------------------------------------------
4. 构建工具 / Build tools
--------------------------------------------------------------------------------

仅用于**构建**可分发的可执行文件，不是运行期依赖。但 PyInstaller 的引导程序
（bootloader）会被**嵌入产出的可执行文件**，因此必须声明。

These are used at **build** time only and are not runtime dependencies. However,
PyInstaller's bootloader is **embedded into the produced executable**, so it
must be declared.

| 组件 / Component | 版本 / Version | 许可 / License |
|---|---|---|
| `altgraph` | 0.17.5 | MIT |
| `packaging` | 26.3 | Apache-2.0 OR BSD-2-Clause |
| `pefile` | 2024.8.26 | MIT |
| `pyinstaller` | 6.22.3 | GNU General Public License v2 (GPLv2) |
| `pyinstaller-hooks-contrib` | 2026.8 | Apache Software License / GNU General Public License v2 (GPLv2) |
| `pywin32-ctypes` | 0.2.3 | BSD-3-Clause |
| `setuptools` | 84.0.0 | MIT |

> **对 `pyinstaller` 一行的人工补充**：其元数据只写「GPLv2」，**未体现附带的特别
> 例外**，而那条例外恰恰是本项目能合法分发打包产物的依据。故单列于此。
>
> **Manual addition for the `pyinstaller` row**: its metadata says only "GPLv2"
> and **does not reflect the bundled special exception**, which is precisely what
> lets this Project distribute the packaged artifact. Hence the note below.

**PyInstaller 的例外条款为何重要**：PyInstaller 本身是 GPL，但它附带一项例外，
明确允许把**被打包的程序**以任意许可分发——否则任何用 PyInstaller 打包的非 GPL
程序都会违反 GPL。本项目正是依赖该例外，因此产出的可执行文件仍为 Apache-2.0。
详见 PyInstaller 的 `COPYING.txt`。

**Why PyInstaller's exception matters**: PyInstaller itself is GPL, but it ships
an exception that explicitly permits distributing the **bundled application**
under any license — without it, every non-GPL program packaged with PyInstaller
would violate the GPL. This Project relies on that exception, so the resulting
executables remain Apache-2.0. See PyInstaller's `COPYING.txt`.


--------------------------------------------------------------------------------
5. 已知限制 / Known limitations
--------------------------------------------------------------------------------

诚实地说明当前的合规边界 / Stated honestly:

- **第 3、4 节各包的许可文本已随可执行产物分发**，位于
  `third_party/packages/<包名>/`。构建时由 `packaging/collect_third_party_licenses.py`
  从**构建环境现场收集**，实测收集到 **27 个文件、覆盖全部 23 个运行时依赖、
  0 个缺失**。
- **Qt 的许可全文由本项目提供**（见 §2.3）——因为 LGPL 明确要求如此，而 Qt 的
  wheel 并不附带（见 §2.2 的说明）。
- **终端形态的产物不包含 Qt 的许可全文**（`third_party/LGPL-3.0.txt` /
  `GPL-3.0.txt`）：那个产物里完全没有 Qt，带上只会让用户以为其中有 Qt 组件。
  各运行时依赖的许可文本**同样会随终端产物分发**。

> **一处此前写错、现已更正的结论。** 早先本文档写着「其余包**既无元数据也无许可
> 文本**」。这个说法是错的——**包里有，是 PyInstaller 没收集**：它只为极少数包
> （实测 23 个里只有 3 个）搬运 `dist-info`。实测每个运行时依赖都自带至少一个许可
> 文件，0 个缺失。**错误的根因会导向错误的解法**：按原来的说法，结论会是「这些包
> 拿不到许可，没有办法」；而真实情况是「我们自己收一遍就好」。

- **The license texts of the packages in Sections 3 and 4 are distributed with
  the executable artifacts**, under `third_party/packages/<name>/`. They are
  collected at build time from the build environment by
  `packaging/collect_third_party_licenses.py` — measured: **27 files covering all
  23 runtime dependencies, 0 missing**.
- **Qt's license texts are provided by the Project** (see §2.3) — the LGPL
  explicitly requires it, and Qt's wheels omit them (see §2.2).
- **The terminal artifact does not carry Qt's license texts** — there is no Qt
  in it at all. Its runtime dependencies' license texts *are* included.

> **A conclusion stated here earlier was wrong and is now corrected.** It said
> the remaining packages ship "neither metadata nor license text". The truth is
> that **the packages do ship them; PyInstaller simply does not collect them**
> (only 3 of 23 distributions had their `dist-info` carried over). Every runtime
> dependency ships at least one license file, 0 missing. **A wrong root cause
> leads to a wrong remedy**: the old wording implied "nothing can be done",
> while the real situation was "we just have to collect them ourselves".


--------------------------------------------------------------------------------
6. 联系方式 / Contact
--------------------------------------------------------------------------------

本项目的源码仓库 / Source repository:

    https://gitee.com/ma_zhenhao/make_harness

许可与合规问题请通过该仓库的 Issue 提出。
For licensing or compliance questions, please open an issue in that repository.
