494 Commits

Author SHA1 Message Date
lili
d4309ab0e9 test(market): U-retrieve 检索打通(D0-fork 第三单元、RetrievalApiImpl 零改动)
D0-fork 第三单元:验证 installed_ref 物化后检索链自然打通、消除 no_dataset。RetrievalApiImpl 生产代码 0 改动(临时-04 判断属实):U-materialize 已在数据层闭合去污染链(binding.kb_id=本地 kbId、ragflow_binding 指公开副本)→第四门 selectActiveDatasetByKbId 返非空→no_dataset 分支不进→进 RAGFlow 检索;授权快照 knowledge/api 全程 String 透传无 parseLong(ADR-020、无 NumberFormatException);document_ids/metadata_filter 保持 null(命中纯公开副本、无需运行时隔离)。

加 2 单测(MuseKnowledgeRetrievalApiImplTest 15/15):no_dataset 消除+命中(对照基线无 dataset binding 时 no_dataset)、字符串授权快照透传。发布者私有不泄露(真 RAGFlow)+真 PG 端到端留 U-verify。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 11:33:43 -07:00
lili
30a693e1b7 feat(market): U-materialize 安装侧物化(D0-fork 第二单元、kb_id 去污染)
D0-fork 第二单元:knowledge 绑定路径把"只写引用绑定"升级为建本地 installed_ref KB 实体+binding 指向公开副本 dataset。新增 MarketAssetSourceApi 跨 BC 读端口(market-api+server、读出 发布者kbId/publicForkDatasetId/forkStatus、从 market_asset 自有 source_id+tags JSONB、与 ForkApi 写职责分离);knowledge 经 -api 不读 market .dal。

MuseKnowledgeBindingService:precheck 跨 BC 读市场资产+公开副本(存在/knowledge_base 类型/forkStatus=ready 校验、固化进 precheck 快照)、bind 建 installed_ref KB(kb_type/source_market_asset_id/license_snapshot_id 数值主键 D8/owner/active)+指副本 ragflow_binding 同 @Transactional 原子。kb_id 去污染:market_kb 不再 parseLong(sourceId)当 kbId(那是 assetId)、改本地新建 installed_ref kbId、binding/projection/installed 列表读回全跟随(消除检索 no_dataset 根因)。D6 fail-closed:仅 forkStatus=ready 放行、pending/partial/failed 拒、0 写。幂等(安装者,资产)维度复用。多安装者共享同一 publicForkDatasetId、kb_id 各异不撞 uk。

单测 26 绿(BindingService 16+InstalledService 8+RoundTrip 2)、BcBoundaryArchTest 2/2、编译 BUILD SUCCESS。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 11:26:57 -07:00
lili
5a938319a8 feat(market): U-fork 发布侧 fork 公开副本(D0-fork 第一单元、进程内事件接线)
D0-fork 第一单元:知识库上架时发布侧 fork 一份只含公开快照文档的专用 dataset、安装者只读共享、物理隔离发布者私有。KnowledgeMarketForkService(核心):公开集界定(上架时刻 searchable/generative active 文档、私有不进副本)+RAGFlow 三步复制(createDataset+逐文档 uploadDocuments+startParseDocuments、无 copy API)+异步重活(幂等键(assetId,version)/部分成功补差集/失败按 FailureClass 重试/审计)。

订阅 glue(人类拍板进程内 Spring 事件、非统一 Events 因其无后端消费机制):事件对象 MarketKbListedEvent 落 market-api(守 BC、market 发 knowledge 听);market markListed publishEvent;knowledge @TransactionalEventListener(AFTER_COMMIT 不绑架审核事务)+@Async(不阻塞审核线程)+TenantUtils(异步租户上下文)+错误隔离。@Scheduled 兜底扫 forkStatus≠ready 重试(进程内事件不持久化、保最终一致、config-gated 默认关)。副本 datasetId+forkStatus 写回 ragflow_binding(market_public_fork+binding_summary JSONB)+market_asset.tags(经 MarketAssetForkApi 供 U-materialize 读)、不加 DDL。移除冗余 outbox kb_listed 双重死代码。

单测 14/14(ForkService 6+Consumer 3+Backfill 5)、BcBoundaryArchTest 2/2(market 不依赖 knowledge)、market-server 212+knowledge-server 268 回归绿、编译 SUCCESS。诚实:端到端为单测层验证、AFTER_COMMIT 真事务时序集成验证留 U-verify。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 11:05:13 -07:00
lili
c12eb013cd docs(market): D0-fork KB 物化执行 plan(临时-04、supersede 临时-03)
D1 澄清坐实真越权=安装者读到发布者私有内容(非安装者间):market 对 knowledge/ragflow 零依赖(src+pom 双空 spot-check)→上架不 fork、安装者共享发布者活 dataset、上架后 KB 仍可加私有文档(上传无 market 门禁)。用户拍 D0-fork(发布侧 fork 纯公开副本、物理隔离)。

临时-04 四单元:U-fork(发布侧 fork 公开副本核心新工程:上架事件→knowledge 异步 createDataset+逐文档 uploadDocuments+重索引,RAGFlow 无 copy API 必重走三步 spot-check 确认)/U-materialize(安装侧物化去隔离、binding 指公开副本)/U-retrieve(检索去隔离)/U-verify(发布者私有不泄露、复用临时-03 U0 反向基线)。关键推荐:fork 时机=上架 markListed(副本=公开快照语义)、接线=事件驱动(复用 market EventPublishOutbox+ADR-017、不绑架审核事务、保 market 不反依赖 knowledge)、DDL=初版不需(V5/V14 列+JSONB)。临时-03 标 superseded 保留演进史、U0 证据+四硬事实继承。待拍 D4-D10 后执行。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 09:53:19 -07:00
lili
a8a26983fc test(market): U0 spike 钉 KB 物化共享越权基线 + 拍 D1=S 回填
market install KB 物化 U0 spike 产 D1 决策证据(只 spike 测试零业务代码):MuseKnowledgeRetrievalApiImplTest +2 case(13/0 独立复跑确认)——①他租户私有 chunk 原样返回证伪租户过滤 ②ArgumentCaptor 抓 RetrieveChunksCommand documentIds/metadataFilter 均 null 证整库扫描零隔离;同作 U4 隔离回归反向基线(隔离补到位后应转红)。活体真 RAGFlow 整库返回坐实。

