# PJ2026-01050205 SuperAPI

## 修改历史

| 版本 | 对应 commit id | 更新日期 | 变更说明 |
| --- | --- | --- | --- |

当前正文仍在规格治理草稿中；未定稿前不新增版本号，不为单次编辑追加 `待提交` 版本。

## 正文

## PJ2026-01050205 SuperAPI 需求规格

## 1. 文档控制

| 字段 | 内容 |
| --- | --- |
| 编号 | PJ2026-01050205 |
| 短名 | SuperAPI |
| 层级 | L3 子课题 |
| 状态 | 已生效 |
| 上级规格 | [PJ2026-010502 APIKey](PJ2026-010502-api-key.md) |
| 关联规格 | [PJ2026-010204 后端Profile](PJ2026-010204-backend-profile.md)、[PJ2026-010604 公开入口](PJ2026-010604-public-entry.md) |
| 规格治理索引 | [规格治理](spec-governance.md) |

## 2. 目的和范围

### 2.1 目的

SuperAPI 负责把企业 skill 的 `name` 和 `description`
绑定到指定下游 API Key，并在请求进入 Codex-compatible 上游前追加到
Agent instructions。SuperAPI 同时提供公开的文档型 Remote Skill registry，
使 Agent 可以按标准 `SKILL.md` 入口获取完整说明和 references 文档。

本规格中的 SuperAPI 是面向 LLM 请求的上游加载与管理服务，不是
[PJ2026-010104 AI网关](PJ2026-010104-ai-gateway.md) 定义的硬件节点执行网关。

### 2.2 范围内

- 每个 API Key 独立绑定零个或多个虚拟 skill 摘要。
- 每条 API Key 与 skill 绑定可以独立选择是否强制注入完整 `SKILL.md`。
- 在 Responses 请求中保留原 instructions 并追加匹配 Key 的 catalog。
- 支持流式与同步 Responses 请求的透明透传。
- API Key、Authorization 和上游响应的脱敏日志与健康状态。
- skill、API Key、绑定关系和请求历史的管理 API 与多页面 Web。
- 通过统一登录页使用 PK01 Sub2API 用户身份，并按所属 API Key 隔离管理资源。
- 通过单个 `SKILL.md`、目录或 ZIP 导入文档型 Remote Skill。
- 自动识别或补齐 `SKILL.md` 的 YAML frontmatter。
- 公开分发 `SKILL.md` 与 references 文档，并提供三平台一次性读取命令。
- native PostgreSQL 持久化、Temporal worker 和网关只读快照。

### 2.3 范围外

- 不执行、安装或代理运行 Remote Skill 中的脚本。
- 不接受包含符号链接、路径穿越、多个不明确 Skill 根或超出容量上限的 bundle。
- 不把虚拟 skill 注册为 Codex 客户端本地 skill，也不承诺出现在 `/skills`。
- 不替代公司内网资源的认证、版本管理和访问控制。
- 不修改模型输出、工具执行结果或上游计费语义。

## 3. 系统边界

| 边界项 | 内容 |
| --- | --- |
| 外部输入 | Bearer API Key、Responses 请求、按 Key catalog 配置。 |
| 受控资源 | API Key 指纹、skill name/description、绑定关系、instructions 注入器、上游路由、请求历史和网关只读快照。 |
| 外部输出 | 原样上游响应、注入摘要、脱敏管理视图、健康和错误状态。 |
| 系统边界 | SuperAPI 只做鉴权匹配、catalog 管理与追加、脱敏捕获和透明代理；Sub2API 继续拥有账号池、调度、计费和上游错误语义。 |

## 4. 原子需求

### 4.1 USER-KEY-SKILL-REQ-001 按 Key 绑定

加载器应通过 YAML 声明 API Key 的 `sourceRef`、`sourceKey` 和虚拟 skill
列表。完整 Key 只能在进程内用于恒定时间匹配和上游转发，不得写入 YAML、
日志、状态文件、错误响应或测试报告。

### 4.2 USER-KEY-SKILL-REQ-002 Instructions 追加

加载器应在 `/v1/responses` 与 `/v1/responses/compact` 请求中，把匹配
Key 的 catalog 追加到现有字符串 instructions；现有 instructions 必须保留。
未匹配 Key、非 JSON 请求或不支持的 instructions 形状必须返回明确错误，
不得静默绕过注入。

catalog 注入格式应保持稳定、简短，并只包含 `name + description`。

### 4.3 USER-KEY-SKILL-REQ-003 透明透传

除 instructions 注入外，请求方法、路径、查询参数、Authorization、流式语义、
上游状态码、响应头和响应体应保持透明。加载器不得把上游失败包装成成功，
也不得实现 Sub2API 调度、重试、切号或计费。

公开入口应同时接受 owning YAML 声明的规范 `/v1/*` 路径和无版本前缀别名。
别名必须在 Gateway 内规范化到同一上游路径，并复用相同的鉴权、注入、捕获和
透明透传逻辑。

### 4.4 USER-KEY-SKILL-REQ-004 YAML-first 与开发等级

上游地址、native bind/probe、固定端口、公开域名、Caddy upstream、Key
SecretRef 和 catalog 必须来自 owning YAML。L0 直接验证配置解析、Key 匹配和
instructions 注入函数；L1 通过项目 CLI 管理 native 服务，并使用真实 Codex
Responses 请求验证公开入口到上游的完整链路。

### 4.5 USER-KEY-SKILL-REQ-005 可观测性

健康和 CLI 状态应披露配置摘要、skill 数量、匹配 profile、请求计数、注入计数、
上游状态和最近错误摘要，但不得披露完整 API Key、Authorization 或 description
全文。每个代理请求应保留或生成可关联的 request id。

### 4.6 USER-KEY-SKILL-REQ-006 YAML 功能开关

owning YAML 应分别声明 skill 注入和诊断请求捕获是否启用。skill 注入关闭时，
加载器不得解析或修改 Responses body，并应保持透明透传；诊断捕获关闭时，
不得生成捕获文件。健康状态和 CLI 配置摘要应披露两个开关的布尔状态，但不得
披露 Secret 值。

### 4.7 USER-KEY-SKILL-REQ-007 全量请求与响应捕获

诊断捕获在 owning YAML 显式启用时，应自动覆盖所有已通过 Key 鉴权且进入允许
上游路径的请求，不要求客户端增加 capture id、header、环境变量或专用配置。
请求和响应必须分别写入独立目录，并按 UTC 日期和小时粒度生成日期目录。落盘
格式必须为 JSONL，文件和目录只允许 owner 访问。

请求记录应同时保留入口请求和注入后的上游请求；响应记录应保留实际返回客户端
的状态、headers 和完整同步或流式 body。Authorization、Cookie、API Key 和
已声明 Secret 值不得落盘。捕获失败不得改变上游状态或阻塞客户端响应，并必须
进入健康指标和 CLI 状态。

查询必须支持显式指定 IANA 时区，并把 UTC `capturedAt` 转换为该时区后展示；
默认查询时区、默认条数和最大条数必须来自 owning YAML。默认列表只披露摘要和
源文件，不展开完整 body；完整 JSONL 继续保留在文件系统中。

### 4.8 USER-KEY-SKILL-REQ-008 容量硬上限

请求与响应捕获共享 owning YAML 声明的总磁盘上限。每次写入前必须计算当前
捕获占用并删除最旧 JSONL 文件，确保写入后总量不超过上限；单条记录大于上限
时应拒绝该条捕获并记录错误，不得影响客户请求。CLI 应披露上限、实际字节数、
文件数、最旧与最新文件、请求与响应目录，但不得展开捕获内容。

### 4.9 USER-KEY-SKILL-REQ-009 管理数据模型

SuperAPI 应使用 owning YAML 引用的 native PostgreSQL 保存以下实体：

- skill：
  - 唯一名称；
  - description；
  - 创建与更新时间。
- API Key：
  - 稳定标识；
  - 用户别名；
  - 不可逆匹配指纹；
  - 脱敏展示值；
  - 创建与更新时间。
- skill 绑定：
  - API Key 与 skill 的唯一关系；
  - 独立启用开关；
  - 默认关闭的完整 `SKILL.md` 强制注入开关；
  - 创建与更新时间。
- 请求历史：
  - request id；
  - API Key 标识；
  - 路径、状态、时间和摘要；
  - 已脱敏的 request 与 response JSON。

