Skip to content

Commit 24107c4

Browse files
tedsluisclaude
andcommitted
docs: reconcile TODO.md's proto-extraction item with actual repo state
pbtk-jar-extract's 0-file result against base.apk was still listed as an unstarted "highest-leverage blocker" with a "target specific classes next" suggestion, but that route was already conclusively ruled out and the schemas were already recovered by a different method: - Confirmed pbtk-jar-extract has no class-filter flag, and a manually-built targeted JAR (candidate classes + the one legacy CodedInputStream/ CodedOutputStream-signature pair still present in the APK) still produced 0 files. Read pbtk's own jar_extract.py source to confirm why: its extraction requires a per-class mergeFrom(CodedInputStream) switch structure that this APK's GeneratedMessageLite.newMessageInfo() codegen never emits. Not a scope/targeting issue, and the GUI shares the same extractor module. - The actual schema recovery (qjc/qja/qhr/nqx, cross-correlated against wire captures) had already happened via scripts/decode_rawmessageinfo.py and DECISIONS.md ADR-019 (maintainer sign-off obtained 2026-08-30) - TODO.md just hadn't been updated to reflect it. Repoints the real remaining leverage point at qhr's still-unchecked wire field numbers (11, 15, 17, 19, 22, 27, 28) instead of a dead pbtk retry. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011phbgsPLyXp3JCmisStthy
1 parent e200640 commit 24107c4

1 file changed

Lines changed: 36 additions & 19 deletions

File tree

