Repository navigation
feat(scope): 写入端 scope 标注存储层(A1,issue #17) - #153
Conversation
v0.8.0 批次 A 第 1 个 PR:scope 隔离的地基——存储层纯增量,feature flag 默认关,关闭时行为与改动前逐字节一致(检索加权/过滤在 A2/A3,面板在 A4)。 - store:memories 新增四列可空迁移 agent_scope/workspace_scope/sensitivity/ occurred_at(只 ADD COLUMN、不带 DEFAULT,存量行零重写,读侧 NULL=未标注 =全局可见);save 写入归一化(非空 trim 字符串收下,脏值落 NULL 绝不阻塞 写入);occurred_at 可解析时间戳统一归一 UTC ISO(A2 时间过滤按字典序比较); update/compareAndUpdate 不触碰 scope 列(写入时标注,落库后不可变) - scope(新模块):写入端解析器 createScopeResolver——agent_scope 取 session header 的 agentPreset(requestHeader() 优先、静态 .header 兜底);workspace 先走 ctx.workspaceRegistry 按 session.id 反查 canonical path,失败回退 header.cwd,再失败留 NULL;全程 try/catch,registry 故障 warn 一次后降级, 绝不让 scope 解析阻断写入 - service:saveWithDedupe 透传 scope 标注;去重键由 (type, title) 扩展为 (type, title, agent_scope, workspace_scope, sensitivity)——不同作用域的同 标题记忆绝不互相物理合并(NULL 归一为未标注,未标注行互相匹配、与已标注 行不匹配);#127 的 _mergeInto 显式并入目标同样过 scope 门,跨作用域语义 相似回落为独立新行,防合并泄漏 - tools:memory_save 接 exec 上下文(exec.agent.session),新增可选参数 sensitivity / occurred_at;agent_scope/workspace_scope 由会话身份解析, 不作为模型参数暴露 - config/settings:scopeEnabled 默认关,进 FEATURE_FLAG_BOOLEANS 白名单 (面板可启停=线上回滚开关) 测试 +16:迁移列形态(可空/无 DEFAULT)、存量形状读回、归一化脏值、update 不可变、flag 关=旧去重、flag 开=三元组隔离与 NULL 匹配语义、_mergeInto 跨 scope 拒绝、解析器降级矩阵(registry 命中/未命中/抛错/无 session/旧宿主)、 memory_save 端到端接线(含 flag 关不标注)。/features effective 键数 49→50。 Refs #17(A1/4,后续 A2 检索加权、A3 strictScope、A4 面板分开提交)
|
Warning Review limit reachedNext included review available in 12 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (14)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
|
@coderabbitai full review |
|
v0.8.0 批次 A 第 2 个 PR,接在 #153(A1 存储层)之后:检索侧软隔离。 scopeEnabled 关闭或调用方未提供会话 scope 时,检索行为与 A2 前逐字节一致。 - service.searchMemories:新增 options.scope(工具层从 exec.agent.session 解析 后传入)——当前会话 scope 两维命中的候选 ×1.25 加成,带他 scope 的候选 ×0.5 降权但保留可见(硬过滤是 A3 strictScope);未标注行(NULL)与无法比较的维度 恒中性,全局/存量记忆不因加权掉位。系数为模块常量,数值等线上反馈再调 - occurred_at 时间窗:store.list/count 新增 occurredFrom/occurredTo 闭区间 (与 updated_at 共用 updatedAtBounds 归一化,date-only 含当日);按 COALESCE(occurred_at, created_at) 比较——未标注行回退创建时间,过滤器对 存量库可用;搜索路径在融合池上先滤再 dedup/slice,rerank 只看窗内候选, list 与 count 同口径保证分页 total 与行一致 - tools:memory_search / memory_list 新增可选 occurred_from / occurred_to 参数;memory_search 接 exec 做会话 scope 加权;三个检索工具的输出 schema 与 render 透出 agent_scope/workspace_scope/sensitivity/occurred_at(provenance 附加段只在有标注时出现);toApiList 条件展开——未标注行 DTO 与 A2 前同形 - updatedAtBounds 从 store.js 导出复用(搜索后置过滤与 SQL 过滤共用边界归一) 测试 +13(store/service 透传、搜索窗、加权翻转/中性/flag 关、toApiList 形状、 memory_search/list/get 工具接线),全量 962 项 961 绿 / 1 既有 skip。 Refs #17(A2/4)
#153 观察 1:tools.js/inject.js 的 createScopeResolver 补传 logger: ctx.logger,registry 反查失败时 warnOnce 才有出口(否则静默降级无观测)。观察 2(workspaceRegistry 经 cordis Proxy 访问可能抛错)已有 try/catch 兜底降级 header.cwd,维持现状。观察 3:scopeMultiplier 实际语义=只有确立 foreign(记忆带标注+当前维度可解析+值不等)才吃 ×0.5,未标注行与命中行同列吃 BOOST ×1.25 而非 ×1 中性——常量注释、searchMemories 注释与测试标题三处对齐(行为不变,仅注释与标题)。
#153 观察 1:tools.js/inject.js 的 createScopeResolver 补传 logger: ctx.logger,registry 反查失败时 warnOnce 才有出口(否则静默降级无观测)。观察 2(workspaceRegistry 经 cordis Proxy 访问可能抛错)已有 try/catch 兜底降级 header.cwd,维持现状。观察 3:scopeMultiplier 实际语义=只有确立 foreign(记忆带标注+当前维度可解析+值不等)才吃 ×0.5,未标注行与命中行同列吃 BOOST ×1.25 而非 ×1 中性——常量注释、searchMemories 注释与测试标题三处对齐(行为不变,仅注释与标题)。
* feat(scope): strictScope 硬过滤与注入侧隔离(A3,issue #17) v0.8.0 批次 A 第 3 个 PR,接在 #155(A2 检索加权)之后。strictScope 关闭时 维持 A2 软隔离(他 scope 降权保留可见);开启后按 issue #17 四象限可见性公式 硬过滤——带他 scope 的记忆在检索、注入、浏览、单取四条用户面路径完全不可见。 - config/settings:新增 strictScope(默认关,进 feature_flags 白名单)。独立于 scopeEnabled 成键:可先开标注积累数据、观察 A2 加权质量后再切硬过滤。 - service.isVisibleInScope(新导出谓词):可见 ⇔ (agent 维未标注或命中当前 agent) AND (workspace 维未标注或命中当前 workspace);当前会话某维度解析不到 时该维度带标注的记忆一律不可见(fail-closed:身份不明只见全局)。sensitivity 为标签不参与可见性判定。 - searchMemories:strict 开启时在融合池先硬过滤(他 scope 出局)再走 occurred 窗/dedup/rerank;与 A2 加权叠加——过滤后剩下的命中行仍吃加成。 - injectCandidates:新增 options.scope,strict 开启时注入候选同口径硬过滤—— scoped 记忆泄进无关注入上下文是最典型的越权通道,仅过滤检索挡不住这里; inject.js 在渲染回调按 ctx(agent.session,与工具 exec 同形)解析 scope 传入。 - store.list/count:新增 visibility 选项(SQL 侧与谓词同口径:未标注 NULL 恒 可见;维度解析不到只放行未标注行),memory_list 分页 total 与行一致;仅显式 传参的用户面调用过滤,dream/质量过滤等内部 store.list 不受影响。 - tools:memory_get strict 下他 scope 的行按不存在处理(无存在性泄漏); memory_list 的 list/count 同口径过滤。 - /features effective 键数 50→51。 测试 +9(四象限语义、匿名 fail-closed、搜索硬过滤、strict 关= A2 行为、SQL 过滤与 total 一致、注入过滤、memory_get 存在性泄漏/行主可取、memory_list 过滤与 total),全量 971 项 970 绿 / 1 既有 skip。 Refs #17(A3/4,剩 A4 面板) * fix(scope): review 观察点——resolver 透传 logger、scopeMultiplier 注释对齐实际语义 #153 观察 1:tools.js/inject.js 的 createScopeResolver 补传 logger: ctx.logger,registry 反查失败时 warnOnce 才有出口(否则静默降级无观测)。观察 2(workspaceRegistry 经 cordis Proxy 访问可能抛错)已有 try/catch 兜底降级 header.cwd,维持现状。观察 3:scopeMultiplier 实际语义=只有确立 foreign(记忆带标注+当前维度可解析+值不等)才吃 ×0.5,未标注行与命中行同列吃 BOOST ×1.25 而非 ×1 中性——常量注释、searchMemories 注释与测试标题三处对齐(行为不变,仅注释与标题)。
* feat(scope): strictScope 硬过滤与注入侧隔离(A3,issue #17) v0.8.0 批次 A 第 3 个 PR,接在 #155(A2 检索加权)之后。strictScope 关闭时 维持 A2 软隔离(他 scope 降权保留可见);开启后按 issue #17 四象限可见性公式 硬过滤——带他 scope 的记忆在检索、注入、浏览、单取四条用户面路径完全不可见。 - config/settings:新增 strictScope(默认关,进 feature_flags 白名单)。独立于 scopeEnabled 成键:可先开标注积累数据、观察 A2 加权质量后再切硬过滤。 - service.isVisibleInScope(新导出谓词):可见 ⇔ (agent 维未标注或命中当前 agent) AND (workspace 维未标注或命中当前 workspace);当前会话某维度解析不到 时该维度带标注的记忆一律不可见(fail-closed:身份不明只见全局)。sensitivity 为标签不参与可见性判定。 - searchMemories:strict 开启时在融合池先硬过滤(他 scope 出局)再走 occurred 窗/dedup/rerank;与 A2 加权叠加——过滤后剩下的命中行仍吃加成。 - injectCandidates:新增 options.scope,strict 开启时注入候选同口径硬过滤—— scoped 记忆泄进无关注入上下文是最典型的越权通道,仅过滤检索挡不住这里; inject.js 在渲染回调按 ctx(agent.session,与工具 exec 同形)解析 scope 传入。 - store.list/count:新增 visibility 选项(SQL 侧与谓词同口径:未标注 NULL 恒 可见;维度解析不到只放行未标注行),memory_list 分页 total 与行一致;仅显式 传参的用户面调用过滤,dream/质量过滤等内部 store.list 不受影响。 - tools:memory_get strict 下他 scope 的行按不存在处理(无存在性泄漏); memory_list 的 list/count 同口径过滤。 - /features effective 键数 50→51。 测试 +9(四象限语义、匿名 fail-closed、搜索硬过滤、strict 关= A2 行为、SQL 过滤与 total 一致、注入过滤、memory_get 存在性泄漏/行主可取、memory_list 过滤与 total),全量 971 项 970 绿 / 1 既有 skip。 Refs #17(A3/4,剩 A4 面板) * fix(scope): review 观察点——resolver 透传 logger、scopeMultiplier 注释对齐实际语义 #153 观察 1:tools.js/inject.js 的 createScopeResolver 补传 logger: ctx.logger,registry 反查失败时 warnOnce 才有出口(否则静默降级无观测)。观察 2(workspaceRegistry 经 cordis Proxy 访问可能抛错)已有 try/catch 兜底降级 header.cwd,维持现状。观察 3:scopeMultiplier 实际语义=只有确立 foreign(记忆带标注+当前维度可解析+值不等)才吃 ×0.5,未标注行与命中行同列吃 BOOST ×1.25 而非 ×1 中性——常量注释、searchMemories 注释与测试标题三处对齐(行为不变,仅注释与标题)。 * feat(scope): 面板显示与开关(A4,issue #17) v0.8.0 批次 A 收官:scope 隔离的面板面。纯前端(lib/client.js,手写不随 sync 覆盖),后端零改动——/features 与 /list 已在 A1-A3 透出所需数据, 未标注行字段缺省即不渲染,前端不感知开关状态(与 heat 徽章同一模式)。 - 设置卡新增「作用域隔离」组:scopeEnabled(作用域标注总开关)与 strictScope(严格隔离硬过滤)两个开关,i18n 中英双语齐全;开关渲染走 /features effective + PUT 增量提交,与既有布尔开关同一套 FeatureRow。 - 记忆条目 provenance 展示: - 详情抽屉 dmeta 新增四行:发生时间(occurred_at,按日期短格式渲染)、 Agent 作用域、工作区作用域、敏感度——仅在字段存在时出现。 - cards 视图脚部与 timeline 行接入 ScopeBadge 徽章(business-primary 色调,tooltip 展示完整 agent/workspace/sensitivity 归属),未标注条目 视觉零变化。 - 测试:client.test.js 新增「A4 面板开关与 provenance 展示」断言(分组、 十个 i18n 键双语齐全、ScopeBadge 组件与三处接线),全量 972 项 971 绿 / 1 既有 skip。 Refs #17(A4/4,批次 A 完结) * docs(client): ScopeBadge 与 A4 测试补 JSDoc(CodeRabbit docstring 覆盖率警告) * fix(client): ScopeBadge tooltip 本地化——标签复用详情抽屉 i18n 键(云端复验观察点)
v0.8.0 批次 A · A1 存储层(Refs #17,1/4)
scope 隔离的地基:存储层纯增量 + 写入端标注 + 去重键扩展。
scopeEnabled默认关,关闭时行为与改动前逐字节一致;检索加权/过滤在 A2、strictScope 硬过滤在 A3、面板显示在 A4,分开提交。English TL;DR: additive storage layer for scope isolation — four nullable columns (
agent_scope/workspace_scope/sensitivity/occurred_at, no DEFAULT, zero rewrite of existing rows), write-time annotation resolved from the session identity (agentPreset + workspace registry lookup with header-cwd fallback, never blocks the write), and the dedupe key extended from(type, title)to include the scope triple. All behindscopeEnabled(default off).变更点
save写入归一化(非空 trim 字符串收下,脏值落 NULL 绝不阻塞);occurred_at归一 UTC ISO(A2 时间过滤按字典序比较);update 路径不触碰 scope 列(写入时标注,落库后不可变)src/scope.js):createScopeResolver—— agent_scope = session header 的agentPreset(requestHeader()优先、静态.header兜底);workspace_scope 先走ctx.workspaceRegistry按 session.id 反查 canonical path,失败回退header.cwd,再失败留 NULL;全程 try/catch,registry 故障 warn 一次后降级——绝不让 scope 解析阻断写入saveWithDedupe透传标注;去重键(type, title)→(type, title, agent_scope, workspace_scope, sensitivity),NULL 归一为未标注(未标注行互相匹配、与已标注行不匹配,存量行语义不变);autoSummarize 每个turn/end都触发且无产出上限——建议新增节流、条数上限与同会话主题抑制(实测单会话日铸 198 条) #127 的_mergeInto显式并入同样过 scope 门,跨作用域语义相似回落独立新行(防合并泄漏)memory_save接exec.agent.session上下文;新增可选参数sensitivity/occurred_at;agent_scope/workspace_scope 由会话身份解析,不作为模型参数暴露scopeEnabled默认关 +FEATURE_FLAG_BOOLEANS白名单(面板可启停=线上回滚开关)测试
test/scope-storage.test.js16 项:迁移列形态、存量形状读回、归一化脏值、update 不可变、flag 关=旧去重、flag 开=三元组隔离与 NULL 匹配、_mergeInto跨 scope 拒绝、解析器降级矩阵、memory_save 端到端接线/featureseffective 键数断言 49 → 50check-syncsrc↔lib 一致边界说明(给 reviewer)
scoped/<agent>/<workspace>/)不在 A1 范围;当前带 scope 行仍渲染平铺目录,内容与现行为一致。sensitivity为自由文本标签(存储层不枚举校验),取值语义留给 A2/A3 的可见性规则定义。