Skip to content

Commit 425ff94

Browse files
tedsluisclaude
andcommitted
re: re-decode existing captures against recovered qhr schema; promote 4 fields to FACT (ADR-019)
Tier 0 re-decoded CAP-020/CAP-021 frames against the WriteSetting schema (qhr) recovered by a same-day APK static-analysis pass, confirming the DLCI 0x02 field5{field4{...}} wrapper's inner content is qhr's own protobuf oneof (byte-verified for fields 4 and 29), and that qhr fields 7/12 match CAP-021's HOLD-* frames exactly (with a corrected qik->qho nesting level). Also verified DLCI 0x08's length field is empirically big-endian across CAP-001/CAP-004, and correlated qjw's field-16/18 "live"/"persisted" code reading against CAP-005/ CAP-015's wire sequences. Tier 2 traced qjc/qja's remaining oneof groups (qhx/qjn/qjt/qjv), resolving most fields by name and finding that qhx/qjn/qjt are very likely a different Buds product's settings schema (three DI-separated, near-disjoint fya implementations), not additional Buds Pro 2 categories; qjv confirmed fully unused in this app version. The maintainer reviewed 4 candidate promotions individually and approved all four (one narrowed to field-number identity only) — recorded in DECISIONS.md ADR-019 per AGENTS.md §6, with PROTOCOL.md/REVERSE_ENGINEERING.md updated and cross-referenced accordingly. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KyjDhdgSZAn46iBvZr7jph
1 parent 228be4e commit 425ff94

11 files changed

Lines changed: 767 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,23 @@ for the "definition of done" that will mark v1.
321321
`CAP-NNN-FINDINGS.md` files use). `TODO.md`'s Phase 2 checklist updated to reflect this groundwork
322322
without checking off any actual analysis work, since no APK has been pulled yet.
323323

324+
- **2026-08-30: Tier 0 (existing-capture re-decode) + Tier 2 (`qjc`/`qja`'s remaining oneof groups)
325+
static-analysis session, then four pending FACT promotions reviewed and approved by the maintainer
326+
per-point** (`AGENTS.md` §6), recorded in `DECISIONS.md` ADR-019: **§2.2a** — DLCI 0x02's
327+
`field5{field4{...}}` wrapper's "..." confirmed 🟢 FACT to be `libmaestro`'s own recovered
328+
`WriteSetting` schema (`qhr`), byte-decoded for 2 sampled fields (4, 29) against `CAP-020`. **§4.5.3**
329+
— the top-level "Use touch controls" toggle (`field 4`) and the press-and-hold action-selection
330+
opcode (`field 7`/`qju`, with a corrected `qik``qho` nesting level) promoted to 🟢 FACT in full,
331+
each backed by both wire+video correlation and a self-describing app-code log message. The
332+
ANC-mode-rotation-checklist opcode's field number (`field 12`/`qht`) promoted to 🟢 FACT; its
333+
equivalence to the app's own "ANC gesture loop" name explicitly declined by the maintainer, staying
334+
🟡 HYPOTHESIS. Separately (Tier 2, not promoted, static-analysis-only): found that `qjc`/`qja`'s
335+
other 4 oneof groups (`qhx`/`qjn`/`qjt`/`qjv`) are very likely an **alternate product's** settings
336+
schema, not additional Buds Pro 2 categories — the app's `fya` settings-write interface has 3
337+
disjoint, DI-separated implementations, one per product variant, and `qjn`'s own internal codename
338+
(found in a log string) is literally "presto." `qjv` confirmed fully unused in this app version
339+
(zero construction sites anywhere in the decompiled tree).
340+
324341
### Removed
325342

326343
- `PROTOCOL_NOTES.md`, `EXPERIMENTS.md` (retired 2026-08-15, see above).

DECISIONS.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,5 +840,86 @@ motivated this).
840840
Neither DLCI 0x08's still-🔴 open identity question nor the "default internal rfcomm socket"
841841
UUID's unexplained absence from every capture searched so far is affected by this decision.
842842