TODO.md

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,18 @@ nothing here is a second copy of that detail, only a pointer plus the reasoning
3030
3. **Phase 2 (APK reverse engineering) — updated 2026-08-30, no longer 0% done.** APK pulled,
3131
JADX/apktool-decompiled, and multiple `§4` keyword-search/follow-up passes done
3232
(`REVERSE_ENGINEERING.md`'s growing class-entry list, 30+ entries as of the last pass), and
33-
`DECISIONS.md` ADR-018 accepted (DLCI 0x02 channel-ownership → 🟢 FACT). The
34-
**current highest-leverage single next step** is a targeted `pbtk`/pw_rpc-schema extraction
35-
attempt against the specific classes `fux`/`fsz` reference (not the whole APK, which wrote 0
36-
`.proto` files) — this is what `PROTOCOL.md` §2.2a's remaining HYPOTHESIS (does DLCI 0x02's
37-
Sent-payload content specifically carry `libmaestro`'s settings commands) needs to close, and
33+
`DECISIONS.md` ADR-018 accepted (DLCI 0x02 channel-ownership → 🟢 FACT), and `.proto`/pw_rpc
34+
schema recovery — updated 2026-09-03, done via a different route than planned here: `pbtk`
35+
confirmed structurally incapable of this APK's codegen (both the whole-APK and a 2026-09-03
36+
targeted-class re-run wrote 0 `.proto` files; root cause is now source-cited, not just the
37+
tool's own caveat — see the Phase 2 checklist item below). The schemas were instead recovered
38+
by hand (`scripts/decode_rawmessageinfo.py`, `DECISIONS.md` ADR-019) and cross-correlated
39+
against wire captures for `qhr` fields 4, 7, 12, and 29. **Current highest-leverage single next
40+
step** is now applying that same static-analysis method to `qhr`'s remaining
41+
confirmed-but-unchecked field numbers (11, 15, 17, 19, 22, 27, 28 — already listed in this
42+
file's "Targeted research follow-ups" section below) — this is what `PROTOCOL.md` §2.2a's
43+
remaining HYPOTHESIS (does DLCI 0x02's Sent-payload content specifically carry `libmaestro`'s
44+
settings commands, beyond the 4 fields ADR-019 already sampled) needs to close further, and
3845
it's what blocks `ARCHITECTURE.md` §2.1's `FrameEncoder`/`FrameDecoder` gate for every DLCI-0x02
3946
feature. **`CAP-033` (Group AA, `SDP-001`/`SDP-002`) is done (2026-08-30)** — see below.
4047
4. **Remaining planned captures** (updated 2026-08-30 — `CAP-008`, `CAP-009`, `CAP-013`, `CAP-014`,
@@ -256,24 +263,34 @@ lower priority than finishing ANC/Battery/EQ):**
256263
how `ClassicBTReceiver`'s connection-state events lead into `gbm`'s socket selection, and how
257264
`fsz`'s `WriteSetting`/`fux`'s per-service calls obtain their `MethodClient` — flagged as
258265
untraced in `REVERSE_ENGINEERING.md`'s Call graph notes.
259-
- [ ] **Extract real `.proto`/pw_rpc schemas — attempted, not yet successful.** `pbtk-jar-extract`
260-
against `base.apk` completed but wrote 0 `.proto` files (its own `--help` caveat: "works
261-
better with older APKs" — confirmed not a stale-install issue, `WORKSTATION_PREPARATIONS.md`).
262-
The reflection-based heuristic did surface `sun.misc.Unsafe`-based field-access patterns
263-
consistent with protobuf-lite's `GeneratedMessageLite$MessageInfo` schema system during the
264-
run, so the classes exist, just weren't resolved to a complete written schema. **Next attempt
265-
should target specific classes** (the `nqs`/`nqo`/message-type classes referenced in `fux`'s
266-
RPC definitions, e.g. `qib.a`, `nia.a`) rather than the whole APK, or try `pbtk`'s interactive
267-
GUI. This is the current single highest-leverage blocker for `ARCHITECTURE.md` §2.1's
268-
`FrameEncoder`/`FrameDecoder` gate on every DLCI-0x02 feature (`PROTOCOL.md` §2.2a).
266+
- [x] **Extract real `.proto`/pw_rpc schemas — done 2026-08-30/2026-09-03, via manual decode, not
267+
`pbtk`.** `pbtk-jar-extract` against `base.apk` wrote 0 `.proto` files, and a 2026-09-03
268+
follow-up confirmed this isn't a scope/targeting problem: `pbtk-jar-extract` has no
269+
class-filter flag, and a manually-built 32-class targeted JAR (`qjc`/`qja`/`qhr`/`nqx`/`fux`/
270+
`fsz`/etc., plus the one legacy `CodedInputStream`/`CodedOutputStream`-signature class pair
271+
still present elsewhere in the APK) still produced 0 files — confirmed against `pbtk`'s own
272+
`jar_extract.py` source: its extraction requires a per-class `mergeFrom(CodedInputStream)`
273+
`switch`-structure in the generated class's own bytecode, which this APK's
274+
`GeneratedMessageLite.newMessageInfo(default, infoString, objects)` reflection-based codegen
275+
never emits, for any class. `pbtk`'s GUI shares the same extractor module, so it is not
276+
expected to differ. **Solved instead via `scripts/decode_rawmessageinfo.py`** (a
277+
dependency-free `RawMessageInfo` compact-schema-string decoder, ported field-for-field from
278+
the public `protobuf` runtime source): `qjc`/`qja` (5-alternative oneof), `qhr` (38 fields,
279+
all field-type/reference info recovered), and `nqx` (`pw_rpc.RpcPacket`, 7 fields) all
280+
decoded and cross-correlated against real wire bytes (`CAP-020` frames 1741/1935). See
281+
`DECISIONS.md` ADR-019 (maintainer sign-off obtained) for the accepted findings. **Not fully
282+
closed:** only `qhr` fields 4, 7, 12 (field-number only), and 29 have been wire-cross-checked
283+
so far — fields 11, 15, 17, 19, 22, 27, 28 are confirmed on the wire but not yet run through
284+
this same method (tracked in this file's "Targeted research follow-ups" section).
269285
- [x] **DLCI 0x02 channel-ownership question — resolved 2026-08-30 (narrow promotion).**
270286
`DECISIONS.md` ADR-018 (Option 2, maintainer-approved): DLCI 0x02 confirmed 🟢 FACT as the
271287
companion app's own internal RFCOMM channel (SDP UUID `25e97ff7-...` = RFCOMM channel 1 =
272288
DLCI 0x02, cross-checked against `CAP-001`/`CAP-002`/`CAP-032`), via the app's own
273-
`gbm.java`/`fzd.java` selection logic — see `PROTOCOL.md` §2.2a. **Not resolved:** whether the
274-
Sent-direction payload *content* specifically carries `libmaestro`'s settings commands —
275-
still 🟡 HYPOTHESIS (strong), which is what the unstarted `.proto` extraction above would
276-
settle.
289+
`gbm.java`/`fzd.java` selection logic — see `PROTOCOL.md` §2.2a. **Not fully resolved:**
290+
whether the Sent-direction payload *content* specifically carries `libmaestro`'s settings
291+
commands, in general — still 🟡 HYPOTHESIS (strong) per `DECISIONS.md` ADR-019's own scope
292+
note, though now substantially strengthened for the 4 `qhr` fields ADR-019 sampled. Settling
293+
it further means running more fields through the manual-decode item above, not `pbtk`.
277294
- [x] **`CAP-033` (Group AA) — done 2026-08-30.** Tested whether the second, never-observed-on-the-wire
278295
"default internal rfcomm socket" SDP UUID (`gbm`/`fzd`) ever appears when SDP is queried by the
279296
OS's own pairing flow before the companion app opens (`SDP-001`); `SDP-002` not attempted (no

0 commit comments

Comments
 (0)