# 开发 Bundle 插件服务

用公开 SDK 实现生命周期执行与重试，保存业务归属并在每次调用前解析引用。

插件拥有外部业务操作逻辑；平台负责认证、安装编排、授权投影与输出校验。
Rust 插件使用 crates.io 的公开协议库：

```toml
[dependencies]
baijimu-bundle-plugin = "=3.0.0"
```

从 `baijimu_bundle_plugin::bundle_plugin` 导入 `BundlePluginLifecycleRequest`、
`BundlePluginLifecycleResponse`、`BundlePluginReferenceRequest` 和 `BundlePluginReferenceResponse`。
库版本、生命周期 `6.0.0`、引用 `4.0.0` 和 CModel envelope `1.0.0` 分别管理。

## 执行与认证

插件运行在 Hosted Service 时，先按
[业务、管理与插件生命周期入口](/development/backend-development/configuration-and-auth/#业务管理与插件生命周期入口)
声明执行 Endpoint，读取平台注入的命名端口变量并实现 listener。推荐使用独立的 `lifecycle` 入口；
部署后用它的真实 HTTPS `baseUrl` 与已实现的 POST 路径组成登记地址。
服务端监听端口、人工管理入口和 `bundleExecution.executeUrl` 不能互相代用；多 Endpoint 不会自动完成插件登记。

提供 JSON POST Endpoint，在 `bundleExecution` 中登记 HTTPS 地址和支持的资源阶段。
按[双向调用凭据](/development/lifecycle-plugin-development/registration-management/#双向调用凭据)
完成接入。验证平台访问插件的独立凭据，再严格反序列化请求并调用 SDK 校验。
按 `operation.operationType` 与 `stage` 执行业务逻辑；不能把仅识别阶段当成支持全部操作。
`resources` 中的业务属性和逻辑引用只包含当前授权范围，不能依赖额外注入的字段。
完整示例见[生命周期与引用协议](/development/lifecycle-plugin-development/reference-protocol/)。

## 外部状态与恢复

保存外部实例与完整 `installation`、资源 Locator、插件身份的关联，校验已传入实例的归属。
Runtime 拥有 `operation.operationId` 及阶段执行记录；插件根据业务系统真实结果处理同一次操作重试。
这不要求每个平台业务组件建立一套插件安装表。

生命周期调用执行必要变更；网络中断后，平台以相同 `operationId + stage` 重试，插件返回对应业务结果和属性。请求与响应不再包含 `intent`。
超时不代表没有执行；无法证明结果时返回 `UNKNOWN`，不得伪造成功或直接重建实例。
`DETACH` 解除本次安装的关联，业务资源清理受所有权约束。
卸载清理使用生命周期身份校验归属，不能通过放宽引用访问授权来取得已撤销的凭据。

## 业务调用与重试

每次调用和重试前向平台入口发送 `POST /bundle-plugin-manager/api/service-reference/resolve`。
平台 API 基地址只保存环境入口，按[基地址与完整路径](/development/lifecycle-plugin-development/reference-protocol/#api-基地址与完整路径)
拼接一次；发布后核对实际注入的配置和最终请求路径。
保存的是 `installation + resource + propertyKey`，每次响应都必须校验相同身份与有效期。
先按当前 `reference` 的 Map 业务键、List 顺序或单个 `serviceId` 选择目标，再取对应 `access[serviceId]`。

地址与 Token 只在当前业务尝试中使用，不持久化；不得任取 access 的第一项，不得跟随重定向转发凭据。
解析失败、安装失效、过期、撤销或重绑都必须影响下一次调用，不使用旧值回退。
排查时分别检查路由、插件凭据和 Bundle 安装状态，见[引用解析失败排查](/development/lifecycle-plugin-development/failure-and-retry/#引用解析失败排查)。
业务事件通过已授权的事件引用投递；用户委托见
[Runtime 用户委托](/development/bundle-development/module-development/actor-delegation/)。

## 返回结果

使用完整 CModel envelope。成功 data 回显请求的协议、插件、安装、操作、阶段和执行顺序，并返回 `outcome` 与
按资源 Locator 组织的 `resources`。仅 `APPLIED` 或 `VERIFIED` 可以返回获授权业务属性；其他结果不回写资源。
不得覆盖引用属性、用户自有配置或 Runtime 安装状态。空输出使用空对象。

请求非法、鉴权失败或执行错误使用标准非零 `errorCode`，公开错误详情不带 Token、上游原文或完整配置。
日志只记录必要关联身份与结果。没有实现的阶段不登记；已经登记的操作不能静默成功。

## 插件自有业务凭据

插件可以为自己拥有的业务实例签发服务 Token，并通过生命周期 `resources` 输出交给 Runtime。
例如 `serviceAccessToken` 可以是声明了 `isSensitive: true` 的字符串 Data 属性，由插件的
`writeProperties` 明确授权；需要在后续生命周期请求读取时，再显式授权 `readProperties`。
它不应加入 `credentialProperties`，后者只授权平台引用解析。

这类 Token 由业务后端负责签发、校验、轮换和撤销，按完整安装身份与业务实例隔离。
它不能复用 Hosted Service 共享管理 Token、平台调用插件的凭据、插件调用平台的凭据，或引用解析返回的 Token。
Runtime 校验当前资源、属性定义、写入授权和响应关联，只接受 `APPLIED` 或 `VERIFIED` 的获准输出；
移除中的资源不接受属性回写。现有生命周期输出合同已支持这一用途，无需另造业务 Token 交付接口。

业务后端应验证重复生命周期调用能恢复同一业务实例及其返回属性。消息插件从同一操作的业务回执返回原租户凭据。系统插件需要模块 Token 时自行调用 ACS，Runtime 不参与签发或凭据清理。
按业务需要安全保存校验材料或用于重试交付的秘密，禁止记录明文 Token、完整请求或响应；
撤销必须以真实业务效果为依据，不能借用 ACS 的平台令牌身份或把平台安装账复制到业务库。

## 系统插件初始化模块 Token

模块是否需要 Token 由其属性和插件能力决定。system-manage 只有在获准写入 `Authorization` 或 `moduleToken` 且当前值缺失时才申请 Token；只配置 `workspaceId`、`serviceBaseUrl` 的模块不调用 ACS。

Token 属性需要同时声明 `readProperties` 和 `writeProperties`，使插件能够保留已有配置。已有 Token 不因升级或卸载自动替换、撤销；这不是安装账的一部分。ACS 的请求只包含工作区、Module、服务主体及签发审计信息，不包含 Runtime、安装单或阶段。

## 顺序与恢复

Runtime 提供正整数 `executionSequence`；同一操作的阶段和重试保持该值。
插件必须把顺序校验与实际业务写入放进同一事务，保留 DETACH 的顺序记录，拒绝迟到的旧操作。
完整规则见[失败与重试](/development/lifecycle-plugin-development/failure-and-retry/)。
