Commit Graph
13 Commits
Author SHA1 Message Date
swaitsandClaude Opus 4.7 4d6f31d152 spec(overview): add prominent unofficial/AI-authored provenance callout
The book's first page previously claimed the spec was "the
authoritative definition of the wire format" derived from the
firmware. That misrepresents the project's stance. Replace the
existing "Status" block with a more honest "Status and Provenance"
block that mirrors the README disclosure:

- This is an unofficial, independent project — NOT part of the
  upstream MeshCore project, not affiliated, not endorsed.
- Primarily AI-authored (Claude / Opus 4.x) under Stephen Waits's
  direction, with human proofreading and editing.
- The upstream MeshCore C++ firmware is the source of truth;
  this spec is downstream. CHANGELOG records the upstream commit
  hash per pass.
- DongLoRa observations refine the spec but never override
  upstream.
- The corpus is a useful signal but not a substitute for
  cross-checking against upstream firmware.

Visible to anyone landing on https://swaits.github.io/meshcore-spec/
or reading the rendered overview chapter.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 09:43:18 -06:00
swaitsandClaude Opus 4.7 d785e35919 feat(mdbook): publish spec via mdBook on GitHub Pages
Set up the protocol spec as an mdBook and add a GitHub Actions
workflow that builds it on every push/PR and deploys to GitHub
Pages on main. The repo is now both a machine-readable corpus and
a browsable, searchable site.

Structure changes (one-time, mechanical):

- Rename the spec source directory from `spec/` to `src/` to match
  mdBook's default convention. All 21 chapter files move; their
  internal relative cross-links are unchanged.
- Add `src/SUMMARY.md` as the mdBook table of contents, grouping
  chapters under Wire Format, Payloads, Cryptography & Identity,
  and Routing & Higher-Layer Protocols.
- Add `book.toml` at repo root: title, author, search enabled,
  fold enabled, edit-on-GitHub links, navy theme.
- Add `.github/workflows/mdbook.yml`: build on push + PR, deploy
  on push to main only (configure-pages + upload-pages-artifact +
  deploy-pages from actions/).
- Add `/book/` to .gitignore.

Reference updates so the old path is fully retired:

- Every `spec_ref` in `corpus/**/*.json` rewritten from `spec/` to
  `src/` (54 files).
- Schema description text and example path in
  `corpus/schema/test-vector.schema.json`.
- `README.md`: prominent link to the published site near the top;
  "What's Here" updated for the new layout.
- `CONTRIBUTING.md`: spec-editing instructions point at `src/`
  and note the SUMMARY.md requirement.
- `CLAUDE.md`: directory-layout notes updated.

CHANGELOG.md historical entries intentionally keep their `spec/`
paths since those record what the paths were at the time of those
commits.

After this lands, the user needs to enable GitHub Pages in repo
settings with source = "GitHub Actions" (one-time, manual). The
workflow will then publish to https://swaits.github.io/meshcore-spec/
on every push to main.

Verified locally: `mdbook build` produces a clean book/ tree with
all 21 chapters rendered and the SUMMARY-driven sidebar populated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 09:36:28 -06:00
swaitsandClaude Opus 4.7 75fb228909 docs(changelog): add 2026-05-12 publication-readiness entry
Record this pass at the top of CHANGELOG.md:

- Upstream baseline: meshcore-dev/MeshCore @ 1a7b361 (2026-04-28).
  Every normative claim was cross-checked against this commit.
- Process: adopted conventional commits; established
  "upstream-firmware-is-the-golden-source-of-truth" as a load-bearing
  principle for the project.
- Added: ack-crc test vectors; explicit ACK CRC algorithm; attempt
  semantics including tail-byte encoding for attempt > 3; reliable
  DM delivery; multipart direct-only and finalizer plain-ACK;
  sender-behavior/transmission-priority section in routing; README
  provenance + Author.
- Clarified: AES plaintext zero-padding scheme; MULTIPART chain
  descending count + plain finalizer.
- Corrected: 17-routing previously misrepresented upstream's
  path-replacement as a hash-size/SNR heuristic; upstream actually
  replaces unconditionally.
- Out of scope: ai-bot-specific values (route TTL, SNR margin,
  1-byte hash rejection, 150ms PATH_RETURN, 0x1424 sync word,
  pending-ACK 64/125s) were considered and dropped since they are
  not upstream behavior. Radio/hardware-state firmware items also
  excluded as out of protocol scope.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 09:27:07 -06:00
swaitsandClaude Opus 4.7 4a13c12ee9 docs(readme): add prominent Provenance disclosure and Author section
Prepare the repo for public release by stating openly:

