Skip to content

Measure whether a record-before-update flow can reach the batch payload of a multi: true update — the one in-repo door #14744's zero does not cover #15356

Description

@os-warren

Filed by the director seat (summon 14, session_01LsEjuNMPitCHwEfYftZ1um, GitHub os-warren) under maintainer decision batch #35 (2026-09-04, verbatim 「同意」), #14744 Q2 = A: measure it. Measurement card, ⛔ not a fix; pr: null is a complete outcome.

Why this exists

#14744's census (PR #15301, merged) found the in-repo population of same-key / per-row-value beforeUpdate rewrites is zero across 23 production registration sites. The dev named one door that zero does not bound: packages/triggers/trigger-record-change/src/record-change-trigger.ts:299 binds beforeUpdate for the record-before-update / record-before-write trigger types and hands the write to user-authored flow metadata. Its conclusion there — buildContext materialises a NEW record object by overlay rather than handing the flow ctx.input.data by reference, so a flow cannot reach the batch payload — is a source reading, explicitly not a measurement (dev report 5538773355; engine seat's confidence gap 3 in 5539235396). If a flow CAN write the batch payload, the in-repo zero stops bounding the risk and the #14744 decision's weighing changes.

What to measure

On a real ObjectQL engine with the record-change trigger plugin loaded:

  1. Bind a flow to record-before-update on an object; issue one multi: true update matching ≥ 2 rows whose pre-images differ.
  2. From the flow, attempt every write shape flow metadata can express (set-field / assignment nodes, script steps if any, direct record.* mutation) and establish whether any of them reaches ctx.input.data / the batch payload — by reference, by copy-back, or through any node that writes the record.
  3. Positive control in the same harness: a script beforeUpdate hook that does assign the payload (the A multi: true hook that writes the SAME key with per-row VALUES still applies one row's value to every matched row — the residue #14099's key-set refusal deliberately leaves open #14744 pinned residue shape) must show the last-dispatch value landing on every row, so the harness is proven to observe the defect when it is present.
  4. Report per shape: reaches payload / does not; and if it does, whether the A multi: true update applies one hook-mutated payload to every matched row, so a transition-stamping hook corrupts rows that did not transition #14099 key-set refusal fires when rows disagree.

Prior reading of this door, for context only: #4862 (closed) — on predicate bulk writes previous was not bound and record was the bare payload; re-check that reading rather than inheriting it.

Constraints

Acceptance

The answer for each flow write shape is measured at runtime with the positive control firing, and #14744 is updated with a one-line verdict: bounded (the zero holds for this door too) or not bounded (name the shape that reaches the payload).

Related: #14744 (parent decision, Blocked-by: this card) · #14099 · #14758 · #4862 · PR #15301.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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