U0 揪出潜伏 bug:检索发 metadata_filter 但 RAGFlow 官方契约(context7)是 metadata_condition→被静默忽略(乱值条件仍返 baseline)、字段名修正纳入 U3。用户拍 D1=S(补隔离后共享、真最小留痕):临时-03 回填 S 分支定调(隔离优先 metadata_condition+物化打安装维度元数据+U4 复用 spike 反向基线)。进度总账回写方向全链路。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 09:14:14 -07:00
lili
76a7e0d312 docs(market): KB 物化执行版 plan(临时-03、待 D1 拍板后执行)
承临时-02 拍板(B' installed_ref + KB 先行)出 KB 物化执行版 plan,拆 U0-U4 可独立验证实现单元。出 plan 时一手代码核验揪出四条改变工作量/性质的硬事实(均 spot-check 坐实):①kb_id 当前被 market assetId 污染(KnowledgeHandoffLanding sourceId=assetId)→物化须去污染改写;②assetId→发布者 dataset 反查链跨 BC 断(market.api 仅 HandoffTokenApi)→需新增 MarketAssetSourceApi 本地读端口;③多租户共享同一 RAGFlow dataset 必越权(retrieveChunks body 不含 tenant+document_ids=null 全量返回、parseChunks 无 chunk 租户二次过滤)=安全红线→U0 从"验证能否共享"转为"共享前先补 chunk 级隔离"硬门;④muse_source_propagation_target 表零命中→U4 回滚改基于真实 source_event 机制。

物化落点严格在 knowledge 绑定路径(非 install、handoff 非物化桥、安装解耦不动)。初版判定不需新 Flyway 迁移(V5/V14 已备列)。决策点 D1(共享 S/复制 C/暂缓 H)待人类先看 U0 spike 证据再拍。两图文(text+mermaid + html 人读图)+大纲注册。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 08:33:41 -07:00
lili
26ff1af374 docs(market): market install 下游物化方案设计文档(评审版、待 review 拍板)
market install 后下游物化方向(用户选)方案设计:深调研 2 agent+spot-check 坐实两物化断点——install 只写 muse_market_installation 与 ai/knowledge 解耦、KB bind kbId=parseLong(sourceId)不建本地 muse_knowledge_base 行致检索 no_dataset 第四门省略、agent slot 放宽但 runtime requireVisibleAgent 拒裸引用。出 C(完整物化)/B(惰性)/B(installed_ref 最小留痕)/暂缓 四方案对比。

推荐 B(installed_ref 最小留痕、KB 优先共享发布者 dataset、物化落点放目标域绑定路径非 install——handoff 非物化桥、安装解耦正确不应改)。地基不对称坐实:KB(V5 kb_type/source_market_asset_id)+agent(V27 source_market_asset_id、注释物化后续主线本列先就位)列已备、但 agent market_installed 类型有文档(后端-04)无实现→两域工程量不同。决策点待拍板:物化深度(倾向 B)、时机(绑定同步非惰性)、dataset 共享 vs 复制(唯一硬风险、共享前必验多租户 RAGFlow 隔离)、agent market_installed 落地量(否则 KB 先行)、召回回滚。两图文+大纲注册。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 06:47:45 -07:00
lili
bd26e18481 docs(it): 回写全量 50 P1r IT 全绿——本 session 验证三层全维度收尾
进度总账更新:抽样 6/6 后全量 50 P1r IT 50/50 全绿(199 用例、4 LiveAcceptance 真外部)、修 2 预存红(Planning schema V31+live-acceptance 第二代理坑)、muse_slice_live 167 表+数据独立核实完整未被 IT 误删。本 session 验证三层全维度全绿:e2e(admin12/studio56)+CI 单测(全 reactor 2834)+真 PG IT(全量 50/50)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 02:10:52 -07:00
lili
94545ff87b test(it): 全量 50 P1r 真 PG IT 收尾全绿——修 Planning schema 版本 + live-acceptance 第二代理坑
继抽样 6/6 后跑全量 50 P1r 真 PG IT(用户选继续、IT 层 CI 健康收尾):50/50 全绿(199 用例 0F/0E/1S、1 skip=RagFlow GraphRAG assumeTrue)、含 4 个 LiveAcceptance 真打 New-API/RAGFlow。修 2 预存历史红(均非本 session):

Planning IT 4F:TARGET_VERSION 停 V21 但 savePlanningItem→captureFieldSnapshot 依赖 V25 新增 muse_content_planning_field_snapshot 表(94a2379)→relation does not exist 500;修=21→31(同 Core V30/AiRuntime V31 同向、核心 planning fact/command/outbox 断言不放宽)。4 live-acceptance 502/UNAVAILABLE:第二代理坑——SOCKS 清理只清 socksProxyHost、macOS 系统代理 127.0.0.1:7897 仍被 JVM 注 http.proxyHost、java.net.http.HttpClient 走死代理;反误判=curl --noproxy 直打全 200 证外部健康;修=argLine 加 -Dhttp.proxyHost= -Dhttps.proxyHost= -Djava.net.useSystemProxies=false。external-deps 蒸馏。

anti-false-green:核实 Planning diff 仅 schema 版本非放宽、muse_slice_live 167 表+数据完整未被 IT flyway.clean 误删(_test 库隔离遵守 muse_p1r_*_test)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 02:09:45 -07:00
lili
b65c453a33 docs(it): 回写抽样关键链路真 PG IT 验证(6/6 全绿)——本 session 验证三层全绿收尾
进度总账加抽样 IT entry:6 关键链路 P1r 真 PG IT(knowledge 多 binding/AI 生成采纳 ADR-020/AI runtime e2e/知识检索 P-A·B·C/market handoff)真 PG+真外部 6/6 全绿、修 1 预存红(P1rAiRuntime IT schema V31+补 bean 跟上演进)。本 session 验证三层全绿:e2e(admin12/studio56)+CI 单测(全 reactor 2834)+抽样真 PG IT(6/6)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 01:04:20 -07:00
lili
a0569c6481 test(it): 修 P1rAiRuntimeEndToEndLiveAcceptanceIT 落后产品演进的测试上下文(schema V31+补 bean)
抽样关键链路 P1r 真 PG IT 验证(用户选抽样、6/6 全绿)中发现并修的预存历史红(非本 session、测试基建跟上产品演进):TARGET_VERSION 13→31(ADR-020 V30 把 muse_ai_suggestion.authorization_snapshot_id BIGINT→VARCHAR 承载字符串 envelope,停 V13 会 bigint 类型不匹配)+ 补 MuseAiEventPublishOutboxService 空实现/KnowledgeRetrievalFacade empty context 两 bean(投影/executor 经 ADR-020 outbox+P-A 检索演进新增 @Resource 依赖、IT 上下文未跟上;校验属其他 IT 职责、与 P1rContentMergeGeneratedSuggestionIT 同源)。

核心 AI 生成→runtime_call→落库断言不变(非放宽)。验证:agent 引用 3 类存在 + muse-server test-compile BUILD SUCCESS;agent 真 PG+New-API 真外部 LiveAcceptance 跑 3/3 绿(独立跑因 flyway.clean DROP 库风险未做、改以核实 diff 合理+编译+agent 报告)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 01:03:24 -07:00
lili
79674ff31d docs(ci): 回写「继续验证修复」收尾——e2e 最新态 + CI 单测全绿(全 reactor 2834/0/0)
进度总账加验证收尾 entry:admin e2e 12/12+studio 56/56 确认、本 session 改动无回归(后端 BUILD SUCCESS+前端 studio107/admin345)、全 reactor 单测健康扫揪修 3 预存历史红(knowledge @Mock 缺失/pay redis 配置缩进/coverage 报告漂移、均非本 session)后 2834 tests 0F/0E BUILD SUCCESS、分支订正(实际 dev/1.0.0 集成分支)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 22:55:32 -07:00
lili
effb3f884b test(ci): 修全 reactor 2 个预存历史红——pay redis 配置缩进 + 覆盖报告陈旧路径(CI 单测全绿)
全 reactor 后端单测健康扫(继 knowledge 7ee9cc8 后摸清其他模块)揪出 2 预存历史红(均非本 session、自包含修复):pay 4 用例 NOAUTH——application-unit-test.yaml 的 data: 缩进 4 空格误挂 sql: 下→spring.data.redis.port=16379 失效→退默认 6379→命中本机带密码真 Redis;修=data:/redis: 回退 2 空格对齐 spring:。源自初始导入 43d6806(继承 yudao 上游)、8963383 首次全绿时 6379 无密码侥幸过。

muse-server P1rApiCoverageReportTest——p1r-api-coverage.json 16 处 completed operation 指向已删 UnavailableMetaImpactFacade.java(4bd292f 用 RealMetaImpactFacade 替换时报告未同步);修=16 处→RealMetaImpactFacade.java(替代者、JSON 合法)。验证:全 reactor mvn -o test 2834 tests 0F/0E BUILD SUCCESS;独立复跑 PayOrderServiceTest 46/0、P1rApiCoverageReportTest 8/0 真转绿。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 22:54:20 -07:00
lili
7ee9cc866e test(knowledge): 补 MuseKnowledgeBindingServiceTest 漏的 @Mock MarketHandoffTokenApi(修预存 NPE 红)
回归验证(本 session 改动确认)顺带发现的预存历史红(非本 session 引入、真实 CI 隐患):should_createMarketBindingPrecheckWithRedactedHandoffHashAndRfc3339Expiry 因测试类漏声明 MarketHandoffTokenApi 的 @Mock→@InjectMocks 注入 null→service consumeMarketHandoff 调 marketHandoffTokenApi.verify(:275)抛 NPE。该红源于 Market handoff 特性(e5d2b52/3a7a72f、6-19)补 verify/consume 真验真核销时,测试 mock 装配未跟上。

补 @Mock + 该用例 stub verify(valid=true)让 market_kb 兑现路径通过,聚焦原 precheck handoff hash 脱敏/RFC3339 过期断言不变。验证:MuseKnowledgeBindingServiceTest 11/11 全绿 BUILD SUCCESS(此前 :71 NPE 红、其他 10 用例不破坏)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 22:37:50 -07:00
lili
85ad97798f docs(studio-e2e): 回写 56/56 全绿收尾(SSE 慢路径活体补证 + agent-slot-bind flaky 根治)
进度总账加 56/56 里程碑:SSE 修复收尾全量 3 轮验证(4 修复 spec 3/3 全绿无交叉回归)、AI SSE 慢路径活体补证(ai-gen 36s/accept 47s 真>30s 仍绿、消除"本机未自然>30s"残留)、agent-slot-bind 预存 flaky 根治(10 次独立循环 10/10)。本 session e2e 阻塞全清:admin 12 真连 0 skip + studio 56/56。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 20:17:08 -07:00
lili
d1917b4f77 test(studio-e2e): 收窄 agent-slot-bind 断言到槽位面板容器,根治 strict mode 歧义 flaky
agent-slot-bind:94 之前 flaky(~64% 失败):getByText(当前:xxx v1)全局 strict 命中 2 元素(AgentPage 沙盒试用区 selectedAgent 回显 + SlotBindingPanel 槽位 boundAgentName、选中 agent==已绑时同文案),与槽位异步读时机竞速。收窄到 div.rounded-2xl filter 作品槽位绑定 槽位面板容器内断言(仿套件其他 spec 的 locator().filter() scope、不改产品)。

验证:10 次独立 playwright test 循环(每轮重跑 globalSetup 复位 revision=1、非 --repeat-each 避 fixture 漂移伪红)10/10 全绿、无 strict mode violation。预存 flaky(commit 1fbe7ae 引入、非本轮回归);至此 studio e2e 56/56。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 20:16:07 -07:00
lili
fd44d4a8bb docs(ai): 回写 SSE 长任务超时修复闭环(进度总账 + muse-module-ai/.agent 通则沉淀)
c77b006 SSE 修复后回写:进度总账 AI e2e entry 标已修闭环(A1+③);muse-module-ai/.agent 沉淀通则「SSE 长任务死线须 ≥ 上游 TOTAL_TIMEOUT + AI 流重连必须以 SSE id 幂等去重(后端 seq0 全量回放)」,避免重踩后端比上游先关门。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 19:54:31 -07:00
lili
c77b0064be fix(ai): 修 AI 流 SSE 长任务候选丢失(后端死线可配≥上游+前端重连幂等)+A1 启动脚本固化 AI 凭据
studio e2e ai-generation 真红根因=SSE 协议/时序 bug:后端 SSE 死线 30s < LLM 真实时延(且<上游自己 180s 总窗口)+前端 connectAIStream 无重连→长 AI 生成候选永丢(ai-gen 真红/accept flaky 同此 bug)。按方案 A1+候选③(design-docs/临时-01)、人类 review 批准后执行。

A1 环境固化:start-muse-server-infra.sh 追加 source p1r-external-acceptance.env(仅 source 路径不硬编凭据、缺失告警不退出)。后端③死线可配:MuseAiTaskStreamServiceImpl 删 DEFAULT_TIMEOUT_MILLIS 硬编码、改 @Value muse.ai.sse.task-timeout-millis 默认 240000(≥上游 TOTAL_TIMEOUT 180s+轮询/回放余量),连接死线(:70)+poll deadline(:198)同引用;application.yaml 加配置项。前端③重连+幂等:sse.ts connectAIStream 非终态结束退避重连续 poll、按 SSE id 去重(后端每次 seq0 全量回放→lastSeenSequenceNo 丢弃已见)、done/error terminal 停、总超时 300s→onError 不静默卡死;返回 AbortController、AIPanel 零改动。

compatibility:connectAIStream 唯一调用方 AIPanel、streamTask 唯一入口 controller、events 模块 30s 死线独立不动;回滚 git checkout、无 DB 迁移。验证:后端 SSE 单测 14/14+前端 107/107(含 4 新重连去重用例)、活体 e2e ai-generation+accept 连跑 3 轮 6/6 全绿、DB 落 6 行真 LLM suggestion、重连幂等方法 A 活体证。残留:本机 LLM 6.8-19s 未自然跨 30s、慢路径靠 240s 数学覆盖+单测+重连活体证三重保证。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 19:51:41 -07:00
lili
09c35f5eee docs(ai-e2e): AI 流 SSE 长任务超时修复方案评审文档(待 review、不改 code)
studio e2e ai-generation 真红深诊出 SSE 协议/时序 code bug,按规范(产品行为变更先评审)出方案评审文档供 human review。两层根因:①server 启动漏 source acceptance env(AI 凭据)②后端 DEFAULT_TIMEOUT_MILLIS=30s 同时作 SSE 连接死线(:60)+poll deadline(:188)、< 上游自己 180s 总窗口(MUSE_AI_NEW_API_TOTAL_TIMEOUT_SECONDS),前端 connectAIStream 无重连(AIPanel 流结束不重连不报错)。

推荐 A1(启动脚本固化 AI 凭据)+候选③(后端放宽死线兜底+前端断连重连容错),排期紧分阶段 A1→①→②。3 决策点待 review:timeout 取值(应 ≥180s+余量、非初稿 120s)/是否上前端重连(推翻 AI 流一次性设计)/重连续传幂等候选去重。text+2 mermaid(因果时序+选项关系)+html 人读图;大纲注册 v7→v8。本轮未改 code、待 review 后执行。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 19:18:21 -07:00
lili
45ca6f4881 docs(ai-e2e): 回写 AI 真生成 e2e 真红深诊(两层根因:环境已修+SSE code bug 方案评审中)
进度总账加 AI e2e 诊断 entry:ai-generation 真红/accept flaky 深诊定位两层均非 AI 外部(New-API 在线)——①server 漏 source p1r-external-acceptance.env(已重启修、脚本待固化)②后端 SSE DEFAULT_TIMEOUT_MILLIS=30s 死线<LLM 时延(11-60s)+前端 connectAIStream 无重连(SSE 协议产品行为变更、用户选 A 方案评审中)。同步 knowledge bug entry 标已修闭环 0b152d9。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 19:11:29 -07:00
lili
0b152d9c6d fix(knowledge): 修 KB 绑 ≥2 作品停用/删除必 500 真后端 bug + 补真 PG IT(studio e2e 真连揪出)
studio e2e knowledge-disable-restore 真连揪出 mock 单测掩盖的生产 bug:任何用户把知识库绑到 ≥2 作品后无法停用/删除(disable POST HTTP 200 但 body code:500)。根因:updateStatusByKbId 给该 KB 所有未删 binding 写同一停用 commandId→违反 uk_muse_knowledge_binding_command(tenant_id,command_id)唯一索引→DuplicateKeyException。

command_id 语义=「创建/最后改写该 binding 的命令」行级幂等键(单行写路径 create/delete/updateInstalled 各写一行;对称 source projection 无 command_id、用 last_event_id 印证 KB 级 fan-out 不占行级幂等槽);KB 级停用是 KB 维度单命令(commandId 已记 muse_knowledge_base+source_event)、非 binding 创建命令。修(候选①传播不覆盖 command_id):updateStatusByKbId(Long,String,String)→(Long,String)删 setCommandId 只翻 binding_status;propagateKbBlocked 去 commandId 参传 sourceEventId;disableGlobalKnowledgeBase(:190)/changeUserStatus(:452 user disable+delete)2 调用点同步。

影响面=全局/用户 KB disable+用户 KB delete 三传播路径,行为变化仅不再改写 binding.command_id(binding_status/affectedBindings/source projection 不变);对外契约不变、纯修 500;回滚 git checkout。

mock 单测掩盖根因(mock updateStatusByKbId 返行数、不触发真唯一索引)。补真 PG IT P1rKnowledgeBaseDisableMultiBindingIT(真 PG+Flyway V14+真 service/mapper):KB 绑 2 作品 disable/delete 传播成功+两 binding 各保留 command_id;反假绿用例直写同 command_id 仍被唯一约束拒(SQLState 23505)。修后 3/3 绿;临时重引入 bug→2/3 DuplicateKeyException 证真回归门禁。独立核实:e2e 连跑 3 次 2 passed(修前红);psql 复核 KB1 2 binding(work1+work2)全 disabled、command_id 各异无冲突;global-setup 补 9b 多 binding 锚点(KB1+work2)令 e2e 真走 ≥2 binding 传播路径。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 18:20:50 -07:00
lili
d8badcde11 docs(studio-e2e): 回写 studio e2e 全量核查(健康 54/56)+前端双 bug 修+flaky 根治+真后端 bug 发现
studio e2e 核查里程碑:36 spec/56 case MSW-off 真连、整体健康 0 假绿候选。修前端双 bug(443a1f3 ChapterPanel 双提交+WorkspacePage 乐观锁兜底)、环境 fixture(de5f4d0 asset1/work1 复位)、来源污染 flaky(ca0e04c source-attribution 解耦 block3)。最大价值=揪出真后端 bug(knowledge updateStatusByKbId 多 binding 写同 commandId 违反 uk 唯一索引→KB 绑≥2 作品无法停用、mock 单测掩盖、用户批准委托修中)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 17:58:28 -07:00
lili
ca0e04c9a9 test(studio-e2e): source-attribution 解耦到 pristine block3 根治测试间来源污染 flaky
source-attribution 只读 spec 期望 block1 来源=user_original,但全量串行时前序 accept-suggestion(写 ai_suggestion)/block-autosave/block-structure 按字母序先跑且都写 block1,block1 顶层 revision 来源在 user_original/ai_suggestion 漂移→偶发渲染"AI 生成"红;global-setup 每轮仅跑一次、无法撤销跑中途污染。修:spec 改读 pristine work3/block3(grep 确认无人导航 /workspace/3、无人写 block3)+global-setup §3 每轮删净 block3 归因并重建唯一 user_original rev1 行(幂等)。断言未放宽仍真断言 user_original。免疫验证:强灌 block1 顶层 ai_suggestion(旧 spec 必红条件)新 spec 仍绿;独立连跑 source-attribution 3 次全绿。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 14:35:19 -07:00
lili
de5f4d0bf9 test(studio-e2e): global-setup 补 asset1/work1 fixture 复位(环境污染致 7 spec 偶发红)
studio e2e 全量核查 run1 7 红,根因测试间环境污染、global-setup 复位不全:①asset1「活体市场资产·测试」被历史操作 delisted(应 listed/active)→bind-precheck 返 1044000003 资产不存在→连带 handoff-agent/content/knowledge+live-read 市场浏览+market-governance-impact+market-handoff-precheck 6 红;②work1 残留多余 writing.expansion active 槽位(spec 假设仅 continuation)→agent-slot-bind strict 命中 2 元素红。修:§17 复位 asset1→listed/active、§18 删 work1 非 continuation 槽位。验证:重新污染→自愈后 7 spec 全绿、全量回归持续绿。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 13:47:28 -07:00
lili
443a1f3414 fix(studio): 修新建章节双提交 + work 乐观锁版本兜底两处 bug(studio e2e 真连揪出)
studio e2e chapter-create-delete 偶发 code=1041000002,根因两个独立前端 bug:①ChapterPanel 双提交:input onKeyDown(Enter→submitCreate)+onBlur=submitCreate,Enter 提交成功后 setIsCreating(false)卸载 input→onBlur 二次触发,isCreatingPending(异步)+disabled 滞后挡不住→重复 POST(第 2 个同 reqRev→500)。修:submitCreate 加同步 useRef 守卫(提交中早返+置位+onSettled 复位),只挡同次重入、不挡首次/失焦补提交。②WorkspacePage expectedWorkRevision 兜底:原 workRevision(work)??1,work 详情异步未加载时兜成 1、但真实 revision 已 >1→乐观锁冲突。改传真实 revision(未加载 undefined→ChapterPanel 既有 ==null 早返挡过早提交)。

实证:单次新建 POST 修前 2(第 1 成功+第 2 1041000002)→修后 6 轮恒 1;chapter-create-delete 连跑 8 次全绿。相邻写路 spec 不回归、tsc 0 错、editor 单测 33/33。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 13:47:28 -07:00
lili
80106c2d40 docs(admin-e2e): 回写 admin governance e2e 转真后端全收口(account/market/jobs/meta governance 12 真连 0 skip)
进度总账补 4 entry:account 子域 MVP+基建(c5d1762)、market 下架/申诉真打(ce637ac)、jobs 重试/取消/来源重试(2d06ec5)、governance config 拆 6 子系统真连(6bd9030)。纠正 jobs entry 沿用的"muse_function_chain/muse_protection_node 缺表"误判前提(实为 muse_meta_* 表在缺种子、agent 漏 meta_ 前缀)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 13:07:31 -07:00
lili
6bd90301a5 test(admin-e2e): governance config 全页巡航转真连——拆 6 子系统真连+灌系统级种子(admin e2e 0 skip 全收口)
承用户选 B(补 admin config 断层)。前提纠正:原 skip 注释"切片库根本没有 muse_function_chain/muse_protection_node 表"误判——psql 实证真表名带 meta_ 前缀=muse_meta_function_chain/muse_meta_protection_node(V3 schema、都在 muse_slice_live、行数 0),真断层是缺系统级公共治理对象种子、非缺表/缺功能。

每锚点真表+真后端过滤契约(curl 实证):story.draft 元结构=muse_meta_schema(列表无 status 过滤);故事链路=muse_meta_function_chain(listQuery 只放行 status=active、displayName 取 chain_snapshot.displayName);事实校验保护节点=muse_meta_protection_node(status=active+policy_snapshot->>chainKey 绑定链路、irreplaceable);候选生成 Prompt=muse_prompt(非 muse_ai_prompt);系统故事智能体=muse_agent(非 muse_ai_agent、agent_type=system、scope=all 不过滤);系统世界观库=muse_knowledge_base(kb_type=global、owner_user_id=0)。

global-setup 加 resetMetaGovernanceFixture(7 幂等 upsert ON CONFLICT、tenant_id=1、照 resetMarketFixture/resetJobsFixture 范式)。spec 删 :456 skip→拆 6 条细粒度真连用例(元结构/功能编排/AI/全局知识/市场/New-API),修 2 处 strict-mode 多命中。New-API 锚点契约纠正(mock 期 user-e2e/usage-e2e 伪造值):真后端绑定行是用户数字 id 字符串、用量 recordId 是聚合派生 {userId}:{period},改对真锚点(活体用户+1:month)、无后端缺口。

独立核实:连跑全量 e2e x2 各 12 passed/0 skipped(account/market/jobs 既有 6 真连无回归、幂等可复现);psql 复核 6 锚点种子真灌(function_chain/protection_node active、muse_prompt/muse_agent system/global KB 各 1 行真实契约)。至此 admin governance e2e 从全 page.route mock 全转真后端:12 真连用例 0 skip。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 13:05:37 -07:00
lili
2d06ec5f31 test(admin-e2e): jobs 子域转真连(重试/取消/来源重试真打+真 PG 反查)、governance config 断层如实标注 skip
jobs 真连(反假绿:真打写命令+真 PG 反查 muse_ai_job 派生行/状态):①重试(:262)→后端校验 retryable 新插 operation_id=adminRetryJob 同 retry_group queued 子 job(MuseJobServiceImpl.retryAdminJob 纯 DB 状态机、活体 code:0),反查派生子 job 行数;②取消+来源重试(:291)→cancel 改 muse_ai_job.status=cancelled、source retry 新插 job_type=source_event_retry job(muse_ai_source_event 90003 needs_recheck 锚点),反查状态/派生行。关键坑:切片库后台 AI runtime worker ~3s 抢 queued→failed,取消锚点须用 running(worker 不接管、前端 canCancelJob 放行);queued 锚点活体 cancel 真返 1040100014 不可取消。

global-setup 加 resetJobsFixture:幂等 seed 90001(failed/retryable muse_ai_job)/90002(running muse_ai_job)/90003(needs_recheck muse_ai_source_event)+清派生子 job/source_event_retry/命令幂等行,每轮自愈。真契约:retry 请求体只接受 {commandId}(JobRetryReqVO 仅此字段、reason 仅 UI 留痕不外发);cancel/source-retry 接受 {commandId,reason}。旧 skip 靠 mock 拦截 payload 字段,改真打+DB 派生行反查(等价更强),删 museAdminPayloadsByPage 收集器。

核心治理配置页(:456)保留 skip:非端点 500,而是切片数据/表断层——muse_function_chain/muse_protection_node 表在 muse_slice_live 根本不存在(psql to_regclass 均 None)、AI Prompt/全局知识库/story.draft 切片未灌种子,faithfully 转需跨 6 子系统伪造数据且两表连结构都没有,不硬转。用例上方写明断层+待补后端项。

独立核实:连跑全量 account+market+jobs e2e 6 passed/1 skipped(背靠背幂等无第二轮假红);psql 复核 90002=cancelled、retry 派生子 job=1、source_event_retry job=1、:456 断层表均 None(证标注诚实)。待补后端:①切片库缺 muse_function_chain/muse_protection_node 表 ②AI Prompt/全局 KB/story.draft 种子 ③jobs/source 三写命令后端无 P1r 真库 IT(现 Mockito 单测、本次 e2e 真连可视首个端到端真验)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 12:32:21 -07:00
lili
ce637ac2b6 test(admin-e2e): market 子域转真后端真连(下架/申诉真打+真 PG 反查落库)
market 5 个 skip 用例全是 MSW payload 拦截的负向断言(验前端预览绑定守卫不发陈旧 payload、靠 museAdminPayloadsByPage),真后端 MSW-off 无 payload 收集器无法逐字搬、且纯前端逻辑已 vitest 覆盖,故替换为真后端真连用例。

真连(反假绿:不只看 UI toast,真 PG 反查 muse_market_* 真实行):①市场治理页渲染三工作台(按激活 tabpanel 收口,ant Tabs 不卸载隐藏 pane);②下架真打命令→真 PG 反查 listing_status=delisted+新增 1 条 applied delist 治理动作;③申诉 maintained 真打处理→真 PG 反查 status=maintained、resolver_id=1。global-setup 加 resetMarketFixture(资产复位 listed+申诉复位 supplementing+软删历轮累积终态申诉(42 条 closed 挤出首页锚点)+清理治理动作/预览)、每轮幂等自愈。

揪出 mock 臆想契约:assetId/appealId 是数字串(非 asset-e2e);publish status DB submitted→API pending(后端 toOpenApiStatus 唯一特例、mock 四态不成立);appeal.resolution 列存处理理由文本非结论枚举(结论在 status);delist expectedStatus 只接受 listed(传别的 400);preview actionType 实为 5 值(含 review_rejection)非 4 值。

isIgnoredRuntimeIssue 增忽略 Failed to load resource: net::ERR_*(资源懒加载抖动、非应用错误,命令正确性另有真 PG 反查兜底)——同解 account 首跑偶发红根因(原误判 console.error,实为 dev-server 负载下 chunk 懒加载超时)。独立连跑全量 account+market e2e x2 各 4 passed;psql 复核 asset1=delisted/appeal1=maintained resolver=1/gov_action=1,与报告一致。restore 票据路径 e2e 未覆盖(用例走 maintained、后端不消费 restore 预览),restore 仍只 mock-service 单测无真 PG IT、缺口待补(:397 注释标注)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 12:06:17 -07:00
lili
c5d1762faa test(admin-e2e): governance e2e 转真后端基建 + account 子域 MVP(反假绿)
admin-governance.spec 此前全 page.route mock /admin-api/muse/**(~20 端点)、前后端契约从未端到端跑;认证注入 localStorage key 硬编码 muse-vben-antd-... 实为 undefined-5.7.0-dev-core-access(VITE_APP_NAMESPACE 未定义→运行时 undefined)、mock 下从不暴露。

命门(实证打通):①认证=与 studio 共用 mock-token Bearer test1(mockSecret test+userId1);②权限=admin 用户原无角色(system_user_role 空)→403,globalSetup 幂等 seed system_user_role(1,1)(super_admin)+DEL redis user_role_ids:1 刷权限缓存→超管跳过 @PreAuthorize;③代理=admin vite 已硬编码 /admin-api→48080、nitroMock 默认关。

基建:新建 global-setup(seed user_role+DEL redis+PG 复位)、playwright.config 加 globalSetup+workers:1、加 pg。spec 改真 localStorage key+token test1+删 routeMuseAdminApis mock(catch-all /admin-api/** 补 tenant-id:1 真打 48080;notify/dict/tenant 平台外壳保留 mock 因切片库无 notify 表返 500)+get-permission-info 走真后端。account 子域真连:真分页 {pageNo,pageSize,total,list} 前端 PageResult 只读 list/total 契约兼容;其他 8 子域 test.skip。独立连跑 15 次绿(含冷启动)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 11:38:56 -07:00
lili
f44c045315 docs(market): 回写 install isAcquired enrich 假绿修复(进度总账+模块 .agent)
market install 用户可见假绿真因=MarketAssetQueryServiceImpl 读模型裸硬编 isAcquired/isInstalled false(install 后端真实已验)、致安装按钮永不渲染;enrich 与 install 写端口同源修复(commit 37e7a8d)。记教训:读模型 enrich 须与写端口校验同源、改 module 跑 server IT 须先 mvn install。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 10:31:50 -07:00
lili
37e7a8dc27 fix(market): 修 install 用户可见假绿——isAcquired/isInstalled/canInstall 按真实授权安装态 enrich
三路盘点发现 market install 头号用户可见假绿:install 后端真实已验(P1rMarketLicenseInstallCompletedApprovalIT 批18 绿),但 MarketAssetQueryServiceImpl 把 isAcquired/isInstalled 裸硬编 false(toCard:181-182 列表 + userActions:386-387 详情 + canInstall:383),致 studio MarketBrowse(assetType!=work && isAcquired && !isInstalled)安装按钮在真后端永不渲染,mock 伪造状态位才现身;批17 IT 把 isAcquired=false 断言为正确→假绿固化。

后端 enrich(读模型、未碰 install 写逻辑/授权语义):仿 isFavorite 范式加 isAcquired(active 授权)/isInstalled(installation)/isInstallable(类型集),与 install 写端口 MarketInstallServiceImpl 严格同源(selectActiveByOwnerAndAsset + INSTALLABLE_ASSET_TYPES={agent,knowledge_base}),避免"显示可装但装不了"新假绿;canInstall=listed && isInstallable && acquired && !installed(对齐 studio assetType!=work 门);批量加载(整页 2 次 IN vs 3N)避免放大 isFavorite 既有 N+1;mapper 加 selectActiveByOwnerAndAssetIds/existsByUserAndAsset/selectByUserAndAssetIds;批17 IT 改三态断言+订正裸写注释。

前端 MarketBrowse 补 onError(install/acquire 失败内联可见提示,对齐 AgentCreateForm/SlotBindingPanel,不再静默吞 ApiError);e2e 新增 market-install.spec(MSW-off:purchase 前置→断安装按钮真渲染→install→psql 验,连跑 2 次)+ global-setup #16 market 表复位。

活体真验(muse_slice_live,重启新 jar 10:08):purchase→isAcquired=T/canInstall=T(修前恒 false)→install→isInstalled=T/canInstall=F;独立 psql+GET 复核 asset1/4(owner1)isAcquired/isInstalled=true。批17 IT 5/5 三态绿(首跑遇 .m2 stale jar 假红、mvn install 刷新转真绿)、market 单测 9/9+11/11+7/7、UI e2e 连跑 2 次 passed。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 10:28:33 -07:00
lili
5c78a2adc4 docs(ai): 回写槽位绑定 authz 孪生收口(C1/V31)——ADR-020 全部 binding 表无漏网
三路盘点发现 muse_agent_slot_binding 是采纳断层(V30)唯一漏网 binding 表(同型 BIGINT+parseLong 丢字符串 envelope),V31 收口并活体真验(binding authz 列存非空 rpe-local、insert+updateById 两路径)。订正上条总账/模块 .agent 的"未误伤 muse_agent_slot_binding"为同型漏修已收口。至此 knowledge V14 + suggestion/attribution V30 + slot V31 全部 binding 表无漏网。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 08:34:44 -07:00
lili
854f18c06a fix(ai): 收口 ADR-020 漏网 binding 表——槽位绑定授权快照 BIGINT→VARCHAR(V31)
muse_agent_slot_binding.authorization_snapshot_id 是采纳断层(ADR-020 方案 A,V30/a16c596)唯一漏网的 binding 表:列 BIGINT、DO Long,bind 时 parseLong(precheck.authorizationSnapshotId) 对真 runtime envelope rpe-local-<uuid> 返 null→授权快照静默丢失、绑定溯源链断。knowledge binding 已 V14、ai_suggestion/content_block_source_attribution 已 V30,此表是同型漏网(三路盘点发现,模块记忆从未记此类型错配)。

- V31:authorization_snapshot_id + source_snapshot_id 两列 BIGINT→VARCHAR(128) USING ::text(仿 V30/V14,source 一并收口避免后续写入被静默截断)。
- MuseAgentSlotBindingDO:两字段 Long→String。
- MuseAgentSlotServiceImpl:bind 两处(insert/updateById persistBinding)直透传 precheck.authorizationSnapshotId(String envelope),删 parseLong 包裹;sameAuthorizationSnapshot 的 parseLong 保留(对字符串 envelope 走 fallback 字符串比较,正确)。
- MuseAgentSlotServiceTest:数值串种子改字符串 envelope + 断言落库幸存(反假绿:旧 parseLong 把 0501/501 归一成 501L 无法区分 precheck 与 request)。

活体真验(muse_slice_live):真 envelope rpe-local-6e29...(issuePermissionEnvelope 签发、过 runtime 授权门)经 precheck→bind,binding authz 列存非空 rpe-local 字符串(insert id=51 + updateById id=50 两路径);列类型 character varying(128);flyway V31 success。修前该列恒 null。单测 26 绿。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 08:31:21 -07:00
lili
3f59ff9079 docs: 订正 market authz type:integer 表述——经核是主键 ID 引用非 ADR-020 业务标识
深入调研发现 market openapi authorizationSnapshotId(integer)是 muse_market_authorization_snapshot/summary 表主键 ID 引用(physical PK int64)、非 ADR-020 管的业务标识(market 业务标识字段 authorizationSnapshot 已 string、合规);符合 ADR-020"物理主键 Long"故不需对齐,盲目改 integer→string 反违"拒字符串主键"。订正 ADR-020 后果段(架构-03 v12)+ 进度总账 2026-06-25 此前"market type:integer 待对齐(同源 ADR-020)"的不准确表述。market 对外暴露主键 ID 是否违后端-04 属独立契约议题、与 ADR-020 不同源、本轮不改。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 02:36:58 -07:00
lili
fc6afe08b5 docs(agent): 回写 AI 采纳断层修复到 ai/content 模块 .agent(ADR-020 方案 A)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 01:36:52 -07:00
lili
fde0866701 docs(ai): 回写 AI 采纳断层修复(ADR-020 方案 A)——授权快照字符串化全链打通、IT 假绿转真绿
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 01:34:25 -07:00
lili
af4ad4d39d fix(test): 补 P1rContentCore/WorkLifecycleCompletedApprovalIT 缺失的 MetaSchemaQueryApi bean(cd85d9d 遗留)
采纳断层 IT 真跑暴露 cd85d9d(D1-2 work→schema 绑定)遗留:ContentAppServiceImpl 新增 @Resource MetaSchemaQueryApi,但这两 IT 的 CompletedApprovalConfiguration @Import ContentAppServiceImpl 却没供该 bean→NoSuchBeanDefinitionException context 加载失败(IT 此前没真跑、靠未执行假绿)。补 @Bean MetaSchemaQueryApi 匿名实现(对齐仓内既有 @Bean 约定,listActiveSchemasByTargetType→List.of/getActiveSchemaById→null);completed approval 不触发 work→schema 路径(body 无 schemaId→resolveWorkSchemaId 短路)故默认值安全。真 PG 跑 Core12/12+WorkLifecycle1/1=13/13 绿。与采纳断层修复解耦,仅补测试配置不改被测代码。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 01:31:46 -07:00
lili
2ede7cb384 test(studio): accept-suggestion 改真生成删 stub,清除 line176② 最后 AI 假绿(采纳断层已修)
采纳断层修复后(commit a16c596 ADR-020,真候选 authz 字符串 envelope 可采纳),accept-suggestion 正路删 /ai/tasks+/stream stub,复用 ai-generation 真链路:WorkspacePage→AIPanel→真 AI task→SSE done→CandidatePanel 采纳替换→真 suggestion-merges code=0+newRevision 自增。反假绿:authz 真 rpe-local 字符串(非种子数值)、sourceAttribution.parentSuggestionId==真生成 id(证非种子)、block revision 实读动态比对(漂移不影响重复跑)。连跑 2 次 2/2 绿(suggestionId 25→26 revision 72→74)+ ai-generation/agent-slot-bind 回归绿。line176② AI 生成 stub 假绿完全清除。flaky:真 SSE 冷启动偶慢(与 ai-generation 同源,CI retries:2)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 01:24:01 -07:00
lili
a16c59662f fix(ai): 修 AI 生成候选采纳断层,授权快照 id 改字符串承载 envelope(ADR-020 方案 A)
真生成候选 authorization_snapshot_id=null 恒不可采纳(1041001001),根因:runtime envelope 是字符串 rpe-local-uuid 但 authz 列 BIGINT 存不下,numericEnvelopeId/requireNumericAuthorizationSnapshot/parseLongQuietly 三处降级门禁致恒拒。方案 A(人类拍板,ADR-020):V30 迁移 muse_ai_suggestion+muse_content_block_source_attribution 的 authorization_snapshot_id BIGINT→VARCHAR(128)(仿 V14);AI 侧直落字符串 envelope(删 numericEnvelopeId);Content 放开两道数值门(删 requireNumericAuthorizationSnapshot/parseAuthorizationSnapshotId/parseLongQuietly);DO authz Long→String 全调用方适配;揭并修 P1rContentMergeGeneratedSuggestionIT 假绿(原注入数值 9001,真 runtime 不产数值,改真字符串 envelope)。活体真验(muse_slice_live,V30 applied):真生成 suggestion authz 现存 rpe-local 字符串→采纳 merge code=0+block revision 69→70(修复前恒 1041001001)→归因新行 authz 字符串,AI 生成→采纳→Canonical 全链打通。编译+test-compile SUCCESS,112 单测绿,未误伤 muse_agent_slot_binding(不在 V30 范围)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 01:03:54 -07:00
lili
180181e4c7 docs(studio): 订正 accept-suggestion stub 根因为真生成候选 authorization_snapshot_id=null(反假绿调研)
正路仍桩 /ai/tasks 的根因经实测订正(非旧注释"AI 本机不可用/缺审字段"):真生成候选已产审三件套+content,唯一缺 authorization_snapshot_id=null→采纳被拒 1041001001"外部 owner 暂不可用"。根因=真 runtime envelope 是字符串 rpe-local-uuid,MuseAiRuntimeProjectionService.numericEnvelopeId Long.parseLong 失败落 null。**揭 P1rContentMergeGeneratedSuggestionIT 假绿**(注入数值 envelope 9001,真 New-API runtime 不产数值→IT 绿≠活体真候选可采纳)。注释 only 无逻辑改,stub 保留(桩生成段、采纳+负路乐观锁全真打后端反假绿),accept-suggestion 2/2 可重复 + agent-slot-bind/ai-generation 回归绿、tsc 0。后续主线:让真生成链产数值授权快照(numericEnvelopeId 解析 rpe-local-* 或列承载字符串 envelope,后端缺口)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 22:08:41 -07:00
lili
abcc08f109 docs(ai): 回写 AIPanel AI 生成 e2e 已补 + connectAIStream 鉴权 bug 修复(line176② AI 生成假绿闭合)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 18:03:19 -07:00
lili
410322cbc0 fix(studio): AIPanel onDone 改用 ref 读流式正文,消除渲染期跨组件 setState
AIPanel onDone 此前在 setStreamContent 更新函数里调父组件 onCandidateGenerated→AIPanel 渲染期触发 WorkspacePage setState(React warn "Cannot update a component while rendering a different component")。改:streamContentRef 在 onChunk 与 streamContent 同步累计,onDone 直接读 ref 调回调,不再渲染期 setState。ai-generation e2e 再跑 React warning grep=0(消失)、仍 passed(26.2s)。顺带修 AgentPage.contract.test 多余 import React(JSX automatic runtime 不需→TS6133;此前写 test 只跑 vitest 漏跑 tsc、commit 4c069d4 带入)。tsc 全量 0、vitest 102/102。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 18:01:56 -07:00
lili
494c9e9b89 test(studio): 补 AIPanel AI 生成真后端 e2e + 修 connectAIStream 漏鉴权头(反假绿暴露真 bug)
补 ai-generation.spec(真后端不 stub,消除 accept-suggestion stub 假绿,进度总账 line176②):真浏览器 WorkspacePage→AIPanel 发送指令→真后端 AI task→SSE→真 New-API LLM→suggestion 落库。**反假绿暴露真 bug**:connectAIStream(src/lib/sse.ts)漏带 Authorization+tenant-id 头→活体 SSE 必 401/400→done 永收不到→候选永不渲染(被 accept-suggestion 的 stub 长期掩盖)。修:补头,与 connectEventStream/client.ts 同源 @/api/auth。SSE 真行为:后端"持久化事件回放+5s 轮询",运行时只落 done 不落 chunk(streamContent 真链路恒空),真 LLM 文本在 suggestion 记录→断言落 suggestion(API+DB 双证)。四断言反假绿:POST 2xx+code0+taskId / suggestion 真 LLM 文本(非空+阈值+主题宽集合不硬编码句子) / CandidatePanel 采纳按钮 / DB muse_ai_suggestion 新行。自验+子代理连跑 4 次绿(suggestionId 12→13→14→15 各不同真 LLM,11-21s 稳定);vitest 102/102(sse.test 16/16);"AI 本机不可用"旧判断已过时(New-API 在线真生成)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 17:59:10 -07:00
lili
e8ca37c9b9 docs(ai): 回写槽位绑定 UI e2e 已补(02D 替换路径端到端真验)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 11:20:12 -07:00
lili
1fbe7ae73c test(studio): 补 agent 槽位绑定 UI e2e(AgentPage→真后端替换槽位,反假绿)
承 02D 死锁修复(9115d4f)+ AgentPage 作品选择器(4c069d4),补端到端 UI e2e(进度总账 line176② 缺口)。agent-slot-bind.spec:真浏览器 goto /agents→selectOption work1→点 agent1 卡片→点"绑定选中智能体"→真后端 precheck→bind。三重反假绿:DB 起点 revision=1 + bind 响应 code=0/slotRevision=2 + UI"绑定已更新"提示 + DB 终态 revision 1→2 active agent1。global-setup §15 每轮复位 work1 writing.continuation 槽位(agent1 revision1 active)保证可重复(bind 成功 revision+1 漂移、不复位二次跑红)。MSW off 真连 muse_slice_live;自验 + 子代理各跑均 passed 可重复、tsc 零报错。诚实范围:只覆盖"替换已有槽位",首次创建 UI 仍缺槽位骨架(Override Slot Contract=方案 B,人类架构决策域未做)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 11:19:44 -07:00
lili
2c9fdb513c docs(ai): 回写 AgentPage workId 硬编码解除(02D 前端槽位绑定 UI 打通)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 10:57:17 -07:00
lili
4c069d482d fix(studio): AgentPage 槽位绑定改用作品选择器,消除 workId 硬编码
承 02D 后端槽位首次创建死锁修复(9115d4f),前端 AgentPage 此前 SlotBindingPanel 用硬编码 WORK_ID_FOR_SLOT_PREVIEW=1(盘点 line176② workId 硬编码),槽位绑定无法用于真实作品。修:接入 useWorkList 作品列表 + 作品选择下拉,SlotBindingPanel 按所选作品 workId 查询/绑定槽位,空作品时提示先建作品。SlotBindingPanel 绑定流(precheck→bind)本就完整(盘点"无真正绑定流"过时:实为后端死锁挡着 bind 必失败,后端修复后真后端 curl 已验 precheck→bind→首次建 binding)。补 AgentPage.contract.test(作品选择→正确 workId 下传 + 非硬编码反向验证)。tsc/eslint 绿,vitest 101→102。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 10:56:01 -07:00
lili
260f11426d docs(ai): 回写 02D 槽位死锁修复 + AI 生成命脉真后端端到端打通
02D 槽位首次创建死锁修复(9115d4f)+ 前端 MVP agentSlotKey 接线(df063cb)+ P-A 检索修复(86c6dba)逐条破除进度总账 line176"AI 生成四重阻塞"。真后端 happy-path 真验(muse_slice_live):work1 writing.continuation precheck(不再 forbidden)→bind 首次建 binding(slotRevision1 active)→AI task 用 agentSlotKey→agent1→completed+suggestion7(真 LLM"星环大陆魔法体系"续写 finishReason stop)。最大假绿点(AI 生成 e2e 一律 stub /ai/tasks)消除。仍缺 Override Slot Contract 主数据(方案 B)/SlotBindingPanel UI 深链。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 10:37:03 -07:00
lili
9115d4f95f fix(ai): 修 02D 槽位绑定首次创建死锁,precheck/bind 改 upsert + 补 active 唯一约束
根因:precheck(line102)/bind(line182)都 requireSlotBinding(binding!=null)缺行抛 AI_RESOURCE_FORBIDDEN;但"替换"是设计中唯一创建入口(替换=首次写入,无独立创建端点是设计有意,见后端-04 line748/产品-02D line507),要求被替换行先存在→死锁,首次绑定永不可达。work4 seed binding 是 E2E 绕此 bug 手插非设计常态。修:precheck 缺行放行;bind 抽 persistBinding upsert(有行 updateById 沿用乐观锁 revision+1,无行 insert revision=1 避免首次 expectedSlotRevision null 拆箱 NPE);V29 补 active partial unique index(tenant+work+slot WHERE status=active,并发首次写兜底);前端 mock protected 槽位对齐后端 startsWith(protected:)口径。验证:MuseAgentSlotServiceTest 26/26 + AppMuseAgentSlotControllerAnnotationTest 4/4 + 前端 useAgents/AIPanel.contract 4/4;handoff/幂等/乐观锁不破坏。范围:不建 Override Slot Contract 主数据(B)/不碰默认 agent 来源/不动 runtime 授权。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 10:09:53 -07:00