# PIKA-CAP PikaPython 能力与配置档规范

## 修改历史

| 版本 | 对应 commit id | 更新日期 | 变更说明 |
| --- | --- | --- | --- |
| v0.1 | `d72a1f52` | 2026-07-21 | 已批准：建立原子 capability、显式依赖图和命名 profile 合同。 |
| v0.2 | `7d4a0b0a` | 2026-07-21 | 已批准：增加最小 stdout `print` 能力及其逐字节回归合同。 |

修改历史只记录规格语义变更，不记录实现进度、阶段基线或一次性证据。

## 正文

## PIKA-CAP PikaPython 能力与配置档规范

## 1. 文档控制

| 字段 | 内容 |
| --- | --- |
| 编号 | PIKA-CAP |
| 短名 | 能力配置档 |
| 层级 | L0 共享规范 |
| 规格状态 | 已生效 |
| 当前生效版本 | v0.2 |
| 实现引用版本 | v0.2 |
| 上级规格 | [PJ2026-05 PikaPython 总规格](PJ2026-05-pikapython.md) |
| 需求规格模板 | [ISO/IEC/IEEE 29148 需求规格模板](../../templates/iso-iec-ieee-29148-requirements-spec-template.md) |

## 2. 目的和范围

### 2.1 目的

本规范为 PikaPython 各内核和执行路线提供统一的能力描述方法：

- 使用稳定、可独立寻址的 capability ID 表达语言和 runtime 能力；
- 使用显式依赖图计算一次构建或字节码产物需要的能力闭包；
- 使用命名 profile 聚合常见产品配置，但不把 profile 建模为线性兼容等级；
- 使用相同能力闭包约束语义测试、资源报告和跨实现比较。

capability 描述对外语义和可裁剪单元，不规定 parser、IR、字节码、对象布局、调用帧或 VM 的内部实现。

### 2.2 范围内

- Python 动态子集及其最小 runtime 语义依赖。
- capability ID、依赖、冲突、裁剪和拒绝语义。
- 命名 profile、定制 profile 和能力清单。
- 编译器、字节码、加载器、测试和资源报告中的能力标识。

### 2.3 范围外

- 用单一数字表示实现成熟度、兼容程度或性能等级。
- 规定某条路线必须实现全部 capability。
- 要求不同 profile 使用不同 VM、字节码或对象模型。
- 用 profile 名称代替 CPython、MicroPython 或 V1 的逐项兼容性测试。
- 自动承诺未在 capability 语义中明确列出的语言行为。

## 3. 术语表

| 术语 | 定义 |
| --- | --- |
| capability | 可独立标识、声明依赖、测试语义和报告资源成本的语言或 runtime 能力。 |
| 依赖闭包 | 从选中 capability 出发递归展开全部必需依赖后得到的完整能力集合。 |
| profile | 有稳定名称和产品意图的 capability 根集合；profile 之间不存在隐含顺序。 |
| 定制 profile | 由产品或应用显式选择 capability 根集合形成的构建配置。 |
| 提供能力清单 | runtime 或固件声明能够执行的完整 capability 集合。 |
| 所需能力清单 | 字节码或其他执行产物声明正确执行所必需的完整 capability 集合。 |
| 能力等价配置 | 所需能力闭包和被测语义一致，并只启用 workload 必需平台模块的配置。 |

“原子”表示 capability 在配置、依赖、测试和报告中可独立寻址，不要求每个 capability 都由单独源码文件或 opcode 实现。

## 4. 初始 capability 目录

下表定义首批稳定 ID。依赖列为空表示该 capability 不依赖其他语言 capability，但仍受平台和资源预算约束。

