oh-my-muse/docs/agent-specs/2026-06-23-market资产物化-review.md
lili b5a6b1b423 docs(handoff): market 资产物化架构评审版(裁决伪缺口 + O1 跨租户验证)
2 路调研 + O1 验证(反假绿 file:line)裁决"market 资产物化":
- B(内容副本)与产品-02F:135 禁止项 + Candidate Envelope 已确认决策冲突 → 否
- O1 实证:单租户运行(system_tenant 仅 id=1)+ AI 消费链路(binding→kb 正文)未建成
  (ai application 全量 grep 零命中)→ C/B' 解决的跨租户可读问题当前不触发、
  服务的消费场景不存在 → 双重假想未来建设(违 YAGNI)
- 结论:整条物化主线暂缓,前置(真多租户 or AI 检索消费链路/RAGFlow)就绪前不投入
- SSOT 内部矛盾(A 不物化 vs B 物化)待人类裁决;V27 物化注释系 P2 自写、证据弱

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 00:52:47 -07:00

11 KiB

market 资产物化 — 架构评审版(裁决"物化"真伪缺口)

版本:v0.1 · 日期:2026-06-23 · 目标读者:架构/产品拍板人 + 实现 agent · 类型:评审版(结论 + 拍板点 + blast radius + 验收,不预写代码) 前置:handoff P0/P1(knowledge)/P2(agent)/P3(content) token 红线三 owner 已交付;本主线是 handoff 诚实范围反复标记的"另一维度——market 资产物化"。

〇、本版定位与核心结论(先行)

本版不是"如何实现物化",而是先裁决"物化"是不是真缺口。 2 路反假绿调研(file:line 实证)得到一个反直觉但证据扎实的结论:

"install 自动把 market 资产物化成内容副本"很可能是伪缺口,且其强版与产品规格的明确禁止项直接冲突。 SSOT 主流(流程-02B / 产品-02F / 后端-01)+ 已确认架构决策(Candidate Envelope 去掉、来源版本实时对比)都指向引用语义、不复制内容。"物化"主张只剩 1 个 schema 枚举值 + 1 条 P2 阶段我自己写的迁移注释支撑。

因此真正待拍的不是"怎么物化",而是三选一的方向裁决(详见 §四拍板点):

  • 方案 C(维持引用,评审倾向):不建实体,source_market_asset_id 降级为纯溯源标记或删除。
  • 方案 B'(installed_ref 引用壳):install 在消费者侧建 kb_type=installed_ref 引用记录(指向 source asset、不复制内容),解决跨租户可见/可绑 + 字段落地——A 主线的一种落地。
  • 方案 B(物化建内容副本):install 复制源 kb/agent 内容成独立实体——与产品-02F:135 禁止项冲突,评审不建议

⚠️ O1 验证后的修订结论(2026-06-23,强化为"暂缓整条主线")

O1 已实证(见 §六):当前单租户运行(system_tenant 仅 seed id=1、muse 表 tenant_id DEFAULT 0)+ AI 消费链路(binding→kb 正文/检索)根本未建成(ai application 全量 grep 零命中、knowledge-api 仅 ErrorCode、source-owner facade 只有 fail-closed 桩)。这意味着:

  • C/B' 解决的"跨租户可读"问题当前不触发(单租户双方 tenant_id 相同);
  • 它们服务的消费场景(作品用 kb 内容生成)还不存在入口

现在做 C/B' = 为「还没启用的多租户」+「还没建的 AI 检索消费链路」双重假想未来建设,违 YAGNI / CLAUDE.md「不为一次性代码建长期抽象」。 故评审最终建议升级:整条 market 资产物化主线暂缓——前置(真多租户需求 AI 检索消费链路/RAGFlow 落地)就绪前不投入。唯一低成本可选动作 = 补 MuseAgentDO 字段映射 + handoff/install 时 set source_market_asset_id纯溯源留痕;高 ROI 不在此主线(下一步方向见 §四 Q5 / 回 2026-06-22 盘点)。


一、现状(2 路调研实证,file:line)

install 当前行为(无歧义事实基线)

  • MarketInstallServiceImpl.installMarketplaceAsset:50-107:install 只校验授权 + 写 muse_market_installation(status=installed)+ 推进 license 投影;显式 targetFactsWritten=false(:95-96:198-200 硬编码)。
  • :62-64 注释:"作品资产不走安装流程;后续 bind/handoff 也不能把 install 当目标 owner 事实写入"。
  • 全方法无任何 kb/agent 建实体调用

