Metadata-Version: 2.4
Name: fairlead
Version: 0.11.1
Summary: A composable, auditable evidence and governance kernel for LLM and agent applications.
Keywords: agent,audit,evidence,governance,llm,pydantic-ai
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries
Classifier: Typing :: Typed
Requires-Dist: pydantic>=2.12,<3
Requires-Dist: pydantic-ai-slim[anthropic]==2.36.0 ; extra == 'anthropic'
Requires-Dist: pydantic-ai-slim[google]==2.36.0 ; extra == 'google'
Requires-Dist: pydantic-ai-harness>=0.27,<0.28 ; extra == 'harness'
Requires-Dist: pydantic-ai-slim==2.36.0 ; extra == 'harness'
Requires-Dist: pydantic-ai-slim[openai]==2.36.0 ; extra == 'openai-compatible'
Requires-Dist: pydantic-ai-slim==2.36.0 ; extra == 'pydantic-ai'
Requires-Dist: pydantic-ai-slim[zai]==2.36.0 ; extra == 'zai'
Requires-Python: >=3.12
Project-URL: Changelog, https://github.com/gugia/fairlead/blob/main/CHANGELOG.md
Project-URL: Homepage, https://github.com/gugia/fairlead
Project-URL: Issues, https://github.com/gugia/fairlead/issues
Project-URL: Repository, https://github.com/gugia/fairlead.git
Provides-Extra: anthropic
Provides-Extra: google
Provides-Extra: harness
Provides-Extra: openai-compatible
Provides-Extra: pydantic-ai
Provides-Extra: zai
Description-Content-Type: text/markdown

# Fairlead

Fairlead 是面向 LLM/Agent 应用的中间件中立证据与治理内核。它不重写 Agent loop，也不接管业务；它把
跨项目最容易漂移、最需要追溯的事实固定成小而稳定的契约：模型目标、Prompt/Context revision、逻辑
Run、实际 Attempt、usage、审计快照和安全错误。

当前源码 release train 为 `0.11.1`。公共 PyPI 只发布核心 distribution `fairlead`；两个 reference
package 继续作为源码模板/私有制品。项目仍处于 Alpha：稳定核心遵守加强的兼容政策，experimental 与
reference 能力只有各自声明的证据边界，不代表生产环境资格。

## 为什么存在

Pydantic AI 和 Pydantic AI Harness 已经提供并持续增强 Agent 执行、工具、结构化输出、消息历史、
通用 memory/compaction、预算和步骤持久化。Fairlead 不再把这些能力包装成第二套框架。

三层职责如下：

| 层 | 最终拥有的语义 |
| --- | --- |
| 业务应用 | Prompt 内容、业务输入/输出、权限、工具副作用、事实优先级、评测、保留授权与用户协议 |
| Pydantic AI / Harness | Agent loop、Model/Provider、工具与输出重试、消息历史、通用 memory/compaction、执行预算与 StepPersistence |
| Fairlead | provider-neutral 证据、Run/Attempt reducer、Journal 资格、usage/metering 投影、Probe、审计一致性和安全默认值 |

