16 KiB
Skill Lifecycle
Date: 2026-10-15 Status: contract reference with documented implementation exception
本文件是 Skill 生命周期的统一导航入口;业务语义结合正式需求、设计与实现测试维护。发现冲突时应明确记录并确认预期,不能自动以代码或旧文档裁定。本次对齐依据见第 8 节;原始 latest 指针的 PRIVATE 例外见第 3.1 节。本页不定义 SuiteVersion 的状态模型。
1. 设计原则
- skill 生命周期不再被建模为一个混杂状态机,而是拆分为容器状态、版本状态、审核工作流状态和可见性覆盖层
- 前端不再从
status + hidden + latestVersionStatus + viewingVersionStatus拼装状态,而统一消费后端 lifecycle projection - destructive action 和 reversible action 必须分离;
withdraw-review只表示撤回提审,不表示删除版本 - 对外仍可保留
latest协议词汇,其公共分发语义必须严格等价于 latest published;原始持久化字段的现状另列
2. 状态模型
2.1 Skill 容器状态
ACTIVEARCHIVED
说明:
hidden是独立治理覆盖层,不属于Skill.statusSkillStatus.HIDDEN不再视为有效生命周期语义
2.2 SkillVersion 版本状态
| 状态 | 含义 |
|---|---|
DRAFT |
历史兼容状态,可提审或删除;不作为普通上传的新建状态 |
SCANNING |
等待当前安全扫描完成 |
SCAN_FAILED |
扫描执行失败;不等同于发现风险 |
UPLOADED |
上传保留,等待提审或 PRIVATE 确认发布;不保证已经扫描 |
PENDING_REVIEW |
已提交审核,等待审核决定 |
PUBLISHED |
已发布;实际分发还需满足可见性、容器状态与可安装条件 |
REJECTED |
审核拒绝后保留的版本 |
YANKED |
曾发布、现已撤回分发的版本 |
2.3 ReviewTask 审核工作流状态
PENDINGAPPROVEDREJECTED
ReviewTask 仅表达审核流程,不再被前端当作展示态来源。
3. 核心语义
3.1 Latest
- 公共
latest、搜索、兼容接口和默认公开分发必须解析到已发布版本,不能把未发布内容作为公开 latest。 - 审核通过及自动发布时,
Skill.latestVersionId指向发布版本;无已发布版本时允许为空。 - 已知实现例外: PRIVATE 上传/重发会将原始
latestVersionId指向新建UPLOADED版本;启用扫描后该版本可能处于SCANNING。发布测试明确覆盖此指针更新,不能把这个字段单独当作已发布证明。 - 详情和 owner summary 的 projection 检查指针目标是否
PUBLISHED,否则查找已发布版本;批量公开摘要只检查原始指针目标是否可安装,不执行该回退。不能假设各读模型都以相同方式修复指针;latest标签和消费者也不能无条件沿用原始指针。 - 是否将 PRIVATE 持久化指针也统一为仅指向已发布版本,需要单独设计并检查消费者、历史数据及测试。本次只记录例外,不改变该行为,也不放宽公共 published 约束。
3.2 Lifecycle Projection
详情页、我的技能、我的收藏、搜索等读模型统一基于以下 projection:
headlineVersion:projection 的默认主展示候选;前端可按选中版本或管理预览选择展示内容,不保证每个页面都直接显示该字段publishedVersion:最新已发布版本ownerPreviewVersion:有权限的管理者可见的新一轮未发布工作版本(排除PUBLISHED/YANKED,且比已有发布版本更新)resolutionMode:PUBLISHED/OWNER_PREVIEW/NONE
约束:
- 默认公开展示、安装与搜索以最新已发布版本为候选;显式版本或自定义标签可指向其他
PUBLISHED版本,仍须通过入口授权与就绪检查 - owner 详情页只有在不存在
publishedVersion时,才允许headlineVersion = ownerPreviewVersion - compat latest 和默认公开下载采用最新已发布版本语义;promotion 可选择来源 skill 的任一
PUBLISHED版本,不要求等于publishedVersion。原始指针与各入口解析差异见第 3.1 节 - 管理者的授权预览下载与公开分发不同:owner 或 namespace ADMIN/OWNER 可下载
UPLOADED/PENDING_REVIEW,当前 owner 另可受控下载自己的DRAFT/REJECTED,仍须通过 Skill 可见性、文件就绪及其他安全检查;不因此放行SCANNING/SCAN_FAILED/YANKED或公开分发未发布版本。常规downloadLatest读取原始指针后也使用相同版本授权判断,因此 PRIVATE 指针例外下,默认下载不一定是已发布版本;该行为不授予公众访问权。 - 已发布版本可安装还要求
downloadReady=true、yankedAt=null;下载要求容器为ACTIVE,元数据可读不等于可下载
4. 代码实际链路
4.1 首次上传
| 上传路径 | 扫描与后续状态 | 审核任务 / latest |
|---|---|---|
普通 PUBLIC / NAMESPACE_ONLY |
要求扫描启用;创建待审版本,触发扫描进入 SCANNING,当前扫描完成后回到 PENDING_REVIEW |
创建 PENDING review task;不移动 published 指针 |
普通 PRIVATE |
启用扫描时 SCANNING -> UPLOADED;未启用时直接 UPLOADED |
不自动创建审核任务;原始指针例外见 3.1 |
| 特权自动发布 | 直接 PUBLISHED;启用扫描时仍扫描,但不降为 SCANNING |
不创建审核任务;更新发布指针 |
- 扫描执行失败可进入
SCAN_FAILED。扫描完成不代表无风险,风险发现、警告确认和审核门槛是独立检查;过期扫描结果不能完成新一轮扫描。 submit-review接受UPLOADED(兼容历史DRAFT),设为PENDING_REVIEW并创建审核任务,保存请求的目标可见性。confirm-publish仅用于 PRIVATE Skill 的UPLOADED(兼容DRAFT):转为PUBLISHED,更新发布时间与 latest,发出发布事件,不触发新扫描。
4.2 审核通过
PENDING_REVIEW -> PUBLISHED- review task 标记为
APPROVED Skill.latestVersionId指向该版本- skill 展示元数据从发布版本刷新,摘要采用该版本有效
short-description(自定义覆盖优先,其次包内值,再退回description);overview仅在选中版本详情展示。提交时的自定义继承冻结在版本快照,审核期间不随其他版本发布而变化。
4.3 审核拒绝
PENDING_REVIEW -> REJECTED- review task 标记为
REJECTED - 版本保留,可后续删除
4.4 撤回审核
withdraw-review的统一语义是PENDING_REVIEW -> UPLOADED- 同时删除关联的
PENDING review_task - 该操作是可逆、非破坏性的
- 当前代码只允许提交人本人撤回
4.5 重传新版本
- 若发现旧的
PENDING_REVIEW版本,会先把旧版本自动撤回到UPLOADED - 然后按可见性及自动发布条件创建新版本,走 4.1 的对应路径
- 普通交互上传的自动撤回与手动撤回保持同一目标状态;Bundle 发布禁止自动撤回,已有待审版本时应阻塞,由用户先处理
4.6 已发布版本重发
- rerelease 当前本质上是从已发布版本复制并重新走发布流程
- 入口先检查生命周期管理权限,要求来源版本为
PUBLISHED、目标版本号未占用;内部传空平台角色集且forceAutoPublish=false,不沿用平台特权直发 - 新版本按原 skill 的可见性及扫描配置进入 4.1 对应的上传、扫描或待审路径;内部绕过重复成员校验不等于绕过审核
- 该能力是复制内容重新发布,不是生命周期展示态
4.7 隐藏 / 恢复 / 归档 / 撤回已发布版本
- 隐藏:设置
hidden=true并记录治理信息,不改变版本状态;不抹除 owner / namespace 管理者的访问权限 - 恢复:设置
hidden=false并更新治理信息 - 归档:
Skill.status = ARCHIVED,保留记录并禁止下载;公开元数据仍可能可读 - 取消归档:
Skill.status = ACTIVE - yank:
PUBLISHED -> YANKED,记录撤回人、时间和原因,设置downloadReady=false;没有对应的恢复发布操作
4.8 Yank 后指针修正
- yank 已发布版本时,若命中当前
latestVersionId,必须重算 latest published pointer,并从回退版本的 metadata 恢复展示名和摘要 - 若仍有其他
PUBLISHED版本,则指向最新一个 - 若已无任何
PUBLISHED版本,则latestVersionId = null
4.9 独立调整已发布技能的可见范围
可见范围属于 Skill 容器,不需要新建 SkillVersion。缩小立即生效;扩大创建 SKILL_METADATA 范围申请,与内容待审互斥。原范围、目标范围和发布版本快照保存在 ReviewTask,审核通过才更新范围;旧审批不能覆盖新版本。未扫描的已发布包复用存量 bundle 扫描,保持 PUBLISHED,申请绑定扫描 taskId;未通过不得批准。头像按目标受众复用同一审核申请。范围事件仅刷新搜索,不发送“新内容版本发布”通知。操作和接口详见使用指南。
5. 对外协议约束
5.1 Public / Search / Compat
- 对外协议可以继续暴露
latestVersion、latest、默认下载等概念 - 但它们都必须严格表示“最新已发布版本”
- compat 层内部实现必须从统一 lifecycle projection 的
publishedVersion映射,不允许自行推导“当前版本”
5.2 Frontend
- 页面状态展示统一消费 projection
- 不再新增旧兼容字段依赖
hidden仅作为治理标记展示,不参与版本状态拼装
5.3 提升更新与撤销
- 提升要求所选版本属于团队来源 Skill 且为
PUBLISHED,可选历史版本,再单独进入平台提升审核;后续更新同一全局 Skill 时为它新增不可变的已发布版本。 - 首次和后续提升均优先从所选来源版本的
parsedMetadataJson读取展示名和摘要;字段为空才回退到审核时来源 Skill 的展示信息,非空但解析失败则抛错。 - 全局 Skill 也可独立上传并审核。提升更新与独立上传使用相同版本号时不能互相覆盖;不同号版本分别发布,latest 指向最后通过审核的版本,不按版本字符串大小排序。
- 撤销提升不同于归档或隐藏:平台审核通过后移除全局派生 Skill 的公众入口及记录,保留来源团队 Skill、提升和撤销审计,并保护共用对象存储文件。重新提升形成新的全局 Skill ID。
5.4 已提升技能如何删除
团队技能与提升生成的全局技能是两条关联记录。只撤回待审核版本、取消更新或撤回尚未批准的申请,不会删除已经发布的全局技能,也不会解除首次提升的关联。
若删除时提示须先撤销全局发布(旧版本提示“已提升的技能须通过审核撤销流程删除”),按以下顺序操作:
- 打开来源团队技能详情页,在提升区域选择“申请撤销全局发布”,填写原因并提交。
- 平台管理员在提升管理的撤销申请中审核;申请处于待审或被拒绝时,全局技能仍然存在,两条技能都不能绕过该流程直接删除。具有相应平台治理权限的管理员也可在来源详情页直接撤销。
- 撤销批准后,全局技能及其地址自动删除,来源团队技能和版本仍保留。此时如需连来源一起删除,由技能所有者或超级管理员执行来源技能的永久删除。
撤销时已有的全局更新申请会失效,不能在全局记录删除后重新发布到该记录。提升撤销保留提升、撤销与删除审计;来源技能后续永久删除仍按既有物理删除流程清理其业务记录,操作审计继续保留。不要通过手工清除来源关联字段来绕过撤销审核。
6. 权限边界
TEAM 成员移除后的当前所有者
账号正常但已不是 TEAM 成员的当前技能所有者,保留自己的技能、私有内容、草稿及历史版本的查看和受控下载权限,不能凭所有者身份执行以下写操作。成员移除不删除技能、不迁移地址、不改 owner、不自动撤回待审核申请;既有审核人继续按原安全与审核规则处理。重新加入且账号正常、所有权未变时恢复原有维护权限。
本条只收紧普通 owner 的成员边界,空间/平台管理员的原有独立权限不变;其他空间和 GLOBAL 原有规则不变。账号停用仍由原认证机制拒绝,不能通过 owner 匹配绕过。以下各行中的 owner 写权限均以这条成员边界为前提,不影响管理员独立路径。
操作边界
withdraw-review:仅提交人本人- 删除版本:owner 或 namespace ADMIN/OWNER,仅限
DRAFT/REJECTED/SCAN_FAILED/UPLOADED,禁止删除最后一个版本。数据库删除提交后清理对象存储,失败调用补偿入口;不是跨存储原子删除,补偿持久化的验证限制见对象存储写入策略 - 归档 / 取消归档:owner 或 namespace ADMIN/OWNER
- 隐藏 / 恢复技能:平台技能治理权限
- yank:owner 或 namespace ADMIN/OWNER 可走普通治理入口;平台治理入口另校验平台权限
- 提交审核:owner 或 namespace ADMIN/OWNER;PRIVATE 确认发布还支持传入平台角色的 SUPER_ADMIN 路径
- 读取:可见性检查区分 PUBLIC、NAMESPACE_ONLY、PRIVATE 和 hidden;没有 latest 指针且未隐藏时,普通 namespace 管理角色不自动获得读取权限,owner 可读。接受平台角色的检查入口另支持 SUPER_ADMIN,不等于每个服务调用均传递该角色
- 写操作授权与读取授权分别校验,不能从管理身份推导所有未发布技能均可读取
7. 当前最终约束
- 一个 skill 生命周期的唯一规范入口就是本文件
- 其它文档如
02-domain-model、05-business-flows、06-api-design、08-frontend-architecture必须与本文件保持一致 - 生命周期行为变化先确认正式需求与验收,再同步修改实现、测试及本文;不能以文档对齐名义静默裁定新业务规则
8. 依据与验证锚点
- 正式语义:核心语义规则 §6、Bundle 发布规格;Bundle 不自动撤回,SuiteVersion 使用独立模型。
- 提升展示信息:版本展示名规格要求标题与摘要匹配所选版本快照,取代旧提升方案中读取来源 Skill 当前展示信息的描述;PromotionService保留空元数据的兼容回退。
- 上传及 PRIVATE 指针:SkillPublishService、发布测试。
- 扫描:SecurityScanService、扫描测试。
- 提审 / PRIVATE 确认:SkillReviewSubmitService、提审与确认测试。
- 撤回 / 删除 / yank:SkillGovernanceService、治理测试。
- 读模型与分发:SkillLifecycleProjectionService、VisibilityChecker、下载测试、可见性测试。
以上锚点用于核对具体行为,不代表覆盖了所有状态组合,也不等于真实部署或对象存储验收。