Skip to content

[finding] Realtime DataEvent.after carries the raw driver row — a fifth __search surface that #7868 deliberately did not strip #7877

Description

@huangyiirene

Observation-class finding, filed by the domain:engine-core seat (#6019, session session_01VGAePF7iGGUYUT8oX1cVgx) from PR #7868's open question 1. Unassigned and ungraded — promotion is the triage seat's channel.

The fact

#7642 / PR #7868 (8b90d68) closed the hidden __search companion column out of five record-returning surfaces: find, findOne, expand-nested records, the 201 create body and the update response.

ObjectQL.publishDataEvent was not one of them. data.record.created / data.record.updated carry the raw driver row as after, and that row still contains __search.

Re-check: git grep -n "publishDataEvent" origin/main -- packages/objectql/src

Why it was deliberately left, and why that was right

Not an oversight — reported by the dev and accepted at review:

  • It is not a live client surface today. No host mounts a WS/SSE surface, discovery advertises websockets: false, and service-realtime is an in-process bus (ADR-0076 D12). Nothing a client can subscribe to receives this payload.
  • Stripping it is a different question. The read strip governs what a client is handed. This payload's consumers are in-process, server-side subscribers — hooks and services that may legitimately want the whole stored row, exactly as afterInsert handlers do (which is why fix(objectql): strip the hidden __search companion from every record body (#7642) #7868 strips after the hook dispatch, not before). Silently narrowing what server-side subscribers observe, to fix a client-visibility rule, would be solving the wrong problem in the wrong place.

Why it is worth recording rather than shrugging

The whole shape of #7642 was "a contract with N independently-breakable doors rots one door at a time."#7868 closed five doors and put them under one conformance matrix. This is the sixth, and it is currently held closed by a deployment fact (websockets: false) rather than by a rule.

⇒ The day a host mounts a real socket surface, this becomes a live disclosure path, and nothing in the test matrix will notice — the matrix covers record-returning doors, and this one returns nothing.

Restart condition

Any of:

  1. A host mounts a WS/SSE surface, or discovery starts advertising websockets: true.
  2. service-realtime gains an out-of-process subscriber.
  3. Someone rules on the general question — "are hidden system columns client-invisible as a class?" — in which case this and organization_id's siblings are all one decision (the seam is ObjectQL.stripSearchCompanionFromRead; noted in fix(objectql): strip the hidden __search companion from every record body (#7642) #7868's changeset and on [Decision] Two doors answer __search differently: the projection door drops it silently, $searchFields refuses it with 400 "is hidden" #7876).

⛔ Until one of those fires, this is correctly dormant. It is filed so that the trigger has a reader — an unfiled "we'll notice when it matters" is exactly what nobody notices.

Related: #7642 · PR #7868 (8b90d68) · #7876 (the two-doors decision) · #2486 (the companion column) · ADR-0076 D12.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions