Commit Graph
10 Commits
Author SHA1 Message Date
Paul HittandClaude Opus 5.5 e001fa9d42 Read and write cards, events and RSVPs in the content codec
DESIGN 1b and 3 add three kinds: card and event are renderable and carry
mid like a text; rsvp is control traffic and never a bubble, with or
without its ctl. Each is built by hand with its keys in the order both
apps agreed, and strings go through a new WireJson.quote that writes
what Swift's JSONEncoder writes with slashes left alone. The framework
org.json escapes every slash and the JVM copy does not, so the existing
quote could not give one set of bytes.

Decoding follows the iPhone: a card object is read leniently, an event
needs an id, a rev of at least 1, a title and a time, and anything
unusable falls through to the unsupported placeholder. Flags are read as
numbers or booleans, whole numbers may carry a fraction, and render
bounds and the sealed-until rule (capped at 400 days from arrival) live
on the types so they can be tested here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 22:28:31 -04:00
Paul HittandClaude Opus 5.5 41dbfeb19d Point links at the extant2000 GitLab group
The messenger repositories move from gitlab.com/paulhitt to
gitlab.com/extant2000. Old web and git URLs redirect; the relay's container
image path does not, so docker-compose.yml names the new registry path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 14:38:57 -04:00
Paul HittandClaude Opus 5.5 d53f6a81bb Merge branch 'fix/echo-peer-survives-errors' into 'main'
The echo peer outlives a failed call instead of exiting

See merge request paulhitt/flamenet-messenger-android!157

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:14:57 -04:00
Paul HittandClaude Opus 5.5 df56cf2e6e The echo peer outlives a failed call instead of exiting
Peer's autoreply loop had no catch, so one failed poll or send to the relay
ended the process. The on-device reply case then waited out its 90 seconds
for an echo from a peer that was gone, which fits the one missed echo seen
in five full runs on 2026-09-28 (its log was lost, so not proven).

Each poll and each echo is now caught, logged to stderr with a timestamp
("poll failed, still answering: ..."), and the loop carries on. The
closing JSON adds an `errors` count. instrumented.sh already prints the
echo peer's log when a run fails, so a recurrence will say why.

Checked against a relay address that refuses connections: the old peer
exits 1 on the first poll with no result; the new one runs its full 8 s,
logs 4 failed polls and prints {"echoed":0,"errors":4}. Against relay1: 0
errors. Full on-device suite with the new peer: 10 of 10.

Harness only: interop/ is not shipped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:11:30 -04:00
Paul HittandClaude Opus 5.5 fdee288111 Merge branch 'fix/await-the-email-field' into 'main'
On-device suite green: sign-up tap, fresh peers, group id, and the chat scroll crash

See merge request paulhitt/flamenet-messenger-android!155

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 09:16:48 -04:00
Paul HittandClaude Opus 5.5 d33bb338de Scroll the chat by request, not by forcing a layout
The chat keeps its newest message in view when it opens and while the
keyboard slides, and both did it with `listState.scrollToItem`, which forces
a layout on the spot. This screen is composed inside the Scaffold's measure
pass, so when the effect ran straight away it asked for a layout in the
middle of one:

  IllegalArgumentException: performMeasureAndLayout called during measure layout
    at LayoutNode.forceRemeasure
    at LazyListState.snapToItemIndexInternal
    at ChatScreens.kt:1740 (the keyboard follow)
    ... LaunchedEffectImpl.onRemembered ... SubcomposeLayout ... Scaffold

It failed ChatFlowTest's send in every full on-device run since 2026-09-18.
The frames that ran the effect inline are the Compose test dispatcher's; the
shipped app posts effects to the next frame, so this has not been seen to
crash a real device. Forcing a synchronous layout from an effect is wrong
either way.

Both now use `requestScrollToItem` (foundation 1.7.6), which the next layout
applies, and the keyboard is what brings that layout. Still instant, still
not animated. The animated follow for new messages is unchanged: it waits
for animation frames before it moves.

