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
Measured while implementing #13241 (PR #13619), raised by the dev as an open question and filed by the domain:cli PM seat. Unlabelled for triage. Pre-existing — this divergence predates #13241 and is not caused by it.
The divergence
userMessage is the author-facing text channel (#9934). The boundaries that carry it do not agree on whether it is bounded:
boundary
bound
/data (packages/rest/src/error-response.ts)
bounded — via boundedDeclaredUserMessage, applying truncateClientMessage (#5423's bound)
verbatim, unbounded (as of #13241 / PR #13619, matching its sibling)
Why the standing meta-criterion does not settle it
The lane's default for one operation, two implementations, inconsistent behaviour is the aligned side wins. ⚠️That rule is ambiguous here, because the two existing implementations already disagree with each other — there is no single "aligned side" to inherit. Whichever way it is ruled, one of the three doors changes.
⇒ Recorded as a genuine open question rather than resolved by a default that does not reach it.
PR #13619 chose to match its closest sibling (errorFromThrown: same package, same ADR-0112 nested envelope, same resolver input, byte-identical expression). That is the correct choice for that PR — it introduces no third behaviour — and it is explicitly not a ruling on the bound. Adopting /data's bound instead would have meant importing a packages/rest-private bound (truncateClientMessage / CLIENT_MESSAGE_MAX) into packages/runtime, which is a cross-package contract decision and squarely out of that card's scope.
The options
Bound everywhere — promote the bound to the shared layer (declaredUserMessage / resolveThrownHttpError, where the "one rule, every door inherits" property already lives), so no door decides it. Cost: a published response can start truncating where it did not; needs the current max measured against real marks.
Leave it per-boundary and document it. Cost: makes "how long may a mark be?" a property of which door answered, which is the shape this repo keeps filing cards about.
⚠️The missing input is the same in all three: nobody has measured what the bound actually is, whether any real mark approaches it, or what /data does when it truncates (silent? ellipsis?). ⛔ Ruling before that is guessing.
Why it is worth a card rather than a note
The mark is text an author wrote for an end user. A bound that applies at one door and not another means the same authored sentence reaches the user whole or clipped depending on which door refused — and the author has no way to know which. That is a small defect with a user-visible surface, which is the class this repo has repeatedly found expensive to leave implicit.
Measured while implementing #13241 (PR #13619), raised by the dev as an open question and filed by the
domain:cliPM seat. Unlabelled for triage. Pre-existing — this divergence predates #13241 and is not caused by it.The divergence
userMessageis the author-facing text channel (#9934). The boundaries that carry it do not agree on whether it is bounded:/data(packages/rest/src/error-response.ts)boundedDeclaredUserMessage, applyingtruncateClientMessage(#5423's bound)errorFromThrown(packages/runtime/src/http-dispatcher.ts)errorResponseBase(packages/runtime/src/dispatcher-plugin.ts)Why the standing meta-criterion does not settle it
The lane's default for one operation, two implementations, inconsistent behaviour is the aligned side wins.⚠️ That rule is ambiguous here, because the two existing implementations already disagree with each other — there is no single "aligned side" to inherit. Whichever way it is ruled, one of the three doors changes.
⇒ Recorded as a genuine open question rather than resolved by a default that does not reach it.
What #13241 did, and why that is not the answer
PR #13619 chose to match its closest sibling (
errorFromThrown: same package, same ADR-0112 nested envelope, same resolver input, byte-identical expression). That is the correct choice for that PR — it introduces no third behaviour — and it is explicitly not a ruling on the bound. Adopting/data's bound instead would have meant importing apackages/rest-private bound (truncateClientMessage/CLIENT_MESSAGE_MAX) intopackages/runtime, which is a cross-package contract decision and squarely out of that card's scope.The options
declaredUserMessage/resolveThrownHttpError, where the "one rule, every door inherits" property already lives), so no door decides it. Cost: a published response can start truncating where it did not; needs the current max measured against real marks./data's bound. Cost: removes a deliberate guard; rest-server 的 4xx 直通把 ≥500 字符的 message 整条换成 "Request failed" —— #5368 刚写好的过滤器拒收措辞,客户端一个字也收不到(实测) #5423 introduced that bound for a reason that should be re-read before it is undone./datadoes when it truncates (silent? ellipsis?). ⛔ Ruling before that is guessing.Why it is worth a card rather than a note
The mark is text an author wrote for an end user. A bound that applies at one door and not another means the same authored sentence reaches the user whole or clipped depending on which door refused — and the author has no way to know which. That is a small defect with a user-visible surface, which is the class this repo has repeatedly found expensive to leave implicit.
Refs
errorResponseBasenever surfacesuserMessage, so the dispatcher exit has no author-facing text channel — the one the 5xx prose withhold assumes as its compensation #13241 / PR fix(runtime): carry the producer'suserMessageto the wire at the dispatcher's throw-transparent exit #13619 — where this was measured; chose sibling-alignment deliberately and flagged this rather than deciding it./dataapplies.declaredCodechannel in scope for 5xx sanitisation at all — and the answer must be applied to all three doors at once #12509 — the "one rule, every door inherits" direction for the code channel, which is the shape option 1 would extend to this one.