Skip to content

Commit 07b0a8b

Browse files
docs: land Bluetooth presence sensor plan (cross-repo with burble) (#45)
## Summary Lands the neurophone-side plan for the cross-repo Bluetooth presence integration designed with sibling repo `burble`. Documentation only — no code changes, no Phase 2 implementation yet. NeuroPhone gains a *BLE presence sensor* (read-only) that feeds the existing `sensor → LSM → ESN → bridge → LLM` pipeline alongside accelerometer / gyro / light / proximity. The authoritative cross-repo plan is in [`burble/docs/architecture/ANDROID-CLIENT.adoc`](https://github.com/hyperpolymath/burble/blob/main/docs/architecture/ANDROID-CLIENT.adoc); this doc is the neurophone-specific projection. ## Privacy posture preserved NeuroPhone's existing README guarantees no mic / no contacts / no personal data. Adding BLE scanning is a real change, handled carefully: - **No `RECORD_AUDIO`.** Neurophone is not getting a voice client. - **No outbound advertising.** Read-only on the Burble protocol. - **`BLUETOOTH_SCAN`** requested with `usesPermissionFlags="neverForLocation"` — no location permission demanded, scan results not treated as location data. - **Toggle defaults OFF.** Separate from main sensor consent. - **Scanning is presence-only.** `BurbleNeighborScanner` filters on Burble UUID and decodes only the published payload fields. Does not do generic device discovery; does not log non-Burble MACs. - **`AI_INSTALLATION_GUIDE.adoc` update is a hard prerequisite for Phase 2 ship** — the AI-driven install flow asks consent questions in a specific order; adding a sensor without updating the script means the AI doesn't ask, which means it's silently enabled. ## Repository ownership | Lives in burble | Lives in neurophone | |---|---| | Wire format (a2ml) | Scanner + decoder | | Idris2 type | Rust crate `bt-presence` | | AffineScript signatures | Kotlin `bluetooth/` package | | Server-side bridge | Bridge context extension | Build-time codegen pulls burble's a2ml manifest into the rust crate — single source of truth, no protocol fork. ## Test plan - [x] Doc renders as AsciiDoc - [x] No code changes to verify - [x] Cross-refs to README, TOPOLOGY, and burble's ANDROID-CLIENT.adoc are valid 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 3ba95d4 commit 07b0a8b

1 file changed

Lines changed: 128 additions & 0 deletions

File tree

docs/BT-PRESENCE-PLAN.adoc

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// SPDX-License-Identifier: PMPL-1.0-or-later
2+
// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell
3+
= NeuroPhone — Bluetooth Presence Sensor Plan
4+
:toc: preamble
5+
6+
[NOTE]
7+
====
8+
*Status:* Design only — no code yet. Authored 2026-05-13.
9+
10+
*Authoritative source:* `burble/docs/architecture/ANDROID-CLIENT.adoc` (in the sibling
11+
`https://github.com/hyperpolymath/burble[burble]` repo) is the canonical plan for the
12+
cross-repo Bluetooth integration. This document covers only the neurophone side.
13+
====
14+
15+
== Scope
16+
17+
NeuroPhone gains a Bluetooth Low Energy *presence sensor* that feeds the existing
18+
`sensor → LSM → ESN → bridge → LLM` pipeline. It is sensor-class only:
19+
20+
* *No microphone access* — `RECORD_AUDIO` is NOT added.
21+
* *No voice* — neurophone is not getting a voice client. The privacy notice in
22+
`README.adoc` ("does not access microphone, contacts, or personal data") remains accurate.
23+
* *No outbound advertising* — neurophone is read-only on the Burble nearby protocol.
24+
25+
The presence signal is consumed exactly like accelerometer or proximity: a stream of
26+
readings that the LSM treats as one more sensor input. The bridge's context output
27+
becomes richer ("user is in a 3-person nearby cluster, salience rising") without
28+
neurophone caring what Burble is. Any future co-located service emitting the same
29+
advertisement schema could replace Burble without code changes here.
30+
31+
== Repository ownership boundary
32+
33+
Burble owns the wire protocol and the voice client. NeuroPhone owns only the consumer.
34+
35+
[cols="2,3",options="header"]
36+
|===
37+
| Lives in burble | Lives in neurophone
38+
39+
| `.machine_readable/6a2/nearby-presence.a2ml` (wire format)
40+
| `crates/bt-presence/` (scanner + decoder + decay)
41+
42+
| `src/Burble/ABI/NearbyPresence.idr` (Idris2 type)
43+
| `crates/sensors/src/bt_presence.rs` (sensor variant)
44+
45+
| `client/lib/src/extensions/NeurophonePresence.affine` (signatures)
46+
| `android/app/src/main/java/ai/neurophone/bluetooth/` (Kotlin scanner)
47+
48+
| `server/lib/burble/bridges/neurophone.ex` (server-side bridge)
49+
| `crates/bridge/src/encode.rs` (context generation extension)
50+
|===
51+
52+
The neurophone build pulls the a2ml manifest from burble at build time (via
53+
`crates/bt-presence/build.rs` codegen) — single source of truth, no protocol fork.
54+
55+
== File-by-file plan
56+
57+
[source]
58+
----
59+
neurophone/
60+
├── crates/bt-presence/ # NEW crate, android target only
61+
│ ├── Cargo.toml
62+
│ └── src/
63+
│ ├── lib.rs # BtPresenceReading public struct
64+
│ ├── ble_scan.rs # JNI wrappers around BluetoothLeScanner
65+
│ ├── burble_filter.rs # ScanFilter on Burble UUID, decode payload
66+
│ └── decay.rs # RSSI → presence score, exponential decay
67+
├── crates/sensors/src/
68+
│ └── bt_presence.rs # register BtPresenceReading as sensor variant
69+
├── crates/bridge/src/
70+
│ └── encode.rs # extend Bridge context with peer cluster info
71+
├── crates/neurophone-android/src/lib.rs # add JNI: bt_scan_event, bt_lost
72+
└── android/app/src/main/
73+
├── AndroidManifest.xml # add BLUETOOTH_SCAN (neverForLocation), BLUETOOTH_CONNECT
74+
├── java/ai/neurophone/
75+
│ ├── NativeLib.kt # add btScanEvent, btLost
76+
│ ├── bluetooth/
77+
│ │ ├── BurbleNeighborScanner.kt # BluetoothLeScanner on Burble UUID
78+
│ │ ├── PresenceCollector.kt # debounce, push into NativeLib
79+
│ │ └── ConsentGate.kt # toggle defaults OFF, separate from main sensors
80+
│ └── NeurophoneService.kt # start/stop scanner alongside accelerometer
81+
└── res/values/strings.xml # consent copy
82+
----
83+
84+
== Privacy posture (don't regress)
85+
86+
NeuroPhone's existing README guarantees the app does not access microphone, contacts,
87+
or personal data, and that sensor data stays on-device. Adding BLE scanning is a
88+
real change to that posture:
89+
90+
. *Default OFF.* The `ConsentGate` toggle defaults to disabled. Scanning never
91+
starts without an explicit user action.
92+
. *Separate toggle from main sensors.* The existing sensor consent (accel, gyro,
93+
light, prox) and the Bluetooth consent are independent. Granting one does not
94+
grant the other.
95+
. *AI install guide update.* `docs/AI_INSTALLATION_GUIDE.adoc` MUST be updated to
96+
describe the new toggle. The AI-driven install flow asks the consent questions
97+
in a specific order; adding a sensor without updating the script means the AI
98+
doesn't ask, which means it's silently enabled — a real privacy regression. This
99+
is a hard prerequisite for shipping Phase 2.
100+
. *Scanning is presence-only.* `BurbleNeighborScanner` filters on the Burble
101+
advertisement UUID and decodes only the published payload fields. It does not
102+
do generic BLE device discovery and does not log non-Burble MAC addresses.
103+
. *`neverForLocation` flag.* `BLUETOOTH_SCAN` is requested with
104+
`usesPermissionFlags="neverForLocation"` so Android does not require
105+
`ACCESS_FINE_LOCATION` and does not treat scan results as location data.
106+
107+
== Phases
108+
109+
NeuroPhone work begins at Phase 2 in the cross-repo plan:
110+
111+
* *Phase 0* (burble-only) — protocol exists, neurophone touches nothing.
112+
* *Phase 1* (burble-only) — burble's Android client ships and emits the advertisement.
113+
* *Phase 2* (~1–2 weeks, neurophone) — this plan. Read-only consumption.
114+
* *Phase 3* and later (burble-only) — does not require neurophone changes.
115+
116+
== Cross-references
117+
118+
* link:../README.adoc[README.adoc] — privacy commitments to preserve.
119+
* link:../TOPOLOGY.md[TOPOLOGY.md] — existing sensor → LSM → ESN → bridge pipeline diagram.
120+
* `burble/docs/architecture/ANDROID-CLIENT.adoc` — authoritative cross-repo plan.
121+
* `burble/.machine_readable/6a2/nearby-presence.a2ml` — wire format that codegen reads.
122+
123+
== Memory pointer
124+
125+
The Claude memory entry
126+
`~/.claude/projects/C--Users-USER/memory/project_burble_neurophone_bt.md`
127+
covers both sides of the integration. This document is the neurophone-specific
128+
projection; burble's `ANDROID-CLIENT.adoc` is the authoritative full plan.

0 commit comments

Comments
 (0)