
鸿蒙 PC Markdown 编辑器工程基线用 PRD、ADR 与阶段闸门控制技术风险本文讨论桌面编辑器如何把产品约束、架构决策、构建验证和阶段退出条件组织成可执行的工程系统。代码示例来自可运行的鸿蒙 PC 应用https://gitcode.com/VON-/codex_md_oh。为什么第一步不是写编辑器鸿蒙 PC 端 Markdown 编辑器同时涉及 ArkUI、ArkWeb、文件授权、中文输入法、大文档性能与安全预览。如果一开始就追求功能数量最容易出现的结果是界面可以演示但关键技术风险没有证据。OhMarkdown 把第一个里程碑定义为技术验证并在代码前建立三类文档docs/PRD.md定义产品边界、竞品差异和各阶段退出条件。docs/EXECUTION_PLAN.md把技术验证拆成稳定编号的工程任务每一点都有产出、完成条件和状态。docs/adr/0001-hybrid-editor-architecture.md记录为什么选择 ArkUI 原生外壳与 ArkWeb 编辑内核。这三类文档的作用不是增加流程而是分别回答“做什么”、“按什么顺序做”和“为什么这样做”。把流程变成可执行的代码工程基线不只是 Markdown 文档。仓库中的scripts/build-debug.sh将 Web 编辑器构建和 HarmonyOS HAP 构建串成一条可重复执行的命令#!/bin/shset-euDEVECO_HOME${DEVECO_HOME:-/Applications/DevEco-Studio.app/Contents}exportJAVA_HOME${JAVA_HOME:-$DEVECO_HOME/jbr/Contents/Home}exportDEVECO_SDK_HOME${DEVECO_SDK_HOME:-$DEVECO_HOME/sdk}$(dirname--$0)/build-editor.shexec$DEVECO_HOME/tools/hvigor/bin/hvigorw\assembleHap\--modemodule\-pproductdefault\-pmoduleentrydefault\-pbuildModedebug\--no-daemon代码来源scripts/build-debug.shset -eu使脚本在命令失败或变量缺失时立即退出环境变量又允许 CI 或其他开发机覆盖默认路径。这比“在 DevEco Studio 里点几下就能构建”更容易回归也更适合后续接入 CI。完成标准本阶段将下列条件写成固定闸门每个步骤只解决一个清晰问题。重大技术取舍必须进入 ADR不只存在于会话中。未通过构建、测试或验收的步骤不得标记完成。每次完成都在docs/PROGRESS.md记录变更、证据和遗留项。用户文件安全、Markdown 源码无损和离线能力高于功能追赶速度。模拟器运行证据下图是工程基线建立后通过统一构建脚本产出并安装到鸿蒙 PC / 2in1 模拟器的 OhMarkdown 工作台。可复用的结论对桌面端编辑器这类高风险工具来说技术路线不应只由界面效果决定。更稳妥的做法是先用 PRD 确定出口再用 ADR 锁定可回退的技术假设最后用执行计划和构建脚本将假设转成可重复的证据。先把“产品成功”翻译成工程约束“做一个好用的 Markdown 编辑器”不是可以直接执行的工程目标。它没有说明用户是谁、什么场景优先、哪些数据不能损坏也没有说明一个功能做到什么程度才算完成。OhMarkdown 面向鸿蒙 PC首批用户是需要长期处理本地 Markdown 的开发者、技术作者和知识工作者因此工程基线先确定了几条不可用功能数量交换的约束用户文档默认保存在本地打开文件必须来自用户授权不把正文上传到远端服务。Markdown 源码是唯一事实源预览、导出和大纲都是派生结果不能反向格式化源码。保存成功必须有明确的持久化结果发生异常时应优先保住旧文件和未保存草稿。鸿蒙 PC 是第一适配目标窗口缩放、键盘、触控板、系统文件选择器和长时间编辑都属于主路径。核心编辑能力必须离线可用安装包不能在运行时依赖 CDN 才能显示编辑器。这些约束会直接改变技术方案。例如“源码无损”意味着不能把富文本 DOM 当作主要数据模型“离线可用”意味着 CodeMirror、Markdown 渲染器和样式必须进入 HAP“用户授权”意味着文件能力应留在 ArkTS 原生侧不能给 ArkWeb 任意目录访问权限。PRD 的价值正在这里它把抽象愿望变成能影响架构的限制条件。用风险清单决定验证顺序编辑器最容易让团队误判进度因为标题、工具栏和侧栏很快就能做出来而真正困难的问题通常隐藏在底层。项目建立基线时没有按界面从上到下开发而是先列出可能导致整体技术路线失败的风险风险如果不提前验证会怎样技术证据ArkWeb 中的编辑内核不可稳定输入中文后续全部编辑功能失去基础中文输入、撤销和重做实测Web 资源依赖网络离线启动失败或存在供应链漂移单 HTML 产物与离线 HAPBridge 每次按键传输全文大文档输入卡顿、内存复制失控节流状态消息与显式保存快照文件读写只在理想路径工作用户文件可能截断或乱码分块读取、字节校验、truncate、fsyncMarkdown 预览可执行恶意内容本地文档成为代码执行入口CSP、DOMPurify、ArkWeb 权限收缩10MiB 文档保持全部高级能力语法树、换行和预览造成内存峰值大文件降级模式与进程组 PSS风险清单不是一次性文档。每发现一个真实问题都要回写它的触发条件、影响范围、修复和回归方法。例如 10MiB 文档连续撤销曾出现内存压力这类事实不能只留在调试记录里而要进入进度文档和阶段评审成为后续性能门槛的依据。PRD、执行计划和 ADR 各管一件事三类文档看起来都在“写计划”实际职责不同。PRD 管产品承诺。它描述用户、场景、功能范围、非功能指标和里程碑退出条件。一个需求如果没有用户价值或验收方式不应直接变成开发任务。执行计划管交付顺序。docs/EXECUTION_PLAN.md使用稳定编号拆分验证项每一项都包含目标、依赖、产物、完成条件和状态。编号稳定后测试报告和进度记录都能引用同一个步骤避免“文件打开已经做了”却无法判断做到了哪一层。ADR 管不可轻易撤销的技术决定。混合编辑架构会影响依赖、调试方式、内存模型和安全边界因此必须记录选择 ArkUI 加 ArkWeb 的理由、未选择纯 ArkUI 文本控件的原因、已知代价和重新评估条件。ADR 不是宣布某个方案永远正确而是保存当时的证据使后来者知道什么变化足以推翻这个决定。一个实用判断是功能取舍写 PRD执行状态写计划跨模块且代价较高的方案写 ADR。三者不互相复制正文只通过稳定编号关联。阶段闸门必须可以判失败如果一个闸门无论结果如何都能解释为通过它就不是闸门。技术验证至少允许出现三种结论通过目标证据完整没有阻断性遗留项。条件通过架构可以继续但明确指标尚未达到正式目标遗留项必须进入下一阶段硬门槛。不通过关键假设被证伪需要替换方案或停止扩展功能。例如 1MiB 文档总加载时间达到目标但完整进程组 PSS 高于正式目标。评审不能把它包装成“性能全部通过”而应根据预先定义的技术验证容差给出条件通过并把真机 Release P95 和内存优化留作后续门槛。这个写法比单独展示一张流畅运行的截图更可信因为它同时记录了成功证据和不满意的部分。证据要能被另一台机器重复一次手工操作成功只是观察不是稳定证据。工程基线要求每个步骤尽量留下四层材料源代码实现位于明确模块关键边界可以审查。自动化适合浏览器或纯函数验证的行为进入测试套件。构建产物Debug 和 Release 都由脚本生成记录 HAP 路径与哈希。设备记录涉及系统选择器、ArkWeb、IME、内存或打印的能力保留设备型号、操作步骤、结果和截图。推荐的本地验证顺序是先构建 Web 编辑器再运行 Web 自动化然后构建 Debug HAP 做高频设备调试最后用 Release HAP 采集性能和阶段证据。这样可以把问题逐层缩小TypeScript 错误不会拖到 ArkTS 构建浏览器逻辑错误不会等到模拟器里才发现性能数据也不会混入 Debug 开销。cdweb-editornpmrun buildnpmrun test:e2ecd.../scripts/build-debug.sh ./scripts/build-release.sh命令来源仓库根目录脚本及web-editor/package.json。执行时还应记录 DevEco Studio、HarmonyOS SDK 和模拟器版本否则同一个 HAP 名称并不能说明环境一致。进度记录要写结果不写情绪docs/PROGRESS.md的记录单位不是“今天做了很多”而是一项可核对的交付。每条记录至少回答改了什么、为什么改、执行了哪些验证、得到什么结果、还有什么没做。遇到失败也要写清触发路径。例如“保存失败”信息量太低应写成“用户 URI 在写入后返回短写预期字节数与实际字节数不一致旧文件是否完整尚需故障注入确认”。这种记录方式会自然形成项目时间线。后来排查回归时可以从现象追到首次实现、对应报告和当时保留的风险而不必从提交历史中猜测产品语义。对准备长期维护和商业化的软件这种可追溯性比短期的任务数量更重要。如何控制范围而不牺牲质量建立基线不等于一开始设计所有模块。首轮只做能够验证架构的纵向切片一个工作台、一份文档、三种视图、受限 Bridge、文件打开保存、安全预览、大文件降级和导出路径。多标签、工作区索引、插件系统和云同步暂时不进入核心实现。控制范围的关键是缩小功能面而不是缩小完成标准。单文件能力虽然少但打开、编辑、保存、重开、异常提示和格式保护必须形成闭环安全预览虽然不支持任意 HTML但不能让脚本标签绕过净化大文件虽然降级显示也必须能继续编辑和保存。这样得到的基础可以扩展而不是需要在功能变多后推倒重写。适合鸿蒙 PC 项目的基线清单在同类桌面工具启动时可以用下面的清单做第一次工程评审是否写清第一目标设备、核心用户和前三个高频任务。是否定义用户数据、权限、网络和遥测的默认边界。是否为启动、打开、保存、内存和大文件设定可测指标。是否把关键架构决定写入 ADR并列出替代方案和回退条件。是否有不依赖 IDE 点击顺序的 Debug、Release 构建脚本。是否固定依赖锁文件生产资源是否可以离线审计。是否区分自动化证据、模拟器证据和真机证据。是否允许阶段结论为条件通过或不通过。是否把未测项放进下一阶段而不是藏在“后续优化”一句话中。是否保证技术文章、测试数据和正式仓库之间有清楚的同步边界。工程基线的最终产物不是几份文档而是一套共同语言需求有编号决定有理由验证有命令结论有证据风险有归属。鸿蒙 PC Markdown 编辑器只有在这套语言上继续扩展功能规模增长时才不会同时放大数据安全、性能和维护成本。用 Definition of Done 消除“代码写完”的歧义桌面编辑器的一项能力通常横跨界面、状态、文件、异常和测试。开发者说“打开文件写完了”可能只代表选择器能返回 URI产品理解的完成却包括取消、超限、非法编码、切换未保存文档、错误提示和重新打开。双方对完成的定义不同进度会持续失真。每类任务应有固定完成清单。文件能力至少包括正常路径、取消、错误、用户数据保持、自动化和设备记录界面能力包括宽窄窗口、长文本、键盘焦点和禁用状态安全能力包括威胁模型、实现、恶意输入回归和权限审查性能能力包括固定语料、Release 包、样本数和完整进程组数据。Definition of Done 不需要为每个任务复制很长模板可以在工程规则中定义通用部分任务只补充特有验收。它的作用是让“进行中”和“完成”之间有客观差异实现存在但设备未测可以准确标记为代码完成、验收进行中而不是勉强二选一。架构边界需要持续守护混合架构确定后最容易出现的是为了赶功能穿透边界。例如让 ArkWeb 直接读取文件可以少写一层服务让 ArkTS 持有实时全文可以方便显示字数用第二套 Markdown 渲染器可以快速完成导出。这些局部捷径都会引入新的事实源、权限面或规则漂移。代码评审可以使用边界问题检查改动新能力属于原生系统能力、编辑状态还是派生展示。是否新增第二份可写正文、第二套净化规则或另一条保存路径。是否扩大 ArkWeb 的网络、文件、存储或原生方法权限。是否让布局变化触发文档生命周期变化。是否在大文档输入路径增加全文扫描、复制或序列化。是否改变用户文件字节而没有明确产品决策。若确实需要改变边界例如多标签需要新的会话管理先用 ADR 写清动机、备选方案、内存影响和迁移策略。架构治理不是拒绝变化而是让变化以可审查的方式发生。技术债务要写成可验证问题“以后优化内存”不是可管理的技术债。更有效的记录应包含当前数据、目标、可能原因、临时缓解和验证方式。例如1MiB 文档完整进程组 PSS 为 324.7MiB正式目标低于 250MiB当前以关闭非必要 ArkWeb 能力和大文件降级控制风险后续分别测量预览 DOM、语法扩展和多会话增量并在目标真机用 Release P95 验收。同样“保存还不够安全”应拆成目标 URI 缺少同目录原子替换、沙箱旧版本备份已实现、短写和强杀窗口尚未稳定注入。这样技术债会随着证据收敛完成条件也不会被模糊描述任意移动。技术债清单还要定期去重。有些条目随着架构变化已经失效有些风险被多个任务重复记录有些“优化”其实没有用户影响。评审时保留仍能复现、仍有明确影响的条目避免清单膨胀成无人阅读的愿望集合。依赖升级也要进入工程流程编辑器依赖代码编辑内核、Markdown 渲染器、净化器和构建工具。依赖升级可能改善性能和安全也可能改变输入行为、HTML 输出或生产包。不能把它当作无风险的版本号维护。一次依赖升级应单独提交先阅读发布说明和安全公告再运行类型检查、全部 Web 回归、生产包外链审计和鸿蒙设备冒烟。CodeMirror 升级重点检查 IME、撤销、选区和大文档markdown-it 与 DOMPurify 升级重点检查危险载荷、链接和导出Vite 与单文件插件升级重点检查 CSP、资源路径和 HAP 内产物。锁文件变化需要审查间接依赖数量和来源。若升级必须更改 CSP 或开放 ArkWeb 权限应视为架构/安全改动而不是普通依赖维护。变更规模与验证范围要匹配小范围文案修改无需重跑所有真机性能但保存服务、Bridge 协议或 EditorState 初始化属于共享边界测试范围必须扩大。可以按影响面选择验证纯样式构建、关键尺寸截图、长文本和窗口回归。Web 编辑逻辑类型检查、浏览器套件、ArkWeb 冒烟。文件与恢复Debug/Release 构建、设备读写、强杀与格式夹具。安全渲染恶意载荷、导出、生产包与权限配置。架构边界ADR、跨模块回归、性能和阶段评审。这个映射让质量投入与风险成比例。所有改动都跑全部测试会让反馈过慢所有改动只跑编译又会遗漏共享回归。工程基线应给开发者足够明确的默认路径并允许根据新证据升级验证等级。数据与截图也需要治理技术验证会产生大文件夹具、用户 URI 文件、截图、录屏、HAP 和性能日志。这些材料不是都适合提交源码仓库。测试报告与无敏感信息的关键证据可以版本化大体积临时语料、设备私有路径、用户文档和用于发表的技术文章应保持本地或进入专用制品存储。截图发布前要检查文件名、目录、账号、通知和正文是否含敏感信息。应用内部截图应展示与用例有关的状态而不是只截系统桌面。性能日志要保留命令和数字删除用户正文。HAP 作为制品应通过哈希关联报告不必反复提交 Git。清楚的材料边界既保持源码仓库整洁也防止为了写文章或报告意外公开用户数据。让指标形成反馈回路工程指标的价值不在于展示数字而在于触发决策。加载时间连续上升时应定位最近引入的扩展内存超过门槛时限制多标签并优先优化 ArkWeb 会话恢复失败率不为零时暂停扩大文件能力安全回归出现未知载荷时阻止发布。指标需要稳定采集条件和负责人。过多无法行动的指标会制造噪声建议围绕启动、打开、首次可编辑、保存、异常恢复、进程组内存和关键回归通过率建立少量核心面板。每个指标都写清采样环境、目标、告警阈值和达到阈值后的动作。当指标、风险和里程碑连在一起阶段计划就不再是静态日程。例如性能未达正式目标时多标签并发架构不能直接按原方案扩展保存故障注入未通过时不能仅凭正常路径宣布数据安全完成。这种反馈回路才是“有规划地开发”的技术含义。基线文档也要接受代码式维护PRD、ADR 和计划需要评审、版本差异和明确变更理由不能成为只增不删的文字堆积。发现实现与文档不一致时先判断是代码偏离约束还是约束已经过时再同步修改其中一方不能保留两个互相矛盾的“真相”。阶段关闭后冻结评审结论后续变化新增记录保留当时决策背景。这样工程基线才会随着产品演进持续提供约束而不是在第一个版本后失效。