Skip to content

Standard Event and Object Schema Registry

This content is not available in your language yet.

0. 规范语言

本文中的规范关键字(MUST / SHOULD / MAY 等)按 normative-language.md 解释;仅大写形式具规范约束力。

1. 目标与真源

本文是 documentation view,不是 schema/event 真源。 下方 §2 schema id 表与 §4 event kind 表是人工维护的阅读节选,并非穷尽清单;两者与机器 registry 不一致时一律 以 JSON registry 为准。“本文定义”的措辞仅指文档级别的展示视图。穷尽且 canonical 的清单是 artifacts/registry/*.json(站点经 MDX 组件 <EventKindTable/> / <SchemaViewer/> 等直接渲染这些 JSON)。 修改流程:contract-registry.json → tools/artifact_pipeline.py generate → 刷新各 *-registry.json。pipeline 不改写本文 md 表;新增 / 改名概念时如需在本节节选表体现,MUST 手工同步对应行,但本节表的滞后不改变「JSON registry 为唯一真源」这一结论。

字段级结构定义见 ../models/common-fields.md 及各对象专属文件(realm-and-space.md / strand-and-message.md / morph.md / relation.md / actor.md / governance-objects.md / private-objects.md / event-and-patch.md)。

机器可读真源(authoritative,本文表格只是其投影):

  • artifacts/registry/contract-registry.json
  • artifacts/registry/schema-registry.json
  • artifacts/registry/track-name-registry.json
  • artifacts/registry/id-kind-registry.json
  • artifacts/registry/event-kind-registry.json
  • artifacts/registry/operation-registry.json
  • artifacts/registry/error-code-registry.json

其中 error-code-registry.json 是标准 service error code 与批处理逐项 reason_code 的 canonical registry;本文后续 event/schema 表只提供文档视图,不重复维护错误码全集。

track-name-registry.json 是 contract-registry.json#track_name_registry.track_names 生成的唯一 TrackName 视图。Strand.tracks、track-scoped constraint、正文与 conformance vector MUST 使用同一 active 集合;owner 的 schema_ref / profile_id 必须可解析,未登记名称 一律 fail closed。

各 registry(schema / event kind / typed ID / operation / profile)的当前 registered 计数及其 CI 门禁(由 tools/artifact_lint 的 check_release_readiness_counts 对照 Canonical registry 自动校验)集中登记在 overview/release-readiness.md §2 的计数表;本文不重复维护计数,引用时以该表与各 Canonical JSON registry 为权威来源。

1.1 schema id ↔ 文件名映射例外(normative)

下游 SDK / IDE 插件不得用 “schema id 去掉前缀 + 换分隔符” 这种机械推导拿文件名;MUST 从 schema-registry.json 读取每条 {schema_id, file, 可选 fragment} 三元组。effective schema reference = file + 可选 fragment 的逐字拼接:fragment 自身已带前导 #,消费者不得再插入分隔符。例如 file="schemas/agent-operations.schema.json" 与 fragment="#/$defs/agent_pairing_bootstrap" 的结果精确为 schemas/agent-operations.schema.json#/$defs/agent_pairing_bootstrap。fragment 是 RFC 6901 JSON Pointer 的 URI-fragment 表示;消费者 MUST 解析其指向的子 schema,MUST NOT 把该 schema_id 绑定到 file 的顶层文档。fragment 省略时 effective reference 即 file 顶层文档。两个 schema_id 映射同一 file 时 MUST 靠 fragment 区分(或其一省略 fragment 表示整包);忽略 fragment、对带 fragment 的行加载顶层文档的实现不合规。fragment 不可解析、或共用同一 file 的多行都省略 fragment(整包映射歧义)时,消费者 MUST fail closed,不得静默择一。该规则的机读声明见 schema-registry.json 的 registry_rules。当前 v1 已知的不能机械推导的对应关系:

schema idcanonical effective reference说明
ak.schema.event.v1schemas/event-envelope.schema.jsonschema id 用 event 保持协议对象名,文件名用 event-envelope 对齐 wire envelope 术语;不得机械推导为 event.schema.json。
ak.schema.capability.v1schemas/capability-grant.schema.jsonid 简化为 capability,文件保留 capability-grant 以区别于其他 capability 相关 schema(grant-constraint、resource-selector 等)。
ak.schema.morph.customer_risk.v1schemas/morph-customer-risk.schema.jsonid 用 dot 分段(morph.customer_risk),文件用 dash(morph-customer-risk);对应规则是 “schema id 里的每段都换成 dash”。其它 dotted-id schema 适用同一规则。
ak.schema.agent_pairing_bootstrap.v1schemas/agent-operations.schema.json#/$defs/agent_pairing_bootstrap与 ak.schema.agent_operations.v1 共用文件,但必须解析 fragment 指向的bootstrap 子 schema(含 runtime_identity),不得加载顶层 DTO oneOf bundle。

新增 schema 时如果出现不能机械推导的命名,必须把对应关系登记到 contract-registry.json 的 schemas[] 条目,并在此表格补充一行;不得只改文件名。

登记范围(normative):schemas[] 只登记 wire schema——被签名、被传输、或被 payload.schema / DTO $ref 按 id 引用的对象。typed current result 的 value 形状不在范围内:它是 reducer 的输出,唯一的登记读取路径是该 family 写入行的 value_schema_ref JSON Pointer,MUST NOT 为它单独发 ak.schema.* id(见 ../sync/current-results.md §1)。文件整体仍可有 id——例如 ak.schema.result_projection.v1 覆盖 typed-current-result.schema.json 顶层文档——但 fragment 指向某一个 value $defs 成员的行不予登记。

1.1.1 error code 命名空间例外(normative)

error-code-registry.json 中的 code / reason_code 值有意使用裸名(例如 json_invalid、policy_violation、failed_precondition),不加 ak. 前缀。错误码只在 service response、batch item 诊断和 reducer reason 上下文中解释,不与 event kind、operation id、schema id 或 capability action 共用命名空间。跨规范聚合错误时,调用方 SHOULD 用 registry 文件或 protocol 名称作为外层 namespace,而不是把 ak. 前缀补进 wire code。

新增标准错误码必须继续登记在 error-code-registry.json,不得因为本例外而在其它 registry 里注册裸名 action / event / operation。

codes vs reason_codes 与双注册模型(normative):error-code-registry.json 有两个并列数组,语义不同:

  • codes:可作为顶层 service error 返回的码,携带 http_status 与 scope(both / service_call / delivery / endpoint)。
  • reason_codes:per-item / per-decision 的子原因(batch item 诊断、reducer reason、auth/policy decision reason),不携带 http_status,由 applies_to 声明适用上下文。

一个 token 同时扮演两种角色时(既能作顶层服务错误返回、又能作某条目的子原因),MUST 在两个数组中各登记一次(双注册),两处描述 SHOULD 一致并互相点明”dual-registered”。双注册是有意设计、不是漂移;新增码若兼具两种角色,MUST 保持两侧同步。算法-agility fail-closed 四项 unsupported_digest_algorithm / unsupported_signature_alg / unsupported_hpke_suite / unsupported_ciphersuite 即按此模型对称双注册(codes 均 http_status=422 / scope=both,且各自在 reason_codes 有对应 per-item 条目),确保 digest / signature / HPKE / MLS ciphersuite 四类未识别 selector 的处置在 registry 中口径一致。

两组公开 code 还共享同一条生产者纪律。每一行 MUST 显式声明 status=active|reserved:

  • active 行 MUST 在 spec/v1/artifacts 的非 report 机器工件中至少有一条逐字生产者路径;只在正文或定义自身的 registry 行出现不算生产者。
  • reserved 行 MUST 携带非空、无重复的 applies_to[] 与 activation_condition,并且任何生产者都 MUST NOT 发射或引用该 code。只有在同一次变更中加入 canonical 机器生产者并把行提升为 active 后,才允许发射。
  • 生产者消失时,行 MUST 在同次变更中转为 reserved(并补齐激活条件)或删除;不得用不收敛的豁免表保留“active 但不可达”的公开合同。
  • tools/reason-code-producer-baseline.json#removed_reason_codes 若以 carried_by_code 指明替代的顶层 code,该承载者 MUST 已登记为 active 且有机器生产者;历史删除理由不得落到一个 reserved 或不可达的承载者上。

tools/artifact_lint/reason_code_producers.py 对 codes[] 与 reason_codes[] 同时执行上述闭包,并对 removed code 执行全仓零残留检查。

1.2 ak.* 命名空间的机读登记边界(normative)

并非所有 ak.* 标识符都要求进入机读 registry。下列命名空间类别豁免机读登记,其权威定义由各自的定义文档承载;豁免类别之外、被正文当作真实 wire 标识符使用的 ak.* id 仍 MUST 有机读归属(registry、schema const 或 profile 矩阵),缺失即为漂移缺陷:

豁免类别例子权威定义位置
算法 / 编码 profile idak.rank.lexofractional.v1定义文档(encoding.md §9);它不是 conformance profile,不进 conformance-profiles.json
client-local scheme id(不进 wire 互操作面)ak.secret_storage.v1、secret storage 的 ak.mls.v1device-lifecycle.md / key-management.md
信封 scheme 常量ak.blob.presign.v1media-and-blob.md §5.4.2(与已进 schema const 的 scheme 并存是允许的;进 schema const 后以 schema 为准)。例外:HPKE 封装 suite id(ak.hpke_*)已进 hpke-suite-registry.json,按 registered 算法 agility suite 处理(与 signature / digest / mls-ciphersuite registry 并列),不属本豁免类别。
hash / transcript 域分隔标签ak.agent_sidecar_circle.v1、ak.invite.claim.binding_proof.v1、ak.invite.claim.subject_proof.v1使用处定义文档(MLS exporter label 除外——它有专属 exporter-label-registry)
feature id(supported_features / supported_features 值)ak.feature.identity.webvh_native_log.v1service-surface.md 与对应能力文档;feature id 是 describe 协商值
DID Document / 外部生态 profile 值ak.organization.governance.v1identity-did.md 示例上下文
Signal plaintext payload kindak.presence、ak.typing、ak.receipt.read、ak.call.signal、ak.message.stream../sync/signal.md §1.1 的封闭登记表;每个 kind 的 closed plaintext schema 仍 MUST 注册(ak.schema.signal_presence.v1 / ak.schema.signal_typing.v1 / ak.schema.read_receipt.v1 / ak.schema.call_signal_plaintext.v1 / ak.schema.signal_message_stream.v1),kind 本身位于 ciphertext、不进 event-kind registry,也不分配 wire_scope
标准 account-data tag 词表ak.favoriteclient-preferences.md §3.1(标准 tag 词表;tag 是加密 account data 内的私有分组标签,不进 wire registry)

1.3 Interop 命名空间例外

以下名称来自外部互通协议的固有术语,不属于 Arkret core 模型命名。forbidden-wire-fields.json 与 registry lint 只允许它们出现在登记的 interop 模块上下文中,授权 / 解析逻辑不得把这些术语提升为 core model 概念:

名称当前语义允许理由防护参考
operation id ak.open.mimi.command.update_room.v1MIMI interop 命名空间内的标准操作;room_update 中的 room 术语与上游 MIMI 规范对齐仅在 MIMI interop module 内部使用,不污染 coreforbidden-model-terms.json 把 Room 列为 interop_module allowed context
Room visibility外部 Matrix/MIMI 互通文档中引用的上游术语;Arkret core 必须拆成 discoverability / join rule / history visibility 三轴仅允许在 interop module 中说明外部语义映射,不得作为 Arkret core 字段或 policy 名forbidden-model-terms.json 把 Room visibility 列为 interop_module allowed context

新增 interop 命名空间例外必须在此表登记并在对应 schema / registry 内联说明允许理由;不得仅靠口头约定。下游漂移扫描器 SHOULD 把此表作为 interop-only allowlist。

2. Standard Object Schema

schema idkind
ak.schema.realm.v1Realm
ak.schema.space.v1Space
ak.schema.actor_profile.v1Actor Profile
ak.schema.circle.v1Circle (intra-Realm scoped event/message boundary; see ../models/circle.md)
ak.schema.agent_sidecar.v1Agent Sidecar (controller-owned private AI workspace; see ../models/sidecar.md)
ak.schema.agent_sidecar_view_state.v1Controller-private encrypted per-context Sidecar display/view state (see ../models/sidecar.md §7)
ak.schema.agent_sidecar_exchange_projection.v1Controller-device-local source-routed exchange Event-fold cache/SDK DTO;非 Account Data / wire truth(见 ../models/sidecar.md §7)
ak.schema.agent_sidecar_event_exchange_binding.v1Sidecar-scoped Message encrypted metadata 内的 closed exchange producer binding(见 ../models/sidecar.md §8)
ak.schema.agent_sidecar_exchange_control.v1ak.agent.sidecar.exchange.control 的加密明文;coordinator 重分配与终态的 durable truth(见 ../models/sidecar.md §8)
ak.schema.strand.v1Strand
ak.schema.message.v1Message
ak.schema.content_block_poll.v1Poll Content Block
ak.schema.morph.v1Morph
ak.schema.relation.v1Relation
ak.schema.view.v1View
ak.schema.policy.v1Policy
ak.schema.invite.v1Invite
ak.schema.read_cursor.v1Read Cursor
ak.schema.notification.v1Notification
ak.schema.capability.v1Capability Grant
ak.schema.event.v1Event Envelope
ak.schema.event_payload.v1Standard Event Payload Classes
ak.schema.cursor.v1Cursor
ak.schema.realm_state_snapshot.v1Snapshot Manifest
ak.schema.realm_state_snapshot.v1Authority-signed 内联 current_state_entries[]、per-stream visible heads 与 history floors;无独立 chunk digest
ak.schema.grant_constraint.v1Grant Constraint
ak.schema.resource_selector.v1Resource Selector
ak.schema.identity_resolution.v1did_core_id/did resolution、PCR evidence 与 AuthenticatedServiceResolution
ak.schema.identity_receipt.v1Identity Receipt
ak.schema.handle_claim.v1Handle Claim
ak.schema.realm_join_candidate.v1Realm join candidate routing hint
ak.schema.media_metadata.v1Media Metadata
ak.schema.read_receipt.v1Read Receipt Signal plaintext(ak.receipt.read;见 ../sync/signal.md §1.1)
ak.schema.blob.v1Blob Metadata
ak.schema.encrypted_envelope.v1MLS Encrypted Payload Envelope
ak.schema.account_data_encrypted_value.v1Principal-private Account Data AEAD envelope
ak.schema.key_backup.v1Encrypted Key Backup
ak.schema.recovery_policy.v1Principal Recovery Policy
ak.schema.recovery_session.v1Device Recovery Session
ak.schema.recovery_receipt.v1Recovery Receipt
ak.schema.account_subscribe_frame.v1Account Subscribe Frame
ak.schema.device_message.v1To-device Message Envelope
ak.schema.applet_registration_epoch_transcript.v1Closed Applet registration epoch security transcript
ak.schema.mimi_interop.v1MIMI Provider Directory / MIMI Room Binding (interop; see ../extensions/mimi-interop.md) / Mapping Receipt
ak.schema.moderation_report.v1Moderation Report
ak.schema.moderation_queue_item.v1Moderation Queue Item

3. Event Type 设计约束

3.1 命名规则

  • 标准事件必须使用命名空间:ak.<domain>[.<subdomain>].<verb>。
  • 所有标准事件必须是 ak. 前缀。
  • 裸名事件(例如 realm.create)不是标准事件。
  • 自由字符串事件(如 custom.*)不能直接登记标准事件,需要通过自定义 schema + capability / state filter 映射。

3.2 wire scope 语义

完整 event kind 集合以 artifacts/registry/event-kind-registry.json 为准。wire_scope 语义如下:

  • durable_event:进入共享 Event Envelope 历史,参与 reducer。
  • actor_private_event:进入加密 account data 或 actor-private stream。

SignalEnvelope 与 DeviceMessageEnvelope 不属于 Event kind registry,因此不分配 wire_scope。 Signal plaintext payload kind(ak.presence / ak.typing / ak.receipt.read / ak.call.signal / ak.message.stream)因此不出现在 §4 的 event kind 文档视图中;其封闭登记表见 ../sync/signal.md §1.1,豁免依据见 §1.2。

实现不得仅靠本文件定义;必须加载机器 registry 或等价生成产物。

4. Event kind 注册表(文档视图)

4.1 Realm 与 Strand

event typepayload
ak.realm.createRealm create
ak.realm.profileRealm profile facet
ak.realm.aliasRealm alias declaration or durable value tombstone(alias 的唯一 wire 承载)
ak.realm.organizationOrganization-authorized Realm relationship statement or revocation
ak.realm.linkTyped Realm link graph edge
ak.realm.join_ruleJoin rule state
ak.realm.history_accessHistory visibility state
ak.realm.discoveryDiscoverability state
ak.realm.preview_policyPreview / peek policy state
ak.realm.read_receipt_policyRealm read receipt disclosure policy state
ak.realm.tombstoneTerminal Realm tombstone or replacement marker
ak.realm.archiveReversible archive state
ak.realm.freezeTemporary freeze state
ak.realm.destroyTerminal decommission marker
ak.member.stateMembership state
ak.strand.createStrand create
ak.strand.updateStrand patch
ak.strand.archiveStrand archive
ak.strand.restoreStrand restore
ak.strand.moveStrand move between Lists
ak.strand.reorderStrand reorder within List
ak.strand.tracks.updateStrand tracks map patch(ak.schema.patch.v1 payload;详见 ../models/strand-and-message.md §4.8)
ak.strand.watch.setSet / clear per-(strand, actor) watch subscription;authority按 commit顺序更新 typed current并派生 watches Relation
ak.space.createSpace create (board / list / swimlane / calendar bucket / …)
ak.space.updateSpace metadata patch
ak.space.parentSpace parent declaration;authority按 commit顺序执行 cycle/depth gate
ak.space.archiveSpace archive (reversible UI hide)
ak.space.restoreSpace restore (archived -> active; only valid when current state == archived)
ak.space.tombstoneSpace tombstone (irreversible; contained Strands MUST be relocated first)

4.2 消息与关系

event typepayload
ak.morph.createMorph create
ak.morph.updateMorph patch
ak.morph.archiveMorph archive
ak.morph.restoreMorph restore
ak.message.createMessage create
ak.message.reviseMessage edit patch
ak.message.redactMessage-scoped redaction
ak.relation.createRelation create
ak.relation.updateRelation patch
ak.relation.tombstoneRelation tombstone
ak.reaction.addReaction add
ak.reaction.removeReaction remove
ak.read_cursor.advanceRead cursor advance event

4.3 授权与治理

event typepayload
ak.capability.grantGrant
ak.capability.revokeRevocation
ak.profile.createActor profile create
ak.profile.updateActor profile patch
ak.profile.realm_overrideRealm-scoped profile override
ak.audit.accessedAuditable access
ak.self.moderation.reportModeration report
ak.session.grantSession grant
ak.device.authorizeDevice authorization
ak.device.revokeDevice revocation

4.4 加密、协作与扩展

5. Extension 约定

自定义 schema id SHOULD 使用反向域名前缀:

com.example.schema.foo.v1

自定义 event type MUST NOT 使用 ak. 前缀,除非被正式纳入标准注册表。

6. 演进约束

Schema evolution MUST:

  • 保留 schema 显式声明扩展位中的未识别字段(规则见下),不得静默剔除
  • 不修改既有字段语义
  • 可选字段应先于必填字段添加
  • reducer 行为变化需提供变更说明
  • 若变更授权、可见性、排序或收敛语义,需声明新 schema 或 fixed reducer semantics

v1 canonical object(Event Envelope / RealmCommit / Operation / Snapshot / Grant / encrypted envelope)的 schema 是封闭的(additionalProperties: false):schema 未声明的未知字段 MUST 被 schema validation 以 schema_violation 拒绝,不存在“接受并保留任意未知字段”的隐式路径。Event kind-bound payload 不允许 {} 空 schema:有限 family 必须由 payload schema直接以 $ref / oneOf 闭合。扩展只能使用该具体 payload显式声明的 x_*/extension member或新的 versioned kind/schema;Event顶层不再提供通用 requirements 或 unsigned 逃生口。ak.schema.define.value 的 wrapper仍 closed且 value必填,schema identity唯一取自 value.$id。receiver MUST执行 payload-validator-profile-registry.json 的定义校验 profile。对 schema允许但实现未识别的显式扩展内容,接收方必须在 canonical bytes、存储、转发和签名校验中原样保留。

