Commit Graph
6 Commits
Author SHA1 Message Date
torlando-agent[bot]andClaude Opus 4.8 b06b3650ae chore(build): unify pre-script libdeps paths on a shared helper + OTA log
OTA hardening follow-up to the patch_nimble.py hardcoded-"tdeck" bug that broke
tdeck-ota linking (undefined reference to nimble_host_reset_reason):
- Add _build_helpers.env_libdeps_dir(env, *parts): the single per-environment
  libdeps path resolver (.pio/libdeps/<PIOENV>/...). Converted all five pre-scripts
  (patch_nimble/msgpack/filestore/littlefs_paths, sync_file_libdeps) to use it, so
  the env component can no longer be hand-rolled/hardcoded wrong per script.
- "OTA: Ready" log -> "OTA: wireless flash service started (pyxis-tdeck:3232)":
  ArduinoOTA.begin() is void and can't confirm a ready state, so log the target
  instead of claiming readiness we can't verify.

Verified: both tdeck and tdeck-ota build, and the NimBLE patch lands in EACH env's
own libdeps tree (nimble_host_reset_reason count 2 in both).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UWZuYkHBRqNb6BZHV8sTG5
2026-06-23 00:01:17 -04:00
torlando-agent[bot]andClaude Opus 4.8 a1c548dbf2 fix: make PYXIS_FILESTORE_DIAG self-contained (define bin_str)
The diagnostic patch injected printf("...%s...", bin_str(key, key_len)) into
FileStore.h but never defined bin_str, so a PYXIS_FILESTORE_DIAG=1 build failed
with an undeclared-identifier error (normal DIAG=0 builds were unaffected).
Inject a standard-C hex-encode helper as a static member alongside the prints
so the diagnostic build is self-contained. Verified: the helper compiles clean
under gnu++11 -Wall -Wextra -Werror and round-trips keys correctly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UWZuYkHBRqNb6BZHV8sTG5
2026-06-19 10:39:15 -04:00
torlando-agent[bot]andClaude Opus 4.7 4c5ca8cbc8 chore(greptile): iteration 4 — applied 1, rejected 0
patch_msgpack.py + patch_filestore.py: read PIOENV instead of
hardcoding "tdeck" in the libdeps path. The hardcode meant the
msgpack public-modifier patch silently no-op'd under tdeck-bluedroid
(and tdeck-ota), making microLXMF's packRawBytes / raw_data /
indices accesses fail to compile. Mirrors the pattern already used
in sync_file_libdeps.py. Resolves the failing tdeck-bluedroid build.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 01:30:50 -04:00
torlando-techandClaude Opus 4.7 7d158a7595 fix(microStore): close active_file before unlinking segments (FD leak)
Local patch via patch_filestore.py for upstream attermann/microStore
issue: \`finalize_compaction()\` and \`clear()\` both call
\`_filesystem.remove()\` on segment files without first closing
\`active_file\`. On filesystems that don't auto-close FDs on unlink
(LittleFS / FAT) the descriptor leaks. Over enough compaction cycles
on pyxis the path-store eventually can't open new files.

Both \`open_segment()\` and \`rotate_segment_if_needed()\` already
close \`active_file\` before reopening — the unlink paths just
forgot. Added \`if (active_file) active_file.close();\` at the top
of each.

Validated: 2-round LXMF soak post-patch, 8 pass / 2 fail, identical
to pre-patch baseline (the 2 fails are the known propagation timing
flake unrelated to FD handling). Patch applies cleanly and re-applies
on every build via the pre-build hook.

Will be reverted once the upstream lands the same fix; tracked in
the vault TODO at "80 Assistant/Memory/pyxis/upstream_patches.md".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 03:16:12 -04:00
torlando-techandClaude Opus 4.7 f6b90a330b fix(serial): silence audio/wire/path-store noise during active calls
Real-LXST 14s call at ULBW (Codec2-700C) was timing out T:CALL_QOS /
T:CALL_STATS responses ~10-15s in. Pyxis itself was still processing
audio fine; the host's serial reader was just overrun by debug-level
prints from three sources, all firing per-packet during voice traffic:

1. TCPClientInterface: per-frame "[TCP] Reading X bytes" / "[TCP]
   First bytes: ..." / "[HDLC] Frame #N: ..." / "[TCP] Processing
   frame" / 5s "[TCP] connected= ..." were unconditional Serial.printf.
   Now gated behind `RNS::loglevel() >= LOG_DEBUG` and the snprintf
   work skipped when it'd be discarded.

2. i2s_capture.cpp: "[CAP] rate=" fired every 2s regardless of
   activity. Now only emits when ringDrops > 0 OR runningPeak > 1000
   (something happened worth noting). Counters still update — only
   the print is gated.

3. microStore upstream: "[ustore] get: key not found in index" fires
   on every path-store miss, which RNS hits constantly during a call.
   patch_filestore.py was already a registered pre-build script for
   diagnostic patches; reactivate it (was commented out in
   platformio.ini) and add a silence patch as the always-on default.
   Diagnostic exists()/put() patches gated behind PYXIS_FILESTORE_DIAG=1
   so they're easy to bring back when investigating path-store drift
   without touching the script each time.

After this, the ULBW real-LXST call validator returns PASS with full
final stats (pyxis_tx=34 rx=119 decode_ok=151 decode_fail=0
pyxis_rms=4410). 1600bps/3200bps profiles still hit serial-timeout
patterns under sustained TX — likely CPU saturation in the main
loop, separate from this fix; tracked in #75 followup.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 01:52:34 -04:00
torlando-techandClaude Opus 4.7 ba18c32c04 feat(test-hooks): T:SEND/SENDOPP/SENDPROP + T:SETPROP/SYNCPROP harness API
Adds a USB-CDC serial command interface gated behind PYXIS_TEST_HOOKS
that lets a host-side harness drive pyxis end-to-end without UI taps.
Built specifically to run /tmp/tdeck_harness.py and prove LXMF DIRECT,
OPPORTUNISTIC, and PROPAGATED delivery against a Mac-side echo bot
over the Mac's rnsd + lxmd.

Commands (all newline-terminated, replies T:OK or T:ERR):

  T:DEST                          — pyxis's delivery dest hash (hex)
  T:ID                            — pyxis's identity hash (hex)
  T:ANN                           — force an announce
  T:PATHS                         — count + dump in-memory path table
  T:HASPATH <hex>                 — Transport::has_path + in-memory check
  T:RECALL <hex>                  — Identity::recall_app_data hex
  T:SEND <hex> <text>             — outbound DIRECT LXMessage
  T:SENDOPP <hex> <text>          — outbound OPPORTUNISTIC LXMessage
  T:SENDPROP <hex> <text>         — outbound PROPAGATED LXMessage
  T:SETPROP <hex> <stamp_cost>    — set outbound propagation node
  T:SYNCPROP                      — request_messages_from_propagation_node
  T:SYNCSTATE                     — current PR_* sync state
  T:STATE <msg_hash>              — LXMessage state for a tracked send
  T:RX                            — drain inbound RX ring
  T:RXCLR                         — clear RX ring

Build-flag side:

  -DPYXIS_TEST_HOOKS               — gates all of the above
  -DPYXIS_TEST_TCP_HOST="..."      — hard-overrides NVS tcp_host so the
                                     harness's rnsd is the only target
  -DPYXIS_TEST_TCP_PORT=...        — same for tcp_port

Also: replaces `lib_extra_dirs = deps/microReticulum` with an explicit
`file://~/repos/microReticulum` lib_dep. lib_extra_dirs
caused PIO to compile microReticulum twice (once through the extra
dir, once through microLXMF's transitive auto-fetch), producing two
copies of `Transport::_path_store` in BSS. Different translation
units linked against different statics, so put() and exists() landed
in different in-memory indexes. Symptom: `T:HASPATH` returned 0 even
when the previous announce's `[ustore] put: wrote key` log line was
visible. Single source path → single static → consistent reads.

`patch_filestore.py` is committed but commented out in extra_scripts
— used during diagnostic when the dual-static issue was being
triaged. Easy to re-arm if FileStore put/exists drift recurs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 14:03:42 -04:00