Metadata-Version: 2.4
Name: aps-kernel
Version: 0.4.0
Summary: Deterministic CP-SAT scheduling kernel, independent schedule validator, and headless CLI — APS standard edition
Author: APS Contributors
License: MIT
Project-URL: Homepage, https://aps.zhinengti.online
Project-URL: Documentation, https://github.com/123aiot/aps/tree/main/docs
Project-URL: Source, https://github.com/123aiot/aps
Project-URL: Changelog, https://github.com/123aiot/aps/blob/main/CHANGELOG.md
Keywords: aps,scheduling,production-planning,cpsat,ortools,finite-capacity,manufacturing,aps-kernel
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Manufacturing
Classifier: Intended Audience :: Science/Research
Classifier: Natural Language :: Chinese (Simplified)
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: License :: OSI Approved :: MIT License
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: ortools>=9.10
Requires-Dist: pydantic>=2.0
Requires-Dist: pyyaml>=6.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: ruff>=0.6; extra == "dev"
Requires-Dist: mypy>=1.10; extra == "dev"
Dynamic: license-file

# aps-kernel — Metis 谋序（APS 标准版）

> **运筹帷幄，谋定后动** —— 同衡·谋序·同枢，智造同频。
> One Truth. One Plan. One Rhythm.

可嵌入的**确定性**排产内核：CP-SAT 求解器、**独立复核器**、
工序-资源适配数据模型、设备槽位与班次日历、headless CLI。

> **标准版 vs 专业版**：本包只含可嵌入内核（无 UI / 无服务 / 无 LLM）。
> 甘特图前端、Web 控制台、AI 编排层（Copilot）、多租户 RLS、审批与 IM 通道
> 属专业版（Docker 镜像 + docker compose）。

🌐 官网：https://aps.zhinengti.online ｜ 家族：Nereus 同衡（数字孪生）· Hermes 同枢（物流调度）

---

## 当前状态

**v0.1.0.dev0 — P0 阶段（骨架 + 数据模型 + 校验 + 演示）**

| 模块 | 状态 |
|---|---|
| 数据模型（6 个核心 dataclass） | ✅ 完成 |
| 输入校验（三项 P0 准则 + 5 类检查） | ✅ 完成 |
| Provenance（快照 hash + 配置/源码/求解器版本） | ✅ 完成 |
| 独立复核器（7 项检查） | ✅ 完成 |
| 演示（20 工单 / 6 槽位 / 2 班制） | ✅ 7/7 通过 |
| 规则引擎（P1） | ⬜ 未开始 |
| CP-SAT 求解（P3） | ⬜ 未开始（当前为贪心，仅证明链路可行） |

**⚠️ 当前排产用贪心实现，只给可行解，`gap=None` 表示未证明最优。**
CP-SAT 求解器是 P3 阶段的工作。

---

## 快速开始

```bash
pip install -e .
python -m aps_kernel.demo      # 完整演示
python -m pytest tests/ -q     # 37 个测试
```

演示输出（实测）：

```
aps-kernel 演示
数据集：20 工单 · 160 道工序 · 4 资源（含 1 台调机技师）· 2 班制工作日

── 输入校验 ─
错误 0 · 警告 0 · 提示 3

── 排产结果 ─
状态        FEASIBLE
makespan    1600 分钟（26.7 小时）
未排        0 道工序

── Provenance ─
  数据快照 sha256:7bcded5ff679
  配置版本 fdb29c7bf7d7
  源码版本 src-20b46ecf6df5
  OR-Tools 9.15.6755
  求解状态 FEASIBLE（gap —）

── 独立复核器（不信任求解器自报时长）──
  ✓ 任务守恒         160 已排 / 0 未排 / 共 160
  ✓ 设备资格         160/160 工序在候选资源内
  ✓ 时长重算         160/160 与输入工时一致
  ✓ 槽位不重叠        6 槽位 · 160 区间 · 0 重叠
  ✓ 工序先后         20 工单 · 0 违序
  ✓ 换型可行         160 工序 · 累计换型 0 分钟
  ✓ 无工序丢失        0 工序既未排也未标记未排
  复核结论    ✅ 7/7 通过
```

---

## 三条不可妥协的建模准则

这三条来自 frePPLe 与 device-aps 的实战教训，已用测试锁定：

### 1. 空适配 ≠ 全设备可用

```python
Operation(resources=())   # ← ERROR，不是"所有设备都能做"
```