未知 critical feature MUST fail closed。能力协商只来自 ServiceDescribe、Realm current policy、kind/schema registry 及具体 typed payload 声明。

OpenAPI DTO MAY 使用 additionalProperties: false。若 DTO 内嵌 canonical protocol object,内嵌对象 MUST 按 registry schema 解析,并按本节规则处理:未声明字段拒绝,显式扩展位内容保留。

6.1 注册表条目演进兼容级别(normative)

上文覆盖字段级演进;本节回答值集级演进:event kind、error code、闭集枚举等新增合法值时的兼容级别,以及已发布实现的处置义务。判定的第一步是区分值集的权威承载形态(与 §1.2 的机读归属规则同源);同一 token 不得同时以两种承载形态声明。

a. 开放注册集(open registry set)——以独立 registry JSON 承载的字符串值集合:event kind(event-kind-registry.json)、error code / reason_code(error-code-registry.json)、relation kind、capability action、typed id kind 与 feature id 等。

  • 新增条目推进 registry 的 version / generated_at;是否需要新 schema ID 由该字段所在 closed schema 决定。
  • registry / profile 的规范内容发生任何变化时,顶层 version MUST 推进;日期形 YYYY-MM-DD 按 (日期, 0) 比较,点号形 YYYY-MM-DD.N 按 (日期, 十进制计数器) 字典序严格比较,日期倒退或同日计数器不增都不算推进。若 artifact 携带 generated_at,该时间戳也 MUST 推进,且 version 的日期部分 MUST 等于 generated_at 按其自身 RFC 3339 offset 解释的 civil date。tools/check_artifact_versions.py 的内容摘要排除这两个元数据字段,并把其余内容绑定到受版本控制的 reference manifest;内容变化但元数据未推进、或 metadata/content reference 漂移,均 MUST 使 release gate 失败。两个字段都 MUST NOT 记为尚未发生的时刻:date-shaped version MUST NOT 晚于 UTC+14 当日,generated_at MUST NOT 晚于写入 reference manifest 的时刻。推进义务只认更大的值,因此一个写在时钟之前的戳会成为后续每次发布都必须超过的基线,并让整套 registry 随每次提交继续向未来漂移;把它改回真实时刻不是一次普通推进,MUST 由 --repair-future-date 逐个 artifact 显式指名,且仅当记录值在未来、替换值不在未来时才被接纳。
  • 同一义务适用于承载协议棘轮、豁免、身份清单或其它发布判定的 tools/ JSON ledger。其封闭集合以 tools/artifact-version-governance.json#governed_tool_artifacts 为唯一机器清单,关联维护脚本以同文件的 governing_scripts 登记;新增带顶层 version 的 tools ledger 若未同批进入清单,或清单/脚本路径悬空,release gate MUST 失败。tools/normative-title-inventory.json 与 tools/refresh_normative_title_inventory.py 属于该集合。
  • 每份 fixture MUST 携带顶层字符串或整数 version。fixture-digests.json 同时记录内容摘要与该版本;已有 fixture 内容摘要变化时,版本 MUST 严格推进,内容不变时不得单独改版本。该义务由 tools/check_fixture_digests.py --write-reference 在写新 reference 前校验,不把 fixture 重复纳入 artifact-version reference。
  • contract-registry.json#derived_registry_views 指向的每个 canonical section 是对应派生 registry 的发布元数据权威,并 MUST 声明 metadata_authority=contract_registry_section:section 自带的 version / generated_at 覆盖 contract 顶层默认值,generate MUST 原样投影,磁盘上旧的派生视图元数据不得因语义内容相同而被保留;任何分歧都属于 projection drift。
  • sdk-conformance-claim-fixture.json 的 schema 正例与负例都 MUST 绑定当前 sdk_conformance_contract digest,并携带对各自 claim body 可验证的签名。恰好一条以 contract_binding_expect_valid=false 标记的专用语义负例 MAY 携带错误 digest,但它的签名仍 MUST 对该错误 digest 有效,以保证失败只来自 contract binding,而不是陈旧签名或别的 schema 错误。
  • 已发布实现遇到不在其本地 registry 快照中的值时,MUST 按未知值保留处理:不得因此让整个对象 / 信封反序列化失败。反序列化层保留之后的语义处置按各消费面既有规则执行——未知值保留不等于语义接受:写入权威接收方对未声明支持的标准 event kind 仍按 conformance-profiles.md §2.1 返回 unsupported_feature / unsupported_event_kind / schema_violation 或 quarantine;未注册 relation kind 按 relation-kind-registry registry_rules 保留为 opaque edge 且不得推断语义;fail-closed 门(未知 critical feature、授权判定)照常适用。
  • 生成代码 SHOULD 为开放注册集值提供 non-exhaustive / Unknown(String) 兜底变体,MUST NOT 用封闭 enum 让未知值导致整体反序列化失败。

