# Assets Module Rules

## 范围与职责

适用于 `src/host/assets/`。

以**单文件 SQLite（`<root>/assets.db`）**保存两类持久化事实，并对外提供其读写入口：

- **资产**：模版的晋升形态。带版本控制、Active 指针、回滚与退役；分角色资产、工作流资产
  与经验生成提示词资产三类。提示词资产是唯一**不可归档**的资产：两款内置提示词各一条
  逻辑资产，Active 指针必须始终存在，只能保存新版本与切换版本；
- **经验**：主体在运行中沉淀的可长期复用知识（九项语义核心 + 检索投影 + 向量），
  其生成策略由提示词资产的两条 Active 版本提供。经验 provenance 继续用
  `generation_prompt_id`（提示词版本行 id）与 `generation_prompt_version`（行版本文本）
  记录生成时使用的版本，历史经验不随提示词回滚而变化。
  主体类型 `team` 已永久退役：两张表的 CHECK 收窄为 `('agent','orchestrator')`，
  存量 team 行与其子行在初始化时物理删除，不留备份表。

判断归属：该修改是否改变「资产/经验被持久化成什么形状、版本如何推进、Active 如何指向」？
只改变业务语义判断（该不该晋升、该不该复用、两条经验是否算重复）应放到调用方模块。

## 时间戳与版本

- 时间戳一律 epoch 毫秒，由本模块记账（`AssetStoreDeps.now` 可注入，测试确定化）。
- `created_at` 是**资产诞生时间**，升版时沿用既有版本行的值；`updated_at` 每次写入刷新。
- `version_id` 从 1 开始、按资产独立递增（`max(version_id) + 1`）；版本行 id 固定
  `<asset_id>@<version_id>`，它是工作流版本行反向引用角色版本行的键，属对外契约。
- 回滚只移动 Active 指针，不新增版本、不改历史行。

## 经验（Experience）

- 磁盘形状：`experiences`（写入即固定，状态只有 `is_active` 两态，没有版本与 Active 表）与
  提示词资产的历史版本表 `experience_prompts` + Active 指针表 `experience_prompt_active`。
  版本行 id 统一为 `<asset_id>@<version_id>`；每个主体类型恰好一个 Active 指针
  （`experience_type` 唯一索引），指针缺失由初始化自愈，不存在删除入口。
- 提示词资产只有**正文**可编辑；名称 / 描述 / 主体类型是内置身份，保存新版本时从基线版本
  继承。内容全等不新增版本；回滚只移动 Active 指针；历史行不可变。
- 向量以 BLOB 存 Float64 数值、维度另列；读侧严格校验字节长度与维度，不可用即按「无向量」降级——
  不得截断、补零，也不得让整次列表读失败。
- 判重算法由经验域以闭包注入；本模块只保证「读活跃行 → 判定 → 写入」在同一笔事务内完成，
  相似度与阈值不得下沉到本模块。
- 向量与检索文本一律在事务外算好随行传入：远程嵌入调用与首次模型加载都不得占用写事务。
- 必填语义字段被清空即拒绝（可行动错误）：经验没有版本，改坏无从回滚。
- 旧形状 `experiences`（无 `experience_type`）在初始化时删表重建，不留旧数据、不留备份表。
- `team` 主体类型退役迁移的判据是「`experiences` / `experience_prompts` 任一表的建表原文仍含 `'team'`」，
  混合态（只收窄了其中一张表）同样收口；重建只针对仍含 `'team'` 的那张表，已收窄的表不重建。
  重建期间外键先关后开，子行（usage / evaluation / stats）必须先于父行删除——三张子表的外键都没有级联删除。
  重建前校验旧表列集合与当前形状一致，不符即报可行动错误并整笔回滚，不静默丢列。
- 两类生成 Prompt 的 V1 正文作为常量随代码发布；播种条件是「该提示词资产没有任何历史行」，
  已存在的行（含用户改写的正文）一律不被覆盖。旧形状（行上 `is_active`）迁移时：
  所有旧行保留为历史版本、原活跃行成为 Active、无活跃行取最新版本；
  存量经验行的 `generation_prompt_id` 映射到新版本行 id，版本文本原样保留。
- 提示词资产没有归档 / 恢复路径；API 对这两类请求返回 `WF_PROMPT_ASSET_ACTIVE_ONLY`。

## 核心原则

1. 资产事实由本模块单独拥有，磁盘形状与错误码属对外契约。
2. 读改写不出事务，失败不留半成品。
3. 历史不可变，Active 即指针；统计是缓存，可重建且有唯一维护点。
4. 时间戳与版本号由本模块记账，注入式时钟保证测试确定。
5. 列表读可用、单资源读可诊断；重建宁可报错也不产半成品。
6. 经验只承担形状与原子边界：判重规则属经验域，本模块不实现相似度。