- The spec is AI-authored (Claude / Anthropic) under Stephen Waits's
  direction. It is an independent project, not affiliated with the
  upstream MeshCore project.
- The official MeshCore C++ firmware is the golden source of truth for
  all protocol behavior; when this spec and upstream disagree, upstream
  wins.
- Clarifications have been driven by observations from building
  DongLoRa firmware and apps against live deployments, but DongLoRa
  divergences from upstream are treated as DongLoRa bugs, not spec
  changes.
- Conformance against this corpus is a useful signal but not a
  substitute for cross-checking against upstream.

Tighten Project Status to reference the new section. Add an Author
section with attribution.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 09:26:28 -06:00
swaitsandClaude Opus 4.7 ac581fccda spec(routing): align path-learning with upstream and document PATH_RETURN delay
Two changes:

1. CORRECTION. The path-learning subsection previously described the
   reference implementation's path-replacement as "replace only if
   the new path's hash size is not smaller and SNR is not materially
   worse" — but upstream's BaseChatMesh::onContactPathRecv() does an
   UNCONDITIONAL replace, with an inline comment flagging hash-size/
   SNR selection as future work. The spec now reflects upstream's
   actual behavior and notes that quality heuristics are an
   implementation extension, not a reference-implementation behavior.
   Likewise, removed the implication that the reference implementation
   has a cached-path TTL — it doesn't.

2. ADDITION. Document PATH_RETURN scheduling delay
   (TXT_ACK_DELAY=200ms default in upstream BaseChatMesh.cpp:9), with
   the rationale of spacing PATH_RETURN, ACK, and reply across
   distinct slots.

Validated against upstream meshcore-dev/MeshCore @ 1a7b361
(BaseChatMesh.cpp:304-307 unconditional replace; cpp:228, 255
TXT_ACK_DELAY-spaced PATH_RETURN emission).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 09:25:50 -06:00
swaitsandClaude Opus 4.7 3a8918fb0e spec(multipart): document plain-ACK finalizer after MULTIPART chain
Clarify that the MULTIPART ACK chain terminates with a plain
PAYLOAD_TYPE_ACK (not a MULTIPART with remaining=0). For K extra
copies, the wire sequence is:

  MULTIPART(remaining=K), MULTIPART(remaining=K-1), ...,
  MULTIPART(remaining=1), then PAYLOAD_TYPE_ACK (plain).

All copies share the same ack_crc. Receivers MUST dedup at the
application layer by ack_crc, since each packet's hash differs.

Validated against upstream meshcore-dev/MeshCore @ 1a7b361
(Mesh::routeDirectRecvAcks, src/Mesh.cpp:362 — while-loop emits
MULTIPART(remaining=extra...1), then createAck(crc) plain ACK).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 09:25:19 -06:00
swaitsandClaude Opus 4.7 c0f9c22efd spec(encrypted): clarify zero-padding scheme for AES plaintext
Tighten the encryption steps to spell out:

- Plaintext is zero-padded on the right to a multiple of 16 bytes
  before AES-128-ECB encryption.
- The padding is NOT PKCS#7 (not unambiguous); the receiver must
  disambiguate trailing zeros using the inner plaintext format
  (e.g., for TXT_MSG, by C-string NUL termination scan).
- Renumber steps so the padding step is explicit and ordered before
  encryption, instead of being a parenthetical on the encrypt step.

Validated against upstream meshcore-dev/MeshCore @ 1a7b361
(Utils::encrypt / Utils::decrypt, src/Utils.cpp:30-, comment
"dest may contain trailing zero bytes in final block").

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 09:25:05 -06:00
swaitsandClaude Opus 4.7 4095fc91c7 spec(routing): add sender behavior and transmission priority
Add a "Sender Behavior (Informational)" section to Section 17 that
captures the cross-implementation conventions for how senders should
behave above the wire format:

- Path Learning: cache the reversed accumulated path from received
  flood-routed packets; replace only when the new path is at least as
  good (hash size, SNR threshold implementation-defined).
- PATH_RETURN: proactive emission lets the original sender switch to
  direct routing without waiting for an explicit path probe.
- Flood Fallback and Retries: track outstanding DMs by expected
  ack_crc, increment attempt on each retry, hold timestamp constant,
  fall back from direct to flood after N unacknowledged direct
  retries.
- Transmission Priority (sender-originated) table: ACK > PATH >
  direct reply > flood reply > req/resp > group > advert.

All of these are informational guidance; numeric tunings remain
implementation-defined. Complements the existing forwarding-priority
table.

Validated against upstream meshcore-dev/MeshCore @ 1a7b361
(BaseChatMesh send/recv flow, Mesh::createPathReturn,
handleReturnPathRetry).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 09:23:12 -06:00
swaitsandClaude Opus 4.7 1c2007dcb5 spec(multipart): constrain MULTIPART ACK to direct paths
Add a "Multipart ACK Usage Constraints" subsection making explicit
what upstream enforces in code but the spec previously left implicit:

