Adaptive Physical Communication System (APCS)

Known Issues

This page lists the limits of the current build and the problems found while writing these documents by reading the code and running it. Each entry gives the symptom, the cause with a file reference, the impact, and a workaround or fix. Nothing here blocks the main demo: Light and Sound fountain transfers of text, photos and short videos work as documented. The Vibration channel is the exception: it is experimental and doesn’t work reliably yet (§2.8).

Back to the documentation index.


Contents

  1. Severity scale
  2. Transfer behaviour
  3. Protocol and simulation
  4. Media and composing
  5. Build, platform and release
  6. Physical limits (by design)
  7. Summary table

1. Severity scale

Level Meaning
High Can make a user-visible transfer fail or report the wrong outcome
Medium Wastes time or airtime, or misleads developers
Low Cosmetic, or only reachable from developer screens

2. Transfer behaviour

2.1 Sound sends were marked “delivered” (fixed)

2.2 Sound messages over 8 KiB silently use a path the receiver can’t decode (High)

2.3 Vibration airtime exceeds the acknowledgement timeout (Medium)

2.4 The Light sender can’t know when the receiver finished (Low, by design)

Light has no return path, so the sender streams until Stop or the 10-minute safety cap. The receiver’s DONE is the only completion signal. Resume streaming continues the same session if the sender stopped too early. See ADR-14.

2.5 The Silent band depends on each phone’s 19 kHz response (Medium, by design)

2.6 Silent’s first frame costs 4.8 s even for “sos” (Low, by design)

A Silent frame always carries a 24-byte block, so a three-letter message takes one 4.8 s frame. A plain two-tone FSK sender at 60 ms per bit needs 4.3 s for the same text, but falls behind from about five characters on and has no error correction. See Sound Channel §14.

2.7 The live frequency readout is approximate in time (Low)

2.8 Vibration transfers are unreliable on real phones (High)


3. Protocol and simulation

3.1 ACKs are treated as cumulative (High for the protocol path)

3.2 Simulation scenarios that should switch channels fail (Medium)

optical-degrades and burst-loss fail in every measured run. The engine makes the right decision (optical ≈0.27, acoustic ≈0.70), but only at the first evaluation (iteration 20), after issue 3.1 has already stalled the transfer. Details and measurements: Simulation Lab.

3.3 Other Simulation Lab quirks (Low)

Quirk Effect
Undiscoverable channels are still tested and can be selected “Acoustic only” scenarios may run on optical
Override profiles replace all fields of a channel Unset fields fall back to class defaults, not to the base profile
“Fixed” comparison strategies still run the adaptive orchestrator Their switch count is hard-coded to 0
Lost packets cost no simulated time Throughput under loss looks better than reality
Progress bars stay at 0%, score rows don’t update after a switch, “Run All” doesn’t refresh the screen UI only
The adaptive comparison uses 4 096 bytes instead of the scenario’s 8 192; “Static Switch” is never run Comparison numbers aren’t like-for-like

3.4 Hardware protocol selection ignores scores (Low)

In hardware mode with acoustic available and no forced channel, TransferManager always selects acoustic (“Acoustic is bidirectional”, fixed score 0.9). The main UI always forces the channel, so this only shows up in the developer screens.


4. Media and composing

4.1 Photos are re-compressed and grow (Medium)

4.2 Text typed next to an attachment replaces it (Medium)

If you attach a photo or video and type text, SendComposeScreen._buildPayload sends only the text. Fix: send both (two envelopes), or disable the text box while an attachment is present.

4.3 The Light frame’s gzip flag is never used (Low)

qrFountainFlagGzip (0x01) and isGzip exist in qr_fountain_frame.dart, but no sender sets the flag and no receiver inflates. Text could gain 2–3× from compression; JPEG and MP4 gain nothing.

4.4 Envelope names are limited to 255 bytes (Low)

nameLen and mimeLen are single bytes. ChatPayloadCodec.encode doesn’t truncate, so a UTF-8 file name over 255 bytes would corrupt the envelope. Fix: clamp names in encode.

4.5 Text in the compose screen uses codeUnits for data (Low)

ComposePayload.data for text is text.codeUnits (UTF-16 units truncated to bytes). The envelope itself is built from text via encodeText (UTF-8), so transfers are correct. Only byteSize shown before sending can be off for non-ASCII text.


5. Build, platform and release

Issue Where Impact Fix
Release builds are signed with the debug key android/app/build.gradle.kts Fine for sideloading and demos; can’t be published on Play Add a release keystore (Build and Release)
applicationId still marked TODO Same file A generic ID may clash with other builds Choose a final reverse-DNS ID before publishing
Brightness boost is Android-only OpticalDisplayControl iOS senders must turn brightness up by hand Add an iOS implementation (UIScreen.main.brightness)
Web: camera needs HTTPS or localhost; no vibration; no Gallery saving Browser limits Web works as a Light receiver/sender demo only By design
flutter test reports the platform as Android on every OS Test environment platform_capabilities_test always takes the “hardware” branch Documented in Testing
CSK and legacy FSK modems aren’t reachable from the main UI By design (ADR-15) Kept as libraries and in tests None needed

6. Physical limits (by design)

These aren’t bugs; they follow from the physics. See Performance.

Limit Value Why
Light range ≈15–40 cm Pixels per QR module at the camera (≥ 5 needed)
Light speed ≈1.3–2.5 KB/s Camera decode rate × bytes per sparse QR
Sound speed 10.8–35.8 B/s audible; 3.4–5.0 B/s Silent Symbol length needed to beat echo; Silent can play only one tone at a time without an audible difference tone
Sound range ≈0.3–2 m audible; ≈0.1–0.5 m Silent Speaker power and room noise; phones are weak at 19 kHz
Vibration speed ≈0.5 B/s (nominal; real transfers are unreliable, see §2.8) Motor spin-up/down time (tens of ms per pulse)
Vibration range Phones touching The accelerometer must feel the other phone’s motor
Security None See Security

7. Summary table

# Issue Severity Area
2.1 Sound sends marked delivered; Stop let a burst play out Fixed App controller, acoustic channel
2.2 Sound > 8 KiB uses an undecodable path High App controller
2.3 Vibration airtime > ACK timeout Medium Transport config
2.5 Silent depends on each phone’s 19 kHz response Medium (by design) Hardware
2.6 Silent “sos” takes one 4.8 s frame Low (by design) Sound profiles
2.7 Live kHz readout slightly ahead of the audio; close chord tones merge Low Sound UI
2.8 Vibration transfers unreliable on real phones (experimental) High Vibration channel
3.1 Cumulative ACK handling High (protocol path) Transport
3.2 Switching scenarios fail Medium Simulation
3.3 Simulation Lab quirks Low Simulation / UI
3.4 Hardware selection ignores scores Low Transfer manager
4.1 Photos re-compressed and grow Medium Media
4.2 Text replaces attachment Medium Compose UI
4.3 Gzip flag unused Low Light frame
4.4 255-byte name limit unchecked Low Envelope
4.5 codeUnits byte size Low Compose model
5 Debug signing, TODO applicationId, platform gaps Medium / Low Build

The Roadmap turns the High and Medium items into planned work.