模块边界(物化的硬约束)

  • market-server 唯一跨模块依赖 = member-api,对 AI/Knowledge/Content 零依赖(muse-module-market-server/pom.xml;grep MuseKnowledgeBaseDO muse-module-market 空)→ market 模块物理上无法建 kb/agent 实体或回源读内容。

asset 不承载内容(物化"内容从哪来"的核心问题)

  • MuseMarketAssetDO / V6__init_market_schema.sql:asset 只存 source_id BIGINT(指向原始 kb/agent)+ 元数据;不含知识条目/agent prompt 正文
  • version snapshot(AdminMarketReviewServiceImpl.createListedVersion:500-507)只快照发布草稿元数据(name/summary/sourceId/...),无源内容本体
  • → 若要建内容副本,必须回源读发布者的 muse_knowledge_* / muse_agent*(跨发布者→消费者复制),market 模块还没这个依赖。

目标侧字段 = 休眠列(零读写)

  • muse_knowledge_base.source_market_asset_id(V5:10,DO MuseKnowledgeBaseDO.java:31 已映射)+ muse_agent.source_market_asset_id(V27:11,DO 未映射):全仓 grep setSourceMarketAssetId / mapper xml 三路皆空——字段在、零写入
  • 现状 binding 直接 kb_id = parseLong(sourceId) 引用 source kb(MuseKnowledgeBindingService:110,148),不建新实体。

二、SSOT 内部矛盾(评审版必须裁决,原文对照)

主线 主张 证据(文档:行) 证据强度
A 不物化/引用 不新增 owner、不自动写入、引用语义 流程-02B:363「市场知识库资产不新增知识库 owner,不自动写入局域知识库」;产品-02F:16「任何市场资产都不能自动写入作品事实」;产品-02F:135 把「安装后自动写入局域知识库」列为禁止项;后端-01:108「只记录授权/安装/可展示;不写目标对象绑定事实 (产品+流程+领域模型,含禁止项)
A 既有架构决策 引用 + 实时对比,非快照 CLAUDE.md 核心决策「Candidate Envelope:去掉,简化为来源版本实时对比」;流程-02B:29 主流程含「来源版本实时校验」 (已确认决策)
B 物化/建实体 install 自动物化建独立实体 后端-04:426 kb_type=installed_ref(枚举值预留);后端-04:428 source_market_asset_id「若来自市场安装,引用市场资产」(注:原文"引用"其实偏 A);V27 SQL 注释「install 自动物化为独立后续主线」 (1 枚举值 + 1 字段注释 + V27 注释系 P2 阶段本 agent 自写)
D 复制为副本 许可允许时用户主动复制 产品-02E:34 / 02D:34「许可允许时可复制为用户知识库/个人智能体 文档有、代码零实现(grep copyKb/cloneAgent 空);且是用户主动非 install 自动

关键裁决张力:B 强版(install 自动复制内容成副本)= 产品-02F:135 明令禁止的"安装后自动写入局域知识库"。二者不可兼得。


三、问题重新框定

