Filing gate: ① a declared≠enforced family, filed as one sweep card per family under ruling A′ item ④ on #18900 (5727134555). This is triage's standing request 5857165909 on the seat post. Family realtime-subscription, seat verdict ENFORCE.
reach: the declared authoring door. packages/spec parses these keys and publishes them in the reference docs. The liveness ledger rows cited below record them as not enforced, and the census re-measured the reader side (§5 cross-checks, each with a lit control).
- The criterion is the maintainer's: 「每族该问的是:主流平台有没有这个能力 —— 有 ⇒ 补消费端(一次做对);没有 ⇒ 退役,而不是看仓里有没有人读」.
- The maintainer's one word, per ruling A′ ④: ENFORCE (the seat's proposal: the mainstream has it, so build the consumer once, correctly) or RETIRE (retire the keys together with their ledger rows).
Census by the domain:spec execution seat 1 (session_01Rjy9MeetSfq34PKn81CRiN, seat post #6017), 2026-09-27. Bases: objectstack a9fb83ef, re-checked against 4d7e740d, where no ledger file or cited surface moved; objectui 6fa5f64a1 (pin f8a9d0fb); cloud 96eb092. Ledger instrument: check-liveness.mts --json, whose byStatus equals the committed state-counts.md row for row. ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim. The ranking is by value, user-visible risk × keys. This family's rank is 6 of 16. The sibling family cards filed so far are #20273, #20274, #20281 and #20282.
Capability: A client subscribes to record-change events (event type, object, filter, channel, transport)
| key |
ledger status |
ledger row |
what the ledger cites |
realtime_subscription.id |
dead (verified 2026-09-04) |
packages/spec/liveness/realtime_subscription.json:5 |
note: 0 read sites at 5f5511f. A subscription's identifier is never read because a subscription is never parsed: the shipped adapter mints and keys its own id (in-memory-realtime-adapter.ts#subscribe returns the id it generates, and #unsubscribe looks it up in a… |
realtime_subscription.events.type |
dead (verified 2026-09-04) |
packages/spec/liveness/realtime_subscription.json:13 |
note: 0 read sites at 5f5511f, and the sharpest row in this file: the accept set is PUBLISHED and every member of it names an event nothing emits. type is RealtimeEventType (realtime.zod.ts:33-38), whose members are record.created / record.updated / `rec… |
realtime_subscription.events.object |
dead (verified 2026-09-04) |
packages/spec/liveness/realtime_subscription.json:19 |
note: 0 read sites at 5f5511f. The per-object narrowing an author writes on a subscription event is never read. ⚠️ The narrowing that IS executed is a different key on a different type: RealtimeSubscriptionOptions.object (packages/spec/src/contracts/realtime-ser… |
realtime_subscription.events.filters |
dead (verified 2026-09-04) |
packages/spec/liveness/realtime_subscription.json:25 |
note: 0 read sites at 5f5511f — the textbook ADR-0049 fourth state, and the easier half of the pair this file seeds: filters: z.unknown().optional().describe('Filter conditions') (realtime.zod.ts:49) is an authorable key with NO SHAPE and NO CONSUMER. Whatever… |
realtime_subscription.transport |
dead (verified 2026-09-04) |
packages/spec/liveness/realtime_subscription.json:33 |
note: 0 read sites at 5f5511f. TransportProtocol (websocket | sse | polling) is validated as an enum and then read by nothing on this schema: no transport is selected, negotiated or refused from a subscription's transport, and the shipped adapter is in… |
realtime_subscription.channel |
dead (verified 2026-09-04) |
packages/spec/liveness/realtime_subscription.json:39 |
note: 0 read sites at 5f5511f. The optional grouping channel is never read from a subscription. ⚠️ Channels are a real runtime concept elsewhere — in-memory-realtime-adapter.ts keys a channel index and contracts/realtime-service.ts declares channel-scoped subscr… |
Mainstream evidence:
- Salesforce Streaming API / Pub/Sub API with Change Data Capture (
ChangeEvents) and PushTopics.
- ServiceNow Record Watcher (AMB) for live list and form updates.
- Supabase Realtime (Postgres changes) and Firebase listeners, the BaaS reference shape.
- Odoo: the
bus.bus websocket pushes record and notification updates to the web client (internal channel).
- Lacking: Dataverse has no client push (webhooks and Azure Service Bus only), and Airtable has server-side webhooks only.
Verdict: ENFORCE — the mainstream has the capability, so build the consumer once, correctly.
Reader that must exist / disposition: objectstack packages/services/service-realtime: a mounted HTTP/WS/SSE subscribe handler that parses SubscriptionSchema. The direction of the event vocabulary is already settled (triage on #14446: the emitted data.record.* wins). #14646 (closed) made discovery stop advertising the unmounted surface; this card mounts it. The two other spellings (websocket.zod.ts#EventSubscriptionSchema, contracts/realtime-service.ts#RealtimeSubscriptionOptions) converge on this one.
User-visible risk (2): The generated API reference (content/docs/references/api/realtime.mdx) publishes an enum of record.* events that no producer emits, so a subscription written from the docs silently never fires.
Acceptance: Every ledger row listed leaves dead/planned/experimental for live, citing the new reader as file#symbol (and a producer where the read depends on a supplied input); pnpm check:liveness green; the family's byStatus in state-counts.md regenerated.
Lane: domain:spec parent + domain:services (service-realtime) sub-issue + objectui sub-issue (client / notification bell)
File surface: packages/spec/src/api/realtime.zod.ts:33,46,57 · packages/spec/src/api/websocket.zod.ts · packages/spec/src/contracts/realtime-service.ts · packages/services/service-realtime/src/* · packages/spec/liveness/realtime_subscription.json
Dedupe: realtime_subscription \| SubscriptionSchema \| RealtimeEventType \| SubscriptionEventSchema \| RealtimeConfigSchema → 0 open hits.
四轴:
- 实际业务需求: 列表和表单实时刷新、通知铃铛实时到达,是 Salesforce CDC 和 ServiceNow Record Watcher 早已提供的体验。本平台已有 in-memory realtime 服务,只缺对外的订阅入口。
- 项目长远合理性: 三种订阅写法并存,只有一种被执行。一次做对 = 挂载一个传输层,只解析一种 schema,事件词汇与发出端一致,另外两种写法收敛进来。
- 防 AI 写错: 今天 AI 按文档写
record.created 永远收不到事件。收敛之后,词汇错误在解析时报错。
- 创业阶段不扩散: 若维护者判定开源框架现阶段不挂 realtime 传输,诚实的替代是退役 SubscriptionSchema。维持「发布了 schema 却无人解析」是最差的状态。
Filing gate: ① a declared≠enforced family, filed as one sweep card per family under ruling A′ item ④ on #18900 (
5727134555). This is triage's standing request5857165909on the seat post. Familyrealtime-subscription, seat verdict ENFORCE.reach:the declared authoring door.packages/specparses these keys and publishes them in the reference docs. The liveness ledger rows cited below record them as not enforced, and the census re-measured the reader side (§5 cross-checks, each with a lit control).Census by the
domain:specexecution seat 1 (session_01Rjy9MeetSfq34PKn81CRiN, seat post #6017), 2026-09-27. Bases: objectstacka9fb83ef, re-checked against4d7e740d, where no ledger file or cited surface moved; objectui6fa5f64a1(pinf8a9d0fb); cloud96eb092. Ledger instrument:check-liveness.mts --json, whosebyStatusequals the committedstate-counts.mdrow for row. ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim. The ranking is by value, user-visible risk × keys. This family's rank is6of 16. The sibling family cards filed so far are #20273, #20274, #20281 and #20282.Capability: A client subscribes to record-change events (event type, object, filter, channel, transport)
realtime_subscription.idpackages/spec/liveness/realtime_subscription.json:5realtime_subscription.events.typepackages/spec/liveness/realtime_subscription.json:13typeisRealtimeEventType(realtime.zod.ts:33-38), whose members arerecord.created/record.updated/ `rec…realtime_subscription.events.objectpackages/spec/liveness/realtime_subscription.json:19realtime_subscription.events.filterspackages/spec/liveness/realtime_subscription.json:25filters: z.unknown().optional().describe('Filter conditions')(realtime.zod.ts:49) is an authorable key with NO SHAPE and NO CONSUMER. Whatever…realtime_subscription.transportpackages/spec/liveness/realtime_subscription.json:33TransportProtocol(websocket|sse|polling) is validated as an enum and then read by nothing on this schema: no transport is selected, negotiated or refused from a subscription'stransport, and the shipped adapter is in…realtime_subscription.channelpackages/spec/liveness/realtime_subscription.json:39Mainstream evidence:
ChangeEvents) and PushTopics.bus.buswebsocket pushes record and notification updates to the web client (internal channel).Verdict: ENFORCE — the mainstream has the capability, so build the consumer once, correctly.
Reader that must exist / disposition: objectstack packages/services/service-realtime: a mounted HTTP/WS/SSE subscribe handler that parses SubscriptionSchema. The direction of the event vocabulary is already settled (triage on #14446: the emitted
data.record.*wins). #14646 (closed) made discovery stop advertising the unmounted surface; this card mounts it. The two other spellings (websocket.zod.ts#EventSubscriptionSchema, contracts/realtime-service.ts#RealtimeSubscriptionOptions) converge on this one.User-visible risk (2): The generated API reference (content/docs/references/api/realtime.mdx) publishes an enum of
record.*events that no producer emits, so a subscription written from the docs silently never fires.Acceptance: Every ledger row listed leaves dead/planned/experimental for live, citing the new reader as file#symbol (and a producer where the read depends on a supplied input); pnpm check:liveness green; the family's byStatus in state-counts.md regenerated.
Lane: domain:spec parent + domain:services (service-realtime) sub-issue + objectui sub-issue (client / notification bell)
File surface: packages/spec/src/api/realtime.zod.ts:33,46,57 · packages/spec/src/api/websocket.zod.ts · packages/spec/src/contracts/realtime-service.ts · packages/services/service-realtime/src/* · packages/spec/liveness/realtime_subscription.json
Dedupe:
realtime_subscription \| SubscriptionSchema \| RealtimeEventType \| SubscriptionEventSchema \| RealtimeConfigSchema→ 0 open hits.四轴:
record.created永远收不到事件。收敛之后,词汇错误在解析时报错。