Skip to content

Filter every OpenTagViewer escrow record, not just this session's - #224

Merged
parawanderer merged 1 commit into
mainfrom
fix/filter-our-own-escrow-records
Sep 16, 2026
Merged

parawanderer merged 1 commit into
mainfrom
fix/filter-our-own-escrow-records

Conversation

@parawanderer

Copy link
Copy Markdown
Owner

Joining the trust circle writes an escrow record beside the user's real hardware, and the recovery picker then asks for "the screen-lock passcode of one of your Apple devices" about a program that has no screen. There is no answer — that passcode was generated, never shown, and was never the user's to know.

The app already dropped one such record. It dropped exactly one.

The filter compared each record against the serial the current session presents, which was correct only while every install presented the same constant. Serials are drawn per install now (rule 11), so the equality test hides this install's record and leaves every other one of ours on the list: the record from before a reinstall, the desktop exporter's, and one more for every trust-circle join. All equally unusable, and there are more of them than there was of the one being filtered.

The change

The match moves to the prefix, which is the stable part by design — SERIAL_PREFIX exists precisely so an entry is identifiable as ours. Both legacy constants fall out for free, since 0PENTAGVIEWR and 0PENTAGXPORT begin with their own prefixes.

written_by_opentagviewer lives in exporter/identity.py because that module is one of the handful shipped into the APK by name, so it is the one place the app bridge and the desktop exporter can share a decision rather than keeping two that drift.

The exporter had no filter at all before this. Its wizard and CLI now use the same one, applied before the "nothing to recover from" check so that message stays true for an account holding only our records.

Tests

Both directions, because they fail in opposite ways: too lax leaves unusable tiles, too eager hides a real Mac and presents as "the app cannot see my device". A record with no serial is kept rather than guessed at — the escrow schema is unstable enough that the field is genuinely sometimes absent.

The duplicated prefix literal is pinned against AdiDeviceIdentity.SERIAL_PREFIX on a device, since a copy nothing compares is a copy that drifts silently, and the symptom would only ever appear on an account nobody testing has.

Verified the key test fails against the old equality check. 303 bridge tests and 675 exporter tests pass; flake8 clean.

Not verified here: no Android toolchain on this machine, so the new instrumented assertion is CI's word, not mine.

🤖 Generated with Claude Code

Joining the trust circle writes an escrow record beside the user's real
hardware, and the recovery picker then asks for "the screen-lock passcode of
one of your Apple devices" about a program that has no screen. There is no
answer: that passcode was generated, never shown, and was never the user's
to know. The app already dropped one such record.

It dropped exactly one. The filter compared each record against the serial
the current session presents, which was correct only while every install
presented the same constant. Serials are drawn per install now, so the
equality test hides this install's record and leaves every other one of ours
on the list: the record from before a reinstall, the desktop exporter's, and
one more for every trust-circle join. All equally unusable, and there are
more of them than there was of the one being filtered.

So the match moves to the prefix, which is the part that is stable by
design - SERIAL_PREFIX exists precisely so an entry is identifiable as ours.
Both legacy constants fall out for free, since 0PENTAGVIEWR and
0PENTAGXPORT begin with their own prefixes.

written_by_opentagviewer lives in exporter/identity.py because that module is
one of the handful shipped into the APK, so it is the one place the app
bridge and the desktop exporter can share a decision rather than keeping two
that drift. The exporter had no filter at all before this; its wizard and CLI
now use the same one, applied before the "nothing to recover from" check so
that message stays true for an account holding only our records.

Tests both directions, because they fail in opposite ways: too lax leaves
unusable tiles, too eager hides a real Mac and presents as "the app cannot
see my device". A record with no serial is kept rather than guessed at - the
escrow schema is unstable enough that the field is genuinely sometimes
absent. The duplicated prefix literal is pinned against Java on a device,
since a copy nothing compares is a copy that drifts silently.

Verified the key test fails against the old equality check.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@parawanderer
parawanderer merged commit 9ab07f0 into main Sep 16, 2026
9 checks passed
@parawanderer
parawanderer deleted the fix/filter-our-own-escrow-records branch September 17, 2026 18:54

This branch was successfully deployed

1 active deployment
Android Build — f6391827 Deployed Sep 16, 2026 by parawanderer via build #280
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant