# Hosted Service 使用 Bundle Capability

为自有 Bundle 的 Hosted Service 签发最小权限凭据，查询已安装资源，并查看或启动工作流和定时任务。

Bundle Capability 是 Bundle 向自己的 Hosted Service 开放的受控内省与执行入口。它适用于后端需要在某个
Application Runtime 中查看本 Bundle 已安装的资源、读取工作流和定时任务状态，或发起已发布的工作流和
单次定时任务执行。

它不是模块属性，也不是每次编译生成的实例地址。调用方使用稳定的公开 Capability 地址；凭据绑定
`environmentKey + bundleId + consumerKey + scopes`，每个请求再显式指定目标 `applicationRuntimeId`。
服务端会在每次请求中确认该 Bundle 确实在目标 Runtime 中处于已验证生效态，因此请求体不接受调用方声明
`workspaceId`、`bundleId` 或 `userId`。

## 能力边界

Bundle Capability 当前提供：

- 查询当前 Bundle 在指定 Application Runtime 中已验证生效的资源和版本。
- 查询工作流、读取工作流定义、查询实例与执行详情、启动工作流实例。
- 查询定时任务、读取定时任务定义与执行记录、触发一次立即执行。

它不提供工作流或定时任务的创建、编辑、发布、删除，也不授予其他 Bundle 的资源访问权。工作流和定时任务
仍按 Bundle 的版本化源码与安装流程交付；Capability 只操作目标 Runtime 中已经生效的版本。

这套入口与 Runtime 模块调用协议相互独立。Hosted Service 不需要伪装成模块实例，也不应把 Capability Token
放进模块属性、Bundle Manifest、Artifact 或源码。Token 明文只在签发时返回一次，应写入目标 Hosted Service
Environment Secret，并通过正常部署或重启流程交付给业务进程。

## 申请客户端与 Token

只有对目标工作区有管理权限、且拥有目标 Bundle 的调用方才能通过 CLI 管理 Capability Client 和 Token。
先从当前 CLI 读取准确命令：

```bash
baijimu bundle capability --help
baijimu bundle capability scopes --help
baijimu bundle capability client --help
baijimu bundle capability token --help
```

列出平台当前允许申请的 scope：

```bash
baijimu bundle capability scopes --workspace-id <workspaceId>
```

为 Hosted Service 建立稳定 consumer。`<bundle>` 必须是自有 Bundle 的精确名称或 `bundleId`，
`consumerKey` 用于审计、轮换和整体停用，不要使用部署生成的临时 ID：

```bash
baijimu bundle capability client create <bundle> \
  --workspace-id <workspaceId> \
  --consumer-key <consumerKey> \
  --name <displayName>
```

按最小权限签发 Token；需要多个 scope 时重复 `--scope`：

```bash
baijimu bundle capability token issue <bundle> <clientKey> \
  --workspace-id <workspaceId> \
  --name <tokenName> \
  --scope bundle.resources.read \
  --scope workflow.definition.read \
  --scope workflow.execution.read
```

Token 明文只在这次响应中出现。保存后只使用 `tokenKey` 查询和吊销，不要把 Token 明文放进命令参数、日志、
聊天消息或 Git：

```bash
baijimu bundle capability token list <bundle> <clientKey> \
  --workspace-id <workspaceId>

baijimu bundle capability token revoke <bundle> <tokenKey> \
  --workspace-id <workspaceId>
```

完整参数、启停 Client、有效期和生效时间以本机对应子命令的 `--help` 为准。

## Scope

| Scope                       | 允许的操作                             |
| --------------------------- | --------------------------------- |
| `bundle.resources.read`     | 查询当前 Bundle 在目标 Runtime 中已验证的资源版本 |
| `workflow.definition.read`  | 查询工作流并读取定义                        |
| `workflow.execution.read`   | 查询工作流实例、实例详情和执行详情                 |
| `workflow.execution.create` | 启动已安装的工作流                         |
| `timer.definition.read`     | 查询定时任务并读取定义                       |
| `timer.execution.read`      | 查询定时任务执行记录                        |
| `timer.execution.create`    | 触发一次已安装的定时任务执行                    |

不要从这张表推断账号当前一定能申请全部 scope；申请前仍以
`baijimu bundle capability scopes --workspace-id <workspaceId>` 返回的动态目录为准。

## HTTP 调用合同

公开基础地址为 `https://api.baijimu.com`。所有操作都是 `POST` JSON 请求，并携带：

```http
Authorization: Bearer <bundleCapabilityToken>
Content-Type: application/json
```

每个请求体都必须显式传入 `applicationRuntimeId`。该值是目标 Application Runtime 的稳定 ID，应来自当前
工作区的权威查询结果或应用自身已经校验的运行上下文；不能用工作区 ID、Bundle ID、展示名称或自行拼接值
替代。Token 不绑定单个 Runtime，同一个 Token 可以在本 Bundle 已验证安装生效的多个 Runtime 间使用，
但服务端会逐次校验 Bundle 身份与安装账本。

