diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d0d1948..d177423 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -47,6 +47,36 @@ that fail CI will be asked to fix it before review. - Public APIs need docstrings; private helpers usually don't. - Tests live in `tests/`, named `test_*.py`. +## Branching + +We use a three-branch convention. + +- **`main`** — release-grade. Protected: every change lands via PR, + history stays linear (rebase + squash, no merge commits), force + push and deletion are disabled. +- **`dev`** — integration. Protected against force push and deletion + but accepts direct pushes from maintainers for fast iteration. CI + runs the same checks here as on `main`. +- **`feat/`** — feature branches. Cut from `dev`, push + freely, rebase as needed, and open a PR to `dev` when done. Delete + after merge. No GitHub-side protection; the prefix is a documented + convention, not an enforced rule. + +Typical loop: + +```bash +git checkout dev && git pull +git checkout -b feat/add-coap-transport +# ... work, commit, push as many times as you want ... +git push -u origin feat/add-coap-transport +gh pr create --base dev --fill +# after review/CI: squash-merge into dev, branch auto-deletes +# release manager periodically merges dev -> main via PR +``` + +If your branch is a bugfix rather than a feature, use the prefix +`fix/` instead. Same rules apply. + ## Commit and PR style - Subject line under 70 chars, present tense (`Add MQTT transport`, not diff --git a/README.md b/README.md index bb6016e..5910079 100644 --- a/README.md +++ b/README.md @@ -73,14 +73,20 @@ device boundary. ## Validated on real hardware -As of v0.3 the reference firmware is **measured-validated on an -ESP32-WROOM-32 dev board** over CH340 USB-Serial at 115 200 baud: +As of v0.3 the reference firmware is **measured-validated on two +physical boards** — an ESP32-WROOM-32 dev board over CH340 USB-Serial, +and an ESP32-S3 (LILYGO T-Panel S3) over the S3's native USB-Serial/JTAG +— both at 115 200 baud: -- 13/13 round-trip tests pass (`tools/test_uart_roundtrip.py`) +- 13/13 round-trip tests pass on each board (`tools/test_uart_roundtrip.py`) - 88/88 Python unit & conformance tests pass -- Compiled firmware: 294 KB flash, 22.7 KB globals (Arduino-ESP32 core 3.3.8) +- Compiled firmware: 294 KB flash, 22.7 KB globals on WROOM-32; + 322 KB / 22.7 KB on the S3 (Arduino-ESP32 core 3.3.8) - The pure DCP layer is approximately 14 KB over a baseline empty sketch (measurement script in `docs/paper/figures/`) +- The S3 run also exercises DCP over a native-USB CDC link rather + than a USB-UART bridge chip — same firmware, no transport-specific + code ![Memory footprint: DCP target vs IoT-MCP measured vs Direct MCP vs Matter](docs/paper/figures/footprint.png) @@ -95,12 +101,14 @@ validation does and does not prove. The reference firmware is portable by design (Arduino `Stream` + a software SHA-256, no SoC-specific code paths in `DCP.{h,cpp}`). It -cross-compiles for every current ESP32 variant *and* for ESP8266, -with end-to-end UART validation pending boards on the bench: +cross-compiles for every current ESP32 variant *and* for ESP8266; +two of those targets are also runtime-validated on real boards, the +rest are build-validated pending hardware on the bench: | Target | ISA | Flash (lamp+blink) | Globals | Status | |-------------------|-----------------------|--------------------|----------|---------------| | ESP32-WROOM-32 | Xtensa LX6 (baseline) | 294 KB | 22.7 KB | runtime ✓ | +| ESP32-S3 (T-Panel)| Xtensa LX7 | 322 KB | 22.7 KB | runtime ✓ (native USB) | | ESP32-C3 | RV32IMC | 289 KB | 13.4 KB | builds ✓ | | ESP32-C6 | RV32IMAC + HW-crypto | 266 KB | 14.0 KB | builds ✓ | | ESP32-H2 | RV32IMAC + 802.15.4 | 292 KB | 14.0 KB | builds ✓ | @@ -294,7 +302,8 @@ MIT. - [x] Conformance test suite (golden frames, language-neutral YAML) - [x] Codegen `--stubs`: emits handler signatures + binding table - [x] Quickstart video script ([docs/QUICKSTART_VIDEO.md](docs/QUICKSTART_VIDEO.md)) -- [x] Real-hardware UART validation (ESP32-WROOM-32, 13/13 round-trips) +- [x] Real-hardware validation on two boards (ESP32-WROOM-32 over + CH340, ESP32-S3 / T-Panel over native USB), 13/13 round-trips each - [x] Cross-compile clean on ESP32 RISC-V family (C3, C6, H2, P4) and ESP8266 - [x] Public repo at `device-context-protocol/dcp` (v0.3.0 released) - [x] PyPI release (`pip install pydcp`) diff --git a/docs/paper/README.md b/docs/paper/README.md index 34e6ee5..14a8fa2 100644 --- a/docs/paper/README.md +++ b/docs/paper/README.md @@ -49,7 +49,7 @@ The tarball is `.gitignored` — regenerate before each upload. ## Before submitting to arXiv -1. **Authors.** Replace `deeplethe` and the placeholder email. arXiv lets +1. **Authors.** Replace `DeepLethe` and the placeholder email. arXiv lets you list affiliations per-author. 2. **Repo URL.** Currently a footnote placeholder (`github.com/device-context-protocol`). Either point to the real public diff --git a/docs/paper/main.tex b/docs/paper/main.tex index a1953cb..e4d9e5e 100644 --- a/docs/paper/main.tex +++ b/docs/paper/main.tex @@ -58,7 +58,7 @@ LLM-Driven Control of Constrained Devices} \author[1]{Dongxu Yang\thanks{Correspondence: \texttt{wayland0916@gmail.com}.}} -\affil[1]{deeplethe} +\affil[1]{DeepLethe} \date{May 2026} @@ -465,22 +465,25 @@ \subsection{ESP32 reference firmware} thirteen round-trip cases (\texttt{tools/test\_uart\_roundtrip.py}) covering calls, reads, dry-run, range rejection, unknown-intent error frames, and a non-idempotent intent with a \texttt{duration} parameter that exercises -the firmware-side CBOR float decode path. All thirteen cases pass against -real hardware. +the firmware-side CBOR float decode path. All thirteen cases pass on two +physical boards: an ESP32-WROOM-32 over a CH340 USB-UART bridge, and an +ESP32-S3 (LILYGO T-Panel S3) over the S3's native USB-Serial/JTAG +interface. The latter exercises DCP over a native-USB CDC link with no +USB-UART bridge chip and no transport-specific firmware changes. \paragraph{Portability across the ESP family.} The same \texttt{firmware/esp32/} library compiles unchanged across the current ESP32 family --- C3 (RV32IMC, 289\,KB / 13.4\,KB), C6 (RV32IMAC, 266\,KB / 14.0\,KB), H2 (RV32IMAC + 802.15.4, 292\,KB / -14.0\,KB), and P4 (RV32IMAFC dual-core, 326\,KB / 22.0\,KB) --- and -additionally on the legacy ESP8266 NodeMCU (Xtensa LX106, 242\,KB / -28.9\,KB), where the lamp example sketch picks the PWM API at -compile time (\texttt{ledcAttach}/\texttt{ledcWrite} on ESP32, -\texttt{analogWrite} on ESP8266) while the protocol layer itself -remains \texttt{\#ifdef}-free. End-to-end UART validation on these -non-Xtensa-LX6 targets is pending bench availability, but the build -artefacts confirm the portability claim beyond the single target on -which the runtime was measured. +14.0\,KB), P4 (RV32IMAFC dual-core, 326\,KB / 22.0\,KB), and S3 +(Xtensa LX7, 322\,KB / 22.7\,KB) --- and additionally on the legacy +ESP8266 NodeMCU (Xtensa LX106, 242\,KB / 28.9\,KB), where the lamp +example sketch picks the PWM API at compile time +(\texttt{ledcAttach}/\texttt{ledcWrite} on ESP32, \texttt{analogWrite} +on ESP8266) while the protocol layer itself remains +\texttt{\#ifdef}-free. Of these, the WROOM-32 and S3 targets are +runtime-validated as described above; the remaining targets are +build-validated, with bench validation pending hardware availability. \subsection{Conformance suite} diff --git a/firmware/esp32/library.properties b/firmware/esp32/library.properties index 3b7a1ba..d000c1f 100644 --- a/firmware/esp32/library.properties +++ b/firmware/esp32/library.properties @@ -1,7 +1,7 @@ name=DCP version=0.3.0 -author=deeplethe -maintainer=deeplethe +author=DeepLethe +maintainer=DeepLethe sentence=Device Context Protocol: bridge LLM agents to physical devices. paragraph=Reference firmware for the DCP wire protocol. Parses COBS-framed CRC-checked DCP frames over Serial OR BLE GATT (with NimBLE-Arduino), decodes a tiny CBOR subset, dispatches to user-registered intent handlers, and optionally verifies per-frame HMAC-SHA256 signatures. category=Communication diff --git a/pyproject.toml b/pyproject.toml index 083f430..af0e64b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ description = "Device Context Protocol — Python reference implementation. A br readme = "README.md" requires-python = ">=3.11" license = { text = "MIT" } -authors = [{ name = "deeplethe" }] +authors = [{ name = "DeepLethe" }] keywords = ["mcp", "iot", "hardware", "llm", "agent", "device", "protocol"] dependencies = [ "cbor2>=5.6",