Skip to content

Latest commit

 

History

History
343 lines (282 loc) · 15.2 KB

File metadata and controls

343 lines (282 loc) · 15.2 KB

Prepare Fedora 44 workstation

Here we keep track of the tools needed for this project.

packages

# Development tools group install
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ sudo dnf group install -y "Development Tools" "C Development Tools and Libraries" || true

# CLI-tools install
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ sudo dnf install -y \
  git git-lfs gh \
  curl wget \
  jq ripgrep fd-find tree htop tmux \
  unzip zip p7zip \
  gnome-terminal \
  make cmake gcc gcc-c++ \
  dnf-plugins-core

NPM and Node

# Install packages
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ sudo dnf install nodejs npm

# Install NPM latest
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ sudo npm install -g npm@latest
added 1 package in 4s
15 packages are looking for funding
  run npm fund for details

# Get NMP installation path
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ npm config get prefix 
/usr/local
# Fix permissions to install NPM Gobal without sudo
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ sudo chown -R $(whoami):$(whoami) /usr/local/lib/node_modules /usr/local/bin /usr/local/share

# Permit Global installs
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ npm config set allow-scripts=@anthropic-ai/claude-code,@github/keytar,node-pty --location=user

Install Claude-code

# Install Claude Code
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ npm install -g @anthropic-ai/claude-code

added 5 packages, removed 36 packages, and changed 4 packages in 11s
npm warn install-scripts 3 packages had install scripts blocked because they are not covered by allowScripts:
npm warn install-scripts   @anthropic-ai/claude-code@2.1.224 (postinstall: node install.cjs)
npm warn install-scripts   @github/keytar@7.10.6 (install: node script/install.js || npm run build)
npm warn install-scripts   node-pty@1.0.0 (install: node-gyp rebuild; postinstall: node scripts/post-install.js)
npm warn install-scripts
changed 9 packages in 12s

# Check Claude Code
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ hash -r
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ claude --version
2.1.224 (Claude Code)

Install Antigravity

# Add Antigravity repo
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] sudo tee /etc/yum.repos.d/antigravity.repo << EOL
[antigravity-rpm]
name=Antigravity RPM Repository
baseurl=https://us-central1-yum.pkg.dev/projects/antigravity-auto-updater-dev/antigravity-rpm
enabled=1
gpgcheck=0
EOL

# Update the package cache
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] sudo dnf makecache

# Install the package
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] sudo dnf install antigravity -y

antigravity --version
1.107.0
15487b3041e65228cae24980a3f796c905ef582c
x64

Install Java 21 OpenJDK

fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ sudo dnf install -y java-21-openjdk java-21-openjdk-devel
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ sudo alternatives --config java || true
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ echo 'export JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java))))' >> "$HOME/.bashrc"
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ java --version
openjdk 21.0.4 2024-07-16 LTS
OpenJDK Runtime Environment Temurin-21.0.4+7 (build 21.0.4+7-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.4+7 (build 21.0.4+7-LTS, mixed mode, sharing)

Python

$ python --version
Python 3.14.6

Git settings

fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ git config --global init.defaultBranch main
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ git config --global pull.rebase false
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ git config --global core.editor "code --wait"

Install VSCode extentions

VSCODE_EXTENSIONS=(
  redhat.vscode-yaml
  esbenp.prettier-vscode
  DavidAnson.vscode-markdownlint
  ms-vscode.cpptools
  vscjava.vscode-java-pack
  fwcd.kotlin
  eamodio.gitlens
  ms-python.python
  ms-python.vscode-pylance
  redhat.vscode-xml
)
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ for ext in "${VSCODE_EXTENSIONS[@]}"; do
  code-insiders --install-extension "$ext" || warn "Can not install extention $ext"
done

Install Wireshark

fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ sudo dnf install -y wireshark wireshark-cli
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ sudo groupadd -f wireshark
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ sudo usermod -aG wireshark,dialout "$USER"

Install Android SDK / adb / logcat

# Android tools
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ sudo dnf install -y android-tools

# Android Studion
fedora ~/git/opencontrolpixelbudspro2 [main L|✔] $ flatpak install -y flathub com.google.AndroidStudio 

Install Kotlin using SDKMAN

if [[ ! -d "$HOME/.sdkman" ]]; then
  curl -s "https://get.sdkman.io" | bash
fi
set +u
source "$HOME/.sdkman/bin/sdkman-init.sh"
sdk install kotlin || warn "Kotlin install using sdkman was skipped or failed."
set -u

Cross-validation between AI models (maintainer strategy)

This is a maintainer-executed workflow, not something a single AI agent session can do to itself — it requires orchestrating two independent model sessions/tools and comparing their output, which is why it lives here rather than as a directive in AGENTS.md (moved from that document's former §14, 2026-08-15). Two installed tools are available for this: Claude Code and Antigravity (see above).

When a protocol hypothesis is significant enough to implement against:

  1. Have one model/session summarize the hypothesis and its evidence.
  2. Give the same evidence (without the conclusion) to a second model, or to a fresh session of the same model — e.g. Claude Code vs. Antigravity, or two independent Claude Code sessions with cleared context.
  3. Compare the two independent interpretations yourself.
  4. On agreement: raise confidence, but still mark the finding as HYPOTHESIS until a physical experiment (logged in the relevant CAP-NNN-FINDINGS.md) confirms it — agreement between two AI readings of the same bytes is not itself proof, since both may share the same training-data blind spot.
  5. On disagreement: do not have either model "resolve" it automatically — treat the discrepancy itself as a signal that more evidence (a distinguishing capture/experiment) is needed before promoting anything.

Reverse engineering tools: JADX, apktool, pbtk

The snippet below is a standalone shell fragment (unlike the transcript-style blocks elsewhere in this file) — it uses two tiny helpers, log/warn, that must be defined in the same shell session before use; they are not built-in commands. Fedora 44's repos (base + RPM Fusion) carry no apktool package (confirmed 2026-08-30, dnf install -y apktoolNo match for argument: apktool), so apktool is installed manually from its GitHub releases, the same way JADX already is below.

log()  { echo "[INFO] $*"; }
warn() { echo "[WARN] $*" >&2; }

APKTOOL_VERSION="3.0.3"
APKTOOL_DIR="$HOME/tools/apktool"
if [[ ! -x "$APKTOOL_DIR/apktool" ]]; then
  log "apktool $APKTOOL_VERSION download and install in $APKTOOL_DIR..."
  mkdir -p "$APKTOOL_DIR"
  curl -L -o "$APKTOOL_DIR/apktool.jar" \
    "https://github.com/iBotPeaches/Apktool/releases/download/v${APKTOOL_VERSION}/apktool_${APKTOOL_VERSION}.jar" \
    || warn "apktool download failed, install manual: https://apktool.org/docs/install"
  printf '#!/bin/sh\nexec java -jar "%s/apktool.jar" "$@"\n' "$APKTOOL_DIR" > "$APKTOOL_DIR/apktool"
  chmod +x "$APKTOOL_DIR/apktool"
  echo "export PATH=\"\$PATH:$APKTOOL_DIR\"" >> "$HOME/.bashrc"
else
  log "apktool already installed in $APKTOOL_DIR, skipped."
fi

JADX_VERSION="1.5.1"
JADX_DIR="$HOME/tools/jadx"
if [[ ! -d "$JADX_DIR" ]]; then
  log "JADX $JADX_VERSION download and install in $JADX_DIR..."
  mkdir -p "$JADX_DIR"
  TMPZIP=$(mktemp)
  curl -L -o "$TMPZIP" "https://github.com/skylot/jadx/releases/download/v${JADX_VERSION}/jadx-${JADX_VERSION}.zip"
  unzip -q -o "$TMPZIP" -d "$JADX_DIR"
  rm -f "$TMPZIP"
  echo "export PATH=\"\$PATH:$JADX_DIR/bin\"" >> "$HOME/.bashrc"
else
  log "JADX already installed in $JADX_DIR, skipped."
fi

After either install, open a new shell (or source "$HOME/.bashrc") so the updated PATH takes effect, then verify with apktool --version and jadx --version.

pbtk (Protobuf toolkit — .proto schema extraction)

Confirmed against pbtk's own README (github.com/marin-m/pbtk, checked 2026-08-30) rather than assumed. Real scope, corrected from an earlier working assumption: pbtk ships two separate extractors relevant here, not one — pbtk-jar-extract for Java-runtime protobuf (base/Lite/Nano/ Micro/J2ME, i.e. DEX/APK-embedded classes), and pbtk-from-binary for "binaries containing embedded reflection metadata (typically C++, sometimes Java and most other bindings)," which the upstream README states "still works well" as of 2026. So native .so extraction is not ruled out the way this project first assumed — whether it actually works against libmaestro/libgfps's specific .so files depends on whether those binaries retain their protobuf descriptor pool (full protobuf runtimes typically do; protobuf-lite builds typically strip it to save size) — this is an ⚪ ASSUMPTION until tried against a real extracted .so, not a known fact either way. Per DECISIONS.md ADR-017, running either extractor and explaining its output is in scope for AI mechanical assistance; deciding what a resulting .proto/candidate struct means for the wire protocol stays the maintainer's call.

Real dependencies (per the upstream README, not assumed): Python ≥ 3.10, PySide 6, Python Protobuf 3, and a handful of external executables (chromium, jad, dex2jar) used by some extractor scripts. Debian/Ubuntu's own documented apt line is python3-pip git openjdk-8-jre python3-qtpy-pyside6; Fedora has no native pbtk package (no snap by default, and the upstream AUR package is Arch-specific), so the upstream-recommended pipx/uv path — which pulls PySide6 and python-protobuf into an isolated environment itself — is used instead:

# Runtime prerequisites pbtk itself doesn't vendor (Java 21 already installed above satisfies
# pbtk's JRE dependency; jad/dex2jar aren't in Fedora's repos — install manually only if a
# specific extractor script reports them missing, per pbtk's own runtime warning).
sudo dnf install -y python3-pip pipx || warn "python3-pip/pipx install failed, check repo availability"
pipx ensurepath

# Install pbtk itself (pulls PySide6 + python-protobuf into its own isolated pipx venv)
pipx install pbtk
hash -r

# Verify — launches the GUI, or use the two extractor scripts directly (no GUI required):
pbtk --version 2>/dev/null || pbtk-jar-extract -h
pbtk-from-binary -h

Keeping pbtk up to date. Checked 2026-08-30 against both PyPI and github.com/marin-m/pbtk's releases: the pipx-installed version (1.1.3) was already the latest published release on both — the one commit ahead of it on master only touches README.md/pyproject.toml/gui.py (adds a version string to the GUI/CLI), not any extractor logic. pbtk-jar-extract's own --help text ("works better with older APKs, needs update") is a built-in caveat about the tool's reflection heuristic against R8/ProGuard-obfuscated, newer-codegen APKs, not a stale-install symptom — running it against reverse-engineering/apk/v1.0.955078536-10253511/base.apk produced 0 .proto files even on this confirmed-latest version — not a stale-install symptom, that part of this finding stands. Root cause corrected 2026-08-30/2026-09-03 (TODO.md's Phase 2 checklist), superseding the generic "obfuscation/newer-codegen" reading above: a targeted 32-class re-run still produced 0 files, and the actual cause is structural, confirmed against pbtk's own jar_extract.py source — this APK's GeneratedMessageLite.newMessageInfo(default, infoString, objects) reflection-based codegen never emits the per-class mergeFrom(CodedInputStream) switch-structure the extractor requires, for any class, regardless of obfuscation. Don't expect an upgrade alone to fix a 0-file pbtk-jar-extract result against this codegen style; re-check PyPI/GitHub release dates the same way before assuming an upgrade will help for a different APK.

To upgrade when a real newer release does exist: pipx upgrade pbtk is the documented path, but was observed to hang indefinitely at the "upgrading pbtk..." step in this environment (2026-08-30) — if that happens, the equivalent uv call run directly against the pipx venv is a reliable fallback and completes in under a second when already current:

uv pip install --python "$HOME/.local/share/pipx/venvs/pbtk/bin/python" --upgrade pbtk

Extracted .proto output lands in ~/.pbtk/protos/<APK name>/ by default (per pbtk's own documented local-storage convention) — copy the relevant files into this project's reverse-engineering/apk/v<versionName>-<versionCode>/pbtk-output/ (see reverse-engineering/APK_VERSIONS.md, not committed to git — see .gitignore) rather than leaving them only in pbtk's own home-directory cache, so a given APK version's extraction output stays associated with that version.

Disaster Recovery

See README.md's bricking disclaimer — this project sends undocumented commands to real hardware, and a malformed or unexpected one could leave the Buds/case in a bad state (e.g. unresponsive to normal pairing, stuck in an unexpected mode). Know this procedure before running any experimental write command against real hardware, not after something goes wrong.

Hardware factory reset (confirmed, TESTPLAN_BLUETOOTH_HCI_SNOOP.md CASE-007):

  1. Place both buds in the case.
  2. Open the case lid, and keep the case connected to power (plugged in).
  3. Press and hold the case button for 30 seconds.
  4. This performs a full factory reset — confirmed via official support documentation and reproduced on-the-wire in CAP-001/CAP-002 (CAPTURE_BLUETOOTH_HCI_SNOOP.md Group P #16). It also resets the Find My Device link on the Pro 2.

What this does and doesn't recover from:

  • Recovers from: a bad pairing/bonding state, a stuck connection, the Buds not responding to the phone in a way normal reconnect doesn't fix — this is the standard, Google-documented "starting over" mechanism.
  • Does not guarantee recovery from a genuinely corrupted firmware state or a malformed command that put the hardware into an undocumented failure mode — there is no lower-level recovery mechanism known to this project (no documented DFU/recovery-mode procedure). If a 30-second reset doesn't restore normal behavior, treat the hardware as potentially bricked and stop sending further experimental commands to it.
  • This is destructive: it clears pairing state and Find My Device linkage. Don't use it casually — it's the last resort referenced by README.md's disclaimer and ARCHITECTURE.md §8.1's Safe Mode design, not a routine troubleshooting step.

https://github.com/tedsluis/opencontrolpixelbudspro2/blob/main/WORKSTATION_PREPARATIONS.md - https://tedsluis.github.io/opencontrolpixelbudspro2/WORKSTATION_PREPARATIONS