API Key 明文只允许在注册请求和 gateway 进程内存中短暂存在。注册完成后，
PostgreSQL、API 响应、Web、CLI、日志、Temporal payload、workflow history 和
网关快照均不得保存或返回明文。已注册 Key 不提供复制或恢复入口。

### 4.10 USER-KEY-SKILL-REQ-010 管理 API 与 Web

SuperAPI 应提供左侧根导航和多页面管理工作区：

- skill 管理：
  - 列表；
  - 创建；
  - 编辑；
  - 删除。
- API Key 管理：
  - 注册 Key 并设置别名；
  - 列表只显示别名和脱敏值；
  - 点击列表行打开绑定对话框；
  - 通过下拉菜单添加 skill；
  - 对每条绑定独立启用或停用；
  - 对每条绑定独立启用或停用完整 `SKILL.md` 强制注入；
  - 删除绑定。
- 请求历史：
  - 主筛选按时间、用户、API Key、路径和状态筛选；
  - 用户、API Key、路径和状态使用完整可见的下拉选项，禁止因控件宽度不足截断当前值；
  - request id 收入默认折叠的高级查询，不占用主筛选区；
  - 高级查询支持通过本地日期时间控件指定任意起止时间；
  - 默认查询最近 2 小时并每页展示 20 条；
  - 时间预设至少包含最近 10 分钟、30 分钟、2 小时、8 小时和 24 小时；
  - 使用服务端稳定游标分页，筛选变化后回到第一页；
  - 每行展示最后一条用户消息的有界摘要，便于在打开详情前辨识请求目的；
  - 每行展示最终 Assistant 回复的有界摘要；
  - 没有 Assistant message 时，使用最后一个非空 reasoning summary 作为回复摘要；
  - Assistant message 存在时不得被 reasoning summary 覆盖；
  - 每行把实际发生的工具调用名称去重后展示为 Tag；
  - 工具定义不得被误判为实际工具调用；
  - 通过稳定 id 打开详情；
  - 详情通过同一个模式控件同步切换 request 与 response；
  - Raw 模式分别显示脱敏后的原始 request 与 response；
  - 分块模式解析 system prompt、user prompt、skill、tool、最终响应、错误和用量；
  - system、developer、user 条目应保留原始顺序，并在卡片表层显示原始 `type`；
  - `message`、`additional_tools` 等不同类型不得仅因角色相同而被误判为同一种 Prompt；
  - 条目内容确实为空时保留该条目，摘要保持空白，不显示虚构的“空内容”；
  - Tools 同时解析顶层 `tools` 和 `input[].type=additional_tools` 内的工具；
  - `type=namespace` 独立投影到 MCP/Namespaces，并展开其嵌套工具；
  - reasoning、tool call、tool output、assistant message 等其余 input 条目投影到 Input Items；
  - Tools、MCP/Namespaces 和 Input Items 即使为空也保留卡片并显示 `0 项`；
  - 每个 skill 与 tool 独占一行摘要，并可展开查看完整脱敏字段。

Web 不得实现第二套业务逻辑。管理 API、默认本地 CLI 和显式 `--over-api` CLI
必须复用相同 contracts、repository port、application dispatcher、DTO 和错误语义。

### 4.11 USER-KEY-SKILL-REQ-011 进程与 Temporal 边界

SuperAPI 的 native 和部署态运行面均应把以下组件拆为独立进程：

- `gateway`：
  - 只负责 API Key 匹配；
  - instructions 注入；
  - 请求与响应捕获；
  - 上游透明透传。
- `api`：
  - 只负责 HTTP envelope；
  - 管理入口鉴权；
  - 状态码；
  - correlation；
  - dispatcher 调用。
- `worker`：
  - 消费 SuperAPI 专属 Temporal task queue；
  - 执行绑定快照生成；
  - 执行捕获历史导入。
- `web`：
  - 提供管理页面；
  - 只调用同源管理 API。

API 与 worker 必须独立启动、停止、观察和恢复。gateway 不得与 API 或 worker
共享进程，也不得把 PostgreSQL、Temporal、API 或 worker 的可用性作为已有
请求透传的前置条件。worker 应把启用绑定生成不含 Key 明文的只读快照并原子
发布；gateway 只加载完整有效快照，刷新失败时继续使用最后有效版本。

### 4.12 USER-KEY-SKILL-REQ-012 请求历史投影

