RxJS Next 迁移契约报告指南:基于 @rxjs/migrate 的机器可读迁移报告字段、Schema 验证与就绪评估
【免费下载链接】rxjsA reactive programming library for JavaScript项目地址: https://gitcode.com/gh_mirrors/rx/rxjs
本文档解读 packages/migrate/skill/assets/migration-report.md 定义的结构化迁移契约报告模板,说明如何在 RxJS 7 迁移到 RxJS Next 的 agent 主导工作流中填写、校验这份报告,并解释其字段与@rxjs/migrate引擎的清单(manifest)Schema、就绪评估 API 之间的对应关系。读完本文,你将掌握迁移报告的完整信息模型、每一张表的字段语义、Schema 验证与就绪评估的区别,以及如何用报告支撑"可复现、可审计、可交接"的迁移收尾。
报告在迁移工作流中的定位
报告模板是 RxJS Next 迁移契约的"人类可读摘要"层,与之并存的还有一份机器可读的迁移契约清单(contract manifest)。SKILL.md 的"Working record"一节明确要求:同时创建(或定位)一份已入库的迁移契约 manifest 与一份简明的人类可读报告,manifest 必须使用安装版@rxjs/migrate导出的 Schema 校验,而报告则使用assets/migration-report.md这个模板。两者定位不同:
- Manifest:结构化决策与证据的权威记录,由 Schema 校验、机器可读,是"事实的单一来源";
- Migration report:面向开发者与评审者的浓缩摘要,将 manifest 中的决策、诊断、验证、阻塞项整理成易读的表格。
报告开头的说明原文即指出:"The manifest validated by the installed@rxjs/migrateschema remains the authoritative structured decision and evidence record"——Schema 校验通过的 manifest 才是权威记录,报告是它的可读投影。这也解释了为什么报告模板中的表格结构与 schemas.ts 中migrationContractManifestSchema的字段一一对应:baseline、units、diagnostics、intentionalDivergences、verification、blockers,正是 manifest Schema 的六个核心集合。
一、Scope and authority(范围与权限)
报告第一张表记录了迁移的授权边界,字段包括:
| 字段 | 含义 |
|---|---|
| Repository | 被迁移仓库标识 |
| Source revision | 迁移起点源码修订号(对应 CLI 的--source-sha) |
| Migration boundary | 允许迁移的目录/文件范围 |
| Authorized write paths | 引擎允许写入的路径(对应--out-dir) |
| Package manager | 项目包管理器(pnpm/npm/yarn,决定如何调用rxjs-migrate与 Skill 安装命令) |
| Network policy | 是否允许网络访问(影响安装依赖、外部验证) |
| Existing changes protected | 迁移开始前已存在的未提交改动清单 |
| Developer/approver | 负责人与审批人 |
这张表对应 SKILL 第 1 阶段"Establish authority and scope"的输出。从 schemas.ts 可以看到一个关键实现细节:Schema 用relativePath校验器拒绝绝对路径、Windows 盘符路径和包含..的父目录穿越路径,这保证了报告与 manifest 中所有sourceLocations、诊断span.file都必须是仓库内相对路径。
二、Tool and dependency identity(工具与依赖身份)
该表记录迁移链路上所有组件的精确版本或摘要:
| Item | 说明 |
|---|---|
| Source RxJS | 源版本,对应 manifest 的sourceRxjsVersion |
| Target RxJS Next | 目标版本,对应targetRxjsVersion |
@rxjs/migrateengine | 引擎版本,对应engineVersion |
| Capability registry | 能力注册表版本,对应capabilityRegistryVersion |
| Canonical Skill | 规范 Skill 的 SHA-256 摘要,对应skillDigest |
| Contract schema | 契约 Schema 版本(当前为schemaVersion: 1) |
身份一致性是就绪评估的第一道关卡。schemas.ts 中的assessMigrationContractReadiness会逐项比对:engineVersion不匹配、capabilityRegistryVersion不匹配、skillDigest不匹配都会产生对应 finding。报告中的 Evidence 列应链接到pnpm-lock.yaml、安装包的 version 常量等可复现证据。引擎版本与注册表版本在 version.ts 中集中定义,注册表本身(见 capabilities.ts)也强制声明schemaVersion、registryVersion、engineVersion,任何不兼容的自定义注册表会被直接拒绝而不改动源码字节。
三、RxJS 7 baseline(迁移前基线)
| Check ID | Command | Environment | Exit | Result | Accepted pre-existing failure |
|---|
基线表记录迁移开始前,对未改动的 RxJS 7 项目执行约定检查(build、type、lint、unit、integration、behavior)的精确结果。每行必须包含:
- Check ID:检查的唯一标识;
- Command:可复现的完整命令;
- Environment:相关环境事实(Node 版本、平台、是否原生 Observable 可用等);
- Exit:退出码;
- Result:通过/失败等状态;
- Accepted pre-existing failure:若起始门禁失败且经开发者同意保留,需在此标注"已接受的既有失败"。
基线的意义由 SKILL 第 3 阶段强制:迁移改变依赖或源码之前必须先建立绿色基线,且每个特征化测试(characterization test)都必须在 RxJS 7 上通过。就绪评估中baseline-not-green正是读取此表对应数据——manifest 中任何 status 为failed或not-run的基线记录都会阻断ready状态(见 schemas.ts)。
四、Risk and coverage assessment(风险与覆盖评估)
| Finding | Source locations | Lifecycle/behavior risk | Coverage disposition | Evidence or approval |
|---|
这是 SKILL 第 2 阶段的产物。评估协议在 references/assessment-and-contract.md 中给出九个排查主题:构造(new Observable、defer、自定义 producer)、重复订阅(retry/refresh/fan-out/cache)、Subjects(replay/terminal/late observer)、订阅所有权与取消、teardown 顺序、时序与调度器、错误投递、输入转换边界、组合与测试装置。每个生命周期敏感路径必须恰好得到一种覆盖处置:
- Covered:已有命名测试证明相关行为;
- Characterize:迁移前补充聚焦的 RxJS 7 特征化测试;
- Unsupported:没有可接受的 Next 表面能保留该行为,保留证据并记为产品缺口;
- Accepted uncovered risk:开发者显式接受缺少证据继续推进,须记录审批人、时间、理由与影响。
该参考文档特别警告:缺少覆盖不是行为安全的证据("Missing coverage is not evidence that behavior is safe")。报告此表的 Coverage disposition 列应如实填写这四种状态之一。
五、Target contract units(目标契约单元)
| Unit ID | Source locations | RxJS 7 claim | Target lifecycle | Evidence classification | Approval | Evidence |
|---|
契约单元是迁移的最小决策单位。manifest Schema 对每个单元要求(见 types.ts 与 schemas.ts):
id:稳定唯一 ID(Schema 拒绝重复 ID);sourceLocations:至少一个精确源码 span(文件 + 起止 offset/line/column);lifecycle:目标生命周期,取值限定为 types.ts 中的六种——platform-shared、producer-per-direct-subscription、subject-hot、not-applicable、unsupported、unresolved;evidenceClassification:兼容性分类,五选一(portable、harness-rewrite、compatibility-only、intentional-divergence、unsupported-or-obsolete);claims:至少一条目标行为声明;approval:审批状态(approved/pending/not-required),一旦标记approved,Schema 强制要求approvedBy、approvedAt、rationale全部填写(见 schemas.ts)。
生命周期选择是这份报告最容易出错的环节。SKILL 与评估参考都强调:不要把平台 Observable 简单标成"hot"或"cold"——平台语义是"第一个观察者启动活跃 producer,并发观察者加入共享,最后一个观察者离开时拆除,后续观察者可重新启动"。unresolved是停止态(stop state),必须暂停等待开发者决策,且 Schema 明确规定unresolved/unsupported单元不允许使用not-required审批(见 schemas.ts)。
六、Migration batches(迁移批次)
| Batch | Scope | Dry-run report | Diagnostics reviewed | Write approved by | Changed files |
|---|
批次表对应 SKILL 第 5、6 阶段。每个批次必须先 dry-run 后 write,其协议细节在 references/engine-and-batches.md 中:
- 用
rxjs-migrate --source-root <root> --source-repo <repo> --source-sha <sha> --mode <cold|platform> --framework preserve <files>执行 dry-run(不带--write),CLI 返回带版本号的 JSON 报告,不写任何文件; - 评审所有诊断与变更文件清单后,开发者批准写入;
- 用相同输入加
--write --out-dir <authorized-destination>执行写入; - 再次无写入运行同一转换,结果必须逐字节不变、诊断稳定——任何输出或诊断漂移都是引擎缺陷,须停止批次并保留复现材料。
CLI 的实现保证了"先计划后写入":createMigrationCliReport先调用planMigrationFiles(dry-run 计划),仅当所有文件结果均非refused时才调用applyMigrationPlan执行写入(见 cli.ts)。退出码四态区分:0成功、1结构化迁移拒绝、2参数无效、3运行失败(cli.ts),且被拒绝的批次不写任何文件。报告此表应引用每次 dry-run 的 JSON 报告(含 engineVersion、capabilityRegistryVersion、operation、status、files、diagnostics)与审批人。
七、Diagnostics(诊断)
| Diagnostic ID | File/span | Disposition | Classification | Required action | Resolution or owner |
|---|
诊断是迁移引擎"说真话"的机制。每个诊断在 manifest 中携带完整结构(见 types.ts 与 schemas.ts):
code:十二种诊断码之一(manual-test-scheduler、scheduler-argument、lifecycle-review、missing-capability、unsupported-overload、unsupported-framework-feature、malformed-source、unsafe-binding、path-outside-root、invalid-contract-manifest、conflicting-provenance、invalid-capability-registry);severity:info/warning/error;disposition:informational/requires-review/refused;refusalScope:none/transform/file/batch/write,标明拒绝影响的范围;classification:兼容性分类;span:精确源码位置;nextAction:一个动作码加人类可读消息,动作码九种(review-source、choose-lifecycle、remove-unsupported-overload、migrate-manually、add-characterization-test、fix-input、update-engine、move-path-inside-root、use-compatible-registry)。
引擎的设计原则是:不支持的构造必须保持可见为诊断,而不是藏在兼容性辅助层后面(见 README.md 的 Contract and Skill integrity 一节)。报告此表的 Resolution or owner 列应填写每个诊断的处置结果或责任归属。
八、Intentional divergences(有意分歧)
| Units | Previous claim | Approved Next claim | User impact | Evidence | Approver/time/rationale |
|---|
有意分歧是"经过批准的 RxJS 7 声明与 Next 声明之间的行为差异"。Schema 要求每条分歧记录(见 types.ts):
unitIds:受影响单元(必须指向 manifest 中已存在的单元,否则 Schema 报"Unknown migration unit");previousClaim/nextClaim:旧行为声明与新行为声明;userImpact:对使用者的可观察影响;evidence:证据列表;approval:审批记录,approved状态同样强制要求审批人、时间戳、理由。
就绪评估对未审批的分歧直接产生divergence-unapprovedfinding(schemas.ts)。SKILL 第 7 阶段进一步规定:任何需要改变测试期望的分歧,必须先在 manifest 中记录批准的新行为与用户影响,才能改期望——绝不能为了"让套件变绿"而弱化行为期望。
九、Verification(验证)
| Check ID | Command | Environment | Exit | Result | Summary |
|---|
验证表记录迁移后的最终检查,遵循 references/verification-and-closeout.md 定义的由窄到宽的验证阶梯:
- 解析与格式化变更文件;
- 聚焦类型检查;
- 运行特征化测试与直接迁移的测试;
- 运行受影响包/工作区的 build、type、lint、test 门禁;
- 运行约定的集成、浏览器、native/polyfill 或仓库级门禁;
- 重跑诊断期间环境发生变化的任何命令。
每行必须记录精确命令、环境事实、退出码、状态与摘要——"本地通过了"而没有命令和环境,不构成验证记录。生命周期敏感代码还要额外验证:producer 激活次数与重启、并发与迟到观察、个体与最终取消、abort 原因与上游关闭、Subject 的 current/replay/terminal 行为、teardown 顺序、时间与调度顺序、错误投递、输入转换接受或拒绝。
十、Outcome classification(结果分类)
报告将最终结果分三类,这是 SKILL 第 7 阶段失败分类的直接映射:
Migration defects repaired(已修复的迁移缺陷)
引擎改写导致的语法、类型、测试意图、映射或契约破坏,在小批次内修复并重跑受影响门禁。
RxJS Next product gaps(RxJS Next 产品缺口)
已接受的目标表面无法满足保留的行为证据。必须保留失败证据并上报产品缺口,不允许用本地替代实现伪装(见 verification-and-closeout.md 的失败分类表:Migration defect / RxJS Next product gap / Intentional divergence / Baseline/environment / Unknown 五类,不允许为了方便而重新归类)。
Environment or baseline limitations(环境或基线限制)
迁移前就存在的失败或所需运行时/工具不可用,保持其原始状态并记录限制或已接受的失败。
十一、Accepted blockers(已接受的阻塞项)
| Owner | Affected units | Reason | Evidence | Prevented outcome | Acceptance |
|---|
阻塞项是"带名、带证据、带明确接受"的未完成事项。Schema 的migrationBlockerSchema要求(schemas.ts):owner、reason、受影响单元(须存在)、证据列表、accepted布尔值。参考文档规定每个已接受阻塞项必须说明:
- 负责人与原因;
- 受影响单元;
- 支撑证据;
- 它阻止的行为、环境或发布声明;
- 开发者的显式接受。
禁止用阻塞项掩盖无法解释的回归。就绪评估会区分blocker-accepted与blocker-unaccepted:只有已接受的阻塞项才能通向ready-with-accepted-blockers。
十二、Readiness and handoff(就绪与交接)
报告结尾的检查清单:
- Manifest schema validation(Schema 校验结果)
- Readiness assessment(就绪评估结果)
- Remaining decisions(剩余决策)
- Next action and owner(下一步行动与负责人)
- Measured migration outcome and limitations(实测迁移结果与局限)
这里必须区分两个常被混淆的概念,README.md 明确指出:parseMigrationContractManifest只回答"结构是否正确",assessMigrationContractReadiness才单独报告未解决的生命周期选择、审批、诊断、验证与阻塞项——Schema 有效绝不等同于迁移完成。
就绪状态机三态(见 schemas.ts):
| 状态 | 触发条件 |
|---|---|
ready | 无任何未解决 finding(不含已接受阻塞项) |
ready-with-accepted-blockers | 仅剩blocker-accepted或unit-unsupported类 finding |
incomplete | 存在其他任何 finding(版本不匹配、基线未绿、验证缺失/未绿、单元 unresolved/unsupported、审批 pending、诊断未解决、分歧未审批、阻塞项未接受) |
SKILL 第 8 阶段规定:只有当就绪评估返回ready或开发者有意选择的ready-with-accepted-blockers时才能声称完成,否则必须以"未完成 + 下一个具体决策或行动"的方式交接。最终报告应陈述实测的项目结果与局限,而非声称"自动迁移成功"。
结语:报告填写与校验的最小闭环
从源码看,一份可交接的迁移报告最终应落到如下闭环:
- 填表:按本模板十二节记录范围、身份、基线、风险、单元、批次、诊断、分歧、验证、结果、阻塞项与交接信息,所有源码位置使用仓库相对路径;
- 对账:报告表格与 manifest 的
baseline、units、diagnostics、intentionalDivergences、verification、blockers六个集合逐一对应(参照 schemas.ts 的字段约束); - 验证:用安装版
@rxjs/migrate导出的parseMigrationContractManifest做结构校验; - 评估:用
assessMigrationContractReadiness得到ready/ready-with-accepted-blockers/incomplete三态结论; - 交接:以 SKILL 的六项汇报要点(行为契约变化、源码与测试变化、门禁与结果、修复的缺陷与保留的缺口、已批准分歧与环境局限、剩余阻塞项与负责人)结束迁移。
模板中每个空表都不是装饰,而是迁移契约信息模型的一部分——它们共同保证一次 RxJS 7 → RxJS Next 迁移可以做到"决策有据、拒绝可见、验证可复现、阻塞有主",这正是@rxjs/migrate作为确定性引擎而非通用迁移产品的设计边界所在。
【免费下载链接】rxjsA reactive programming library for JavaScript项目地址: https://gitcode.com/gh_mirrors/rx/rxjs
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考