详见 [当前需求](https://github.com/gugia/fairlead/blob/v0.11.1/docs/product/requirements.md)、
[能力所有权](https://github.com/gugia/fairlead/blob/v0.11.1/docs/product/capability-ownership.md)和
[职责边界 ADR](https://github.com/gugia/fairlead/blob/v0.11.1/docs/architecture/0018-pydantic-ai-harness-and-application-boundaries.md)。历史
`v0.x-scope.md` 只解释对应版本，不再定义当前产品目标。

## 安装

纯核心只依赖 Pydantic：

```bash
uv add fairlead
```

若现有项目需要继续试用 v0.10 已公开的 experimental Pydantic AI adapter：

```bash
uv add "fairlead[pydantic-ai]"
```

若业务要直接组合当前依赖兼容范围内的官方 Harness：

```bash
uv add "fairlead[harness]"
```

这个 extra 只安装经过依赖解析验证的 Harness/Pydantic AI 组合；Fairlead 当前没有 Harness adapter，
业务代码直接使用官方 Harness API，再把需要治理的事实映射到 Fairlead 核心契约。核心最小安装不会安装
Pydantic AI、Harness 或 provider SDK。`fairlead.experimental.pydantic_ai` 是迁移期兼容路径，不是稳定
facade；未来目标是独立 distribution/import `fairlead-pydantic-ai` / `fairlead_pydantic_ai`，但该包尚未
公开发布。

支持 Python 3.12、3.13 和 3.14。上游已验证组合与实际依赖以
[上游支持与资格矩阵](https://github.com/gugia/fairlead/blob/v0.11.1/docs/contracts/upstream-support.md)、
当前 `pyproject.toml`、lock 和 CI 为准，
不能从“能 import”推定完整兼容。

## 稳定窄腰

稳定公共面包括：

- 不可变、拒绝未知字段的 v1 Pydantic contracts；
- `RunJournal`、`ModelRuntime`、`PromptSource`、`EventPublisher`、`LiveEventPublisher` 与
  `PreparedAttempt` 的既有 Protocol；
- `validate_run_creation` / `project_run_event` 权威 reducer；
- `build_run_audit_bundle` / `verify_run_audit_bundle` / `read_run_audit_bundle`；
- `project_run_metering`；
- `fairlead.testing` 的 Journal conformance；
- `fairlead.errors` 的稳定错误类型与 code。

`fairlead` 根包保留 0.10.0 已发布的 70 个便利导出；高级使用建议从 canonical module 导入。每个符号的
成熟度、owner 和未来动作见
[API 成熟度清单](https://github.com/gugia/fairlead/blob/v0.11.1/docs/contracts/api-maturity.md)，兼容政策见
[ADR-0019](https://github.com/gugia/fairlead/blob/v0.11.1/docs/architecture/0019-public-api-maturity-and-compatibility.md)。

```python
from fairlead import ModelCapability, ModelTarget

target = ModelTarget(
    target_key="support-primary",
    revision="2026-08-30.1",
    provider="openai-compatible",
    model_name="example-model",
    declared_capabilities=frozenset({ModelCapability.TEXT, ModelCapability.STRUCTURED_OUTPUT}),
)
```

`ModelTarget` 是声明配置，不是实时健康；一次实测用 `ProbeReport`，一次真实调用最终解析到的
provider/model 用 `ModelAttemptRecord`。三种事实不得互相覆盖。

## 采用方式

Fairlead 可以逐段接入已有 Agent 项目，不要求先替换执行框架：

1. 先把 target、resolved Prompt、业务 Context 和 Schema revision 固定为引用；
2. 在 provider I/O 前创建逻辑 Run，并在实际调用前提交 `attempt.started`；
3. 将已完成响应的 usage 归属到精确 Attempt，保留 unknown outcome；
4. 用公共 reducer、AuditBundle 和 metering 投影验证内部一致性；
5. 只有业务确实需要时，再选择 reference PostgreSQL Result/Artifact/Outbox/HTTP/SSE 片段。

Fairlead Journal、Harness StepPersistence、业务 ResultStore 和 Artifact/MediaStore 保存不同事实。采用时
必须为每一份事实指定 owner、事务边界、恢复语义和保留政策，不能通过双写制造两个权威状态源。

## Context、压缩与预算

`ContextBundle` / receipt 记录业务应用已经授权的来源、排序、选择、裁切、脱敏、摘要和 producer
lineage。Fairlead 不替业务读取正文或决定该丢什么，也不把 Pydantic AI/Harness 的 MessageHistory 和
通用 compaction 复制成第二套消息协议。

模型生成的业务摘要必须是独立 Run/Attempt/Result，再由 child Bundle 引用；通用 history compaction
可以委托上游，但不能冒充同一类业务证据。

以下五个数必须分开：事前业务预算、Context token 估算、框架执行限额、已完成响应的 usage、供应商
请求/账单。Fairlead 的 `CostEstimate` 是带币种和价格目录 revision 的估算证据，不是账单。

## Result 正文生命周期

ResultStore 目前只属于 `reference/postgres-host`，不是核心端口。新 v2 Result 的默认正文政策为保存后
30 天逻辑到期；采用项目可通过已批准的版本化配置选择其他正期限或
`retain_until_explicit_delete`。后者只表示没有计划到期，不表示不可删除或法律意义的永久保存。

逻辑到期后普通读取立即拒绝正文，即使 janitor 尚未物理清理；Result 元数据、hash、size、policy 和
purge receipt 长期保留。`record_body`、`output_body` 与相同 output Artifact body 属于同一保留域并在
同一清理事务处理。0.10.0 已有 v1 行保持 `result-retain-until-explicit-delete-v1` grandfather 语义，
不会被新默认回溯清理。

详见
[Result retention ADR](https://github.com/gugia/fairlead/blob/v0.11.1/docs/architecture/0020-result-body-retention.md)与
[规范性契约](https://github.com/gugia/fairlead/blob/v0.11.1/docs/contracts/result-retention.md)。

## 中间件与 reference

核心不依赖 PostgreSQL、Redis、FastAPI、任务队列或前端框架。推荐拓扑仍可按业务需要组合：

```text
PostgreSQL  Journal / Result / Artifact metadata / Notification / Outbox
Redis       可选、可丢失的实时 hint
HTTP        提交与授权读取
SSE         非权威实时接收，断线后从 PostgreSQL 补读
```

- `reference/postgres-host`：PostgreSQL Journal、Operation、Worker、Result/Artifact、Outbox、HTTP/SSE、
  retention/recovery 和运维接线模板；
- `reference/answer-service`：可审计摘要与问答链模板；
- `fairlead.experimental.providers`：provider-specific doctor 与协议资格资产。

reference 的仓库测试不自动证明目标环境的 fsync、断电恢复、HA、RPO/RTO、容量、真实 IdP、供应商
exactly-once 或业务语义质量。资格结论必须标明环境、版本、时点、预算、实际执行数和 skip。

## Schema 与包资源

v1 JSON Schema 作为包资源随 wheel/sdist 发布：

```python
from importlib import resources

schema_root = resources.files("fairlead").joinpath("schemas", "v1")
run_event_schema = schema_root.joinpath("run-event.schema.json").read_text(encoding="utf-8")
```

Schema 只表达跨语言形状；状态机、时间、usage、幂等和跨字段不变量仍以 Pydantic validator 与公共
reducer 为准。Schema major、包 SemVer、数据库 migration 和 Prompt/Context revision 是不同版本轴。

## 开发与验证

Windows 仓库建议通过 WSL 运行工具，避免 WSL 创建的 `.venv/lib64` 被 Windows Python 误解：

```bash
cd /mnt/d/Projects/fairlead
export UV_LINK_MODE=copy
uv lock --check
uv sync --locked --all-groups
uv run ruff format --check .
uv run ruff check .
uv run mypy
uv run python scripts/export_api_manifest.py --check
uv run python scripts/export_contract_schemas.py --check
uv run pytest
uv build --no-sources
uv run python scripts/verify_distribution.py
```

核心要求 100% statement/branch coverage、McCabe ≤ 8、mypy strict、确定性 Schema/API manifest、历史
0.10.0 fixture backward-read，以及独立 wheel 安装。完整门禁和证据口径见
[质量门禁](https://github.com/gugia/fairlead/blob/v0.11.1/docs/quality/quality-gates.md)。

PostgreSQL/provider live qualification 需要显式隔离环境和预算；未设置条件产生的 skip 不能称为通过。
默认测试不读取 `.env.local`，不发真实模型请求。

## 发布边界

- 公共 PyPI：只包含 `fairlead`；
- 私有/source template：`fairlead-reference-postgres-host`、`fairlead-reference-answer`；
- tag、GitHub Release、quality run、构建候选和 PyPI OIDC 身份必须绑定同一 commit；
- 依赖锁、构建成功和仓库覆盖率不能替代独立安装或目标环境资格。

发布流程见
[PyPI Trusted Publishing runbook](https://github.com/gugia/fairlead/blob/v0.11.1/docs/guides/pypi-trusted-publishing.md)。
变更记录见 [CHANGELOG.md](https://github.com/gugia/fairlead/blob/v0.11.1/CHANGELOG.md)。

## License

[MIT](https://github.com/gugia/fairlead/blob/v0.11.1/LICENSE)