gateway 捕获记录应包含稳定 request id，使同一请求和响应可以在管理读模型中
关联。worker 应以幂等方式把已脱敏 JSONL 导入 PostgreSQL；重复扫描不得产生
重复历史。流式响应只有在完整捕获完成后才进入 response 详情。

历史默认查询只返回有界摘要和分页游标。详情查询必须按稳定 history id 或
request id 精确读取；禁止默认展开全量 body、扫描全部历史或把原始未脱敏内容
返回 Web。

历史分页游标必须同时包含排序时间和 request id，保证同一时间戳的记录跨页时
不重不漏。默认窗口、可选窗口、页大小和慢查询判定阈值必须由 owning YAML
声明。L0 与 L1 均应报告历史列表查询耗时；达到慢查询阈值时，应先检查查询计划
并优化索引或查询边界，再进入下一等级。

请求详情的 Skills 投影必须同时识别 SuperAPI 注入的 Company Skills、强制启用
文档和 Codex 原生 `skills_instructions` / `Available skills` 清单。技能按规范化
名称合并为一行，重复注入或在多个提示段重复出现时不得重复展示；合并后必须保留
全部来源、原生 skill 位置、公开文档 URL 和强制启用状态，便于判断技能究竟来自
SuperAPI 还是 Codex 原生运行面。Company Skills 解析只能移除对应目录区块，不得
吞掉其后的 system/developer prompt。L0 应覆盖重复目录和原生技能混合输入，
L1 应使用真实 Codex 历史回归，并分别披露解析耗时。

### 4.13 USER-KEY-SKILL-REQ-013 YAML-first L0-L3

owning YAML 应声明：

- PostgreSQL configRef 与 Secret sourceRef；
- Temporal serviceRef、namespace、task queue、超时和重试；
- gateway、API、worker 与 Web 的 native entrypoint、固定端口、PID、日志、状态目录、停止等待上限和启动就绪等待上限；
- 管理 API 的同源路径；
- L1、L2 和 L3 各自独立的固定 HTTPS origin；
- L2 与 L3 各自独立的 namespace、Service、Deployment、SecretRef、
  PostgreSQL 连接、Temporal task queue 和运行时状态目录；
- L2 master 分支与 L3 release 分支的自动交付关系；
- gateway 快照路径与刷新策略；
- CLI 默认 local target 和 `--over-api` target。

交付和回归顺序覆盖 L0-L3：

1. L0 直接调用 repository、dispatcher、快照构建和历史导入函数；
2. L0 使用 native PostgreSQL 完成 skill、API Key、绑定和历史查询闭环；
3. L1 通过项目 CLI 独立启动 worker、API、Web 和 gateway；
4. L1 用同一 CLI 的 `--over-api` 重复管理操作；
5. L1 从 `https://superapi-local.hwpod.com` 验证多页面 Web 和 `/v1/*` gateway；
6. L2 由 master 分支的正常 push 事件自动构建并收敛到开发 namespace，
   从 `https://superapi-dev.hwpod.com` 验证同一管理与 Gateway 业务路径；
7. L3 只消费已经通过 L2 的同一提交链，由 release 分支的正常 push 事件自动构建
   并收敛到生产 namespace，从 `https://superapi.hwpod.com` 验证正式业务路径；
8. release 必须保持为 master 的祖先，生产发布只允许把 release 快进到已经通过
   L2 回归的 master 提交，禁止在 release 上直接开发、cherry-pick 或生成独有提交；
9. L2 与 L3 禁止共享进程、临时状态卷或捕获目录；数据库可以使用同一 PostgreSQL
   服务，但必须使用独立数据库或独立 schema，避免开发数据污染生产数据；
10. L1、L2 与 L3 的公开入口、运行对象和发布状态均由 owning YAML 选择，禁止通过
   命令行 URL、临时端口、裸 Kubernetes apply 或手工 Caddy 配置形成第二真相。

### 4.14 USER-KEY-SKILL-REQ-014 文档型 Remote Skill 导入

管理入口应支持以下三种来源，并复用同一个导入器：

- 单个 UTF-8 `SKILL.md`；
- 浏览器目录上传；
- ZIP 压缩包上传。

