服务器当前结果与有界基线
本文规范用语遵循 规范性语言。
1. 权威来源
治理 Station 按目标 stream 的 RealmCommit 顺序接纳 Event,并在同一事务内更新该领域的当前结果。客户端 MUST 把 Station 返回的 typed current result 作为共享状态的当前权威视图;Event timeline 用于审计与内容读取,不要求客户端 重放 Event 来恢复共享状态。
Realm、每个 Circle、每个 Sidecar 分别拥有独立 commit stream。当前结果响应携带本次视图所覆盖 stream 的
stream_heads[];不同 stream 之间不存在隐含总顺序。producer Event 不携 predecessor,只有 RealmCommit 的
previous_commit_ref 串联同一 stream。
机器合同为 current-result-registry、 typed-current-result schema 与 account-current-result schema。实现 MUST NOT 发明协议级通用状态键、 通用合并算法或客户端求值规则。
value 形状的唯一命名方式(normative):typed current result 的 value 形状由该 family 的
result_writes[].value_schema_ref 以 JSON Pointer 指向 typed-current-result.schema.json
的一个 $defs 成员,MUST NOT 另外获得自己的 ak.schema.* id。
schema-registry.json 登记的是 wire schema——被签名、被传输、被 payload.schema 或 DTO
$ref 按 id 引用的对象;typed current result 的 value 不是其中任何一种,它是 reducer 的输出,
唯一的读取路径就是那条指针。给某个 value 单独发一个 schema id,会让它看起来像 wire schema,
并诱导实现按 id 绑定而绕过登记的写入合同。ak.schema.result_projection.v1 仍然登记,
因为那是该文件整体的 id;realm_authority_root_value 曾是唯一带独立 id 的 value 例外,该 id 已撤销;
它的写入方本来就只引用指针,所以除那个 id 之外没有任何东西被移除。
2. 领域 selector 与 revision
每条结果是一个 closed typed object,包含领域 selector、revision 与完整领域值。v1 登记的 selector kind 为:
realm_profile:当前 Realm profile;calendar_schedule_source:以 strand_id 选择与该 Strand current 同一 stream/revision 的最小日程来源与加密重建上下文,见 Calendar §6;- 以下十五个是 per-Realm 单例 Realm facet,subject 为 JSON null
(
../conformance/encoding.md§9.5.1 禁止把 envelope 的realm_id再写进 subject),各由同名 facet Event kind 单独承载:realm_schema、realm_join_rule、realm_discovery、realm_alias、realm_policy_bundle、realm_asset_privacy_policy、realm_plaintext_visible_services、realm_media_service、realm_read_receipt_policy、realm_preview_policy、realm_tombstone、realm_destroy、realm_set_default_strand、realm_archive、realm_freeze。 最后两个是可逆对:realm_archive由ak.realm.archive/ak.realm.restore写{archived}的 true / false,realm_freeze由ak.realm.freeze/ak.realm.unfreeze写{frozen}的 true / false,效果由 event kind 本身确定,payload 只带可选reason(../models/realm-and-space.md§2.6.0 的表为 normative)。 值是单成员对象而不是裸布尔,理由与space_parent相同:裸标量没有字段可供 CAS 谓词指名。 这两条不解除终态、redaction、另一道 gate 或任何 capability 上限;Realm 没有 materializedstate成员,所以 archive 不是对象 lifecycle 而是一条 facet; mimi_room_binding:以 MIMI room URIpayload.mimi_room_uri选择一条 MIMI 房间绑定 (见../extensions/mimi-interop.md§3);subject 是外部 room URI 而不是 Arkret id——同一 Realm / Strand 可被绑进多个 room,该值是向 MIMI 的投影,从不是 Arkret 侧的真相;moderation_franking_proof:以被证明 Event 的payload.event_id选择一条接收方 franking 证明 (见../governance/content-moderation.md§3.4);证明独立于任何后续 report 产生,因此report_id/target_ref既不是 payload 字段也不进 subject。授权披露后的 closed current 安装与 moderator 举报验证分别执行;普通 baseline 不以举报 UI 或独立存在时间证明为前置;moderation_report:以来源举报 Event 自身的 EventId 选择一条已受理的ak.self.moderation.report(见../governance/content-moderation.md§3.3);value 是原封闭 report payload,family 不可变。ak.moderation.decision{decision="dismiss"}的payload.target_ref逐字 就是这个 subject,因此驳回按同一 EventId 查询,subject 语法里没有也不需要 retype 步骤;服务面的 moderation queue item 是本 family 与moderation_state的读取侧 View,不是本 family 的 value;consent:以 producer 分配的稳定payload.consent_id选择 holder PCR 内的一条 Consent 记录 (见../identity/consent-model.md§2);value 同层承载 grant body 与 reducer 派生的status(active | revoked),expired不是投影状态而是 §5 的验证时窗口判定; peer 永不可读该结果(§8);moderation_state:以被裁决对象payload.target_ref的 canonical string 选择该 target 的 committed moderation 断言集合(见../governance/content-moderation.md§5.3); 值是keyed-set projection的 dot 集合,ak.moderation.decision与ak.moderation.decision.lift都是keyed_set_add——lift 是再加一条断言而不是删掉原 dot,因为多个 issuer 的 record 可以同时 active (../models/common-fields.md§2 的 join 是唯一真源); active record 筛选与hard_deny > quarantine > require_review > none折叠都是读侧折叠,不是存储状态;object_redaction:以被裁剪对象payload.message_id(ak.message.redact)或payload.target_ref(ak.redaction)选择该对象上的 redaction 断言集合 (见../models/event-and-patch.md§4.2.4);两种拼法各自成 subject, 从不合并;值是keyed-set projection的 dot 集合,两个 kind 都只能keyed_set_add—— 同一对象上可以并存多条 redaction,协议不为它们定义任何排序或择一规则(ak.message.redact的 Message 主体是例外:撤回是 Message 终态,至多一个 dot,见../models/strand-and-message.md§9.5.1), 因此这里既没有”最后一条生效”也没有单值redaction_ref;ak:event:目标只裁剪该 Event 自身;applet_discovery:以 AppletId 选择该 Applet 的 discovery 设置,整体置换封闭 value, Directory 仍须独立验证resource_kind与directory_ids[];organization_moderation_policy:以payload.organization_id选择一个 Organization 的 moderation 策略, 整体置换;policy:以payload.policy_id选择一份 Policy 文档整体,由ak.policy.set单一写者整体置换 (见../models/governance-objects.md§3.2);rules[]是该值的必填非空成员,优先级与default_effect求值全在这份文档内进行, 因此单条 rule 不是自己的 subject——PolicyRule.rule_id是文档内局部符号,不命名任何结果, 改一条 rule 也是把整份被授权的 Policy 文档经ak.policy.set重新提交;policy_action:ak.policy.action的 action 审批配置,whole-value set。 selector 按 payload 顶层policy_id/action_id的 closed XOR 带标签分成两支:policy_ref取(policy_id, value.action),realm_action取(action_id); 两支是两个命名空间,MUST NOT 无标签合并(见../models/governance-objects.md§3.4);view:以view_id选择一个 View,由ak.view.create、ak.view.update、ak.view.reconcile三个 kind 写同一个 family(../models/views.md§3.2 对此为 normative);create与reconcile整体置换,update对冻结前态apply_patch; 自报的id不进值内——subject 已经是它;三个写者的result_writes[]均已登记,ak.view.update的allowed_paths与state_changed_at/updated_by/updated_at三个 reducer 派生成员在 registry 内逐项封闭;写者清单以 views.md §3.2 为准;realm_link:以(target_realm_id, link_kind)选择一条 Realm 间链接 (见../models/realm-links.md§5);member_state:以完整actor_id选择成员状态;agent_interaction:以完整agent_account_id选择本 Realm 的 Agent 模式,value 为{controller_account_id,interaction_mode},由ak.agent.interaction.set单一 whole-value writer 写入, controller-only proof 与 expected_revision CAS 见 Agent 交互。 Circle/Strand 消费父 Realm current,不注册局部覆盖;snapshot 缺项不是默认私人证明。
parent_membership admission 同时把 current realm_policy_bundle、目标 Realm 内每个 source 对应的 active
realm_link{link_kind="join_gate_from"}、source/target current authority tenure 与 source member_state 当作权威事务输入。
它们必须在 governing Station 的同一原子接纳事务中锁定、读取并重验;进程内 projection、replica、snapshot、历史 Event、
Directory 或 caller proof 都不是 current result。全部 source 依赖必须可验证,随后至少一个 source 的 exact current
membership 为 join 才满足 gate(../governance/join-policy.md §4)。
-
actor_profile:以actor_profile_id选择一个全局 Actor Profile,由ak.profile.create与ak.profile.update共写 (../discovery/profiles-presence.md§2.3 对此为 normative);create 整体置换作者区域并派生schema/realm_id/created_at/updated_by/updated_at, update 对冻结前态apply_patch,六条allowed_paths只覆盖展示成员;principal_id与actor_kindcreate-locked,resolution由identity_resolution投影、status已完全移出 durable 对象(改为读取响应的可选account_status,见该节); -
actor_profile_realm_override:在目标 Realm 内以actor_profile_id选择一份显示字段覆写;target_realm_id必须等于 envelope Realm,因而不重复进入 selector。value 是 exact patch Event 的 dot-tagged assertion set;读侧按 accepted commit 顺序折叠同一组六个展示路径,并以expected_state_digest对折叠后的当前覆写作 CAS(摘要输入见本节下文); -
agent_action_approval:以approval_id选择一条 controller 对 exact 预写 Event 的不可变确认;(controller ActorId, approval_nonce)是一次性分配,exact replay 返回原结果,换字节复用 nonce 必须零写入拒绝; -
agent_sidecar_exchange_controls:以(sidecar_id, source_context_ref)选择 encrypted control assertion keyed set;exchange_id只在认证密文明文内,禁止复制到 selector。获授权参与者解密后按exchange_id、basis_event_ids与action折叠 coordinator / terminal 状态; -
applet_registration:以applet_id选择 accepted 完整 registration snapshot;package proof、registration_epoch、namespace 与 installer authority 全部在置换前验证; -
key_backup_active_series:以(ActorId, backup_kind)选择当前 active series record;首次版本只能为 1, 后续只能为当前series_pointer_version + 1,回退、跳号或同版本分叉均零写入拒绝; -
member_identity_updates:在 Realm 内以(member_id, segment)选择 append-only update assertion set;replaces[]是读侧 effective-set fold,坏 replacement edge 不得删除被引用 Event;可选expected_state_digest对该 fold 的前态作 CAS(摘要输入见本节下文); -
message_revision:以 MessageId 选择 create / revise chain 的当前 accepted carrier;create 的 id 由 EventId 重类型,revise 明示同一message_id。物化 Message 联合读取 creation history、当前 carrier 与独立的object_redaction,不得把 redaction 伪装成 revision payload; -
realm_organization:在 Realm 内以(organization_id, relationship)选择最新完整组织关系 statement;statement_id只承载审计/替换链,Realm-side 与 Organization-side 两层授权均在置换前验证; -
circle_member_state:以(circle_id, member_actor_id)选择 Circle 内一个 Actor 的 membership;expected_membership是三态 CAS guard,不进入值;effective_at缺省时取 accepted Eventcreated_at;join值逐字保存 producer 签名的parent_membership_revision,其它值不带;effective Circle membership 由它与父 Realm 同 cut 的member_staterevision 比较得出(../models/circle.md§9.1),父资格结束不改写该值; -
realm_search_policy:Realm singleton,完整置换搜索 profile、服务 allowlist、数据类别与泄漏等级; -
rsvp:以(event_ref, canonical occurrence, responder_actor_id)选择一个响应,值为完整rsvp_entry; -
schema_definition:以稳定 JSON Schema$id选择 create-once 定义;exact replay 幂等,异字节复用同 id 拒绝; -
sidecar:以 Event-derivedsidecar_id选择 native Sidecar 物化值;create 同时占用(realm_id, controller_account_id)singleton,禁止第二个 live Sidecar; -
sidecar_context:以(sidecar_id, canonical source_context_ref)选择版本化 UI context attach; -
strand_watch:以(strand_id, watcher_actor_id)选择 watch current value;值是null或{level, level_public?},expected_value只作 whole-value CAS,不进入结果; -
strand:以strand_id选择 Strand; -
circle、morph、space:各以同名<kind>_id选择该对象的当前值,值就是对象自身的 封闭 schema;relation以封闭的payload.primary_conflict_domain(single-componentcanonical_jsoncomposite)选择一个可直接写关系域,值是带 event-derived RelationId 的完整 Relation。 create/update/tombstone 都写同一 domain subject并由 payload 的 exactexpected_revisionCAS; relation identity 字段 create-lock,改变 domain 必须 tombstone 旧值后 create 新值(见../models/relation.md§6)。这些族与strand、view是同一对象 current-value 形态。 需要给 producer 取得该 exact revision 时,只能调用ak.self.current_results.read.exact.v1:它以 closedprimary_conflict_domain、moderationtarget_ref或agent_interaction{agent_account_id}读取一个 selector,并在同一 durable cut 返回当前治理任期、effective stream head 与 selector-identicalpresententry/获授权never_written。never_written为 Relation create 的 null CAS 以及 Agent mode 首写/已确认私人默认开口;Relation update/tombstone 与 moderation lift 必须消费present.revision。 Agent mode read 必须已获授权知道 exact Agent AccountId,不能用 guessed ID 探测私人参与;返回的 mode 不授予 selector/profile 披露或第三方唤醒权。权限不足、不可见、未知或跨 Realm 统一not_found,不得通过 absence 分支枚举状态;generation/head/selector 不匹配一律 fail closed; 带物理 lifecycle 的五族(circle/morph/relation/space/strand)的state成员只由专用ak.<kind>.archive/.restore/.tombstone写入, reducer 按../models/common-fields.md§5.2 的 kind → state 映射 以object_lifecycle_state产出,payload 不携带目标状态;普通 update MUST NOT 复活终态。 五族的成员来源均按value_member_maintenance逐项封闭:create 只投影 author business region, schema / Realm / creator / create-time / initial state 与 update metadata 由 reducer 派生;普通 update、 stage/history 专用写者及 lifecycle 写者分别登记允许路径、派生成员与完整 retained members。space_parent/space_child_scope_policy仍是 Space 对象之外的独立 family,Circle MLS group 仍由mls_groupfamily 单源维护,不复制为第二个可写对象字段; -
strand_position:以typed_pair(id:space(board_space_id), id:strand(strand_id))选择一条 Strand 在某个 Board 上的位置,值为{list_space_id, rank}或null(尚未上板) (见../models/realm-and-space.md§3.6); -
space_parent:以space_id选择一个 Space 的结构父,值为单成员对象{parent_space_id}(成员可空,null 即 root),值本身不是裸 null——本 family 的 compare-and-set 是对已存字段的谓词,裸 null 没有字段可比 (见../models/realm-and-space.md§3.5); -
space_child_scope_policy:以space_id选择该 Space 的子资源 placement policy,值为封闭 policy 对象或null(未声明); 它由ak.space.create与ak.space.update顶层child_scope_policy成员上的专用非 patch 写维护(见../models/circle.md§7.1); -
message_reactions:以被表态对象的payload.target_ref选择该 target 的 reaction 断言集合(v1 core 的 target MUST 是同一 effective scope 内的ak:message:,见../models/strand-and-message.md§9.8.2);值是keyed-set projection的 dot 集合,不是(target_ref, key, members[], count)默认视图——后者是它之上的读侧折叠(§9.8.3); -
mls_group:以 Realm 或 Circlescope_ref选择 MLS group; -
realm_authority_root:singleton,值为typed-current-result.schema.json的封闭realm_authority_root_value(由各写入方的value_schema_ref以 JSON Pointer 指向;它没有、也 MUST NOT 有自己的ak.schema.*id,见上节末段与realm-and-space.md§2.5.1); -
agent_key:以(agent_id, agent_key_id)选择一把 Agent 签名 key 的 registered authorization 投影; -
agent_status:以agent_id选择该 Agent 的 lifecycle 值; -
agent_provisioning:以agent_id选择一条 Agent provisioning 事实,值为四个 create-locked 成员{controller_principal_id, principal_control_realm_id, controller_authorization_ref, requested_scope_digest};它是commit-ordered projection,由ak.agent.provision的四个原子投影之一写入,subject 是 Agent DID 而不是完整 account ActorId(见../identity/key-management.md§3.6.3); -
agent_selector_claim:以(controller principal, agent_slug)(不含 Station)选择一条 controller-scoped Agent selector 绑定,值为{subject_account_id, visibility, audience?};唯一写入方是ak.agent.provision的 selector 投影,AccountId 由已登记派生agent_account_id_from_provision产出,同 slug 的后续 provision 整体置换该绑定,见../models/actor.md§3.3; -
agent_pcr_genesis_declaration:以principal_control_realm_id选择该 realm id 的前向声明,值为单成员索引{agent_id};Agent PCR genesis 不携带指回 provision 的 ref,因此对本家族的反查就是那条绑定,无行即 fail closed 且零写入(同上 §3.6.3); -
realm_genesis:singleton,create-locked identity/security core(ak.schema.realm_genesis.v1),由ak.realm.create的 registered write 一次写入; -
realm_history_access:singleton,Realm history-access FSM 当前值(since_join/all_history_for_current_members); -
identity_resolution:singleton,Realm 当前 did resolution 的五成员resolution_projection;genesis object 携带initial_resolution时由ak.realm.create条件初始化,此后只由ak.identity.resolution.update改写(见../identity/identity-did.md§4.2); -
identity_accountability:以(issuer principal, subject principal, 归一化 exact scope set)选择一条问责背书;第三个分量按ak.accountability_scope_set.v1摘要,因此 wire 上的单个字符串与它的单元素数组落在同一个 subject;它有两个写入方(独立的ak.identity.accountability_grant与ak.agent.provision的原子问责投影),见../models/actor.md§3.3.1; -
capability_grant:以grant_id选择一条 Capability Grant 的完整投影(含 reducer 派生的authority_depth/authority_root_refs,见capabilities.md§10);自有受限授权原 issuer 的非枚举 exact read 也使用
ak.self.current_results.read.exact.v1与该 family 的完整 selector,返回含 ineffective/terminal grant 的同 cut value/revision;不返回 grant never_written,不要求 issuer 仍有被授行动权。读取、撤回 CAS 与独立授权闭合见 owned-agent-authority.md。 -
pin:以完整封闭的pin_scope({kind, id})选择一个 pin scope 的 tagged 断言集;它是keyed-set projection, 三条ak.pin.*各加一条断言,roster、remove-wins 与冲突视图都是读侧折叠(见../models/pins.md§4.1); -
direct_conversation_binding:以pair_key选择一条 canonical Direct Conversation 的 participant endorsement 集合;它是keyed-set projection,tag 为 Event dot、元素值是完整的 endorsement payload,两名 participant 对同一 binding 的背书共存,去重键(binding_digest, envelope.actor_id)是读侧折叠;不同 semantic binding digest 在投影前即拒绝。 结果活在该 Direct Conversation 自己的 Realm 内,因此realm_id/main_strand_id不是 selector 成员 (见../identity/contact-and-direct-conversation.md§8.3); -
invite_lifecycle:以invite_id选择一条 Invite 的流程状态轴;它是transition_contracts登记的 状态机 family,值只有状态名本身(见../models/governance-objects.md§5.3); -
invite_live_target:以canonical_json(invitee_account_id)选择该 invitee 在本 Realm 的唯一 live direct invite 槽位,值为{create_event_id}或null(空槽);subject 不含realm_id; -
invite_directed_invitee:以invite_id选择该 Invite 的 create-locked 定向目标{invitee_account_id}; 它是invite_live_target的反向索引,三方(3PID)Invite 不写这条,故其前态为缺失而不是null; -
call_state/call_focus/call_moderation/call_roster:以call_id选择ak.call.state对应轴的 commit-ordered 投影(见call-state.md§4.1);call_mute_override保留 call-only 形状但 v1 无可接纳写入,不构成媒体授权; -
call_recording_state/call_transcript_state:以(call_id, recording_id)段键选择该段捕获的许可状态; -
call_recording_artifact/call_transcript_artifact:以(call_id, recording_id)段键选择该段捕获的 ready/failed 结果; -
device_authorization:以device_id选择该设备在本 principal control Realm 内的当前授权事实,整体置换写入;封闭 value 与被排除的成员(device_status/attested_at/authorization_window)见../crypto-media/device-lifecycle.md§5.5.1; -
device_generation:单值 selector(除 kind 外无成分,一个 PCR 一份),值只有current_device_generation_ref;写入方是registration_anchor分支的ak.device.authorize(置1)与ak.device.reanchor(置new_device_generation),见../crypto-media/device-lifecycle.md§5.5.4; -
device_revocation_proposals:以device_id选择针对该设备的已接纳撤销提案 keyed set,元素不可变、永不删除;revocation_pending/rejected/revoked是每个元素与其覆盖 command result 的读侧折叠,不是存储轴,见../crypto-media/device-lifecycle.md§5.5.3。
selector 的身份字段来自已接纳 Event 的 typed payload,不得由调用方另行声明或由服务端按显示名称猜测。新增领域结果 必须先扩展 registry 与 schema;未知 selector 必须拒绝,不能退化为任意 JSON。
revision 是 closed {commit_id, stream_position}。commit_id MUST 指向最后改变该结果的 RealmCommit,
stream_position MUST 等于该 commit 在所属 stream 的位置。每份 closed typed current result 还 MUST 携带
source_stream_ref,逐字等于该 covering Commit 的 stream_ref;此成员是来源坐标的必填部分,不能由 selector、
值或相同数字位置推测。source_stream_ref 不属于二元 CurrentRevision,既有 expected_revision CAS 仍逐字段比较
{commit_id, stream_position}。时间戳、到达顺序与 EventId 均不得替代 revision。
领域写操作需要并发保护时,payload 使用该领域定义的 expected_revision。Station 只在它与当前 typed revision
逐字段相等时接纳;不相等返回 failed_precondition 且零写入。v1 的 Problem 响应不携带通用 typed current result:
detail、reason_detail、未登记的 current/current_result 或任意扩展 bag 均不得冒充机器可读前态。
调用者需要重写时,只能通过该 selector 已有且获授权的 current 读取操作或 §3 的可见当前结果重新取得前态,
核对 Realm、完整 selector、governance generation、stream head 与 revision,并重新确认后签发新 Event;
没有已登记读取路径、读取未授权或结果缺席时必须停止,不能从错误字符串、旧缓存或 snapshot 缺项猜测 current,
也不能自动用旧签名重试。重新读取是独立操作,不属于失败响应或同一接纳事务的返回值;提交时仍须重新检查 CAS。
首次创建可使用该领域 schema 明确允许的 null,不得使用字符串哨兵或通用条件表达式。
expected_state_digest 的摘要输入(normative):以 expected_state_digest 声明前态的 kind(actor_profile、
Realm authority root、View、Morph、Circle、Space、Strand、Relation 等单值 family)一律使用同一算法:
expected_state_digest = "sha256:" || lowercase_hex(SHA-256(RFC8785_JCS(v))),其中 v 是接纳事务冻结的该
typed current result 的完整当前 value,逐字等于其 value_schema_ref 下的物化值(含 reducer 派生成员,
不含 revision、source_stream_ref 或 selector),摘要输入不加 domain 前缀。不相等时以不带 reason_code
的 failed_precondition 零写入拒绝,除非该 kind 的正文另行登记了专用 reason。keyed-set family 的前态是读侧
fold,v 取 fold 的结果值,算法不变:
actor_profile_realm_override:v是按 accepted commit 顺序把 assertion set 中每条patch依次应用到空对象{}上得到的展示对象,只含实际被设置的路径($op=unset删除该路径,嵌套路径形成嵌套对象);尚无任何 assertion 时v = {}。member_identity_updates:v是该(member_id, segment)的 effective set(按replaces[]有效替换边折叠后仍 未被替换的 update)中每条 update 的逐字签名 payload 对象组成的数组,按承载 Event 的event_id字符串 升序排列;effective set 为空时v = []。失配 reason 为已登记的member_identity_state_mismatch。
逐字节 known answer 见 expected-state-digest-kat-fixture.json。
2.1 生命周期轴与转换合同
某个领域结果若带有生命周期轴(状态机),该轴的转换真源是 contract registry 的
event_kind_registry.transition_contracts 中同名 family 条目:它封闭该轴的状态集合、入口
(initial_state / initial_states / template 三者恰取其一)、终态与允许的 (from, to) 边。
本节只定义合同的读法,不复制任何一张转换表。
- 写入已在
transition_contracts登记的 family 的 Event MUST 使用transition投影并声明from与to;MUST NOT 使用整值投影。整值写入会绕过allowed_transitions,使转换表退化为注释而不是规则。 from与to各自 MUST 恰好声明const与field之一。一行需要承载多条边(前态取值不止一个)时 用field指向 payload 中已封闭该取值集合的字段,不得在 registry 里另抄一份常量。- 未在
transition_contracts中登记的 family MUST NOT 使用transition投影:没有状态集合的from/to对没有任何可校验的对象。 - 终态 MUST NOT 带出边。终态性只由转换表本身承载;实现不得以约定、服务端表或默认值补充。
存储的生命周期轴有三种登记载体,带此类轴的 family MUST 恰取其一(本节此前只写了第一种,使
authz/capabilities.md §12.1 的 capability_grant 读起来像违例,
并让”稳定 ID + 不可变 body + 终态”这一类 family 无处登记;随后补上的「二选一」又反过来把
view 的作者状态路径判成违例):
transition_contracts轴 +transition投影:result value 只承载状态名本身(invite_lifecycle即此形),该 family 的其它事实各自另立 family。- 封闭 reducer 派生成员:status 是 value body 内与其它字段同层的一个成员,由
result_writes[].derived_members[].derivation中一个封闭派生名物化,MUST NOT 由 producer 自填; 该 family MUST NOT 出现在transition_contracts中(capability_grant、consent即此形)。 - 有界的作者状态路径:status 是 value body 内的一个成员,由作者在已登记的
apply_patchallowed_paths[]内直接写入;该 family MUST NOT 出现在transition_contracts中, 取值集合 MUST 由该成员的 value schema 封闭,终态、禁止复活与转换边 MUST 由该领域正文逐条写死 (view即此形,见models/views.md§3.1)。这一形态的代价是转换边不被 机读件封闭,只有准入实现在读正文,因此新增此形 MUST 同批登记一条覆盖该终态的 conformance vector, 并在该 family 的 reducer-managed 路径上把状态转换时间之类的派生成员钉住, 使作者无法连同状态一起自填转换事实。
keyed-set family 不在这三种之内:它没有存储的状态轴,生命周期是读侧 fold
(models/common-fields.md §2),moderation_state 即此形——
ak.moderation.decision 与 ak.moderation.decision.lift 都只能 keyed_set_add,
当前效力由读侧折叠得出。MUST NOT 为了形式统一再存第二份权威 status。
expected_revision 不决定 value 形状。 它要求的只是目标 typed result 存在可比较的 exact
revision:scalar 状态轴、keyed set 与 body+status 组合对象都可以被它保护,也都可以不被它保护。
ak.moderation.decision.lift 带着它却写 keyed set,view 不带它却有作者可写的 state,
两者都合法。决定 body 与 status 是否必须同处一个 result 的是原子不变量:若一个逻辑对象的
body 与 status 之间有必须原子保持的不变量,整对象 CAS MUST 绑定同一条 result revision,
MUST NOT 拆成两份各自独立的权威副本。capability_grant 与 consent 取形态 2 是这个理由,
不是因为它们的 payload 里出现了 expected_revision 这个字段名。
无论取哪一形态,该 family MUST 逐项登记:每个 value 成员的来源与维护闭包、终态与禁止复活规则、
准入 guards,以及 revision 的比较方式。这四项都 MUST NOT 由「payload 有没有 expected_revision」
二分推出。三种形态同样禁止把状态放在两处:一个 family 只有一个状态真源。
该合同缺失时 MUST 视为失败,不得当作「该轴无约束」:读不到转换表的检查只能证明没有人检查过。
2.2 消费清单(normative)
写入方向已经封闭:每个 family MUST 至少有一个 Event kind 在 result_writes[] 里写它,这条由
check_every_result_family_has_a_writer 强制。读取方向此前既无门禁也无记录——一个 family 可以有写者、
有投影、有 schema,却没有任何一节正文把判断条件挂在它的当前值上。这种 family 在注册表里与真正被消费的
family 完全无法区分,正文读起来像是「该状态存在」,而实际上没有任何行为依赖它。
因此 current-result-registry.json 的每一行 MUST 携带 consumption,三个成员都 MUST 给出:
class:取自该文件consumption_classes的封闭词表,见下;consumed_by[]:读取该 family 当前值的正文小节引用,形如<page>.md §N, 由check_artifact_prose_section_refs解析校验;note:说明读到的是什么、用来决定什么。
词表封闭为三类,MUST NOT 扩充:
class | 含义 |
|---|---|
admission_input | 读当前值会改变某个 Event 或请求是否被接纳/授权。 |
delivery_input | 读当前值决定某个服务面返回或投递什么、或合规客户端必须怎么做,但不参与准入判定。 |
record_only | v1 没有任何正文依据该值做判断;它只作为审计或展示记录存在。 |
三条判定规则:
record_onlyMUST 被显式声明,MUST NOT 由「没人提起」推出。没有正文引用该 family 不等于它是纯记录 用途,只等于没有人查过;两者在注册表里长得一样,正是本清单要消除的歧义。- 除
record_only外,consumed_by[]MUST 非空;record_only行的consumed_by[]MUST 为空, 且其noteMUST 指名声明该 family 用途的那一小节,使该判定本身可查。 - 一个 family 的 class MUST 取其最强的消费方式:只要存在任何一处准入判定读它,就是
admission_input, 即便它同时也参与投递。delivery_input的含义是「v1 全文没有任何准入判定读它」,而不是「主要用于投递」。
清单只登记「谁读」,MUST NOT 被读成授权或可见性声明:某一节被列入 consumed_by[],不意味着调用者有权读取该
selector——响应可见范围仍由 §3 决定。
3. 当前结果响应
AccountCurrentView.current 是 closed:
realm_id:结果所属 Realm;governance_generation:当前治理 Station 任期代次;stream_heads[]:调用者获准读取的 Realm/Circle/Sidecar stream heads;entries[]:closed typed results。
同一 selector 在同一 revision 下必须具有完全相同的 canonical bytes。发现相同 revision、不同值时,客户端 MUST
拒绝整批响应并重新获取当前 authority bundle;不得任择覆盖。较新 revision 原子替换旧值;来自旧
governance_generation 的响应不得覆盖新任期结果。
此一致性比较的前提是两条结果均符合现行 closed typed value schema。本地持久缓存若无法通过该 schema, 客户端 MUST 将该行及依赖它的 authoring 读取视为不可用,并重新获取、验证当前 authority bundle 和完整签名 Realm state snapshot;仅在该验证成功后,MAY 在原子持久事务中以快照的原始 typed row 重建无效缓存。 客户端 MUST NOT 为缓存补字段、归一化已签字节或从 UI/Event 猜测值。恢复仍 MUST 检查相同 source stream、 同 position 的 Commit identity、revision/stream head 单调和 governance generation;它不豁免两个有效结果的 同 revision 异字节拒绝规则。增量或未验证响应 MUST NOT 触发此恢复,身份密钥、MLS 私有状态与待发送队列 MUST NOT 随投影缓存重建而清除。
响应只包含调用者当前有权读取的 selector。省略不表示空值、删除或权限;领域若允许显式空值,必须由其 typed value 表达。成员退出、Circle 撤权或 Station 更换后,客户端必须按新授权范围清除不可再见的缓存,但不得由响应差异推断隐藏对象。
strand_watch 的 whole-value CAS 不能从本列表、Realm snapshot 或 stream scan 中的缺项推断
never_written。本人需调用 strand-and-message.md §8.3
的 exact current read;它在同一治理任期和 effective stream head 下明确区分未写入与写后清空。
该精确响应也只是一时观察,不豁免提交时的当前授权与 CAS 再验证。
Agent/Applet Policy 的 exact CAS 读取沿 ak.self.current_results.read.exact.v1 已登记 policy selector,
仅当前 scope 有 ak.policy.set 权限者可得原 typed row 或权威 never_written;不凭省略推断初次 null,
不枚举其他 Policy,read permission 不代替写入时的 current CAS 和审批校验。
4. 有界基线与续传
AccountCurrentView.coverage 携带 realm_id、stream_heads[] 与 complete_for_authorized_streams。只有在:
- 所有获准 stream 都已扫描到所声明 head;
- 对应 entries 已耐久安装;
- 本次读取期间
governance_generation未改变;
三项同时成立时,服务端才可返回 complete_for_authorized_streams=true。
分页 cursor 必须绑定 realm_id、governance_generation、每个已覆盖 stream head 与最后一个稳定排序键。缺页、重复页、
governance_generation 改变或任一 head 改变时,客户端 MUST 废止该基线并从当前 authority bundle 重新开始。Circle 与 Sidecar 的
分页进度分别绑定各自 stream;不得借 Realm stream head 声明它们已完整。
Realm join bootstrap 默认从当前治理 Station 获取 authority bundle、获准 stream heads、committed Events 与 current results。邀请人服务器只转交邀请和当前 governance Station 定位证据;它不是 bootstrap 真相源,除非它恰好就是经验证的 current governance Station。
5. 预算与失败
单次响应必须遵循 transport 的 canonical 与 wire 大小上限。分页只能在完整 entry 之间切分;一个 entry 不得截断。 结果暂不可计算、依赖 commit 缺失或授权状态不完整时,服务端 MUST fail closed,并要求调用者从当前 governance Station 重新同步;不得伪造默认值、让客户端从部分 Event 猜测结果或跨 stream 拼出虚假的全局顺序。
当前结果不授予写权限。每次提交仍由治理 Station针对当前 capability、成员资格、policy、领域 revision 与 MLS 约束重新校验。