b. schema 内闭集枚举(closed enum)——由 JSON Schema enum 关键词在 canonical schema 中承载的封闭值集:如 Actor Profile 的 actor_kind(user / organization / team / agent / bot / service / integration)、cursor 的 purpose(stream / barrier)。

  • 已发布 stable schema 向闭集枚举新增值 MUST 伴随对应 schema 版本 bump,并经 §6 的变更说明流程反映到 conformance-profiles.json#profile_requirements 的 required_schemas。尚未发布的 current-v1 candidate 在冻结前发现分类错误时 MUST 直接修正 current-v1 canonical schema、fixtures、SDK 与全部 consumer,不得为未发布错误保留 compatibility alias 或另造 v2。
  • 已发布旧实现对新值按 schema_violation 硬拒是合规行为,不是互操作缺陷;发起方在对端未声明新 schema 版本前 MUST NOT 发送新值(能力交集原则)。
  • 生成代码 MAY 用封闭 enum 类型(无 Unknown 兜底)表达闭集值;闭集枚举值导致的反序列化失败不违反 a 条的”未知值保留”义务——该义务只适用于开放注册集。

b.1 registry-backed schema selector(算法 agility 的唯一分类)——signature、digest、HPKE 与 MLS ciphersuite registry 是算法 token 与参数元组的唯一机器词表,但具体 canonical object schema 中的 selector 仍是按 schema 版本冻结的闭集,不属于 a 类开放注册集。“enum 由 active rows 生成”只允许发生在创建或 bump 该 canonical schema 版本时;registry release 不得原地扩写已发布 schema 的 enum。

  • reserved 算法行翻为 active 前,MUST 先发布包含该值的新 schema 版本、更新 profile required_schemas / capability negotiation,并满足 registry 的全部 activation requirements;旧 schema 的 enum 与签名字节保持不变。
  • producer 只有在对端声明新 schema 版本与相应算法 profile 后才可发送新 selector。旧 schema receiver 拒绝该新值是合规的版本协商结果。
  • 已选定 schema 版本后,selector 不在该版本 enum 内时,receiver MUST fail closed。对已知算法 selector 字段,错误映射优先使用对应稳定码 unsupported_digest_algorithm / unsupported_signature_alg / unsupported_hpke_suite / unsupported_ciphersuite;对象其它闭集 enum 违例仍使用 schema_violation。预解析器 MAY 保留原始字符串用于形成该错误,但不得把 Unknown 变体交给 reducer 或密码学库执行。
  • SDK/codegen 对这些 selector MUST 生成 per-schema-version 的封闭类型;可在 transport diagnostic 层提供 Unknown(String) 以承载稳定错误,但该值不得构造为已通过 schema 验证的 canonical object。registry consumer 不得把”registry 中 active”误解为”所有旧 schema 自动接受”。