目录或 ZIP 中必须能够唯一识别 Skill 根及其 `SKILL.md`。导入器应拒绝路径穿越、
符号链接、绝对路径、多个无法唯一判断的 Skill 根、压缩炸弹和超出 owning YAML
声明的文件数、单文件与总容量上限。当前阶段只保存 `SKILL.md` 和 references
文档，忽略系统元数据并拒绝可执行脚本；任何上传内容都不得在服务端执行。

导入器应识别 `SKILL.md` 顶部的 YAML frontmatter。已有非空 `name` 和
`description` 时采用文档值；缺失字段时必须由上传表单或 CLI 明确提供，并在
持久化前注入标准 frontmatter。冲突值必须在预览结果中同时披露，发布操作不得
静默覆盖。发布内容统一为 UTF-8 和 LF 换行。

### 4.15 USER-KEY-SKILL-REQ-015 公开分发与版本

公开文档读取不鉴权，并至少提供：

- `GET /skills/{skill_id}`：公开详情与安装说明；
- `GET /skills/{skill_id}/SKILL.md`：标准 Skill 主文档；
- `GET /skills/{skill_id}/references/{path}`：文档资源。

文档响应应使用准确的 `Content-Type`、内容摘要 `ETag` 和
`X-SuperAPI-Skill-Revision`。Skill 记录应保存标准化主文档、发布时间和
SHA-256 revision；文档资源应按 Skill、相对路径、内容摘要和媒体类型独立保存。
删除 Skill 时应级联删除其公开文档。

公开详情必须分别展示 Windows PowerShell、Linux shell 和 macOS shell 的一条
建议一次性读取命令。命令应把文档输出到标准输出供 Agent 当次读取，不创建本地
目录、不写入本地文件。URL 只引用公开入口，不携带 API Key、Cookie、
Authorization 或其他凭据。

### 4.16 USER-KEY-SKILL-REQ-016 Remote Skill L0/L1 验收

L0 应直接调用同源导入器、repository 和公开响应渲染函数，使用 `docs-spec`
作为真实样本，分别验证单文件、目录和 ZIP 的解析结果一致；同时验证缺失
frontmatter 注入、ZIP 安全拒绝、revision 稳定、三平台一次性读取命令和数据库清理。

L1 应通过项目 CLI 启动既有独立 API、worker、Web 与 gateway 进程。管理 Web
提供上传、frontmatter 预览、补齐字段、发布 URL 和一次性读取命令；公开 `/skills/*`
由 API 进程提供且不经过管理 Basic Auth。浏览器验收复用项目 typed web-probe。
公网 shared edge 只通过 owning YAML 和自动交付链收敛，不执行人工确认式 apply。

### 4.17 USER-KEY-SKILL-REQ-017 GitHub 多 Skill 扫描与导入

管理入口和 CLI 应支持输入公开 GitHub 仓库 URL，扫描仓库中的多个文档型 Skill，
预览后一次批量发布。首期只接受 `https://github.com/{owner}/{repo}` 形式的公开
仓库，不接受任意 host、URL userinfo、查询参数、fragment 或重定向后的非 GitHub
下载源。

扫描前应通过 GitHub API 解析默认分支或显式 ref，并固定为不可变 commit SHA；
归档下载、扫描结果和发布结果必须披露 owner、repository、请求 ref 与解析后的
commit。扫描器应把每个 `SKILL.md` 所在目录视为一个独立 Skill 根，并只关联该根
下的 `references/**/*.md`。单个 Skill 的 frontmatter、文档标准化和安全限制继续
遵循 USER-KEY-SKILL-REQ-014。

扫描预览应返回发现数量，以及每个 Skill 的名称、description 摘要、相对根目录、
revision 和 references 数量。超过 owning YAML 声明的仓库归档大小、展开总量、
文件数、单文件大小或 Skill 数量时必须在持久化前拒绝。

批量发布必须在一个 PostgreSQL 事务中完成。同名 Skill 按既有发布语义更新；
任意 Skill 校验或持久化失败时整批回滚。成功后只刷新一次 gateway snapshot，
并返回逐项公开 URL 与三平台一次性读取命令。

L0 应使用内存多 Skill ZIP 验证多根扫描、references 归属、重复名称拒绝和容量
限制，不启动 API、worker 或网络请求。L1 应通过正式 API 与 Temporal worker，
使用 `https://github.com/RT-Thread/rtthread-skills` 验证真实扫描和批量发布；
Web 应提供 GitHub URL 输入、扫描预览和明确的批量发布动作。

