You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Maintainer adjudication 2026-08-19: measurement reconciliation runs before either #9612 or #9613 is scoped. Both are blocked on this card.
The disagreement
Two published measurements describe the same operation — a flow publish through the shipped runtime publish gate, before any #4716 widening — and do not agree.
Reading A — #9613 body, sourced from #4716 comment 5309105113, measured on origin/main @ 66beee0f3 by a throwaway harness:
Today's shipped gate — before anything from the P2 widening lands — costs 33.4 ms at 21 objects → 506 ms at 420 objects per flow publish, linear in the tenant's object count.
Reading B — PR #9825 body, the BEFORE column, measured on dist/runtime.cjs, medians of 30 iterations after warmup, origin/main registry rebuilt and preflighted absent:
write
N stored objects
BEFORE
flow publish
21
2.00 ms
flow publish
420
20.11 ms
N
Reading A
Reading B
ratio
21
33.4 ms
2.00 ms
16.7×
420
506 ms
20.11 ms
25.2×
The ratio is not constant, so this is not a unit error or a constant-factor harness offset. Something structural differs.
PR #9825 treats the two as compatible — "the flow rows above show this PR adds nothing to it" — and that claim is fine on its own terms (it is a within-harness delta, and it is genuinely ~zero). But "my change adds nothing" does not establish which absolute baseline is true, and #9825 never claimed it did. Nobody has reconciled them.
Why this blocks both cards
#9612's acceptance criterion is quoted from its own body:
option (a) per-save p50 = 201 ms at 306 items, 822 ms at 1530, 1.8 s at 3060 … Any implementation must beat or bound this, or gate it.
Those numbers come from the same harness family as Reading A. If that harness is measuring something other than what its label says, then #9612's acceptance target is unreliable and a dev dispatched against it would be optimising toward a possibly-wrong number — and, worse, could "pass" by beating a target that was never real.
The product conclusion also inverts between the two readings. At 420 objects, Reading A says a Studio designer waits half a second on an interactive publish (perceptible, and it grows with exactly the number that grows as a tenant succeeds); Reading B says 20 ms (imperceptible). One of these is a priority and the other is a non-issue.
The three hypotheses — and the measurement that separates them
The harnesses measure different spans. One may time the whole saveMetaItem round-trip (schema parse, persistence, hooks) while the other times only the gate call; or one is cold and the other post-warmup; or they seed structurally different stacks (a 420-object stack with no flows/expressions is a different workload from one with them).
The code genuinely got faster between 66beee0f3 and today's 1408ae337.
One measurement is simply wrong — a harness bug, a mis-set N, a stale build.
Only (2) would be real improvement; (1) and (3) are instrument faults. Measure current main with BOTH methodologies — that single comparison separates them. If both methodologies agree on today's main, hypothesis 2 is live and the delta is attributable to a commit range. If they still disagree on the same tree, it is (1) or (3), and the job is to say which and why.
Deliverable
A reconciled number for the shipped gate's per-publish cost as a function of stored-object count, with the disagreement explained — not averaged, not quietly dropped. Name which of the three hypotheses holds and show the evidence for it. "One of them was wrong" is an acceptable answer if you can say how.
A repo-resident benchmark, not a third throwaway harness. Both existing readings came from one-off scripts that no longer exist in a runnable form, which is exactly why this card exists. Whatever you build must be re-runnable by the next person from a documented command, and must state its own span (what is inside the timed region and what is outside), its warmup policy, and the shape of the stack it seeds.
A benchmark that cannot fail is not a benchmark. Demonstrate yours responds to the thing it claims to measure: ablate one hot rule (validateStackExpressions is ~70% of the option-(a) bill by both cards' accounting) from the runtime-publish surface, show the number moves in the expected direction and by roughly the expected share, then restore and show the tree is byte-identical. A benchmark whose reading does not move when you remove 70% of its claimed workload is measuring something else, and that fact is itself the answer to this card.
Maintainer adjudication 2026-08-19: measurement reconciliation runs before either #9612 or #9613 is scoped. Both are blocked on this card.
The disagreement
Two published measurements describe the same operation — a
flowpublish through the shipped runtime publish gate, before any #4716 widening — and do not agree.Reading A — #9613 body, sourced from #4716 comment
5309105113, measured onorigin/main@66beee0f3by a throwaway harness:Reading B — PR #9825 body, the BEFORE column, measured on
dist/runtime.cjs, medians of 30 iterations after warmup,origin/mainregistry rebuilt and preflighted absent:The ratio is not constant, so this is not a unit error or a constant-factor harness offset. Something structural differs.
PR #9825 treats the two as compatible — "the flow rows above show this PR adds nothing to it" — and that claim is fine on its own terms (it is a within-harness delta, and it is genuinely ~zero). But "my change adds nothing" does not establish which absolute baseline is true, and #9825 never claimed it did. Nobody has reconciled them.
Why this blocks both cards
#9612's acceptance criterion is quoted from its own body:
Those numbers come from the same harness family as Reading A. If that harness is measuring something other than what its label says, then #9612's acceptance target is unreliable and a dev dispatched against it would be optimising toward a possibly-wrong number — and, worse, could "pass" by beating a target that was never real.
The product conclusion also inverts between the two readings. At 420 objects, Reading A says a Studio designer waits half a second on an interactive publish (perceptible, and it grows with exactly the number that grows as a tenant succeeds); Reading B says 20 ms (imperceptible). One of these is a priority and the other is a non-issue.
The three hypotheses — and the measurement that separates them
saveMetaItemround-trip (schema parse, persistence, hooks) while the other times only the gate call; or one is cold and the other post-warmup; or they seed structurally different stacks (a 420-object stack with no flows/expressions is a different workload from one with them).66beee0f3and today's1408ae337.Only (2) would be real improvement; (1) and (3) are instrument faults. Measure current
mainwith BOTH methodologies — that single comparison separates them. If both methodologies agree on today'smain, hypothesis 2 is live and the delta is attributable to a commit range. If they still disagree on the same tree, it is (1) or (3), and the job is to say which and why.Deliverable
node-metadata-manager's watcher has the same one-shot delivery structure #9339 just repaired, with no reconciliation behind it #9701 branch-deletion correction.Anti-vacuity requirement
A benchmark that cannot fail is not a benchmark. Demonstrate yours responds to the thing it claims to measure: ablate one hot rule (
validateStackExpressionsis ~70% of the option-(a) bill by both cards' accounting) from the runtime-publish surface, show the number moves in the expected direction and by roughly the expected share, then restore and show the tree is byte-identical. A benchmark whose reading does not move when you remove 70% of its claimed workload is measuring something else, and that fact is itself the answer to this card.Scope fences
surfaces/runtimeTypes/surfaceReason. This card produces a number and an instrument. The fix is runtime gate: full runtime-safe rule snapshot for the publish door — the expensive half split out of the object-gating card #9612/finding: the shipped runtime publish gate already costs linearly in tenant object count — 506 ms per flow publish at 420 objects, before any widening #9613's, and how to scope it is a maintainer decision that is explicitly still open (per-rule scoping vs caching+invalidation vs size threshold — and the size-threshold option is a deliberate fail-open at scale, so it is not a dev's pick).1408ae337; the flow door was untouched by [P2] 运行时授权门扩到 object 写入 + 全量 runtime-safe 规则快照(#4463 P1 之后) #4716 (feat(lint): the five gating object rules cross the runtime publish gate (#4716) #9825's premise re-derivation), which is what makes the flow-publish number comparable across the two refs in the first place — verify that rather than assuming it, because it is the load-bearing assumption of this whole comparison.Refs: #9612 · #9613 · #4716 (comments
5309105113,5309093362) · PR #9825 (merged1408ae337) ·origin/main@66beee0f3(Reading A's ref).