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:
Paul Hitt
2026-08-29 11:07:32 -04:00
co-authored by Claude Opus 4.8
parent cc8f4ca1d0
commit c9e386ec0d
2 changed files with 83 additions and 1 deletions
@@ -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"}""")