:用证据契约与硬切规则取代旧版 App/Template 基准动物园)
Plate 编辑器基准实验室的 Evidence Kit 引导Bootstrap用证据契约与硬切规则取代旧版 App/Template 基准动物园【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate本文基于 Plate 仓库中benchmarks/editor/iterations/000-bootstrap-evidence.mdEvidence Harness Bootstrap第 000 期迭代记录展开介绍 Plate 如何用一套证据优先evidence-first的 Evidence Kit 实验台lab替换掉旧的独立 Next/Vite 基准应用确立目标自有的基准行归一化契约、来源配置、注册表控制平面与硬切hard-cut守护并给出完整的验证命令。读完本文你将掌握该实验台的目录骨架、行归一化契约的字段语义、硬切机制的实现位置、基准注册表的运作规则以及从npm run check到npm run evidence:full的完整验证链路从而能够在该实验台内新增或审查一条 Slate v2 vs Slate 的基准证据行。背景与动机为什么旧的基准应用动物园必须被替换在本次引导之前benchmarks/editor是一个独立的 Next/Vite 基准应用app与模板template集合用于承载编辑器框架基准研究。该迭代记录verdict: accepted明确指出这个形态存在结构性问题大量apps、templates等应用脚手架占据了默认归属权基准实验的默认所有者变成了浏览器应用壳而不是证据产物本身历史上的临时基准 JSONtmp/*benchmark*.json散落在各包中无法区分当前有效的证据与一次性的历史输出在 Slate v2 与 Slate 还没有可靠的对比行之前任何关于性能数字的宣称都缺乏可验证的形态。因此本次引导的 Goal 非常明确用更小、更证据优先的实验台替换benchmarks/editor专门用于编辑器框架基准研究。其核心原则是默认所有者是证据产物evidence artifacts而非浏览器应用脚手架。这一点也在实验台 READMEbenchmarks/editor/README.md中得到了复述This directory is an Evidence Kit lab for editor framework benchmark research. It replaces the old standalone Next/Vite benchmark app. The default owner is now evidence artifacts, not browser app scaffolding.目标定义一个证据优先的编辑器基准实验室第 000 期记录把目标收敛为一句话Replacebenchmarks/editorwith a smaller evidence-first lab for editor framework benchmark research。展开来看这个目标包含三层含义缩小而非扩编不再维护庞大的浏览器应用/模板矩阵实验台只保留证据所需的骨架先证明自身再输出数字实验台必须先能证明自己产出的证据形态是正确的之后才允许任何人引用 Slate v2 vs Slate 的数字Current Result 原文The lab can prove its own evidence shape before anyone starts claiming Slate v2 vs Slate numbers硬切守护一旦旧应用/模板路径复活基准行必须失败fail从而阻止无意的回归。实验台骨架全景Evidence Kit scaffold 的组成第 000 期记录列出了引导阶段已经实现的骨架Implemented对照 benchmarks/editor 目录可以逐一印证骨架组件说明仓库中的落点Fuzzer模糊测试随机生成基准行并校验归一化契约benchmarks/editor/test/fuzz/core-fuzz.mjsCorpus语料固定种子用例与生成用例一起覆盖契约benchmarks/editor/test/fixtures/corpus.jsonBenchmark基准行核心/对比/富文本等基准行生成与检查benchmarks/editor/benchmarks 下多个*.mjsSource fetchers来源抓取器抓取编辑器框架来源配置供研究使用benchmarks/editor/benchmarks/fetch-editor-frameworks-research.mjs、fetch-source-pass-research.mjsPackage-boundary check包边界检查限制源码文件数、包体积、dry-run 打包体积benchmarks/editor/benchmarks/package-boundary-gates.mjsStartup check启动检查校验包导入的 P95 耗时与导出数量上限benchmarks/editor/benchmarks/startup-import.mjsScope hash范围哈希由 evidence-kit 生成/更新基准作用域通过npm run bench:scopeevidence-kit scope --updatePerf docs性能文档生成 HTML 看板与可检索的 perf 文档benchmarks/editor/docs/perfevidence.html、index.html、rich-text.html、slate-v2-internals.html其中 fuzzer 是验证整个契约的第一道门它读取 corpus 中的固定用例再以可复现的种子默认0x5e_ed即 24237生成随机用例逐条调用normalizeBenchmarkRow并做深度相等比较此外它还会调用createEvidenceReadinessRows校验硬切就绪行、用构造的 Slate 对比产物校验三个活动面slate-v2:dom-present、slate-v2:default-render-auto、slate各产出一行归一化结果。如果契约被破坏npm run fuzz会直接失败。目标自有的行归一化契约Target-owned Normalization Contract第 000 期记录强调了一个关键设计基准行的归一化契约由目标target自己拥有实现在 benchmarks/editor/src/index.mjs。这意味着一行证据长什么样不是由上层应用壳定义的而是由证据实验台与目标仓库共同约定。目标声明editorTargetsexport const editorTargets Object.freeze([ { id: slate-v2, label: Slate v2, role: engine-and-react-runtime, sourcePath: ../../.tmp/slate-v2, evidenceOwner: scripts/benchmarks plus packages/slate*, }, { id: slate, label: Slate, role: legacy-baseline, sourcePath: ../../../slate, evidenceOwner: upstream package behavior and local clone, }, ]);从源码结构看实验台当前只声明两个活动目标slate-v2角色为引擎 React 运行时本地源码路径指向.tmp/slate-v2相对本实验台为../../.tmp/slate-v2证据所有权归属于 Slate v2 自身的scripts/benchmarks与packages/slate*slate角色为遗留基线legacy-baseline本地源码路径指向../../../slate证据所有权归属于上游包行为与本地克隆。这两个目标同时出现在 benchmarks/editor/research/editor-frameworks-sources.json 的来源配置中说明来源配置与目标声明是相互印证的同一事实。行契约字段normalizeBenchmarkRowconst normalized { category: requireString(row.category, category), fixture: requireString(row.fixture, fixture), library: requireString(row.library, library), status: requireString(row.status, status), };一行归一化后的基准行至少包含四个必填字段另有四个可选的度量字段字段类型语义categorystring必填基准类别例如slate-react-huge-document-legacy-comparefixturestring必填场景/固件标识例如5000-blocks/combined-selection/startupMslibrarystring必填被测实现例如slate-v2:default-render-auto、slatestatusstring必填状态例如ok、missing-source、missing-artifact、over-budgetmedianUsnumber可选中位数耗时统一换算为微秒p95Usnumber可选P95 耗时统一换算为微秒opsnumber可选采样次数 / 操作次数bytesnumber可选字节类指标如堆增量notestring可选可读上下文附在结果 JSON 中所有数值字段都会经过requireFiniteNumber校验任何NaN/Infinity都会抛错——这是契约对脏数据的零容忍设计。normalizeBenchmarkResult则在行之上再包一层结果对象name、generatedAt、nodeNode 版本与rows数组并兼容rows与results两种负载键名。毫秒到微秒的统一换算时间类指标在写入结果前统一由msToUs转换为微秒并保留三位小数function msToUs(value) { return Number((requireFiniteNumber(value, milliseconds) * 1000).toFixed(3)); }度量字段的识别遵循命名约定以Ms/Duration结尾的视为时间指标写medianUs/p95Us以Bytes/MB结尾或unit bytes的视为字节指标写bytes否则视为普通计数写ops。这保证了来自不同产物的指标最终都落到同一行形态上。三个活动面的顺序与命名export const slateLegacyCompareSurfaceOrder Object.freeze([ v2DefaultRenderAuto, v2DomPresent, legacyChunkOn, ]);Slate 遗留对比产物中的三个活动面分别映射为slate-v2:default-render-auto、slate-v2:dom-present与slatechunk-on 基线顺序固定便于在结果 JSON 与文档看板中稳定呈现。硬切Hard-cut旧路径回归即失败第 000 期记录中Hard-cut benchmark row that fails if old app/template paths return是本引导最有特色的机制。它的实现分为两部分。第一部分是硬编码的陈腐表面路径清单benchmarks/editor/src/index.mjs 中的staleSurfacePathsexport const staleSurfacePaths Object.freeze([ apps, app, assets, components, data, lib/benchmark-types.ts, scripts/benchmark/run_contract_benchmarks.mjs, templates, tests/config, website, ]);第二部分是createEvidenceReadinessRows与findStaleSurfaces只要这些路径中任何一个在实验台根目录重新出现legacy-app-surface-removed这一行的状态就会从ok变为stale-surface并在 note 中列出命中的路径。三行就绪证据evidence-readiness分别为editor-framework-source-map来源配置条数是否不少于目标数sources.length editorTargets.lengthlocal-editor-targets本地目标源码根是否存在knownTargets.length editorTargets.lengthlegacy-app-surface-removed旧应用/模板路径是否已被清除staleMatches.length 0。这三行由 fuzzer 在每次运行时强制校验if (readinessRows.length 3) throw也被npm run check与npm run evidence:full覆盖。也就是说任何人只要把apps、templates、website之类的旧目录放回实验台整条验证链就会红——这就是硬切的落地方式不是靠人约定而是靠基准行失败来强制执行。来源配置editor-frameworks-sources.json 与源码抓取第 000 期记录提到 Editor framework source config inresearch/editor-frameworks-sources.json。该文件benchmarks/editor/research/editor-frameworks-sources.json当前声明了 2 个来源{ version: 1, topic: editor-frameworks, generatedBy: shapeshift-labs/evidence-kit, sources: [ { name: slate-v2-package, type: file, path: ../../.tmp/slate-v2/package.json, fileName: slate-v2-package.json, why: Slate v2 owns current deep Slate benchmark commands and artifact families. }, { name: slate-package, type: file, path: ../../../slate/package.json, fileName: slate-package.json, why: Slate is the local baseline for Slate v2 compare lanes. } ] }src/index.mjs中的readResearchSources会校验每个来源的name与type为非空字符串why字段记录了该来源被纳入研究的理由——Slate v2 拥有当前深度基准命令与产物家族Slate 是对比道的本地基线。对应的抓取命令是npm run research:editor-frameworks:fetch与npm run research:source-pass:fetch抓取产物用于研究目录benchmarks/editor/research下的证据源地图。控制平面benchmark-registry.json 的注册表规则虽然第 000 期主要完成的是引导骨架但后续第 003 期benchmarks/editor/iterations/003-evidence-control-plane.md将注册表确立为控制平面其规则在第 000 期的决策中已经埋下伏笔未来对比应进入本实验台而不是恢复旧的 app/template 动物园。注册表benchmarks/editor/research/benchmark-registry.json的核心政策是policy: { activeArtifactRule: Only artifacts listed here are active benchmark evidence., discardRule: Unregistered benchmark JSON files are ignored historical output. }即只有注册在案的产物才是活动证据未被注册的旧tmp/*benchmark*.json一律视为被忽略的历史输出除非为它添加注册表条目、目标自有适配器、fuzzer、corpus 用例、基准行或来源记录README 的 Rule 一节。注册表当前登记的产物家族包括React 大型文档react-huge-document-legacy-compare5,000 块、3 次迭代、20 次类型操作、combined-selection 道、react-huge-document-overlays、react-huge-document-browser-trace、react-huge-document-slate-browser-traceReact 局部性react-rerender-breadthReact 打字react-active-typing-breakdown核心当前core-normalization-current、core-query-ref-observation、core-node-transforms、core-text-selection、core-editor-store、core-refs-projection、core-transaction-current可选核心对比core-huge-document-compare、core-normalization-compare、core-observation-compare、core-rich-text-operations-compare、history-compare剪贴板 / 协作 / issue 回放clipboard-large-payload、collab-readiness、issue-6038-transaction-execution、history-retained-memory可选。每个产物条目都携带id、category、kindslate-legacy-compare/current/compare/browser-trace/rows、owner、family、cwd、实际运行命令command、产物路径path、required标志与decision该基准要回答的问题。required: true的产物缺失会被健康报告标记为missing-artifact反之标记为optional-missing-artifact——这正是第 002 期记录benchmarks/editor/iterations/002-rich-text-editor-evidence-matrix.md中红行有用机制的基础缺件、超预算、未注册都会显式暴露出来而不是被静默吞掉。验证命令从 check 到 evidence:full第 000 期记录给出了三条核心验证命令全部在 benchmarks/editor 目录内执行npm run check npm run evidence:full npm run docs:perf:search -- editor benchmark结合 benchmarks/editor/package.json 的脚本定义可以拆解出完整链路npm run check对src/index.mjs、fuzzer、全部benchmarks/*.mjs逐个执行node --check语法检查然后执行npm run evidence:full。这是语法 全量验证的总入口。npm run evidence:full按序执行test:evidencefuzzer 跑 200 个生成用例 包边界门禁--bytes 200000 --files 32 --packBytes 1250000 --packFiles 96即源码 ≤200KB / ≤32 文件、dry-run 打包 ≤1.25MB / ≤96 文件fuzzfuzzer 跑 1000 个生成用例并写入复现文件--write-repro test/fixtures/repro-latest.jsonbench:evidence依次产出core-latest.json、slate-v2-legacy-latest.json、rich-text-editors-latest.json再以--p95Ms 100 --exports 32检查启动导入最后执行evidence:healthbench:startup:check、bench:package:gatesbench:scopeevidence-kit scope --updatedocs:perf与docs:perf:check生成并校验 HTML 看板research:list。npm run docs:perf:search -- editor benchmark调用evidence-kit search在生成的 perf 文档中检索关键词。例如要检索 Slate v2 与 Slate 的对比证据可执行npm run docs:perf:search -- slate-v2 slate见第 001 期记录 benchmarks/editor/iterations/001-slate-v2-legacy-evidence.md。bench:evidence的核心产物都落在 benchmarks/editor/benchmarks/results 目录包括slate-v2-legacy-latest.json第一个直接的 Slate v2 vs Slate 运行时对比结果5,000 块工作负载rich-text-editors-latest.json综合基准矩阵从活动注册表再生成benchmark-health-latest.json健康报告与排名后的下一步行动next actionscore-latest.json、startup-import-latest.json、package-boundary-gates-latest.json、benchmark-scope-latest.json核心行、启动检查、包边界门禁与作用域快照。当前结果与决策先证明形态再谈数字第 000 期记录对当前结果的表述非常克制The lab can prove its own evidence shape before anyone starts claiming Slate v2 vs Slate numbers.也就是说引导阶段的验收标准不是某个性能数字而是证据形态本身可证明——契约可校验、来源可追溯、硬切可执行、产物可再生成。配套的 Decision 则划定了边界未来的编辑器对比应该在本实验台内添加来源可追溯的 Slate v2 vs Slate 基准行不应恢复被删除的 app/template 动物园除非某条基准行证明了浏览器目标应用才是正确的所有者。后续迭代印证了这一决策的落地方式第 001 期把slate-v2-legacy对比产物作为第一条真实对比道并刻意保留混合结果——部分选择密集行偏向 Slate chunking就如实保留因为保留不舒适的行而不是把基准变成营销the lane is useful because it preserves uncomfortable rows instead of turning the benchmark into marketing第 002 期把综合矩阵作为当前富文本基准权威并公开列出超预算红行如cutTwoBlocksEditMsP50/cutTwoBlocksMsP50与可选缺失产物slate-transaction-benchmark.json、slate-history-retained-memory-benchmark.json第 004 期benchmarks/editor/iterations/004-clipboard-over-budget-investigation.md则直接围绕剪贴板超预算行展开调查。这套红行即线索的做法正是证据优先实验台的核心价值。延后事项与演进路径第 000 期记录的 Deferred 部分明确了两项遗留工作更多的 Slate v2 vs Slate 浏览器交互证明Additional Slate v2 vs Slate browser interaction proof——当前对比道集中在巨大文档工作负载浏览器交互面selection、输入法、拖拽等仍需补充将更多既有 Slate v2 基准产物规范化进本实验台——即按注册表规则逐一登记、归一化而不是直接引用历史 JSON。对想深入该实验台的读者建议按以下顺序阅读实验台总览与命令清单benchmarks/editor/README.md归一化契约与目标声明benchmarks/editor/src/index.mjs活动注册表与控制平面benchmarks/editor/research/benchmark-registry.json来源配置benchmarks/editor/research/editor-frameworks-sources.json迭代记录benchmarks/editor/iterations000–004最新证据产物benchmarks/editor/benchmarks/results生成的 HTML 看板benchmarks/editor/docs/perf。小结第 000 期引导为 Plate 的编辑器基准研究确立了三个不可退让的基线证据契约归一化所有产物落到统一的category/fixture/library/status/medianUs/p95Us/ops/bytes行形态、来源与注册表可追溯只有注册在案的产物才算活动证据、硬切守护旧 app/template 路径一旦回归验证立即失败。在此之上实验台先用npm run check/npm run evidence:full证明自身形态成立再逐步吸纳 Slate v2 vs Slate 的对比道——无论结果是否好看都以红行如实呈现。这种先证明形态、再输出数字的纪律正是富文本编辑器基准研究区别于营销型基准的关键所在。【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考