843+
## ADR-019 — `qhr`'s oneof structure confirmed inside DLCI 0x02's `field5{field4{...}}` wrapper (2 sampled fields); `qhr` fields 4 and 7 promoted to FACT; `qhr` field 12's field-number identity (not its name) promoted to FACT
844+
845+
- **Date**: 2026-08-30
846+
- **Status**: Accepted
847+
- **Context**: a 2026-08-30 session combined (a) a Tier 0 re-decode of existing captures against a
848+
same-day APK static-analysis pass that recovered `libmaestro`'s real `WriteSetting` request schema
849+
(`REVERSE_ENGINEERING.md`'s `qjc`/`qja`/`qhr`/`qjo`/`qju`/`qjg`/`qht` entries), and (b) a Tier 2
850+
static-analysis pass tracing `qhr`'s remaining write/read call sites. `ADR-013` had promoted only
851+
DLCI 0x02's *outer* `field5{field4{...}}` wrapper shape to FACT, explicitly leaving the "..." itself
852+
undecoded; `ADR-018` (Option 2) separately promoted the *channel*'s ownership to FACT while leaving
853+
its payload *content* at 🟡 HYPOTHESIS (strong). This session's findings were presented to the
854+
maintainer as four discrete candidate promotions (session of 2026-08-30); the maintainer reviewed
855+
each individually and approved all four, three as proposed and the fourth in its narrower form
856+
(field-number identity only, not the semantic name), per `AGENTS.md` §6's requirement that an agent
857+
may propose but never unilaterally commit a FACT promotion.
858+
- **Findings being recorded**:
859+
1. **DLCI 0x02's `field5{field4{...}}` wrapper's inner content, for the two fields sampled, is
860+
`qhr`'s own protobuf oneof, addressed via standard wire-format tags — not merely "plausible" per
861+
`ADR-013`'s own note.** Two existing `CAP-020` Sent frames already identified as
862+
`field5{field4{...}}` (`CAP-020-FINDINGS.md` §3/§4, frames 1741/1935 — `TOUCH-001`/`HEAD-001`)
863+
were re-pulled directly from the raw log, HDLC-unescaped/CRC-verified, and decomposed one level
864+
further than that file's own original decode. Frame 1741's inner bytes decode to `qhr` field
865+
**4**, value `1`; frame 1935's to `qhr` field **29**, value `2` — an exact, byte-for-byte match to
866+
the independently-derived (APK code, not wire) `qhr` schema, on both sampled fields, no
867+
counter-example. This is two independent evidence paths (real wire bytes vs. compiled app code)
868+
converging on the same structure, not one path repeated.
869+
2. **`qhr` field 4 = the "Use touch controls" master enable toggle** (`PROTOCOL.md` §4.5.3's
870+
top-level toggle). Evidence: `CAP-020` frame 1741 (wire+video correlation, `TOUCH-001`, already
871+
🟡 HYPOTHESIS) **and**, independently, the app's own code — write site `fyo.java:124-144`, read
872+
site `fxb.java` case 4 logging `"Log Gestures Enable setting"` (self-describing, not a naming
873+
inference).
874+
3. **`qhr` field 7 = `qju` = the Left/Right press-and-hold gesture-*action* customization**
875+
(ANC / Digital assistant / None), matching `PROTOCOL.md` §4.5.3's already-strong press-and-hold
876+
HYPOTHESIS. Evidence: `CAP-021` frames 1895/3619/4315/4976 (`HOLD-001``HOLD-004`, all 4 of the
877+
2×2 Left/Right × ANC/Assistant combinations, wire+video correlated) **and**, independently, the
878+
app's own code — write site `fyo.java:300-374` (`t(gdx)`), read site `fxb.java` case 7 logging
879+
**`"Log Gestures Customization for touch and hold setting, left: %s, right: %s"`** — a literally
880+
self-describing match, not an inference from shape or position. Re-decoding the 4 wire frames
881+
also surfaced a nesting level finer than `CAP-021-FINDINGS.md`'s original notation: the value
882+
sits inside a `qju.field{1|2}``qik``qho` chain, not a bare varint directly under
883+
`field1`/`field2` — recorded as a correction to that file's own decode, not a new claim.
884+
4. **`qhr` field 12 = `qht` — the field-*number* identity only.** Evidence: `CAP-021` frames
885+
5237/5247/5255 (`HOLD-005`) decode to `qhr` field 12 with exactly 4 boolean sub-fields, matching
886+
`qht`'s independently-confirmed shape (APK code: `qhr`'s field-12 alternative, write site
887+
`hgj.java:216-331`, read site `fxb.java` case 12 logging `"Log ANC gesture loop to Clearcut"`).
888+
**Not promoted**: whether the app's own internal name for this field, "ANC gesture loop," is the
889+
*same* UI feature as `PROTOCOL.md` §4.5.3's existing "ANC-mode rotation checklist" (`HOLD-005`)
890+
HYPOTHESIS — the two could describe the same setting seen from two angles, or two different
891+
settings that happen to share a 4-boolean shape; this has not been reconciled, and the maintainer
892+
explicitly declined to promote that equivalence at this time.
893+
- **What this ADR does NOT clear**:
894+
- The nesting-structure finding (1) is sampled on exactly 2 fields (4 and 29) in one capture
895+
session — it establishes that the "..." *is* `qhr`'s oneof for those two instances, not that every
896+
one of `qhr`'s 38 fields has been wire-confirmed to decode this way. It does not by itself resolve
897+
`ADR-018`'s own remaining HYPOTHESIS (that DLCI 0x02's Sent-direction content specifically carries
898+
`libmaestro`'s settings-write commands in general) — it substantially strengthens that HYPOTHESIS
899+
for the specific fields tested, but `ADR-018`'s broader claim is not re-litigated or promoted by
900+
this entry.
901+
- Finding (2)'s field 4 is one-direction (OFF→ON) only, one session.
902+
- Finding (3)'s 4/4 combination coverage is strong, but still one capture session for the wire half;
903+
the code half (the self-describing log message) is a separate, independent confirmation type, not
904+
a second capture.
905+
- Finding (4) explicitly does **not** promote `qht`'s app-internal name or its equivalence to the
906+
rotation-checklist HYPOTHESIS — only that wire field 12 = code's `qht` (a field-number/shape match).
907+
- `qhr` field 29 (Head gestures, `PROTOCOL.md` §4.5.4) was also re-confirmed at the wire level this
908+
session (frame 1935) but is **not** part of this ADR — no self-describing code-side name was found
909+
for field 29 (its write call site was not located by the static pass), so only one evidence path
910+
exists for it; it remains 🟡 HYPOTHESIS, unchanged.
911+
- **Decision**: findings 1, 2, and 3 above are accepted as 🟢 FACT in full. Finding 4 is accepted as
912+
🟢 FACT for the field-number identity (`qhr` field 12 = `qht`) only; the "ANC gesture loop" /
913+
"ANC-mode rotation checklist" naming equivalence remains 🟡 HYPOTHESIS.
914+
- **Consequences**: `PROTOCOL.md` §4.5.3 updated — the top-level toggle and press-and-hold-action
915+
opcodes move from 🟡 HYPOTHESIS to 🟢 FACT; the rotation-checklist opcode gains a FACT-confirmed
916+
field number but keeps its HYPOTHESIS status for what the field represents. `PROTOCOL.md` §2.2a/§2.3
917+
and §6's "what do DLCI 0x02's confirmed inner field numbers actually represent" open item are
918+
updated to record that, for the 3 fields tested, the answer is "real `qhr` protobuf field numbers
919+
from the app's own recovered schema," narrowing (not fully closing, per the scope note above) that
920+
question. Does not unblock `ARCHITECTURE.md` §2.1's `FrameEncoder`/`FrameDecoder` implementation gate
921+
for DLCI 0x02 generally — that still requires the broader payload-content HYPOTHESIS in `ADR-018` to
922+
reach FACT, which this ADR narrows but does not itself complete.
923+
843924
---
844925
https://github.com/tedsluis/opencontrolpixelbudspro2/blob/main/DECISIONS.md - https://tedsluis.github.io/opencontrolpixelbudspro2/DECISIONS

0 commit comments

Comments
 (0)