### 4.18 USER-KEY-SKILL-REQ-018 Remote Skill 自动加载提示

启用绑定快照应为存在公开主文档的 Skill 保存精确 `SKILL.md` URL。URL 必须由
owning YAML 的 `publicExposure.publicBaseUrl` 和数据库中的稳定 Skill id 生成，
不得包含 API Key、管理凭据、Cookie 或其他 Secret。没有公开主文档的普通 Skill
继续只保存名称和 description。

gateway 注入目录应要求 Agent 在任务匹配 Remote Skill 时先一次性读取对应
`SKILL.md`，再按主文档要求读取同一 Skill 根下的相对 `references/*.md`。读取应
输出到标准输出供当次任务使用，不在客户端持久化；客户端网络或工具权限不足时
应明确报告阻断，禁止仅依据 description 伪装成已加载完整 Skill。

- 多 Skill 同时匹配或用户明确要求读取全部绑定 Skill 时：
  - catalog 必须提供由当前公开文档 ID 生成的批量读取 URL；
  - catalog 必须提供 Windows、Linux 和 macOS 的单命令读取方式；
  - Agent 应按当前系统直接执行其中一条命令读取批量 URL；
  - 动态批量 URL 不应先交给网页搜索、浏览器或索引型 URL reader；
  - Linux 与 macOS 命令应避免继承无效的本地代理配置；
  - 批量响应必须包含每份完整 `SKILL.md` 的名称和明确边界；
  - Agent 不应再逐个请求 catalog 中的单 Skill URL。
- 只有一个 Skill 匹配时：
  - Agent 继续读取该 Skill 的单独 `SKILL.md` URL；
  - 单 Skill 与批量读取均保持公开、无鉴权且不携带 API Key。

请求历史的分块模式应把 Remote Skill 的文档 URL 与名称、description 一并解析，
且继续保持每个 Skill 一行摘要、展开后查看完整字段。L0 应同时覆盖普通 Skill
兼容行为和 Remote Skill URL 渲染；L1 应使用没有本地同名 Skill 的真实 Codex，
在用户不补充 URL 的情况下读取公开主文档及所需 reference，并返回可由 reference
内容判定的结果。

### 4.19 USER-KEY-SKILL-REQ-019 外部身份与 Key 所有权

SuperAPI 的统一登录页应支持通过 owning YAML 声明外部身份提供方。首个提供方为
PK01 Sub2API，并复用其原生用户认证与用户 API Key 列表接口：

- 登录页只显示一套账号和密码输入，不显示身份类型或提供方选择；
- 页面应提示用户可以直接使用 `api.pikapython.com` 账号登录；
- 用户在账号字段输入 Sub2API 邮箱和密码登录；
- 管理员在同一账号字段输入 `admin` 和管理员密码登录；
- Web 只向服务端提交 `identifier + password`，不得提交或判断身份模式；
- 服务端将 owning YAML 声明的管理员用户名自动路由到管理员认证；
- 其他 identifier 自动路由到 owning YAML 中首个 Sub2API provider；
- Sub2API 用户登录成功后，服务端同步该账号当前已有的 API Key；
- Web 只显示 Key 稳定标识、名称、脱敏值和可用元数据；
- 用户不需要在 API Key 页面再次登录或手工录入已有 Key；
- 手工注册任意 API Key 只允许管理员使用。

Sub2API 用户是受限管理主体，只能读取和修改自己账号名下 API Key 的本地别名和
Skill 绑定。Skill 目录允许登录用户读取并用于绑定；Skill 的创建、编辑、删除、
上传和 GitHub 导入只允许管理员。请求历史的导航、列表、筛选和详情只允许管理员
访问，普通用户的 Web 中不得出现请求历史入口，服务端也必须拒绝普通用户访问历史
API。管理员拥有全部 API Key、Skill、绑定和请求历史的管理权限。所有权和授权必须
由 API、dispatcher、Temporal activity 和 PostgreSQL 查询共同执行，禁止只通过
Web 隐藏按钮或客户端过滤。

