test(recall): lock inject-decoupling reroll invariant

Add controller-level coverage for no-new-user reroll behavior:
AFTER_COMMANDS defers recall, BEFORE_COMBINE deterministically reapplies
stored per-floor recall, and misses fall back to legacy compute. Update
docs to describe compute/injection decoupling and recall cards as the
editable per-floor bme_recall source.
This commit is contained in:
youzini
2026-06-01 06:56:40 +00:00
parent 433d274a26
commit ea1e515694
5 changed files with 233 additions and 5 deletions

View File

@@ -28,7 +28,12 @@
召回输入按优先级解析(`resolveRecallInputController`override → 待发送意图send intent→ 聊天尾部用户楼层 → 已发送用户 → 最新用户楼层。
**持久召回复用**`resolveReusablePersistedRecallRecord`):如果当前输入匹配某条已持久化的用户楼层召回记录,可直接复用已存的注入内容,**跳过全部新检索**,返回 `llm.status="persisted"`。reroll / regenerate / continue 场景由宿主 `type` 判定为 no-new-user 生成后,会绑定父 user 楼层的持久召回,而不是根据 textarea / send-intent 等输入源猜测(见 [`../architecture/control-plane.md`](../architecture/control-plane.md) 的 reroll 不变量)。
**持久召回复用有两条路径:**
1. **no-new-user 主路径**`reapplyPersistedRecallBlock`reroll / swipe / regenerate / continue 由宿主 `type` 判定为 no-new-user 后,`GENERATION_AFTER_COMMANDS` 不计算召回;`GENERATE_BEFORE_COMBINE_PROMPTS` 直接读取父 user 楼层的 `message.extra.bme_recall`,校验绑定文本未过期后确定性重放注入块。命中后不会进入 transaction / `runRecall` / 新检索。
2. **compute fallback 内部复用**`resolveReusablePersistedRecallRecord`):当主路径没有可用记录(例如无记录或陈旧)而落回 `runRecallController()` 时,如果当前输入匹配某条已持久化的用户楼层召回记录,可在控制器内复用已存注入内容,跳过新检索,返回 `llm.status="persisted"`
fresh `normal` 发送仍走正常输入选择与召回计算路径no-new-user 的父楼层绑定来自宿主生成上下文,而不是根据 textarea / send-intent 等输入源猜测(见 [`../architecture/control-plane.md`](../architecture/control-plane.md) 的 reroll 不变量)。
## 5. 向量预筛