diff --git a/docs/en/rfcs/1859_artifact_merge.md b/docs/en/rfcs/1859_artifact_merge.md new file mode 100644 index 0000000000..333b3f6e63 --- /dev/null +++ b/docs/en/rfcs/1859_artifact_merge.md @@ -0,0 +1,150 @@ +- Proposal Name: `artifact_merge` +- Start Date: 2026-10-07 +- RFC PR: [oceanbase/powercontext#1859](https://github.com/oceanbase/powercontext/pull/1859) + +# Summary + +Extract Atomic Memory's merge and undo into shared operations backed by one common set of database tables for merge state, +input-to-result relationships, and undo records. Every Artifact Family can integrate with and reuse these operations and tables +without creating its own merge, relationship, or undo tables. All Artifact creation and revision use the common write layer +(`ArtifactRepository` and its shared persistence implementation), with content and revisions remaining in existing Artifact storage. +Each Artifact's business logic decides whether to initiate a merge. + +# Motivation + +[RFC #1809](https://github.com/oceanbase/powercontext/pull/1809) defines new merge results, frozen inputs, preserved history, +and undo. The implementation branch in [PR #1857](https://github.com/oceanbase/powercontext/pull/1857) stores related state in an +Atomic Memory-specific table and determines input revisions from merge information in the result's first revision and lineage. + +Other Artifacts need the same information when merging: which inputs were used, which result was created, when inputs became +frozen, and which objects undo should restore. Common Artifact identities and revisions can express this information without +separate tables and repeated relationship-management and undo implementations for each Family. + +This proposal moves those capabilities into the shared layer. Atomic Memory also uses the same operations and tables for merge +and undo. + +# Guide-level explanation + +## Merge + +A caller supplies exact revisions of at least two distinct Artifacts in the same Scope and Family, plus the merged content. +The shared operation creates a new Artifact C, records the relationships from A and B to C, and freezes A and B. +A and B leave normal use while their content and history remain readable through exact revisions. Subsequent revisions affect C. + +The caller decides how to produce the result content. Whether initiated by a user or an automatic task, merging uses the same +shared operation and writes to the same common tables. + +## Undo + +To undo the merge that created C, the shared operation reads its inputs from the merge record and restores A and B to their +pre-merge states. Each restored input appends a revision under its existing Artifact identity, using its frozen content. +An explicit `restore` may select a historical revision only for its target; `undo_merge` does not accept a historical revision. +C also appends a revision under its existing identity to record retirement. Each new +revision is the Artifact's current revision plus one; existing revisions and the original merge relationships remain intact. +Later revisions of C are not automatically distributed back to A and B. C's history remains readable, and its retired identity +cannot be reactivated. Default effective reads follow the new revisions. + +Successive merges follow currently effective relationships. If A and B form C, and C and D form E, restoring B undoes E and then C, +restores A, B, and D, and retires C and E. Undoing only E restores C and D while A and B remain frozen. +Ordinary evidence references do not trigger cascading undo, and external operations that used a result are not rolled back. + +A caller can preview the impact before undo or request undo directly, letting the server calculate and return the actual impact. +Execution based on a preview must reject it if relevant revisions, states, or relationships have changed rather than expanding +the confirmed scope. + +If no state changes are needed and no historical revision is selected, the operation is a no-op and does not append revisions. + +# Reference-level explanation + +## One common set of tables + +Common tables store merge information for Artifacts, identifying objects by Scope, Family, Artifact identity, and exact revision. +They are not tied to any Family's content format. Shared storage must represent: + +- The inputs, result, and exact revisions used by each merge. +- Input freezing, pre-merge states, and each input's current merge destination. +- Whether merge relationships remain effective and how successive merges are connected. +- Undo records with exact references to the revisions actually restored or retired and the frozen or selected historical + revisions used for restoration. Existing revision and provenance records can retain these references without a separate + operation ledger. The actual group result remains queryable by the operation's primary exact revision, subject to read + permission checks on the affected Artifacts. + +The shared layer maintains these authoritative records for merge and undo. Content stays in existing Artifact revisions and is +not duplicated in the common tables. Ordinary lineage continues to record evidence; it cannot replace merge records or establish +that an Artifact has been merged. + +Integrating a new Family requires neither Family-specific merge-state, relationship, or undo tables nor changes to the common +table structure. Families must not maintain another independent authoritative set of merge records. Derived state used for +retrieval must remain consistent with the common records. The number of tables, fields, indexes, and physical layout belong to +subsequent implementation design. + +## Shared operations and integration + +All Artifact creation and revision ultimately pass through the common Artifact write layer, which maintains revisions and +checks shared merge state. Families can retain their business entry points but cannot bypass the common write layer to modify +Artifact content, revisions, or merge state. + +The shared layer also provides merge, relationship queries, undo preview, and undo execution. It owns freezing, restoration, +relationship traversal, and concurrency checks. Each Artifact's business logic decides whether and when to merge, which inputs +to select, and how to generate the result. When a merge is needed, the caller explicitly submits input references and result +content. The shared merge operation reuses the same write foundation and updates the associated states and relationships. +A new Family does not copy the merge algorithm, implement dedicated merge storage, or add name-based branches to the shared entry +point. + +The common write layer does not search for similar Artifacts, decide to merge, or create merge relationships on an ordinary +create or revise operation. Ordinary revision centrally rejects changes to frozen inputs; only explicit merge or undo operations +perform the corresponding relationship and state transitions. Default reads and search also honor merge state: frozen inputs and +retired results cannot be used as current effective Artifacts. Authorized exact historical reads always return the original revision +without redirecting to the merge result. Integration does not require enabling automatic retrieval, content generation, or merging. + +## Consistency + +Merge and undo check permissions, revisions, states, and relationships for every affected Artifact. Reads during content generation +do not replace publication-time checks. Result publication, input freezing, common relationships, and associated current state +become effective together. Undo is also effective as a group; failure must not leave partially frozen or restored inputs. +The revisions appended for restoration and retirement and their current state become effective in the same transaction. +An input can belong to only one currently effective merge result. Concurrent operations cannot merge the same input into two +simultaneously effective results. + +## Integration and acceptance + +Atomic Memory's merge capability uses shared operations and common tables from its initial delivery, implementing the merge and +undo behavior of RFC #1809. Common records are authoritative for merge and undo. Undo does not rewind Source consumption progress. + +Acceptance should cover Atomic Memory and another Family, confirming that both use the same operations and common tables without +adding dedicated merge tables. It should also verify that ordinary writes do not trigger merges, that business entry points +cannot bypass freeze checks, and that successive merges, cascading undo, stale previews, concurrent competition, group failure, +and exact historical reads behave as specified. Restoration and retirement must append the next revision under each existing +identity, preserve exact undo references, and leave unchanged requests without a selected historical revision as no-ops. + +# Drawbacks + +Extracting shared operations from Atomic Memory requires separating the parts tied to that Artifact type and verifying that +multiple callers can reuse the same behavior. Once operations and tables become shared dependencies, subsequent changes require +validation across all integrated callers. + +# Rationale and alternatives + +- **Shared operations and common tables.** Maintain merge and undo together and let subsequent Families reuse storage without + repeating table definitions. +- **A common interface with separate Family tables.** Standardizes calls but still duplicates relationship storage and undo logic, + failing this proposal's reuse objective. +- **Lineage alone.** Records evidence but cannot distinguish references from merges or determine effective relationships and undo scope. + +# Prior art + +RFC #1809 and PR #1857 provide the behavioral basis for merge and undo, which this proposal makes shared. +[RFC #1549](1549_artifact_family_unification.md) provides a direction for Family capability registration that can support +integration with the shared operations. + +# Unresolved questions + +Implementation design will determine the common table structure, reuse of existing common storage, and operation parameters. +These choices must satisfy the requirement that a new Family does not need its own merge tables. + +This proposal excludes cross-Scope or cross-Family merging, physical deletion, and rollback of external effects. + +# Future possibilities + +Common merge records can support shared relationship graphs, operation history, and undo impact views without separate implementations +for each Artifact type. diff --git a/docs/zh/rfcs/1859_artifact_merge.md b/docs/zh/rfcs/1859_artifact_merge.md new file mode 100644 index 0000000000..5030d5418f --- /dev/null +++ b/docs/zh/rfcs/1859_artifact_merge.md @@ -0,0 +1,129 @@ +- Proposal Name: `artifact_merge` +- Start Date: 2026-10-07 +- RFC PR: [oceanbase/powercontext#1859](https://github.com/oceanbase/powercontext/pull/1859) + +# Summary + +将 Atomic Memory 的合并与撤销提取为统一方法,并用一套公共数据库表保存合并状态、输入与结果关系及撤销记录。 +所有 Artifact Family 都可以接入并直接复用这套方法和表,不需要为各类制品分别建立合并、关系或撤销表。 +所有制品的新增和修订统一经过公共写入层(`ArtifactRepository` 及其共享持久化实现), +正文及版本继续使用已有 Artifact 存储;是否发起合并由各制品业务决定。 + +# Motivation + +[RFC #1809](https://github.com/oceanbase/powercontext/pull/1809) 定义了“新建合并结果、冻结输入、保留历史、 +支持撤销”的方式。[PR #1857](https://github.com/oceanbase/powercontext/pull/1857) 的实现分支将相关状态保存在 +Atomic Memory 专用表中,并结合结果首版正文中的合并信息和 lineage 确定输入版本。 + +其他制品需要合并时,也需要记录用了哪些输入、生成了哪个结果、输入何时被冻结,以及撤销时恢复哪些对象。 +这些信息可以用通用制品身份和版本表达,无需每个 Family 单独建表、重复实现关系维护和撤销流程。 + +本提案将这些能力下沉到公共层,Atomic Memory 也通过同一套方法和公共表完成合并与撤销。 + +# Guide-level explanation + +## 合并 + +调用方提供同一 Scope、同一 Family 内至少两个不同制品的精确版本,以及合并后的内容。 +公共方法创建新制品 C,记录 A、B 到 C 的合并关系,并冻结 A、B。 +A、B 退出正常使用,正文和历史仍可按精确版本读取;后续修订继续作用于 C。 + +合并后的内容如何产生由调用方决定。无论来自用户操作还是自动任务,最终都调用同一个公共方法,写入同一套公共表。 + +## 撤销 + +撤销产生 C 的合并时,公共方法从合并记录中找到输入,将 A、B 恢复到合并前状态。 +每个实际恢复的输入都在原制品身份下追加新版本,正文来自冻结版本。 +只有显式 `restore` 可以为其目标选择历史正文;`undo_merge` 不接受历史版本选择。 +C 也在原身份下追加新版本记录退役。新版本号均为该制品当前版本加一,旧版本和原始合并关系保留。 +C 的后续修订不会自动拆分回 A、B,C 的历史仍可读取,退役身份不重新启用。默认有效读取跟随新版本。 + +连续合并沿当前仍生效的关系处理。例如 A、B 合并为 C,C 与 D 合并为 E: +恢复 B 时,依次撤销 E、C,恢复 A、B、D,退役 C、E;只撤销 E 时,恢复 C、D,A、B 仍被冻结。 +普通证据引用不会触发级联撤销,也不会回滚已使用结果的外部操作。 + +调用方可以先预览影响,再执行撤销;也可以直接请求撤销,由服务端计算并返回实际影响。 +按预览执行时,若相关版本、状态或关系发生变化,应拒绝过期预览,不能扩大已确认的范围。 + +若无需改变状态,且没有指定历史版本,操作仍为 no-op,不追加版本。 + +# Reference-level explanation + +## 一套公共表 + +公共表面向 Artifact 保存合并信息,通过 Scope、Family、制品身份和精确版本定位对象,不绑定某一种制品的正文格式。 +公共存储需要表达: + +- 一次合并的输入、结果及其精确版本。 +- 输入的冻结状态、合并前状态,以及当前所属的合并结果。 +- 合并关系是否仍然生效,及连续合并之间的关联。 +- 撤销记录中实际恢复、退役对象的新版本精确引用,以及恢复所用的冻结版本或指定历史版本。 + 这些引用可以由既有版本和来源记录保存,不要求另建操作账本。 + 实际整组结果可按本次操作的主版本精确引用查询,读取时检查受影响制品的权限。 + +这些信息由公共层统一维护,是合并与撤销的权威记录。制品正文仍保存在原有 Artifact 版本中,公共表不复制正文。 +普通 lineage 继续记录证据关系,不能代替合并记录,也不能据此推断某个制品已经被合并。 + +接入新 Family 不新增该 Family 专属的合并状态表、关系表或撤销表,也不要求修改公共表结构。 +各 Family 不再保存另一套独立的权威合并记录;需要用于检索的派生状态应与公共记录保持一致。 +具体表数量、字段、索引和物理布局由后续实现设计确定。 + +## 统一方法与接入方式 + +所有制品的新增和修订最终经过公共 Artifact 写入层,统一维护版本并检查公共合并状态。 +各制品可以保留自己的业务入口,但不能绕过公共写入层修改制品正文、版本或合并状态。 + +公共层同时提供合并、合并关系查询、撤销预览和撤销执行,统一维护冻结、恢复、关系遍历及并发检查。 +是否合并、何时合并、选择哪些输入以及如何生成结果,由各制品业务决定。需要合并时,调用方显式提交输入引用和结果内容, +公共合并方法复用同一写入基础,并完成相关状态和关系更新。 +新增 Family 无需复制合并算法、编写专属合并存储,或在公共入口增加按 Family 名称判断的分支。 + +公共写入层不会因为一次普通新增或修订而自动检索相似制品、决定合并或创建合并关系。 +普通修订统一检查并拒绝修改被冻结的输入;只有显式合并或撤销操作才执行相应的关系和状态变更。 +默认读取和检索同样遵守合并状态,冻结输入和退役结果不能作为当前有效制品使用。 +有权限的精确历史读取始终返回原版本,不自动跳转到合并结果。 +本提案只提供公共合并能力,不要求同时启用自动检索、内容生成或自动合并。 + +## 一致性 + +合并和撤销检查全部受影响制品的权限、版本、状态及合并关系;生成内容期间的读取不能替代提交时检查。 +结果发布、输入冻结、公共关系和相关当前状态一起生效,撤销也整组生效。失败不能留下部分冻结或部分恢复。 +恢复、退役所追加的版本和对应当前状态在同一事务中生效。 +一个输入只能属于一个仍生效的合并结果,并发操作不能将同一输入合并到两个同时有效的结果。 + +## 接入与验收 + +Atomic Memory 的合并能力从首次落地起直接使用公共方法和公共表,实现 RFC #1809 中的合并与撤销行为。 +公共记录是合并与撤销的权威来源,撤销不回退 Source 消费进度。 + +验收应覆盖 Atomic Memory 和另一个 Family,确认两者使用相同公共方法和公共表,接入时无需新增专属合并表。 +同时验证普通写入不会触发合并、各业务入口不能绕过冻结检查,以及连续合并、级联撤销、预览失效、并发竞争、 +整组失败和精确历史读取。恢复、退役应在各自原身份下追加下一版本,保留撤销的精确引用; +无变化且未指定历史版本的请求仍为 no-op。 + +# Drawbacks + +将 Atomic Memory 的实现提取为公共方法,需要拆分其中与具体制品绑定的部分,并验证多个调用方可以复用同一套行为。 +公共方法和表结构成为共同依赖后,后续修改需要验证所有已接入的调用方。 + +# Rationale and alternatives + +- **统一方法和公共表。** 共同维护合并与撤销,后续制品接入时复用相同存储,不再重复建表。 +- **只统一接口,各 Family 分别建表。** 调用形式一致,但关系存储和撤销逻辑仍重复,不满足本提案的复用目标。 +- **只记录 lineage。** 可以表达证据来源,但不能区分普通引用与合并,也不足以确定当前有效关系和撤销范围。 + +# Prior art + +RFC #1809 和 PR #1857 提供合并与撤销的行为基础;本提案将其公共化。 +[RFC #1549](1549_artifact_family_unification.md) 提供 Family 能力注册方向,可用于接入统一方法。 + +# Unresolved questions + +公共表的具体结构、已有公共存储的复用方式及方法参数,在实现设计中确定。 +这些选择应满足“新增 Family 无需另建合并表”的要求。 + +本提案不包含跨 Scope 或跨 Family 合并、物理删除和外部副作用回滚。 + +# Future possibilities + +基于公共合并记录,可以统一展示合并关系图、查询操作历史和预览撤销影响,无需为每种制品分别实现。