| Scope                       | 路径                                                                 | 请求用途                           |
| --------------------------- | ------------------------------------------------------------------ | ------------------------------ |
| `bundle.resources.read`     | `/capability/bundle-runtime/bundle/resources/query`                | 查询 Bundle 资源，可选 `resourceType` |
| `workflow.definition.read`  | `/capability/bundle-workflow/workflows/query`                      | 查询工作流                          |
| `workflow.definition.read`  | `/capability/bundle-workflow/workflows/definition`                 | 按 `resourceLocator` 读取定义       |
| `workflow.execution.create` | `/capability/bundle-workflow/workflows/instances/start`            | 按 `resourceLocator` 启动实例       |
| `workflow.execution.read`   | `/capability/bundle-workflow/workflows/instances/query`            | 查询某工作流实例                       |
| `workflow.execution.read`   | `/capability/bundle-workflow/workflows/instances/detail`           | 按 `instanceId` 读取实例详情          |
| `workflow.execution.read`   | `/capability/bundle-workflow/workflows/instances/executions/query` | 按 `instanceId` 读取执行详情          |
| `timer.definition.read`     | `/capability/bundle-timer/timers/query`                            | 查询定时任务                         |
| `timer.definition.read`     | `/capability/bundle-timer/timers/definition`                       | 按 `resourceLocator` 读取定义       |
| `timer.execution.read`      | `/capability/bundle-timer/timers/executions/query`                 | 查询执行记录                         |
| `timer.execution.create`    | `/capability/bundle-timer/timers/executions/trigger`               | 触发一次立即执行                       |

所有响应使用平台统一 CModel：`errorCode` 为 `0` 表示成功，业务结果位于 `data`；非零错误必须按失败处理，
不能只依据 HTTP 2xx 判断成功。

## Resource Locator

`resourceLocator` 是 Bundle 安装账本返回的稳定资源身份。调用工作流或定时任务接口前，先通过资源查询或对应
的 `query` 接口取得 Locator，再原样传回；不要根据 Bundle 名、资源名或历史 ID 自行构造。

可选 `resourceType` 使用以下登记值：

`MODULE`、`SKILL`、`AGENT`、`PLATFORM_APPLICATION`、`WORKFLOW`、`ISSUE_DEFINITION`、
`EVENT_TRIGGER`、`TIMER`、`PERMISSION_DEFINITION_SET`、`ROLE_TEMPLATE_SET`。

查询工作流资源：

```bash
curl --fail-with-body 'https://api.baijimu.com/capability/bundle-runtime/bundle/resources/query' \
  --header 'Authorization: Bearer <bundleCapabilityToken>' \
  --header 'Content-Type: application/json' \
  --data '{
    "applicationRuntimeId": "<applicationRuntimeId>",
    "resourceType": "WORKFLOW"
  }'
```

## 启动工作流

先查询工作流并取得 `resourceLocator`，再启动已安装定义：

```bash
curl --fail-with-body 'https://api.baijimu.com/capability/bundle-workflow/workflows/instances/start' \
  --header 'Authorization: Bearer <bundleCapabilityToken>' \
  --header 'Content-Type: application/json' \
  --data '{
    "applicationRuntimeId": "<applicationRuntimeId>",
    "resourceLocator": "<resourceLocator>",
    "input": {
      "source": "hosted-service"
    },
    "metadata": {
      "requestId": "<requestId>"
    }
  }'
```

`input` 和 `metadata` 都是可选对象。业务字段必须符合目标工作流自己的输入合同。

## 触发定时任务

Capability 只允许对已安装 Timer 触发一次执行，不修改原有 CRON、EVERY 或 AT 定义：

```bash
curl --fail-with-body 'https://api.baijimu.com/capability/bundle-timer/timers/executions/trigger' \
  --header 'Authorization: Bearer <bundleCapabilityToken>' \
  --header 'Content-Type: application/json' \
  --data '{
    "applicationRuntimeId": "<applicationRuntimeId>",
    "resourceLocator": "<resourceLocator>"
  }'
```

## 生命周期与失败处理

- 为每个稳定用途创建独立 Client，并只签发所需 scope；不同后端或自动化用途不要共用 Token。
- 轮换时先签发新 Token、更新 Environment Secret 并完成部署验证，再按 `tokenKey` 吊销旧 Token。
- Client 被停用、Token 被吊销或过期后，请求立即失败；不要在应用中缓存“曾经授权成功”的结果。
- Bundle 所有权变化、退出可申请状态，或目标 Runtime 中安装不再处于已验证生效态时，请求失败关闭。
- `404` 不等于可以换一个 Bundle 或猜 Locator；应回查目标 Runtime 的 Bundle 安装与资源查询结果。
- `403` 应检查 Token 状态、Client 状态和精确 scope，不要把管理 CLI 的账号凭据改作服务 Token。

## 机器可读合同

AI 客户端和代码生成器应读取版本化
[Bundle Capability OpenAPI 1.0.0](/contracts/bundle-capability/1.0.0/openapi.json)。该合同列出全部公开路径、
请求字段、scope 和示例；当前页面说明生命周期与安全边界。若本机 CLI 帮助、机器合同和运行态结果不一致，
停止调用并保留实际版本与响应，不要自行增加兼容分支。
