diff --git a/20-product-tdd/cross-unit-contracts.md b/20-product-tdd/cross-unit-contracts.md index d3ae7a8..9b77f48 100644 --- a/20-product-tdd/cross-unit-contracts.md +++ b/20-product-tdd/cross-unit-contracts.md @@ -23,15 +23,11 @@ Record durable data and behavior contracts that span more than one unit reposito ## Extension State Contract -- `installed`, `enabled`, and `running` are different states and must not be collapsed into one concept. -- `installed` means the deployment has the extension package and its persisted installation record. -- `enabled` means a specific client is allowed to run that extension. -- `running` means the current runtime has actually started that extension and applied its runtime side effects. -- Starting or stopping an extension is not a pure flag flip; it changes runtime capabilities and API surface for that client. +[Extension 分发发布与 Peer 参与契约](extension-release-and-installation.md)拥有独立原生发布坐标、部署共享业务状态、Peer 精确安装选择,以及启用意图和实际运行的区别。插件拥有业务与数据兼容,各 Unit 分别拥有构建发布流程和宿主执行边界。 ## Extension Documentation Hosting Contract -- Author-built static documentation, exact Release/scope identity, conditional whole-site +- Author-built static documentation, exact native Release identity and historical scope compatibility, conditional whole-site corrections, snapshot-origin isolation, and consumer discovery follow the [Extension Documentation Hosting Contract](extension-documentation-hosting.md). - Registry owns hosting and executable API details; authors own site content and structure. diff --git a/20-product-tdd/extension-documentation-hosting.md b/20-product-tdd/extension-documentation-hosting.md index e8a3fc0..2759d63 100644 --- a/20-product-tdd/extension-documentation-hosting.md +++ b/20-product-tdd/extension-documentation-hosting.md @@ -14,18 +14,9 @@ installable by itself. ## Identity And Document Ownership -A documentation set belongs to one Extension name, one exact Release version, and one scope: +新文档集属于一个精确 Native Release,即 Extension name、Distribution 类型和该分发版本。其发布者维护这个入口中的概念、操作、配置和限制;不以另一种分发的版本或 scope 声明文档适用关系。Web、CLI 和 Agent 是读者接口,不是额外的 Distribution。文档可选,不增加共同插件版本或独立文档语义版本。 -| Scope | Meaning | First-party source owner | -| --- | --- | --- | -| `global` | Extension-wide concepts, workflows, and limits across channels | `core-py` | -| `python` | Python Distribution operation and configuration | The Python producer in `core-py` | -| `module-federation` | Web Distribution interfaces and behavior | The MF producer in `client-web` | - -These are separate, optional sites, not inheritance or override layers. Registry does not merge -them. A channel-specific set requires the corresponding Distribution association on that Release; -global documentation does not require a Web Distribution. Web, CLI, and Agent instructions are -reader interfaces, not additional Distribution channels. +历史统一 Release 的 `global`、`python`、`module-federation` 入口继续作为历史文档坐标读取。既有 Snapshot、发布 receipt、URL、ETag 和来源不因迁移被重新命名或赋予另一个 owner。尤其 `global` 不自动归给 Python 或 MF;有明确来源的历史分发文档可以引用复用,不能伪造一次新的 publication。新入口和历史入口各自保留身份,Registry 不合并、继承或静默替换它们。 First-party sites share a template maintained in `InKCre/docs`, with producer repositories using an explicit template revision. This does not require ecosystem authors to adopt that template or @@ -35,16 +26,9 @@ being copied into each consuming site. ## Discovery And Consumption -Registry exposes documentation discovery separately from Release installation metadata. Consumers -ask their configured Registry for the exact installed Release and receive the available scopes, -stable entry addresses, current content identities, update times, and publication provenance. -Adding documentation must not invalidate existing strict Release consumers. +Registry 的文档发现与安装元数据分开。新版消费者按精确原生分发选择查询自己的入口、内容身份、更新时间和发布来源;旧消费者查询历史统一版本及 scopes。新增文档不能破坏严格安装模型。 -An absent scope is genuinely absent. Consumers may explicitly offer global documentation instead -of a missing channel site, but must not silently substitute another scope or version. Page paths -inside a site remain an agreement between its author and consumers, not Registry-defined content -semantics. Consumers follow Registry-provided entry addresses rather than constructing content -hostnames or assuming documentation shares the management origin. +缺失的入口就是缺失。消费者可以明确提供历史文档链接,但不能静默替换分发、版本或 scope。站点内路径是作者与消费者的约定,Registry 不解释文档结构。消费者采用 Registry 返回的入口地址,不构造内容 hostname,也不假定文档与管理服务共享 origin。 ## Publication And Corrections @@ -69,20 +53,14 @@ available for a later retry. Clients do not refresh the write precondition, gene identity, or infer failure merely because a response was lost. Authentication and Release lifecycle rules also apply when confirming an earlier commit. -Documentation can be corrected without a new Extension Release. There is no separate documentation -semantic version, automatic inheritance between Releases, or many-to-many applicability mapping. -Updating one scope does not update another or mutate Python/MF artifacts. Snapshot content is -immutable; its identity serves integrity and resource consistency, not a second author-managed -version scheme. +文档可以在不发布新 Native Release 的情况下修订。更新一个分发的入口不会更新另一个分发,也不改变 wheel 或 MF 产物。没有跨版本自动继承或多对多适用矩阵。Snapshot 内容不可变,其身份用于完整性和资源一致性,不是另一套作者管理的版本。 -Previously published snapshots remain available while their owning Release permits public reads, -so an already opened page can finish loading its original resources. Each public snapshot remains -bound to its exact Release and scope even when underlying byte storage is deduplicated. +已发布历史快照在所属发布允许公开读取时继续可用,使已打开的页面能加载原有资源。即使底层字节去重,快照仍绑定其原始精确坐标;迁移不修改其发布凭证或暗示它仍是当前入口。 ## Static Content Boundary Each snapshot is served at the root of its own content origin, separate from Registry management -and from other snapshots. A stable Release/scope entry selects the current snapshot; navigation and +and from other snapshots. A stable Native Release entry, or retained historical Release/scope entry, selects the current snapshot; navigation and assets within that site continue to use that snapshot. This prevents mixed-version assets and separates script, browser storage, and Service Worker authority. Separate URL directories on one origin do not satisfy this boundary. @@ -103,6 +81,8 @@ Registry-owned. ## Release Lifecycle +新版文档遵循所属 Native Release 的生命周期。历史入口同时遵循原统一 Release 及其关联原生发布的限制,不能借旧 state 绕过 native block。类型明确的原生下载与文档入口分别检查对应 owner,历史 global 不能被任意重新归属以规避封禁。 + Documentation may be prepared alongside a preparing Release, but preparing content is not public. Published Releases expose their documentation normally. Yanked Releases retain exact-version documentation, and Registry entry surfaces identify that withdrawal; documentation corrections do diff --git a/20-product-tdd/extension-release-and-installation.md b/20-product-tdd/extension-release-and-installation.md new file mode 100644 index 0000000..6f535bc --- /dev/null +++ b/20-product-tdd/extension-release-and-installation.md @@ -0,0 +1,62 @@ +# Extension 分发发布与 Peer 参与契约 + +Extension 发布者、Registry、开发工具和宿主共同消费本契约。Registry 拥有原生产物及发布生命周期的可执行协议;宿主拥有原生加载和运行生命周期;插件拥有业务、持久数据与协作兼容。本契约通过新版 Registry、宿主及数据库协议共同交付,不能将某一 Unit 的单独升级视为部署已经完成切换。 + +## 插件身份与原生发布 + +一个 Extension Name 标识一个逻辑插件。Python、Module Federation 等 Distribution 为各自所在的 Peer 增加能力,以不同或重叠的分工参与同一插件业务。语言、仓库、迁移职责或某次调用方向不决定哪一种实现是业务中心。 + +一个 Native Release 由 Extension Name、Distribution 类型和该分发的精确版本共同标识。不同分发独立选择版本、构建和发布;版本相同不证明业务兼容,版本不同也不证明不兼容。平台不求解跨分发版本范围或为它们维护另一个共同产品版本。 + +各 producer 只构建本仓维护的原生产物,原生依赖仍通过各自包工具消费。发布候选固定本分发的源码、元数据和产物身份;重试使用保存的原候选,不以当前分支的新构建覆盖同一个坐标。宿主 SDK 条件、Python Project/Version 和 MF manifest 等格式约束由相应 Unit 校验,不成为跨分发业务兼容声明。 + +prepare、upload、publish 一次针对一个 Native Release。只有它自己的全部原生对象齐备时才可公开,检查与提交之间改变产物身份或关联必须重新验证。发布 Python 不等待 MF,发布 MF 不等待 Python。已发布的坐标及产物身份不可覆盖;相同请求可幂等重试,冲突需要新版本。文档不使缺少可执行产物的分发成为可安装版本。 + +## 部署共享状态与 Peer 参与 + +部署中一个插件只有一个逻辑身份及其共享配置、业务状态。安装选择属于 `Peer × Extension`:该 Peer 选择一种宿主支持的 Distribution 及精确版本,并保存自己的启用意图。数据库保存这些持久事实;运行端报告实际加载的分发、版本和运行结果。 + +| 事实 | 含义 | +| --- | --- | +| 部署 Extension 身份 | 共享显示信息、配置与业务状态,不具有统辖所有 Peer 的包版本 | +| Peer 安装选择 | 该 Peer 下次应用的精确原生分发版本,不意味着产物已经加载 | +| Peer 启用意图 | 期望该 Peer 参与,不证明进程已启动或仍在线 | +| Peer 运行事实 | 当前宿主实际完成启动的实现及版本、失败或重启需求,不能由意图推断 | + +管理界面保持一个插件入口,展示它在哪些 Peer 使用。默认安装和升级作用于当前或明确选定的 Peer;批量操作需要明确目标,并分别报告结果。自动恢复使用已选择的精确版本,不追随 latest。一个 Peer 的版本更换不修改其他 Peer 的选择,包括睡眠的 Peer。 + +目标宿主通过新版管理协议报告自己实际支持的原生格式。离线缓存只表示最近观察;没有可靠事实时不得根据 Peer 名称、浏览器类型或应用版本猜测。纯 Python 插件可以由 Web 界面管理其他 Peer 的安装,但不能在不支持 Python 的 Web Peer 上提供可成功启用的承诺。 + +停用或移除某个 Peer 的参与不会删除共享配置、账号、业务状态、Source 游标或 info-base 内容。部署级删除是单独明确的操作;运行节点的停止不改变持久业务和信息的所有权。 + +## 业务协作与配置 + +各分发可直接操作已准入的共享数据库协议、解释持久图、提交工作或领取自身能够执行的 Job。确实需要另一个 Peer 执行时,才使用已有的 capability delegation。平台不把所有扩展点改为远程调用,也不为同进程每个插件建立另一份 Peer 身份和租约。 + +插件拥有共享配置、业务 state、Source 配置及游标、Job 参数、持久图类型和调用协议的兼容。原生发布版本只是安装坐标,不能替代这些业务契约。独立 Peer 选择允许不同版本同时参与;插件应保持必要的读写兼容,或提供明确的业务升级流程,不通过清空正常数据完成包版本变更。 + +配置 schema 标明产生它的精确分发来源,为选定运行端提供编辑和输入验证信息;配置数据仍属于部署。最后启动的实例不覆盖唯一的全局 schema 权威,平台不合并多份 schema 或推断所有版本都理解新配置。插件在自己接受和执行业务输入时维护对应契约。 + +共享业务 state 的写入对已准入原生和 PostgREST Peer 保持同一协议能力,不以当前实现位于 Core 为由建立独占写角色。合法数据形状和身份不可修改仍由协议约束,匿名调用不获此权限;插件自己的原子更新和并发保护不能被整对象覆盖替代。业务 state 可以含凭据,通用安装管理响应不因写权对等而展示其内容。 + +## 应用版本与失败边界 + +宿主在改变运行状态前校验目标坐标、发布状态、元数据、原生产物和 SDK 条件。启用成功须包含完成启动和相应副作用;持久化失败需要按宿主生命周期清理或报告真实未收敛状态。保存目标版本不等于升级完成。 + +显式启用和停用命令先保存参与意图,再应用运行变化;运行失败保留意图并报告实际错误,不以运行成功回调重新写入意图。自动恢复只消费已有意图,不能将用户已撤回的启用写回。宿主串行处理同一参与记录的生命周期,并在异步初始化或激活后复核精确选择与启用意图;若意图已撤回或版本已变,清理迟到实例,不将它报告为当前运行结果。该串行边界只协调当前宿主,不能排除其他已准入客户端的数据库写入,也不保证持久意图与进程状态瞬时原子切换。 + +离线 Peer 只能接收待应用选择,不能被宣称已停止旧实例或已运行新版。租约过期不证明进程停止。Python 等宿主若安装会修改共享原生依赖环境,应暂停该 Peer 的执行,安装后从新进程启动;只停目标插件不足以证明其他已加载依赖安全。应用失败应报告失败或待处理,不能假定自动恢复旧环境或撤销插件已经执行的业务迁移。具体进程、打包和恢复操作留在宿主本地文档。 + +## 历史坐标与协议迁移 + +Registry v2 提供独立原生分发读写。v1 只读取历史统一坐标,不将两个独立新版本拼成一个旧 Release;旧发布写入明确要求升级。历史原生产物、URL、摘要和来源可继续复用,但公开读取必须遵守对应原生发布的当前封禁与撤回状态。历史入口不能绕过新发布生命周期限制。 + +迁移保留旧部署身份、配置和业务状态,以及可恢复的旧安装快照。旧启用成员转为各 Peer 的参与记录,保留原精确版本及意图。缺少原生格式证据时保留待解析的旧引用,旧全局配置 schema 仅留在快照,不能被赋予未知分发的来源;新版实际宿主识别并条件更新后,才填写有来源的 schema。不得猜测格式或自动改为最新版本。原版本不存在对应分发时明确待修复,不静默选另一个版本。没有记录的停用参与历史不能补造。 + +新版 Extension 管理与数据库协议共同改变旧全局版本语义。切换需要新版消费者和明确的旧写入退出,不能维护两份可写版本权威。暂停活跃旧运行端、迁移数据库并启动新版宿主后,睡眠旧 Peer 返回也必须先升级;协议 revision 改变本身不停止进程。具体 schema、guard、切换和恢复步骤由数据库与宿主 owner 验证并记录。 + +## 验收边界 + +发布验收观察每种分发独立发布、缺少自身产物时保持不可公开、候选重试和提交身份一致,以及历史公开读取遵守封禁。部署验收包含精确旧版本迁移、未知分发延迟解析和非空业务 state 保留。 + +完整运行验收从实际 Client Web 安装入口进入目标 Peer 的启用、运行、停用和刷新恢复。一个 Peer 升级不能改变另一个同种分发 Peer 的选择;睡眠恢复、离线待应用和 Python 环境更新后的新进程也属于验收。插件案例需覆盖已有内容读取与按需执行、设置 UI 的先行运行以及共享业务数据延续。仅构建、独立 import 或调用 MF 容器不能代替实际入口验收。 diff --git a/20-product-tdd/system-state-and-authority.md b/20-product-tdd/system-state-and-authority.md index 6a967e7..7a8fae2 100644 --- a/20-product-tdd/system-state-and-authority.md +++ b/20-product-tdd/system-state-and-authority.md @@ -25,9 +25,12 @@ Record durable ownership of authoritative state across units and distinguish it ## Extension Installation Authority -- Extension installation state is authoritative at the deployment level. -- One deployment must not carry multiple installed records for the same extension ID. -- Installation state is distinct from client-scoped permission and distinct from current runtime activity. +- 一个部署对一个 Extension 保持一个逻辑身份、共享配置和业务状态。不同运行端通过各自的能力共同参与该业务,持久数据不归某个执行节点所有。 +- 共享业务 state 的更新属于已准入 Peer 协议,原生与 PostgREST Peer 依据插件契约维护同一数据;当前 Python 实现了写入流程不构成 Core 独占写权。身份、数据形状与匿名拒绝仍由协议边界约束,插件继续拥有事务和业务并发不变量。 +- 精确原生分发版本和启用意图属于 `Peer × Extension` 的持久参与记录。同一插件可以在不同 Peer 使用不同版本;一个 Peer 的选择不改变其他 Peer,也不建立部署全局包版本。 +- 实际加载版本、运行成功、失败与重启需求是对应宿主报告的运行事实,不能从安装选择、启用意图或过期 lease 推断。 +- 配置编辑 schema 保留其精确分发来源;它是选定运行端的编辑说明,不改变共享配置权威,也不证明其他分发理解同一写入。 +- 安装选择与 client-scoped permission、当前运行活动分别记录。具体发布、参与和历史迁移遵循 [Extension 分发发布与 Peer 参与契约](extension-release-and-installation.md)。 - Validated extension configuration is deployment-scoped durable state. External protocol profiles or credentials projected from that configuration do not create an InKCre User or tenant authority. diff --git a/20-product-tdd/unit-topology.md b/20-product-tdd/unit-topology.md index 6ece843..dd96d47 100644 --- a/20-product-tdd/unit-topology.md +++ b/20-product-tdd/unit-topology.md @@ -28,6 +28,8 @@ Define cross-unit technical boundaries and ownership so changes do not leak resp ## Knowledge Capability Topology +Extension 的不同 Distribution 为所在 Peer 增加可不同、互补或重叠的能力,共同参与同一逻辑插件的共享业务与信息。它们可以直接操作已准入的协议、解释持久图、提交或领取工作,也可在需要远端执行时使用 delegation;不能以语言、仓库或当前能力分工预设中心实现与附属实现。发布、精确安装选择和共享状态的边界遵循 [Extension 分发发布与 Peer 参与契约](extension-release-and-installation.md)。 + - The [Knowledge Capability Contract](knowledge-capability-contract.md) owns the shared collection, organization, application, graph, resolver, storage, and extension-protocol boundaries.