c. status 字段纪律——schema-registry.json 的 schema 条目只允许 active;未知或非 active 状态一律 fail closed,不存在为了旧数据解析而保留的 schema 行。省略 status 的 source row按 active 解释;新增或修改 schema 行 MUST 显式写出 status。其它 registry 若定义 profile_extension 等状态,只在其自身 closed contract 内有效,不得套用到 schema registry。

  • 新增条目 MUST 以 active(或 profile_extension)登记进 canonical 真源(generated registry 一律经 contract-registry.json → pipeline 再生成,见 §1)。
  • schema registry 只包含 current-v1 的 active canonical 条目;解析必须精确命中登记的 schema id 与 shape。 历史快照不属于当前 schema registry 的输入,消费者 MUST 只接受当前 registry 声明的 shape。

6.2 禁字段的机读上下文(normative)

forbidden-wire-fields.json 的 context_definitions、context_matching 与每条 entry 的 match 是唯一匹配合同。context 选择先于禁字段匹配:以调用面的已知文档类别、owning schema 引用和实例 JSON Pointer 域选中规则,再按登记的 match_scope 执行;不得在实现中维护另一份 context 名称到 Event kind 的手写映射。Event payload 的 owning schema 只从 event-kind registry 的 payload_schema_ref 取得。嵌套 typed instance 由 owning schema 确认,不能因为一个对象碰巧 含 kind、schema 或 track_name 就猜其类型。

