|
| 1 | +# Macula SDK — Backlog |
| 2 | + |
| 3 | +Tracked work items not yet scheduled. Newest first. |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +## Pub/Sub delivery leaks `{:text, _}` for CBOR text strings |
| 8 | + |
| 9 | +**Filed:** 2026-06-01 |
| 10 | +**Severity:** medium (correctness / consumer ergonomics; no data loss) |
| 11 | + |
| 12 | +Delivered pub/sub fact payloads surface CBOR **text strings (major 3)** as |
| 13 | +`{text, binary()}` tuples (Elixir `{:text, bin}`) — in map KEYS and VALUES, at |
| 14 | +any depth — instead of plain binaries. CBOR **byte strings (major 2)** correctly |
| 15 | +decode to plain binaries, so the leak only bites publishers that emit text |
| 16 | +strings (e.g. `hecate-parksim` → the `macula-realm` ClankerCab demo). |
| 17 | + |
| 18 | +**Impact:** every consumer of a text-string fact must defensively unwrap |
| 19 | +`{:text, _}` or it crashes the moment a key/value reaches `String.Chars` |
| 20 | +interpolation. This already forced two band-aids in `macula-realm`: |
| 21 | +- `clanker_cab_subscriber.ex` — recursive `{:text, bin}` → `bin` normalize at |
| 22 | + the subscriber boundary (commit `52bc2d2`). |
| 23 | +- `topology/mesh_subscriber.ex` — the same `normalize/1` at `decode_record` + |
| 24 | + `decode_app_payload`, a `{:text, _}` clause in `get_str/2`, and a hardcoded |
| 25 | + `Map.get(payload, {:text, "superseded_key"})` tombstone lookup. |
| 26 | + |
| 27 | +**Proper fix:** pub/sub delivery decode should return CBOR text strings as plain |
| 28 | +`binary()` (matching byte-string behaviour), not `{text, _}` tuples. The |
| 29 | +`{text, binary()}` representation is `macula_record_cbor`'s internal canonical |
| 30 | +form (correct for deterministic sig encoding) — it should not surface in the |
| 31 | +app-facing decoded payload. Likely fix point: the SDK delivery/decode path that |
| 32 | +hands the fact term to subscribers (where it currently preserves the |
| 33 | +`macula_record_cbor` value rep instead of converting major-3 to binary). |
| 34 | + |
| 35 | +**When done:** drop the two normalize band-aids in `macula-realm` (search for |
| 36 | +`TODO(macula)` and the ClankerCab `normalize/1`). |
| 37 | + |
| 38 | +**Likely introduced:** a macula version between the realm's prior pinned build |
| 39 | +and 4.8.0 (the realm's ClankerCab worked with plain binaries before the bump). |
0 commit comments