把"物化"拆成两个被混淆的不同诉求:

  1. 内容复制(B 强版) — install 自动把发布者 kb/agent 内容拷成消费者独立副本。与禁止项冲突 + 违背 Candidate Envelope 决策,评审不建议。 真要"拥有副本"应走 D(用户主动复制),非 install 自动。

  2. 引用壳 + 溯源(B') — 真正可能的缺口在这:现状 binding 用 kb_id=parseLong(sourceId) 直接引用发布者 kb id(P1 诚实范围已记:e2e 绿靠 fixture 巧合 asset1→kb_id=1)。跨租户下,消费者作品直接绑发布者租户的 kb 实体,可见性/租户隔离存疑(未确证、列开放项 O1)。 kb_type=installed_ref 的设计本意很可能是:install 在消费者侧建一条引用记录(指向 source asset、内容仍引用源、实时对比),让消费者有自己租户下的可绑条目 + 让 source_market_asset_id 溯源落地。这是 A 主线的合规落地,不复制内容、不违反禁止项。

→ 评审主张:否掉 B,在 C(纯引用,最小)与 B'(installed_ref 引用壳,解决跨租户+溯源)之间裁决


四、拍板点(请你定)

# 拍板点 选项 评审建议
Q1 install 是否物化建内容副本(B 强版) 是 / ——与产品-02F:135 禁止项 + Candidate Envelope 决策冲突
Q2 是否需要 installed_ref 引用壳(B',消费者侧建引用记录、不复制内容) 需要(若跨租户绑定确有隔离问题)/ 不需要(维持直接引用 source) 先验证 O1 跨租户可见性 → 有问题则 B'、无问题则 C
Q3 source_market_asset_id 休眠字段去留 降级纯溯源标记(install set、不建实体)/ 配合 B' 落地 / 删除 跟随 Q2:选 C→纯溯源标记或删;选 B'→配合落地
Q4 是否做 02E/02D"用户主动复制为副本"(D,独立功能) 本主线做 / 列独立功能按需排期 列独立功能(文档有代码无、用户主动授权、非 install 自动,与本主线解耦)

五、blast radius(按方案)

  • 方案 C(纯引用 + 溯源标记):最小。install 处可选 set source_market_asset_id(纯标记)+ 补 MuseAgentDO 字段映射 + 删/留休眠列决策。不碰模块依赖、不碰内容复制。 风险极低。
  • 方案 B'(installed_ref 引用壳):中。需定 install 时由建引用记录(market 无 knowledge/ai 依赖 → 经各 owner 的 -api 端口反向回调,如 P1-P3 的 BC 端口模式)+ kb_type=installed_ref / agent market_installed 枚举落地 + 工作台"已安装 kb/agent"列表与绑定接线 + 跨租户可见性方案。涉及 knowledge/ai/market 三模块 BC 边界,须 ArchUnit 守。
  • 方案 B(内容副本):大且不建议。market 反向依赖 knowledge/ai 回源读内容 + 多表内容复制(异步任务/幂等/补偿,CLAUDE.md 铁律)+ 与禁止项冲突需先改 SSOT。

六、开放项(实现前须验证)

  • O1(决定性, 已验证 2026-06-23):结论 (b)+(d)+(c') 复合——① binding 阶段不查 kb(直接信前端 sourceId,MuseKnowledgeBindingService:110,148 无 kbBaseMapper 注入)→ 跨租户不因绑定失败;② 租户隔离基线完整(kb/document/entity/relation/binding 全 extends TenantBaseDOV5 各表 tenant_id NOT NULL DEFAULT 0、无 @TenantIgnore,yudao 拦截器自动注入租户条件,MuseKnowledgeEntityMapper:36 注释自证)→ 设计上跨租户读不到内容(b);③ 当前实际单租户(system_tenant 仅 seed id=1、muse 表 tenant_id DEFAULT 0)→ 问题当前不触发(d);④ 额外铁证(c'):AI 域当前根本没有 binding→kb 正文的读取/检索路径(muse-module-ai application 全量 grep 零命中、muse-module-knowledge-api 仅含 ErrorCode、MuseExternalSourceOwnerFacade 只有 fail-closed 桩 Unavailable...)——"用到发布者内容"今天连入口都没有。→ installed_ref/物化只在「多租户化 + 消费链路建成」双前置就绪后才有意义,二者当前都不存在(见 §〇 修订结论)。
  • O2:muse_market_installation 账户记录 与 假想的 installed_ref kb 条目职责是否重叠? 工作台"可绑定 kb 清单"现在读哪张表?
  • O3:agent 侧 agentType='market_installed'(04a 注释枚举)与 P2 已落的 agent_type='market'(handoff 放宽用)关系——是否同一概念两套命名,需统一。

七、验收(方案确定后细化)

  • C:字段决策落地 + DO 映射补齐 + 单测/无回归;不新增 e2e(无行为变更)或补"溯源标记可读"读端 e2e。
  • B':install→引用记录→工作台可见→绑定 真后端 e2e + BC 边界 ArchUnit + 跨租户隔离用例。

下一步:先答 O1(跨租户可见性,决定 C vs B')与 Q1/Q4(否掉内容副本、D 解耦),即可定主线方向。评审强烈建议:不做 B 内容副本;在确认 O1 后于 C / B' 间取一。