root 字段路径只相对于该实例根;descendants 才允许在子对象重复匹配。match 明确区分字段、 路径、patch 路径和标量值;entry id 是审计标识,不是供 consumer 猜测的 DSL。未定义 context、 不可解析 schema 引用、未知 matcher 均使 artifact 门禁失败。引用类 allowed_contexts 不能豁免 任何真实提交的 wire 数据。

patch scope 显式将 owning create context 的字段/路径规则应用于该更新实例的 canonical patch 映射,包括 direct value、显式 set/add 与祖先替换中的剩余路径;不是按字段名猜测 create 类型。

track_name/message 只禁止物化 Message 对象复制 track;ak.message.create payload 的 track_name 仍是必填签名事实。Message 中不相关嵌套用户字段不得被根字段规则误拒。对象整体 替换和 patch set 的嵌套值仍按其 owning create context 检查,不能通过替换祖先逃过禁字段。

6.3 Normative 标题身份与删除审计(normative)

tools/normative-title-inventory.json 是 spec/v1/zh/**/*.md 中所有标题正文含 (normative) 标记的小节身份全集。每行由相对 page、完整 heading 与按当前 Markdown 规则派生的 fragment 三元组唯一标识;集合与顺序均封闭。新增、移动、改名或删除这类标题都属于协议变化, MUST 同批推进该 inventory,并由门禁对当前正文重新求全集,不得用行数阈值、同文件最近标题或裸编号 锚点猜测等价小节。

删除、移动或合并已登记标题时,变更记录 MUST 说明原义务的唯一处置:moved、merged、 restored 或 intentionally_removed。前三者必须指向当前真实标题 fragment;后一种必须说明为何该义务 不再属于 current v1,且必须同批清除仍断言它的 canonical registry、schema、fixture 与 operation。 仅仅找不到机器引用,不构成删除依据;反过来,机器工件仍引用该义务时也不得把锚点改指语义不同的邻节 来换取门禁通过。