TheKeyboardDoesNotHideTheMessagesTest read the source for
`listState.scrollToItem(`; it now requires `requestScrollToItem(` and refuses
`scrollToItem(` in the keyboard effect. Put the old line back and it fails.

Result on relay1: the full on-device suite passes, 10 of 10, and the crash
buffer has no performMeasureAndLayout. App unit tests: 358 debug, 323
release, all green.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 08:13:25 -04:00
Paul HittandClaude Opus 5.5 a44624cfad Find the new group by its hex id, not by a number
aGroupIsCreatedAndListed waited for a row matching `group-\d+`. The relay
mints group ids with randomHexToken(), so the tag is `group-` plus 64 hex
characters, and the pattern only matched when the id happened to start
with a digit: ten times in sixteen. The rest of the time the test failed
with "the group never appeared in the list after Create" while the dump
showed the group in the list ("Test Crew, peer96035270, You", tag
group-eea4ceeb...).

Now `group-[0-9a-f]{16,}`, which matches that tag and still not
`group-name` or `group-member-N`. Checked both patterns against the tag
from the failing run: old no match, new match. On device: passes.

The keyboard was ruled out first: with it fully open (top at y=1517) the
member row and Create sat at y=1201-1377, above it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 07:52:51 -04:00
Paul HittandClaude Opus 5.5 cd5d1d8f44 A fresh peer for each on-device run, not peerjvmone
The suites added `peerjvmone`, one standing account on relay1 whose only
device came online when somebody ran the interop peer by hand. Nobody did.
On relay1 it had no one-time prekeys left, classical or PQ, and 114
messages it would never collect, and every run added more strangers to it.
Adding it and delivering to it failed in some runs and not others.

scripts/instrumented.sh now creates two accounts with the interop peer
before the run and passes them as `contactPeer` and `echoPeer`: one for the
add-and-send cases, one running `autoreply` for the reply case alone, since
an autoreply peer answers the first new account that writes to it. The
peer runs from `:interop:installDist` with plain java, not a second Gradle
build, and the exit trap stops it and waits for it.

The suites no longer fall back to peerjvmone; without the arguments they
say to use the script. The reply case now fails when no echo arrives
instead of logging a warning and passing. FeatureUseTest waited for the
confirm button, which is on screen but disabled until the lookup resolves,
so it tapped a disabled button; it now waits for the lookup result like
the other two suites.

On relay1: 8 of 10. The reply round trip passes. Still red: the group case
("the group never appeared in the list after Create", not yet diagnosed)
and ChatFlowTest's send, which crashes in the app with "performMeasureAndLayout
called during measure layout" at ChatScreens.kt:1740, the keyboard-follow
scroll recorded on 2026-09-18.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 07:36:15 -04:00
Paul HittandClaude Opus 5.5 332d3803e9 Version 0.31, build 31
One change since 0.30, android!154: the unsealed-send and changed-address
notices. versionCode and versionName move together, as the comment above
them requires.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 07:14:56 -04:00
Paul HittandClaude Opus 5.5 32a258bc1f Tap "Create an account" before the relay is typed, not after
The on-device sign-up helpers typed the relay and then tapped the
toggle-register button. Typing raises the keyboard, which slides in after
performScrollTo has measured the screen, so the tap landed on the keyboard
and the form stayed on sign-in. The failure read as a missing email field,
and was taken for a race with the relay probe.

Logged on the emulator: after the scroll the toggle sat at y=1878 while the
content ended at y=1517, the top of the keyboard. Every failure dump already
said "This server keeps its own accounts.", so the probe had answered.

Now the toggle is tapped first, while nothing is moving, and the email field
is waited for because the probe decides whether this relay asks for one.
Same change in FeatureUse, CrudSurface, ChatFlow, CrossPlatform and
LiveSignUpFleet. On relay1, every sign-up in the suite now gets through;
the remaining red is the shared peerjvmone fixture, not sign-up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 20:03:54 -04:00