Consume control kinds this build has never heard of (§6.10)
`isRenderable` asked `kind !in Kind.CONTROL` — an allowlist of the four control kinds that existed when it was written. A control kind from a newer peer is in no set here, so it fell through and rendered as an "[unsupported attachment]" bubble: a message the user can neither read nor act on, for something addressed to a layer rather than a person. Every control kind added from here would have shipped that to every older install. `ctl: 1` is the flag that stops it; `isControl` trusts the flag as well as the list, since the four that predate it do not carry it and never will. ⚠️ `needsNewerClient` is deliberately NOT part of `isRenderable`. Unknown *content* already parses to a placeholder and is shown, which is right — the first cut of this change suppressed it and an existing test caught that immediately. Dropping a real message silently is the one failure a messenger cannot make, so the flag decides rather than the unknown-ness. engine 144, client 90, app 32. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
cc8f4ca1d0
commit
c9e386ec0d
@@ -137,6 +137,47 @@ class ContentTest {
|
||||
assertEquals("to everyone", parsed.text)
|
||||
}
|
||||
|
||||
/**
|
||||
* 🔴 Forward compatibility for control traffic.
|
||||
*
|
||||
* Control messages ride the same channel as chat and are recognised by
|
||||
* NAME — an allowlist of kinds this build knows. A control kind from a
|
||||
* newer peer is in no such set, so it fell through and became a
|
||||
* `[unsupported attachment]` bubble: a message the user can neither read
|
||||
* nor act on, for something never meant for them to see.
|
||||
*
|
||||
* `ctl: 1` is what lets every kind added from here on stay quiet.
|
||||
*/
|
||||
@Test
|
||||
fun `a flagged unknown control kind is consumed, not rendered`() {
|
||||
val parsed = Content.parse("""{"fnc":1,"kind":"something-new","ctl":true}""")
|
||||
assertTrue(parsed.isControl, "a ctl-flagged envelope is control traffic")
|
||||
assertFalse(parsed.isRenderable, "and must never reach the thread")
|
||||
}
|
||||
|
||||
/**
|
||||
* ⚠️ The opposite has to stay true. Unknown *content* is still shown, with
|
||||
* a placeholder — silently dropping a real message is the one failure a
|
||||
* messenger cannot make, so the flag is what decides, not the unknown-ness.
|
||||
*/
|
||||
@Test
|
||||
fun `an unknown kind without the flag is still shown`() {
|
||||
val parsed = Content.parse("""{"fnc":1,"kind":"hologram"}""")
|
||||
assertTrue(parsed.needsNewerClient)
|
||||
assertFalse(parsed.isControl)
|
||||
assertTrue(parsed.isRenderable)
|
||||
}
|
||||
|
||||
/** Kinds that predate the flag keep working without carrying it. */
|
||||
@Test
|
||||
fun `known control kinds are still control without the flag`() {
|
||||
for (kind in listOf("delivery_key", "kt_head", "sent", "avatar")) {
|
||||
val parsed = Content.parse("""{"fnc":1,"kind":"$kind"}""")
|
||||
assertTrue(parsed.isControl, "$kind must stay control traffic")
|
||||
assertFalse(parsed.isRenderable, "$kind must not render")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `an unknown attachment kind shows a label rather than disappearing`() {
|
||||
val parsed = Content.parse("""{"fnc":1,"kind":"hologram"}""")
|
||||
|
||||
Reference in New Issue
Block a user