- MULTIPART-wrapped ACKs MUST only be emitted on direct-routed return
  paths. When no direct path is known, the sender MUST fall back to a
  plain PAYLOAD_TYPE_ACK via flood. Matches sendAckTo() and
  routeDirectRecvAcks() in upstream.
- All MULTIPART and plain copies of the same ACK carry an identical
  4-byte ack_crc; receivers MUST dedup by CRC at the application
  layer (Section 16 packet-hash dedup does not catch them because the
  wrapper byte makes each copy hash-distinct).
- Typical inter-copy delay ~300 ms plus the direct retransmit delay;
  exact count via getExtraAckTransmitCount() (reference default 0).

Validated against upstream meshcore-dev/MeshCore @ 1a7b361
(Mesh::routeDirectRecvAcks, BaseChatMesh::sendAckTo).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 09:23:04 -06:00
swaitsandClaude Opus 4.7 ce358996ad spec(encrypted): clarify attempt semantics and reliable DM delivery
Two additions to the TXT_MSG section:

1. Attempt Counter Semantics. Spells out that bits 0-1 of
   txt_type_attempt carry attempt & 3, the input the ACK CRC depends
   on. For attempt > 3, upstream appends a [NUL][attempt_full] tail
   after the text (BaseChatMesh.cpp:410-412), recovering the full
   attempt value at the cost of 2 bytes of text capacity. The tail is
   NOT part of the ACK CRC input, so attempt=4 and attempt=0 collide
   on CRC and senders relying on >3 must verify the trailing byte.

2. Reliable DM Delivery. Documents the sender-side ACK tracking
   contract: maintain a pending-ACK table keyed by expected CRC,
   retry with attempt incremented, consume MULTIPART-wrapped or plain
   ACKs identically, and the receive-side option to cache replies per
   peer for duplicate-DM loss recovery.

Validated against upstream meshcore-dev/MeshCore @ 1a7b361
(BaseChatMesh::composeMsgPacket, onPeerDataRecv TXT_MSG handling).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 09:22:56 -06:00
swaitsandClaude Opus 4.7 277d4463c1 spec(ack): document explicit ACK CRC computation algorithm
Spell out the SHA-256-truncation algorithm previously described in
prose:

  ack_crc = SHA-256(plaintext_prefix || sender_pub_key)[0..3]

where plaintext_prefix = timestamp(4) || txt_type_attempt(1) || text
(excluding any trailing NUL terminator). Add the SIGNED_PLAIN variant
(includes 4-byte signature prefix, hashes against receiver's pub_key).
Reference the upstream functions that implement each side.

Resolves the ACK CRC vagueness called out in the 2026-04-01 audit.
Paired with the new corpus/crypto/sha256/ack-crc.json vectors.

Validated against upstream meshcore-dev/MeshCore @ 1a7b361
(BaseChatMesh.cpp:222, 249, 407; Utils::sha256 two-fragment form).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 09:22:48 -06:00
swaitsandClaude Opus 4.7 2cf3d29fe1 corpus(crypto): add ack-crc test vectors
Add four SHA-256-truncation vectors covering ACK CRC computation with
incrementing attempt values (0..3) over a stable (timestamp, text,
sender_pub_key) triple. Demonstrates that each retry produces a
distinct expected CRC, fixing the algorithmic ambiguity noted in the
2026-04-01 audit.

Algorithm: SHA-256(timestamp(4) || txt_type_attempt(1) || text ||
sender_pub_key(32))[0..3] as little-endian uint32.

Validated against upstream meshcore-dev/MeshCore @ 1a7b361
(BaseChatMesh::composeMsgPacket, src/helpers/BaseChatMesh.cpp:407).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 09:22:41 -06:00
swaitsandClaude Opus 4.6 9db901088e Add comprehensive spec audit results and pyMC_core issue reports
- CHANGELOG.md: Full audit findings organized by severity
- PYMC_CORE_ISSUES.md: 7 evidence-based bug reports for pyMC_core
  (wrong constants, broken path_len decoding, wrong TRACE hash,
  wrong SNR calculation)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Add comprehensive spec audit results and pyMC_core issue reports

- CHANGELOG.md: Full audit findings organized by severity
- PYMC_CORE_ISSUES.md: 7 evidence-based bug reports for pyMC_core
  (wrong constants, broken path_len decoding, wrong TRACE hash,
  wrong SNR calculation)
- Remove ERRATA.md: contents already covered by audit findings

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 21:37:57 -06:00