Aethon 现状：`RouteStep` 只有单值 `work_center_id`，无法表达 FJSP。
**没有它，求解器只能做单资源分配。**

### 2. 容量是池不是槽位

```python
Resource(slots=(EquipmentSlot("S1", ...), EquipmentSlot("S2", ...)))
# 一台 3 腔注塑机 = 3 个 slot，可同时跑 3 个部分工单
```

若直接把设备当槽位，数据库层的排除约束会错误地限制成"一台设备同时只能跑一个工单"。

### 3. 换型本身要占用资源

```python
Resource(setup_resource="RES-SETUP")   # 调机技师
```

**换模要调机技师，技师不空闲就换不了模。** 这是工业现场最常被漏掉的约束。

---

## 独立复核器

> **校验器不调用求解器，也不信任排程结果自带的加工时间。
> 它使用输入数据重新核对，因此可以发现导出或后处理阶段篡改结果的问题。**
> —— 抄自 rtd `validation.py` 的设计原则

7 项检查：

| 检查 | 内容 |
|---|---|
| 任务守恒 | `scheduled ∪ unscheduled == pending` 且交集为空 |
| 设备资格 | 每个工序的资源必须在其候选集内 |
| **时长重算** | 用输入的 `duration` 重算，不信求解器自报 |
| 槽位不重叠 | 同 slot 区间不重叠（`[)'` 半开，相接不算） |
| 工序先后 | 同一工单内工序不逆序 |
| 换型可行 | 相邻任务的换型有 SetupRule 匹配 |
| 无工序丢失 | 不允许工序"消失" |

### 复核器真的有用：它抓出了两个真实 bug

本项目的第一版演示就抓出了自己的两个 bug：

| Bug | 现象 | 根因 | 修复 |
|---|---|---|---|
| **浮点工时截断** | 6 处 1 分钟重叠 | `int(22.5) = 22` 排程用截断值，复核用真实值 | `Assignment.end_minute` 改向上取整 |
| **多槽位未全遍历** | makespan 2551 → 1580 | 每个资源只取第一个槽位 | 遍历全部 slot |

**如果没有独立复核器，这两个 bug 会一直留到客户现场。**

---

## 确定性的机制（为什么可以信）

抄 cps-twin 的确定性文化：

| 机制 | 本项目实现 |
|---|---|
| 固定时间栅格 | 分钟偏移 `start_minute`，**墙钟不进结果** |
| 具名 RNG | 演示数据用固定 seed，同 seed 同数据 |
| 快照 hash | `data_snapshot_hash = sha256(规范化输入)` |
| 配置版本 | `config_version = sha256(规则配置)` |
| 源码版本 | `code_version`（git commit 或源码 hash） |
| 求解器版本 | `solver_version`（`ortools.__version__`） |

**目标：同一数据快照 + 同一配置版本 → 同一输出。** 解决 cp_sat_demo 自陈的
"同一排程编号重开会得到不同结果"缺陷。

### 求解状态诚实报告

```python
solver_status = "FEASIBLE"    # 找到可行解
gap = None                     # ⚠️ 未证明最优
```

**绝不伪称 OPTIMAL。** 这是与市面黑箱求解器的核心差异。

---

## 行业参数必须标注来源

```python
SetupRule(
    priority=100, from_pattern=".*", to_pattern=".*",
    duration_minutes=35.0,
    source="行业基准：注塑跨族换型 30-60 分钟（symestic 2026）",  # ⚠️ 必填
)
```

校验器会为**未标注来源**的换型规则报 WARNING。

当前已引用的基准值（见 `docs/规则与权重KnowHow来源.md`）：

| 参数 | 值 | 来源 |
|---|---|---|
| 注塑跨族换型 | 30-60 min | symestic（引 ISO 22400） |
| 注塑手工螺栓下限 | 10-20 min | kinghou.net |
| 两班设备利用率 | 36-45% | symestic |
| 单班设备利用率 | 18-22% | symestic |

---

## 项目结构

```
src/aps_kernel/
├── models.py        # 数据模型（6 个核心 dataclass）
├── validator.py     # 输入校验（三项 P0 准则）
├── provenance.py    # 快照 hash + 版本绑定
└── demo.py          # 演示（含独立复核器）
tests/
├── test_models.py      # 模型与校验器测试
└── test_validator.py   # 复核器与确定性测试
docs/
└── aps详细实施计划.md   # P0-P7 阶段计划
```

---

## License

MIT

⚠️ 行业规则库与默认权重表属专业版 —— 见 `docs/aps免费版与专业版功能对比.md`