Sub2API access token、用户密码和 API Key 明文只允许在 SuperAPI API 进程内存中
短暂存在。Web、URL、日志、PostgreSQL、Temporal payload、workflow history、
CLI 输出和错误响应均不得返回或保存这些值。登录成功后应创建有过期时间的随机
HttpOnly 会话；会话过期、API 进程重启、用户切换账号或主动退出后必须拒绝复用。
Temporal 只允许携带脱敏后的主体类型、提供方和不可逆主体标识。

服务端应按经过认证的 Sub2API 身份和提供方 Key id 同步 Key，不信任客户端回传的
Key 明文、所有者或可访问 Key id。重新登录时，从该账号最新 Key 列表刷新可管理
范围；已从上游列表消失的 Key 不再进入该用户的可管理列表和 Gateway 快照。
管理员既有 Key 的全局管理语义保持不变。

L0 应使用两个受控 fake provider 用户和一个管理员验证登录、分页 Key 聚合、
脱敏、会话过期、Key 同步、用户间隔离、越权拒绝、普通用户历史 API 拒绝、
普通用户历史导航不可见、管理员全局权限和错误响应不泄密。L0 全部通过前不得进入
L1。L1 应创建专用的 PK01 Sub2API 普通测试用户，从
`https://superapi.hwpod.com/login` 完成真实普通用户登录、已有 Key 同步、别名和
Skill 绑定管理、他人资源拒绝、历史导航不可见与历史 API 拒绝的全流程验证；同时
保留管理员登录和管理工作区回归，并确认浏览器网络、DOM、console 和 SuperAPI
日志中不存在用户密码、access token 或 API Key 明文。本需求不修改 Sub2API 源码、
版本、账号池或运行配置。

### 4.20 USER-KEY-SKILL-REQ-020 绑定级完整 Skill 强制注入

每条 API Key 与 Skill 绑定应具有独立的 `forceEnabled` 布尔字段，默认值为
`false`。该字段属于绑定关系，不属于 Skill 全局属性；同一个 Skill 绑定到不同
API Key 时，各绑定可以采用不同值。现有 `enabled` 字段继续独立控制绑定是否进入
Gateway 快照，`forceEnabled` 不得隐式启用已停用绑定。

`forceEnabled=false` 时，Gateway 应保持现有稳定行为：

- 注入 `name + description` 摘要；
- 存在公开主文档时提供精确 `SKILL.md` URL；
- 由 Agent 在任务匹配时按 Remote Skill 加载合同一次性读取文档。

`forceEnabled=true` 时，Gateway 应在保留稳定 Skill 身份和边界标记的前提下，把
该绑定对应的完整标准化 `SKILL.md` 原文直接追加到请求 instructions。强制注入
不得要求客户端增加 header、环境变量或专用配置，也不得读取或注入 references、
脚本和其他资源。没有完整 `SKILL.md` 的普通摘要 Skill 必须由服务端拒绝开启
`forceEnabled`，禁止保存无法生效的配置或静默退化为摘要模式。

管理 API、默认本地 CLI、显式 `--over-api` CLI 和 API Key 绑定对话框应读写同一
绑定字段。Web 应为每条绑定分别显示普通启用开关和“强制注入完整 Skill”开关；
不支持强制注入的 Skill 应显示不可用状态，而不是隐藏服务端限制。每次变更都应
沿既有 dispatcher 和 snapshot refresh 路径原子发布，并继续执行 API Key
所有权校验。

L0 应验证：

- 新建绑定的 `forceEnabled` 默认为 `false`；
- 默认模式只注入摘要和文档 URL，不包含 `SKILL.md` 正文；
- 显式开启后同一 API Key 的 instructions 包含完整正文；
- 同一 Skill 在另一个 API Key 上保持默认关闭；
- 普通摘要 Skill 开启强制注入时被拒绝；
- 关闭普通 `enabled` 后，即使保存 `forceEnabled=true` 也不进入快照；
- 快照和 CLI/API 输出不包含 API Key 明文。

L1 应通过普通 Sub2API 测试用户完成自己 API Key 上的强制注入开关读取、开启、
回读和恢复，并通过 typed Web smoke 验证两个独立开关及不可用状态。公网 Gateway
验收应使用标准 Responses 请求确认默认摘要模式与强制全文模式的实际 instructions
差异；本需求不修改 Sub2API 源码、版本、账号池或运行配置，不进入 L2/L3。
