Agent guidance (AGENTS.md)
This repo is built primarily by AI agents with human review. The docs are the spec; the tests are the law. Read this file fully before changing code.
Ground rules
Section titled “Ground rules”- Protocol changes are allowed, but never accidental. This is still a
green-field system, so do not let wire-format work become a blocker when a
refactor or protocol change is the right design. The
tests/test_packet.cpp::packet_golden_bytestest pins LPP v1 byte-for-byte; if your change breaks it or changes any parsed packet payload, updatedocs/PROTOCOL.md, apply the wire-change checklist, bump/version the design when compatibility requires it, and say so loudly in your PR. Never “fix” the golden test to match new bytes without documenting the protocol event. - Core stays portable.
core/must compile for ESP32/nRF52/POSIX with noArduino.h, no sockets, no exceptions/RTTI-dependent constructs, no hidden allocation on the radio path. Platform access goes through the seams incore/include/lrc/types.h(Clock,Rng) and caller-provided buffers. Heap/std::string are allowed only in the IRC gateway layer (core/src/irc/) and above. - Docs and code move together. Every behavioral change updates the
matching file in
docs/in the same commit. The docs are normative; reviewers diff them first. - Every feature lands with tests. Unit tests in
tests/(framework:tests/lrctest.h, zero deps). Cross-node behavior goes intests/test_node.cpp(in-process network simulation — preferred) ortests/smoke_lrcd.py(real sockets). If you can’t test it on the host, refactor until you can; that’s the architecture working as intended. - RF safety is not reviewable by CI. Anything touching
firmware/variants/, RF-switch handling, TCXO voltage, or TX paths needs a human sign-off and a pointer to the rule indocs/HARDWARE.mdyou’re honoring. When in doubt: receive-only defaults. - No new dependencies without discussion. Current external surface: RadioLib (firmware), vendored orlp/ed25519. That’s it on purpose.
Build & verify loop
Section titled “Build & verify loop”cmake -S . -B build && cmake --build build -j # must be warning-clean (-Werror)./build/lrc_tests # all green, alwayspython3 tests/smoke_lrcd.py # if you touched daemon/ or irc/(cd firmware && pio run) # if you touched core/ or firmware/| You’re changing… | Read first | Tests to extend |
|---|---|---|
| wire format / codec | docs/PROTOCOL.md | test_packet.cpp |
| keys, tags, signatures | docs/IDENTITY.md | test_crypto.cpp |
| registration handshake | docs/IDENTITY.md §2 | test_reg.cpp |
| dedup/frag/seq recovery | docs/PROTOCOL.md §Recovery | test_transport.cpp |
| CHANSYNC / gap healing | docs/PROTOCOL.md §Recovery | test_node.cpp (node_gap_heals_via_chansync) |
| lane plans / schedule / airtime | docs/RADIO.md | test_lanes.cpp |
| flash message store | docs/STORAGE.md | test_lrclog.cpp |
| IRC behavior | docs/ARCHITECTURE.md §IRC gateway | test_irc.cpp |
| TUI | docs/ARCHITECTURE.md §The TUI | test_tui.cpp |
| node glue / federation | docs/ROUTING.md | test_node.cpp + smoke_lrcd.py |
| firmware | docs/HARDWARE.md + POWER.md | host tests still gate; hardware notes in PR |
- C++17, 4-space indent, ~100 col. Match the file you’re in.
- Comments explain constraints and why, not what the next line does. The codebase deliberately reads as documentation for the next agent — keep that bar.
- Counters: any new observable behavior gets a
lrc::Counterand shows up instatsfor free. Stable names are API (docs/TELEMETRY.md). - Commit messages:
area: what changedplus a body that names the invariants you preserved (golden bytes, portability, RF safety).
Things that look like bugs but aren’t
Section titled “Things that look like bugs but aren’t”SEQ3 = 0xFFFFFFsentinel everywhere: “not yet sequenced” — see PROTOCOL.md before “fixing”.- Tags computed over the unstamped canonical image: the router rewrites SEQ3 after signing; this is by design (IDENTITY.md §7).
- The dedup ring accepting a bounded false-negative rate: documented
trade in
dedup.h. *lrcservice nick violates RFC nick grammar: deliberate — it can never collide with a real user.
Skills
Section titled “Skills”.claude/skills/ contains task recipes (lrc-wire-change, lrc-add-test).
If your harness supports skills, use them; they encode the checklists above.