| capability ID | 语义边界 | 直接依赖 |
| --- | --- | --- |
| `exec.module` | 模块入口、常量装载和顺序执行。 | 无 |
| `value.int` | 有符号整数值及其稳定溢出语义。 | `exec.module` |
| `value.bool` | 布尔值和布尔结果。 | `exec.module` |
| `value.none` | `None` 单例值。 | `exec.module` |
| `value.float` | 浮点值和目标配置声明的浮点语义。 | `exec.module` |
| `value.string` | 字符串构造、比较和基础只读操作。 | `exec.module` |
| `value.bytes` | 字节序列构造、比较和基础只读操作。 | `exec.module` |
| `name.local` | 局部变量绑定和 slot 访问。 | `exec.module` |
| `name.global` | 模块全局名称绑定和访问。 | `exec.module` |
| `op.integer` | 整数算术和比较。 | `value.int` |
| `op.float` | 浮点算术和比较。 | `value.float` |
| `protocol.truth` | 对全部已启用值类型执行真值判断。 | `value.bool` |
| `flow.branch` | 条件分支。 | `protocol.truth` |
| `flow.loop` | `while`、`break` 和 `continue`。 | `flow.branch` |
| `logic.short-circuit` | `and`、`or` 和 `not` 的短路语义。 | `flow.branch` |
| `builtin.print` | 使用默认格式向 stdout 输出一个已启用标量值并追加换行；不包含多参数、`sep` 或 `end`。 | `exec.module` |
| `call.positional` | 位置参数函数、调用、返回和递归。 | `name.local` |
| `call.defaults` | 默认参数绑定。 | `call.positional` |
| `call.keyword` | 关键字参数绑定。 | `call.positional` |
| `call.variadic` | `*args` 和 `**kwargs` 参数绑定。 | `call.positional`、`container.tuple`、`container.dict` |
| `iter.range` | `for`、`range` 和最小内部迭代协议。 | `flow.loop`、`value.int` |
| `container.tuple` | tuple、索引和迭代。 | `exec.module` |
| `container.list` | list、索引、迭代和基础变更。 | `exec.module` |
| `container.dict` | dict、键查找、迭代和基础变更。 | `exec.module` |
| `module.import` | 模块命名空间和 `import`。 | `name.global` |
| `binding.c` | Python 到 C 模块的基础调用。 | `module.import`、`call.positional` |
| `object.attribute` | 属性读取、写入和绑定方法。 | `name.global`、`call.positional` |
| `object.class` | `class`、实例构造、实例字段和基础继承。 | `object.attribute` |
| `exception.basic` | `raise`、`try` 和 `except`。 | `exec.module` |
| `exception.finally` | `finally` 和异常展开清理。 | `exception.basic` |
| `protocol.context` | 基础上下文管理协议。 | `exception.finally`、`object.attribute` |
| `closure.cell` | lambda、闭包和 `nonlocal`。 | `call.positional` |
| `iterator.user` | 用户对象迭代协议。 | `flow.loop`、`object.attribute` |
| `generator.basic` | `yield`、可暂停帧和生成器迭代。 | `iterator.user`、`call.positional` |
| `comprehension.basic` | 基础列表、字典和生成器推导。 | `flow.loop`、`closure.cell`、`container.list`、`container.dict`、`generator.basic` |
| `async.basic` | 目标版本明确承诺的基础异步语法和调度语义。 | `generator.basic`、`exception.basic`、`module.import` |

新增 capability 必须使用新的语义 ID。既有 ID 不得被复用为不兼容语义；删除能力时保留 ID 并标记废弃。

## 5. 依赖与 profile 合同

### 5.1 依赖解析

能力解析必须满足以下条件：

- 输入是命名 profile 或显式 capability 根集合；
- 输出是去重、稳定排序且可序列化的依赖闭包；
- 缺失依赖、未知 ID、循环依赖和显式冲突必须在构建或编译阶段拒绝；
- parser 能识别某个语法节点，不代表对应 capability 已启用；
- 未启用能力必须产生稳定的 unsupported-capability 诊断或等价错误。

依赖闭包约束语义和产物兼容，不要求实现按 capability 拆成运行时分支。

### 5.2 命名 profile

命名 profile 是常见产品配置，不是从低到高的兼容等级。

| profile | 产品意图 |
| --- | --- |
| `compute-min` | 最小整数计算、分支和函数调用。 |
| `control-core` | 小型控制逻辑、循环和短路表达式。 |
| `embedded-app` | 常见嵌入式脚本、容器、模块和 C 扩展。 |
| `dynamic-full` | V2 承诺的广义动态语言能力，不表示 MicroPython 全兼容。 |

profile 根集合如下：

- `compute-min`：
  - `op.integer`；
  - `flow.branch`；
  - `call.positional`。
- `control-core`：
  - `value.none`；
  - `op.integer`；
  - `logic.short-circuit`；
  - `iter.range`；
  - `call.positional`。
