oh-my-muse/docs/agent-specs/2026-07-07-2.0.0单人版改造-review.html

256 lines
16 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Muse 2.0.0 单人版改造 · 一页边界图</title>
<style>
:root{
--ink:#1c1e26; --muted:#6b7080; --line:#e3e5ec; --bg:#f7f8fb; --card:#ffffff;
--keep:#0f766e; --keep-bg:#ecfdf5; --keep-line:#99e3cf;
--iso:#b45309; --iso-bg:#fffbeb; --iso-line:#fcd9a0;
--ret:#b91c1c; --ret-bg:#fef2f2; --ret-line:#fbc6c6;
--dify:#4338ca; --dify-bg:#eef2ff; --dify-line:#c7d2fe;
--polish:#0369a1; --polish-bg:#f0f9ff; --polish-line:#bae0f8;
}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;background:var(--bg);color:var(--ink);padding:32px 40px;line-height:1.5}
.page{max-width:1180px;margin:0 auto}
header{margin-bottom:22px}
h1{font-size:26px;font-weight:700;letter-spacing:.5px}
.sub{color:var(--muted);font-size:14px;margin-top:6px}
.sub b{color:var(--ink)}
h2{font-size:15px;font-weight:700;margin:0 0 12px;display:flex;align-items:center;gap:8px}
h2 .no{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:6px;background:var(--ink);color:#fff;font-size:12px}
section{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:20px 22px;margin-bottom:18px;box-shadow:0 1px 2px rgba(20,22,40,.04)}
/* ---- 依赖终态 ---- */
.dep{display:grid;grid-template-columns:1fr 60px 1.2fr;gap:0;align-items:center}
.dep-col{display:flex;flex-direction:column;gap:10px}
.dep-title{font-size:12px;color:var(--muted);font-weight:600;margin-bottom:2px;letter-spacing:1px}
.svcrow{display:flex;align-items:center;gap:10px}
.muse{background:var(--ink);color:#fff;border-radius:10px;padding:14px 18px;font-weight:700;font-size:15px;text-align:center;min-width:110px}
.svc{border-radius:10px;padding:10px 14px;font-size:13px;border:1.5px solid var(--line);background:#fff;flex:1}
.svc b{display:block;font-size:14px;margin-bottom:2px}
.svc small{color:var(--muted)}
.svc.na{border-color:#d3d6df}
.svc.rf{border-color:var(--ret-line);background:var(--ret-bg)}
.svc.rf b{color:var(--ret)}
.svc.df{border-color:var(--dify-line);background:var(--dify-bg)}
.svc.df b{color:var(--dify)}
.arrow-mid{display:flex;align-items:center;justify-content:center;font-size:26px;color:var(--muted)}
.edge{width:26px;height:2px;background:#b9bdc9;position:relative;flex:none}
.edge::after{content:"";position:absolute;right:-1px;top:-3px;border:4px solid transparent;border-left-color:#b9bdc9}
.edge.dash{background:repeating-linear-gradient(90deg,#b9bdc9 0 4px,transparent 4px 8px)}
.after-box{border:1.5px solid var(--dify-line);background:var(--dify-bg);border-radius:12px;padding:14px}
.after-box .cap{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
.chip{background:#fff;border:1px solid var(--dify-line);color:var(--dify);border-radius:20px;padding:4px 12px;font-size:12.5px;font-weight:600}
.upnote{margin-top:10px;font-size:12.5px;color:var(--muted)}
.infra{margin-top:14px;font-size:13px;color:var(--muted)}
.infra b{color:var(--ink)}
.strike{text-decoration:line-through;color:var(--ret)}
/* ---- 功能象限 ---- */
.quad{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.qcard{border-radius:12px;padding:14px 16px;border:1.5px solid}
.qcard h3{font-size:14px;margin-bottom:8px;display:flex;align-items:center;gap:8px}
.tag{font-size:11px;border-radius:5px;padding:2px 8px;color:#fff;font-weight:600}
.qcard ul{list-style:none;font-size:13px}
.qcard li{padding:3px 0 3px 16px;position:relative}
.qcard li::before{content:"·";position:absolute;left:4px;font-weight:700}
.qcard li small{color:var(--muted)}
.q-keep{background:var(--keep-bg);border-color:var(--keep-line)} .q-keep h3{color:var(--keep)} .q-keep .tag{background:var(--keep)}
.q-iso{background:var(--iso-bg);border-color:var(--iso-line)} .q-iso h3{color:var(--iso)} .q-iso .tag{background:var(--iso)}
.q-ret{background:var(--ret-bg);border-color:var(--ret-line)} .q-ret h3{color:var(--ret)} .q-ret .tag{background:var(--ret)}
.q-pol{background:var(--polish-bg);border-color:var(--polish-line)} .q-pol h3{color:var(--polish)} .q-pol .tag{background:var(--polish)}
/* ---- 装配图 ---- */
.asm{display:grid;grid-template-columns:2.2fr 1fr;gap:14px}
.server{border:2px solid var(--ink);border-radius:12px;padding:14px}
.server .cap{font-weight:700;font-size:13px;margin-bottom:10px}
.mods{display:flex;flex-wrap:wrap;gap:8px}
.mod{border-radius:8px;padding:7px 12px;font-size:12.5px;font-weight:600;border:1.5px solid var(--keep-line);background:var(--keep-bg);color:var(--keep)}
.mod.off{border-style:dashed;border-color:var(--iso-line);background:var(--iso-bg);color:var(--iso)}
.fallback{margin-top:12px;border-top:1px dashed var(--line);padding-top:10px;font-size:12.5px;color:var(--muted)}
.fallback b{color:var(--ink)}
.sidecol{display:flex;flex-direction:column;gap:10px}
.sidebox{border-radius:10px;border:1.5px dashed var(--line);padding:10px 12px;font-size:12.5px;color:var(--muted)}
.sidebox b{display:block;color:var(--ink);margin-bottom:2px;font-size:13px}
.sidebox.iso{border-color:var(--iso-line);background:var(--iso-bg)} .sidebox.iso b{color:var(--iso)}
/* ---- 节奏 ---- */
.lane{margin-bottom:10px}
.lane-cap{font-size:12px;color:var(--muted);font-weight:600;margin-bottom:6px}
.steps{display:flex;gap:8px;flex-wrap:wrap}
.step{border-radius:9px;padding:8px 11px;font-size:12.5px;border:1.5px solid var(--line);background:#fff;position:relative;flex:1;min-width:120px}
.step b{display:block;font-size:12px;color:var(--muted);margin-bottom:1px}
.step.dify{border-color:var(--dify-line);background:var(--dify-bg)}
.step.iso{border-color:var(--iso-line);background:var(--iso-bg)}
.step.gate{border-color:#c9cdd8;background:#f3f4f8}
.step.fin{border-color:var(--keep-line);background:var(--keep-bg)}
.pol-strip{display:flex;gap:8px;flex-wrap:wrap;margin-top:4px}
.pol-item{border:1.5px solid var(--polish-line);background:var(--polish-bg);color:var(--polish);border-radius:9px;padding:8px 11px;font-size:12.5px;font-weight:600;flex:1;min-width:130px}
.pol-item small{display:block;color:var(--muted);font-weight:400;margin-top:1px}
.foot{color:var(--muted);font-size:12px;margin-top:6px}
.legend{display:flex;gap:14px;font-size:12px;color:var(--muted);margin-top:10px;flex-wrap:wrap}
.dot{display:inline-block;width:10px;height:10px;border-radius:3px;margin-right:5px;vertical-align:-1px}
</style>
</head>
<body>
<div class="page">
<header>
<h1>Muse 2.0.0 单人版改造 · 一页边界图</h1>
<div class="sub">目标:<b>单人自用创作工具</b> —— 外部依赖收敛到 <b>Dify 一个服务</b>,多用户/平台功能整体隔离,先收地基(1a)再打磨体验(1b)。评审版 v0.1 · 2026-07-07 · 详见同名 .md</div>
</header>
<section>
<h2><span class="no">1</span>外部服务终态:3 个 → 1 个</h2>
<div class="dep">
<div class="dep-col">
<div class="dep-title">改造前(1.0.0)</div>
<div class="svcrow"><div class="muse">Muse</div><div class="edge"></div>
<div class="svc na"><b>New-API</b><small>生成主链 · 导入解析 · 账户配额管理</small></div></div>
<div class="svcrow"><div style="width:110px"></div><div class="edge"></div>
<div class="svc rf"><b>RAGFlow</b><small>知识运行时(建库/上传/检索);GraphRAG 生产零调用</small></div></div>
<div class="svcrow"><div style="width:110px"></div><div class="edge dash"></div>
<div class="svc df"><b>Dify</b><small>Agent 运行时(刚接入,未部署)</small></div></div>
<div class="svcrow"><div style="width:110px"></div><div class="edge dash"></div>
<div class="svc na"><b>yudao 厂商脚手架 ×9</b><small>gemini/doubao/mj/suno… enable:true + 明文 key 在仓(须显式关停)</small></div></div>
</div>
<div class="arrow-mid"></div>
<div class="dep-col">
<div class="dep-title">改造后(2.0.0 单人版)</div>
<div class="svcrow">
<div class="muse">Muse</div><div class="edge"></div>
<div class="after-box" style="flex:1">
<b style="color:var(--dify);font-size:15px">Dify(唯一外部依赖)</b>
<div class="cap">
<span class="chip">chat/workflow:生成主链 + Agent 运行时</span>
<span class="chip">chat/workflow:导入全书解析</span>
<span class="chip">Datasets API:知识库 上传/索引/检索</span>
</div>
<div class="upnote">模型 provider 配在 Dify 内,上游可指向自有 New-API 网关(对 Muse 透明)。Prompt 组装与知识授权过滤仍在 Muse 侧 —— Dify 只是运行时,不是事实源。</div>
</div>
</div>
<div class="infra">基础设施:<b>PostgreSQL + Redis + Dify</b> · <span class="strike">RAGFlow</span>(退役删除) · <span class="strike">New-API 直连</span>(代码保留,不再配置) · <span class="strike">yudao 脚手架×9</span>(enable→false+启动断言+key 出仓) · <span class="strike">gateway/Nacos</span>(不部署)</div>
</div>
</div>
</section>
<section>
<h2><span class="no">2</span>功能边界:留什么 / 隔离什么 / 退役什么 / 打磨什么</h2>
<div class="quad">
<div class="qcard q-keep">
<h3><span class="tag">保留</span>单人创作主线</h3>
<ul>
<li>作品列表 + 写作台<small>(编辑器/章节/AI 候选采纳/版本 diff/导入导出)</small></li>
<li>智能体工作台<small>(自建 Agent 生命周期、槽位绑定、沙盒试用)</small></li>
<li>知识库<small>(上传索引、草稿确认、实体关系图谱、授权检索)</small></li>
<li>元引擎 MetaSchema<small>(admin 定义 → 动态表单)</small></li>
<li>单账号登录 + 用量观测</li>
<li>admin 治理核心<small>(元结构/功能编排/AI 配置/全局知识库/任务/审计)</small></li>
</ul>
</div>
<div class="qcard q-iso">
<h3><span class="tag">隔离搁置</span>多用户 / 平台面(代码保留,装配摘除/开关关闭/入口删除)</h3>
<ul>
<li>市场全链<small>(发现/详情/发布/审核/申诉/handoff/物化/召回)—— 后端摘装配</small></li>
<li>member 多用户子域<small>(权益/配额/归因/New-API 绑定/安全深面/偏好通知)—— 既有开关</small></li>
<li>admin:市场治理、用户与权限<small>(muse.ts 隐藏)</small>;yudao 用户/角色/租户/会员/支付/公众号/BPM 菜单<small>(菜单数据停用)</small>;newapi 页禁写降只读</li>
<li>studio:市场 5 路由、个人中心 5 段、市场耦合入口</li>
<li>meta 影响预览 all-real(P0-09)、admin e2e(P0-10)划归多用户线</li>
</ul>
</div>
<div class="qcard q-ret">
<h3><span class="tag">退役</span>不再回来(git 可考古)</h3>
<ul>
<li>RAGFlow adapter + live 验收 IT + env 样例<small>(端口中立化为 KnowledgeRuntimeClient)</small></li>
<li>GraphRAG 全部脚手架<small>(生产零调用,零损失)</small></li>
<li>studio 废弃 EditorPage demo 壳</li>
<li>端口上 7 个从未被生产调用的操作</li>
</ul>
</div>
<div class="qcard q-pol">
<h3><span class="tag">1b 打磨</span>单人主线缺口(按序补齐)</h3>
<ul>
<li>P0-11 规划候选生成<small>(后端空桩→真实现,走 Dify)</small></li>
<li>P0-12 AI 文风检查<small>(后端空桩→真实现)</small></li>
<li>P0-06 知识处理失败恢复 UI<small>(基于 Dify indexing-status)</small></li>
<li>P0-03 版本恢复写入<small>(走 Content 写边界+审计)</small></li>
<li>P1-11 SSE 统一客户端接业务组件</li>
</ul>
</div>
</div>
</section>
<section>
<h2><span class="no">3</span>后端装配终态(muse-server 单体)</h2>
<div class="asm">
<div class="server">
<div class="cap">muse-server(单进程,直服 /app-api 与 /admin-api)</div>
<div class="mods">
<span class="mod">content 作品/正文</span>
<span class="mod">ai 编排/生成</span>
<span class="mod">knowledge 知识库</span>
<span class="mod">meta 元引擎</span>
<span class="mod">member(仅登录/资料/用量)</span>
<span class="mod">system/infra 底座</span>
<span class="mod off">market(pom 注释摘除)</span>
<span class="mod off">pay / bpm / mp / report(维持不装配)</span>
</div>
<div class="fallback"><b>摘除前置:</b>新增 3 个 fail-closed 兜底 Bean(@ConditionalOnMissingBean)—— MarketHandoffTokenApi→token 无效 · MarketAssetSourceApi→not found · MarketAssetForkApi→false。market 装回时真实现自动优先。member 投影已有 Unavailable 兜底。</div>
</div>
<div class="sidecol">
<div class="sidebox iso"><b>租户红线</b>保持 muse.tenant.enable=true、固定 tenant=1。关掉会全线 NPE(getRequiredTenantId)。</div>
<div class="sidebox"><b>worker 现状</b>多用户向 worker 默认全关;仅 AI dispatcher 与本地质量评估常开。</div>
<div class="sidebox"><b>门禁先行</b>覆盖门 market 域标 dormant、market IT 按装配分组;契约文件原地保留不删。</div>
</div>
</div>
</section>
<section>
<h2><span class="no">4</span>节奏:1a 地基 → 1b 打磨</h2>
<div class="lane">
<div class="lane-cap">阶段 1a · 两条线并行(S0 基线与 S2 机制先于 S3 摘除;S1 是 Dify 线前提)</div>
<div class="steps">
<div class="step gate"><b>S0</b>坐实并修复现红门禁基线</div>
<div class="step dify"><b>S1</b>部署 Dify + contract test 钉契约</div>
<div class="step gate"><b>S2</b>门禁/测试树机制(profile+dormant)</div>
<div class="step iso"><b>S3</b>market 摘装配(兜底 Bean,原子生效)</div>
<div class="step iso"><b>S4</b>member/yudao 脚手架/admin 收口</div>
<div class="step iso"><b>S5</b>studio 前端裁剪</div>
</div>
<div class="steps" style="margin-top:8px">
<div class="step dify"><b>S6</b>知识运行时 Dify adapter(5 操作)</div>
<div class="step dify"><b>S7</b>S7.0 输出契约裁决 → 生成主链切 Dify</div>
<div class="step dify"><b>S8</b>导入解析 Dify parser(New-API 退出门)</div>
<div class="step fin"><b>S9</b>单机 compose + 黄金旅程 smoke</div>
<div class="step fin"><b>S10</b>文档沉淀(专题-05/ADR/缺口清单订正)</div>
</div>
</div>
<div class="lane">
<div class="lane-cap">阶段 1b · 逐项独立立项,真后端 e2e 验收</div>
<div class="pol-strip">
<div class="pol-item">P0-11 规划候选<small>规划台可创建/采纳</small></div>
<div class="pol-item">P0-12 文风检查<small>可追踪结果</small></div>
<div class="pol-item">P0-06 知识失败恢复<small>重试/删除/重传</small></div>
<div class="pol-item">P0-03 版本恢复<small>新 revision+归因审计</small></div>
<div class="pol-item">P1-11 SSE 接组件<small>任务进度/通知</small></div>
</div>
</div>
<div class="legend">
<span><span class="dot" style="background:var(--dify-bg);border:1px solid var(--dify-line)"></span>Dify 迁移线</span>
<span><span class="dot" style="background:var(--iso-bg);border:1px solid var(--iso-line)"></span>隔离线</span>
<span><span class="dot" style="background:#f3f4f8;border:1px solid #c9cdd8"></span>门禁</span>
<span><span class="dot" style="background:var(--keep-bg);border:1px solid var(--keep-line)"></span>收口</span>
<span><span class="dot" style="background:var(--polish-bg);border:1px solid var(--polish-line)"></span>1b 打磨</span>
</div>
<div class="foot">1a 验收:local 门禁全绿 · real-PG 全绿 · Dify live 三链真打 · fail-closed 反向证据 · 创作主线 MSW-off e2e 全绿 · 单机 compose 起全栈黄金旅程 smoke · market API 物理 404。</div>
</section>
</div>
</body>
</html>