- `embedded-app`：
  - `value.none`；
  - `op.integer`；
  - `op.float`；
  - `value.string`；
  - `value.bytes`；
  - `logic.short-circuit`；
  - `container.tuple`；
  - `container.list`；
  - `container.dict`；
  - `iter.range`；
  - `module.import`；
  - `binding.c`；
  - `exception.basic`。
- `dynamic-full`：
  - `embedded-app` 的全部根 capability；
  - `object.class`；
  - `call.defaults`；
  - `call.keyword`；
  - `call.variadic`；
  - `exception.finally`；
  - `protocol.context`；
  - `closure.cell`；
  - `iterator.user`；
  - `generator.basic`；
  - `comprehension.basic`；
  - `async.basic`。

profile 合同如下：

- profile 名称稳定，但可通过规格修订改变其根集合；
- profile 是否包含另一个 profile 只能由展开后的能力集合判断；
- runtime、编译器和加载器不得根据 profile 名称推断未声明能力；
- 产品可以声明定制 profile，但必须记录完整根集合、依赖闭包和资源预算；
- 同名 profile 在不同路线中必须保持语义等价，内部实现可以不同。

`builtin.print` 不默认加入现有命名 profile。
需要脚本输出的产品或测试配置必须：

- 把它作为显式 capability 根；
- 同时选择被输出值类型的 capability。

### 5.3 产物与加载

- 编译产物必须携带 capability schema 版本和所需能力清单；
- runtime 必须携带 capability schema 版本和提供能力清单；
- 仅当所需能力集合是提供能力集合的子集时，加载器才可执行产物；
- 字节码格式版本与 capability schema 版本分别演进，不得互相替代；
- 主机预编译和目标内编译必须使用相同 capability 语义；
- 未知 capability 或语义版本不匹配必须明确拒绝。

### 5.4 实现边界

- V2 默认使用一个共享内核架构实现全部已支持 profile；
- 构建期根据能力闭包移除未启用 opcode、对象、模块、错误路径和只读数据；
- profile 不得默认选择一套完全独立的 VM；
- 只有能力等价的 A/B benchmark 证明存在稳定收益时，才允许为局部热点提供专用实现；
- 局部专用实现必须保持相同 capability 语义、产物校验和错误合同；
- V1、静态加速和后续内核可以独立实现相同 capability，不继承 V2 内部结构。

## 6. 路线应用

- V1：
  - 通过兼容性映射声明已交付行为对应的 capability；
  - 不要求为遵循本规范重写 parser 或 runtime。
- V2：
  - 使用 capability 依赖图驱动前端拒绝、字节码清单、runtime 裁剪和测试选择；
  - 使用一个共享内核作为默认实现，不按 profile 完整重写 VM；
  - 可通过主机侧 V1 parser 适配器引导前端，但不得让 V1 内部类型进入 V2 IR 或目标 runtime。
- 静态加速：
  - 声明接受的 capability 输入范围；
  - 静态约束属于独立合同，不改变 capability 的动态语义；
  - Viper 或其他静态执行结果只用于静态路线对照。

## 7. 验收合同

- 每个 capability 必须有正向语义测试、禁用时的负向测试和依赖缺失测试；
- 每个命名 profile 必须能确定性展开为完整能力闭包；
- 编译器必须拒绝使用未启用 capability 的源码；
- 加载器必须拒绝所需能力不属于 runtime 提供能力的产物；
- 资源报告必须绑定 capability 闭包，并分别披露 Flash、静态 RAM、峰值堆、VM 栈、宿主栈和动态分配；
- 跨 V1、V2 和 MicroPython 的产品比较必须使用能力等价配置；
- profile 名称相同但能力闭包不同的结果不得声明为可比较。
- `builtin.print` 的正向测试：
  - 必须把目标 stdout 与 CPython 对相同受支持值的输出逐字节比较；
  - 输出通道失败必须返回明确错误。

## 8. 过程控制

- capability 和 profile 的目标事实源为 `config/pikapython-capabilities.yaml`；
- SPEC 定义稳定语义和验收合同，owning YAML 定义启用状态、依赖映射、profile 根集合和资源预算；
- V1、V2 和静态路线按各自适用范围引用本规范；
- 当前实现进度、benchmark 数值和一次性差异证据进入 TaskTree、阶段报告或 GitHub issue；
- 改变 capability 语义、依赖或命名 profile 合同时必须先修订本规范。
