<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>bolt1, branch HEAD</title>
<subtitle>Base Lightning protocol, per BOLT #1 (docs.ppad.tech/bolt1).
</subtitle>
<entry>
<id>0a19559d878ad6701d9d10fd08a32b736bcee662</id>
<published>2026-04-18T03:08:07Z</published>
<updated>2026-04-18T03:08:07Z</updated>
<title type="text">readme: add pre-release note</title>
<link rel="alternate" type="text/html" href="commit/0a19559d878ad6701d9d10fd08a32b736bcee662.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 0a19559d878ad6701d9d10fd08a32b736bcee662
parent 660d865dfa031a7a1e5ddfd686f6a95998a76f6b
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sat, 18 Apr 2026 11:08:07 +0800

readme: add pre-release note

</content>
</entry>
<entry>
<id>660d865dfa031a7a1e5ddfd686f6a95998a76f6b</id>
<published>2026-04-12T08:14:07Z</published>
<updated>2026-04-12T08:14:07Z</updated>
<title type="text">plans: add old IMPL5 doc</title>
<link rel="alternate" type="text/html" href="commit/660d865dfa031a7a1e5ddfd686f6a95998a76f6b.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 660d865dfa031a7a1e5ddfd686f6a95998a76f6b
parent 9acf4e37bf31a5a6db4a5fc478e4538fd8c50574
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 12 Apr 2026 16:14:07 +0800

plans: add old IMPL5 doc

</content>
</entry>
<entry>
<id>9acf4e37bf31a5a6db4a5fc478e4538fd8c50574</id>
<published>2026-01-25T11:00:43Z</published>
<updated>2026-01-25T11:00:43Z</updated>
<title type="text">Merge branch &#39;impl/weigh&#39; - comprehensive allocation benchmarks</title>
<link rel="alternate" type="text/html" href="commit/9acf4e37bf31a5a6db4a5fc478e4538fd8c50574.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 9acf4e37bf31a5a6db4a5fc478e4538fd8c50574
parent 2a3373657b7ba5c0b137ca0781657f4110569171
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 15:00:43 +0400

Merge branch &#39;impl/weigh&#39; - comprehensive allocation benchmarks

Add allocation tracking benchmarks covering:
- Primitive encoders/decoders
- Truncated unsigned encoders (small/full values)
- Minimal signed encoder (1/2/4/8 byte outputs)
- BigSize encoder (1/3/9 byte outputs)
- TLV operations (encode/decode for varying record counts)
- All BOLT#1 message encoders/decoders
- Envelope operations

</content>
</entry>
<entry>
<id>2a3373657b7ba5c0b137ca0781657f4110569171</id>
<published>2026-01-25T11:00:38Z</published>
<updated>2026-01-25T11:00:38Z</updated>
<title type="text">Merge branch &#39;impl/criterion&#39; - comprehensive criterion benchmarks</title>
<link rel="alternate" type="text/html" href="commit/2a3373657b7ba5c0b137ca0781657f4110569171.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 2a3373657b7ba5c0b137ca0781657f4110569171
parent f829f581231d810fa0ca8e9c2121f757b986171e
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 15:00:38 +0400

Merge branch &#39;impl/criterion&#39; - comprehensive criterion benchmarks

Add wall-clock timing benchmarks covering:
- Primitive encoding/decoding (u16/u32/u64, s8/s16/s32/s64)
- Truncated unsigned integers at boundary values
- Minimal signed integers at boundary cases
- BigSize encoding/decoding across all size thresholds
- TLV operations (encode/decode for 1/5/20 records)
- All BOLT#1 message types with variants
- Envelope operations with/without extension TLVs
- Round-trip benchmarks for each message type

</content>
</entry>
<entry>
<id>f829f581231d810fa0ca8e9c2121f757b986171e</id>
<published>2026-01-25T11:00:32Z</published>
<updated>2026-01-25T11:00:32Z</updated>
<title type="text">Merge branch &#39;impl/fixtures&#39; - benchmark fixtures module</title>
<link rel="alternate" type="text/html" href="commit/f829f581231d810fa0ca8e9c2121f757b986171e.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit f829f581231d810fa0ca8e9c2121f757b986171e
parent c4d99cf2411b7b18d7d0a25d0d50a53eac5e7eba
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 15:00:32 +0400

Merge branch &#39;impl/fixtures&#39; - benchmark fixtures module

Add bench/Fixtures.hs with pre-constructed values for benchmarking:
- Sample ByteStrings of various sizes (64B, 1KB, 16KB)
- Sample ChainHash and ChannelId values
- All BOLT#1 message types with minimal and realistic configurations
- TlvStream values (empty, small/1, medium/5, large/20 records)
- Pre-encoded message bytes for decode benchmarks

</content>
</entry>
<entry>
<id>2ff2e822ecf6c096b2e5da9de101bfdbe35de893</id>
<published>2026-01-25T10:59:51Z</published>
<updated>2026-01-25T10:59:51Z</updated>
<title type="text">bench: add comprehensive criterion benchmarks</title>
<link rel="alternate" type="text/html" href="commit/2ff2e822ecf6c096b2e5da9de101bfdbe35de893.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 2ff2e822ecf6c096b2e5da9de101bfdbe35de893
parent c4d99cf2411b7b18d7d0a25d0d50a53eac5e7eba
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 14:59:51 +0400

bench: add comprehensive criterion benchmarks

Add wall-clock timing benchmarks covering all major API surface areas:

Primitive encoding/decoding:
- Fixed-size unsigned integers (u16, u32, u64)
- Fixed-size signed integers (s8, s16, s32, s64)
- Truncated unsigned integers (tu16, tu32, tu64) at boundary values
- Minimal signed integers (encodeMinSigned) at boundary cases
- BigSize encoding/decoding across all size thresholds (0, 252, 253,
  65535, 65536, 0x100000000)

TLV operations:
- encodeTlvRecord for single records
- encodeTlvStream with 1, 5, and 20 records
- decodeTlvStreamRaw, decodeTlvStream, decodeTlvStreamWith
- parseInitTlvs and encodeInitTlvs for init-specific TLVs

Message encoding/decoding:
- All message types: Init, Error, Warning, Ping, Pong, PeerStorage,
  PeerStorageRetrieval
- Minimal and data-carrying variants where applicable

Envelope operations:
- encodeEnvelope with and without extension TLVs
- decodeEnvelope and decodeEnvelopeWith

Round-trip benchmarks:
- Full encode-then-decode cycle for each message type

All fixtures use NOINLINE pragmas to prevent constant folding. Uses
whnf for encoding functions (ByteString results are strict) and nf for
decoding functions (returning Maybe/Either with tuples).

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>5a0f1476450374dd61c233de3931b9aaa83b9b01</id>
<published>2026-01-25T10:59:19Z</published>
<updated>2026-01-25T10:59:19Z</updated>
<title type="text">bench: implement comprehensive weigh allocation benchmarks</title>
<link rel="alternate" type="text/html" href="commit/5a0f1476450374dd61c233de3931b9aaa83b9b01.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 5a0f1476450374dd61c233de3931b9aaa83b9b01
parent c4d99cf2411b7b18d7d0a25d0d50a53eac5e7eba
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 14:59:19 +0400

bench: implement comprehensive weigh allocation benchmarks

Add allocation tracking benchmarks covering:

- Primitive encoders: encodeU16/U32/U64, encodeS8/S16/S32/S64
- Truncated unsigned encoders: encodeTu16/Tu32/Tu64 (small/full)
- Minimal signed encoder: encodeMinSigned (1/2/4/8 byte outputs)
- BigSize encoder: encodeBigSize (1/3/9 byte outputs)
- Primitive decoders: decode variants for all primitive types
- TLV operations: encodeTlvRecord, encodeTlvStream (1/5/20 records)
- TLV decoding: decodeTlvStreamRaw, decodeTlvStream
- Message encoders: all BOLT#1 message types with variants
- Message decoders: all decode functions with pre-encoded bytes
- Envelope operations: encodeEnvelope, decodeEnvelope

All fixtures use NOINLINE pragmas to prevent constant folding.

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>4f59b3bb1785a9e1b6b4c1e7ccd547ebb980583b</id>
<published>2026-01-25T10:59:14Z</published>
<updated>2026-01-25T10:59:14Z</updated>
<title type="text">feat: add benchmark test fixtures module</title>
<link rel="alternate" type="text/html" href="commit/4f59b3bb1785a9e1b6b4c1e7ccd547ebb980583b.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 4f59b3bb1785a9e1b6b4c1e7ccd547ebb980583b
parent c4d99cf2411b7b18d7d0a25d0d50a53eac5e7eba
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 14:59:14 +0400

feat: add benchmark test fixtures module

Add bench/Fixtures.hs with pre-constructed values for benchmarking:

- Sample ByteStrings of various sizes (64B, 1KB, 16KB)
- Sample ChainHash values (mainnet, testnet genesis hashes)
- Sample ChannelId values
- All message types with minimal and realistic configurations:
  - Init (minimal, with features, with TLVs, full)
  - Error (minimal, with data, with long data)
  - Warning (minimal, with data)
  - Ping (minimal, with response, with padding, large padding)
  - Pong (minimal, with padding, large padding)
  - PeerStorage (minimal, small, large)
  - PeerStorageRetrieval (minimal, small, large)
- TlvStream values (empty, small/1 record, medium/5, large/20)
- Pre-encoded message bytes for decode benchmarks

All fixtures use NOINLINE pragmas to prevent constant folding during
benchmarking, ensuring accurate measurements.

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>c4d99cf2411b7b18d7d0a25d0d50a53eac5e7eba</id>
<published>2026-01-25T10:39:46Z</published>
<updated>2026-01-25T10:39:46Z</updated>
<title type="text">meta: docs</title>
<link rel="alternate" type="text/html" href="commit/c4d99cf2411b7b18d7d0a25d0d50a53eac5e7eba.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit c4d99cf2411b7b18d7d0a25d0d50a53eac5e7eba
parent 3948fa2302ddc49b547a88fd212db03837558637
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 14:39:46 +0400

meta: docs

</content>
</entry>
<entry>
<id>3948fa2302ddc49b547a88fd212db03837558637</id>
<published>2026-01-25T10:31:00Z</published>
<updated>2026-01-25T10:31:00Z</updated>
<title type="text">feat: add ChainHash newtype for type-safe chain hashes</title>
<link rel="alternate" type="text/html" href="commit/3948fa2302ddc49b547a88fd212db03837558637.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 3948fa2302ddc49b547a88fd212db03837558637
parent fb851aecb90a25964163f9a41c07b1e4ae1a20b8
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 14:31:00 +0400

feat: add ChainHash newtype for type-safe chain hashes

- Add ChainHash newtype with 32-byte validation
- Add chainHash smart constructor
- Update InitNetworks to use [ChainHash]
- Update TLV parsing/encoding for ChainHash
- Update tests

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>4f4dd33a850eb03978de3ea49924ff13130a453f</id>
<published>2026-01-25T10:30:55Z</published>
<updated>2026-01-25T10:30:55Z</updated>
<title type="text">feat: add ChainHash newtype for type-safe chain hashes</title>
<link rel="alternate" type="text/html" href="commit/4f4dd33a850eb03978de3ea49924ff13130a453f.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 4f4dd33a850eb03978de3ea49924ff13130a453f
parent af22e72c4b9258f4ec5f48af5c9bc4bf5260cdfb
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 14:30:55 +0400

feat: add ChainHash newtype for type-safe chain hashes

- Add ChainHash newtype with 32-byte validation in Prim module
- Add chainHash smart constructor and unChainHash accessor
- Update InitNetworks to use [ChainHash] instead of [ByteString]
- Update TLV parsing/encoding to wrap/unwrap ChainHash
- Add unsafeChainHash test helper for known-valid test data

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>fb851aecb90a25964163f9a41c07b1e4ae1a20b8</id>
<published>2026-01-25T10:30:15Z</published>
<updated>2026-01-25T10:30:15Z</updated>
<title type="text">feat: add TlvStream smart constructor with ordering validation</title>
<link rel="alternate" type="text/html" href="commit/fb851aecb90a25964163f9a41c07b1e4ae1a20b8.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit fb851aecb90a25964163f9a41c07b1e4ae1a20b8
parent 7dc02f80403bf219e8322850a3575563217e7dc1
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 14:30:15 +0400

feat: add TlvStream smart constructor with ordering validation

- Add tlvStream smart constructor (validates strictly increasing)
- Add unsafeTlvStream for internal/trusted use
- Hide TlvStream data constructor from public API
- Add tests for ordering validation

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>7dc02f80403bf219e8322850a3575563217e7dc1</id>
<published>2026-01-25T10:30:12Z</published>
<updated>2026-01-25T10:30:12Z</updated>
<title type="text">feat: add ChannelId newtype for type-safe channel identifiers</title>
<link rel="alternate" type="text/html" href="commit/7dc02f80403bf219e8322850a3575563217e7dc1.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 7dc02f80403bf219e8322850a3575563217e7dc1
parent af22e72c4b9258f4ec5f48af5c9bc4bf5260cdfb
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 14:30:12 +0400

feat: add ChannelId newtype for type-safe channel identifiers

- Add ChannelId newtype with 32-byte validation
- Add channelId smart constructor and allChannels constant
- Update Error/Warning to use ChannelId
- Update Codec encode/decode for ChannelId
- Update tests

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>82bc4e46f21942423984099fba7b2e3bc7ebe74d</id>
<published>2026-01-25T10:30:10Z</published>
<updated>2026-01-25T10:30:10Z</updated>
<title type="text">feat: add TlvStream smart constructor with ordering validation</title>
<link rel="alternate" type="text/html" href="commit/82bc4e46f21942423984099fba7b2e3bc7ebe74d.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 82bc4e46f21942423984099fba7b2e3bc7ebe74d
parent af22e72c4b9258f4ec5f48af5c9bc4bf5260cdfb
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 14:30:10 +0400

feat: add TlvStream smart constructor with ordering validation

- Add tlvStream smart constructor (validates strictly increasing types)
- Add unsafeTlvStream for internal/trusted use
- Hide TlvStream data constructor from public API
- Update internal uses in decode functions to use unsafeTlvStream
- Add tests for ordering validation

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>5b57c48bc7effea56205c9b9dcbdd0ef10fdc37f</id>
<published>2026-01-25T10:30:07Z</published>
<updated>2026-01-25T10:30:07Z</updated>
<title type="text">feat: add ChannelId newtype for type-safe channel identifiers</title>
<link rel="alternate" type="text/html" href="commit/5b57c48bc7effea56205c9b9dcbdd0ef10fdc37f.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 5b57c48bc7effea56205c9b9dcbdd0ef10fdc37f
parent af22e72c4b9258f4ec5f48af5c9bc4bf5260cdfb
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 14:30:07 +0400

feat: add ChannelId newtype for type-safe channel identifiers

- Add ChannelId newtype wrapping 32-byte ByteString
- Add channelId smart constructor with length validation
- Add allChannels constant for connection-level errors
- Add unChannelId accessor for Codec use
- Update Error/Warning records to use ChannelId
- Update Codec encode/decode to handle ChannelId
- Update tests to use unsafeChannelId helper

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>af22e72c4b9258f4ec5f48af5c9bc4bf5260cdfb</id>
<published>2026-01-25T07:16:54Z</published>
<updated>2026-01-25T07:16:54Z</updated>
<title type="text">fix: address review findings for IMPL3</title>
<link rel="alternate" type="text/html" href="commit/af22e72c4b9258f4ec5f48af5c9bc4bf5260cdfb.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit af22e72c4b9258f4ec5f48af5c9bc4bf5260cdfb
parent 98b9bbba12f72665f6bed7575a571fd4a9b37a40
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 11:16:54 +0400

fix: address review findings for IMPL3

Review: REVIEW-98b9bbba.md

- Add decodeEnvelopeWith for configurable extension TLV handling
  Allows callers to specify which extension TLV types are known,
  enabling future support for negotiated even extension types.

- Add payload size check in encodeMessage (max 65533 bytes)
  Ensures payloads cannot exceed the message limit even when
  encodeMessage is used directly without encodeEnvelope.

- Document unhex test helper partiality
  Clarify that error usage is intentional for test-only code
  where hex literals are known-valid constants.

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>98b9bbba12f72665f6bed7575a571fd4a9b37a40</id>
<published>2026-01-25T07:07:36Z</published>
<updated>2026-01-25T07:07:36Z</updated>
<title type="text">feat: implement BOLT #1 stabilization (IMPL3)</title>
<link rel="alternate" type="text/html" href="commit/98b9bbba12f72665f6bed7575a571fd4a9b37a40.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 98b9bbba12f72665f6bed7575a571fd4a9b37a40
parent b8731a656b99e3bc13cb719ee0f4bf85a94ab075
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 11:07:36 +0400

feat: implement BOLT #1 stabilization (IMPL3)

Phase 1 - Fundamental types:
- Add signed integers: encodeS8/S16/S32/S64, decodeS8/S16/S32/S64
- Add truncated unsigned: encodeTu16/Tu32/Tu64, decodeTu16/Tu32/Tu64
- Add minimal signed encoding per Appendix D test vectors
- Add 68 new tests including all Appendix D vectors

Phase 2 - Validation hardening:
- Add EncodeMessageTooLarge error type
- Enforce message size limit (type + payload + extension &lt;= 65535)

Phase 3 - Extension TLV policy:
- Verified unknown even TLVs rejected in extensions
- Unknown odd types properly skipped

Phase 4 - Module split:
- Lightning.Protocol.BOLT1.Prim: primitive encoding/decoding
- Lightning.Protocol.BOLT1.TLV: TLV types and stream handling
- Lightning.Protocol.BOLT1.Message: message types and ADTs
- Lightning.Protocol.BOLT1.Codec: message encoding/decoding
- Lightning.Protocol.BOLT1: re-exports preserving public API

All 145 tests pass.

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>b8731a656b99e3bc13cb719ee0f4bf85a94ab075</id>
<published>2026-01-25T07:07:21Z</published>
<updated>2026-01-25T07:07:21Z</updated>
<title type="text">docs: add ARCH2 architecture notes and IMPL3 plan</title>
<link rel="alternate" type="text/html" href="commit/b8731a656b99e3bc13cb719ee0f4bf85a94ab075.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit b8731a656b99e3bc13cb719ee0f4bf85a94ab075
parent c9aef2076cf97347841c16de38657caa531c1622
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 11:07:21 +0400

docs: add ARCH2 architecture notes and IMPL3 plan

ARCH2 outlines module decomposition strategy for BOLT #1 stabilization.
IMPL3 details the implementation phases:
- Phase 1: Fundamental types (signed/truncated unsigned integers)
- Phase 2: Validation hardening (message size limits)
- Phase 3: Extension TLV policy verification
- Phase 4: Module split into Prim/TLV/Message/Codec

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>c9aef2076cf97347841c16de38657caa531c1622</id>
<published>2026-01-25T06:44:22Z</published>
<updated>2026-01-25T06:44:22Z</updated>
<title type="text">docs: add README and implementation plans</title>
<link rel="alternate" type="text/html" href="commit/c9aef2076cf97347841c16de38657caa531c1622.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit c9aef2076cf97347841c16de38657caa531c1622
parent e94d28f4bcbf99fe3e6d74f615ee60e9507d3463
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 10:44:22 +0400

docs: add README and implementation plans

- README.md: library overview, usage example, dev instructions
- plans/: architecture notes, implementation plans (IMPL1-*), reviews

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>e94d28f4bcbf99fe3e6d74f615ee60e9507d3463</id>
<published>2026-01-25T06:29:37Z</published>
<updated>2026-01-25T06:29:37Z</updated>
<title type="text">Merge branch &#39;impl/ext-even-check&#39;</title>
<link rel="alternate" type="text/html" href="commit/e94d28f4bcbf99fe3e6d74f615ee60e9507d3463.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit e94d28f4bcbf99fe3e6d74f615ee60e9507d3463
parent 56d27f6673b4a125218f55ff1ee0d2d74889183b
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 10:29:37 +0400

Merge branch &#39;impl/ext-even-check&#39;

Fix extension TLV validation per BOLT #1:

Unknown even TLV types in message extensions must cause failure.
Previously decodeEnvelope used decodeTlvStreamRaw which accepted
all types. Now uses decodeTlvStreamWith (const False) to enforce
the even/odd rule:

- Unknown even types → fail (spec requirement)
- Unknown odd types → skip (ignored per spec)

Tests: 75 → 76 (added unknown-even-in-extension coverage)

</content>
</entry>
<entry>
<id>41855291dc1943189ade89d7d519c002f32cd721</id>
<published>2026-01-25T06:29:31Z</published>
<updated>2026-01-25T06:29:31Z</updated>
<title type="text">fix: reject unknown even TLV types in extensions</title>
<link rel="alternate" type="text/html" href="commit/41855291dc1943189ade89d7d519c002f32cd721.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 41855291dc1943189ade89d7d519c002f32cd721
parent 56d27f6673b4a125218f55ff1ee0d2d74889183b
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 10:29:31 +0400

fix: reject unknown even TLV types in extensions

Per BOLT #1, unknown even TLV types must cause failure. The previous
implementation used decodeTlvStreamRaw for extensions, which accepts
all types without enforcing the even/odd rule.

Now decodeEnvelope uses decodeTlvStreamWith (const False), which:
- Rejects unknown even types (fails per spec)
- Skips unknown odd types (ignores per spec)

Also updates decodeTlvStreamRaw docstring to clarify it does NOT
enforce the BOLT #1 unknown-even-type rule.

Tests updated to verify:
- Unknown even types in extensions cause DecodeInvalidExtension error
- Unknown odd types in extensions are skipped (not returned)
- Mixed even/odd extensions fail on the even type

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>56d27f6673b4a125218f55ff1ee0d2d74889183b</id>
<published>2026-01-25T06:24:13Z</published>
<updated>2026-01-25T06:24:13Z</updated>
<title type="text">Merge branch &#39;impl/review-fixes&#39;</title>
<link rel="alternate" type="text/html" href="commit/56d27f6673b4a125218f55ff1ee0d2d74889183b.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 56d27f6673b4a125218f55ff1ee0d2d74889183b
parent 80d0966d9fc9cf42d98d8f3d1d470defbdad6a01
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 10:24:13 +0400

Merge branch &#39;impl/review-fixes&#39;

Address review findings for BOLT #1 message codec (REVIEW-80d0966):

High severity fixes:
- decodeEnvelope now parses and returns extension TLVs
- Add decodeTlvStreamWith for configurable known-type predicates
- Add decodeTlvStreamRaw for raw TLV parsing without type validation

Medium severity fixes:
- Add bounds checking for u16 length fields (EncodeLengthOverflow error)
- Encoding functions now return Either EncodeError ByteString
- decodeMessage returns DecodeUnknownOddType for unknown odd types

API changes:
- encodeMessage/encodeEnvelope return Either EncodeError ByteString
- decodeMessage returns (Message, ByteString) tuple for remaining bytes
- decodeEnvelope returns (Maybe Message, Maybe TlvStream)
- New exports: decodeTlvStreamWith, decodeTlvStreamRaw, EncodeError

Tests expanded from 55 to 75 cases covering extension handling,
bounds checking, and proper error types.

</content>
</entry>
<entry>
<id>e5ac39b7d1deaa3705f7a5448405670c1601d107</id>
<published>2026-01-25T06:22:07Z</published>
<updated>2026-01-25T06:22:07Z</updated>
<title type="text">fix: address review findings for message codec</title>
<link rel="alternate" type="text/html" href="commit/e5ac39b7d1deaa3705f7a5448405670c1601d107.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit e5ac39b7d1deaa3705f7a5448405670c1601d107
parent 80d0966d9fc9cf42d98d8f3d1d470defbdad6a01
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 10:22:07 +0400

fix: address review findings for message codec

High severity:
- decodeEnvelope now parses and returns extension TLVs
- Add decodeTlvStreamWith for configurable known-type predicates
- Add decodeTlvStreamRaw for raw TLV parsing without type validation

Medium severity:
- Add bounds checking for u16 length fields (EncodeLengthOverflow)
- encodeMessage/encodeEnvelope now return Either EncodeError
- Fix decodeMessage to return DecodeUnknownOddType (not InsufficientBytes)

Low severity:
- Test helper unhex now uses error (still partial, but clearer)

API changes:
- encodeMessage :: Message -&gt; Either EncodeError ByteString
- encodeEnvelope :: Message -&gt; Maybe TlvStream -&gt; Either EncodeError ByteString
- decodeMessage :: MsgType -&gt; ByteString -&gt; Either DecodeError (Message, ByteString)
- decodeEnvelope :: ByteString -&gt; Either DecodeError (Maybe Message, Maybe TlvStream)
- New: decodeTlvStreamWith, decodeTlvStreamRaw, EncodeError, DecodeUnknownOddType

Tests expanded from 55 to 75 cases.

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>80d0966d9fc9cf42d98d8f3d1d470defbdad6a01</id>
<published>2026-01-25T06:00:16Z</published>
<updated>2026-01-25T06:00:16Z</updated>
<title type="text">Merge branch &#39;impl/message-codec&#39; - BOLT #1 message codec (IMPL1-4)</title>
<link rel="alternate" type="text/html" href="commit/80d0966d9fc9cf42d98d8f3d1d470defbdad6a01.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 80d0966d9fc9cf42d98d8f3d1d470defbdad6a01
parent 1b7add76c3d13003e32a6e0166fd231624b47b0f
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 10:00:16 +0400

Merge branch &#39;impl/message-codec&#39; - BOLT #1 message codec (IMPL1-4)

Implements complete encode/decode support for BOLT #1 messages per the
specification at https://github.com/lightning/bolts/blob/master/01-messaging.md

## Core Primitives

- Big-endian unsigned integers: u16, u32, u64 encode/decode
- BigSize variable-length encoding with minimality validation per spec
- All primitives return remaining bytes for streaming decode

## TLV (Type-Length-Value)

- TlvRecord and TlvStream types for extension data
- Encoding uses minimal BigSize for type and length fields
- Decoding enforces BOLT #1 validation rules:
  - Strictly increasing type ordering (no duplicates)
  - Non-minimal encoding rejected
  - Length exceeding remaining bytes rejected
  - Unknown even types fail (close connection)
  - Unknown odd types silently skipped

## Message Types

All BOLT #1 messages implemented with strict fields:

- Setup: Init (type 16) with init_tlvs (networks, remote_addr)
- Setup: Error (type 17), Warning (type 1)
- Control: Ping (type 18), Pong (type 19)
- Peer Storage: peer_storage (type 7), peer_storage_retrieval (type 9)

## Message Envelope

- encodeEnvelope: type (u16) + payload + optional extension TLV
- decodeEnvelope: parses type, dispatches to message decoder
- Unknown odd message types return Nothing (ignore per spec)
- Unknown even message types return error (close connection per spec)

## Tests (61 total, all passing)

- BigSize encode/decode vectors from BOLT #1 Appendix A
- Primitive roundtrip tests
- TLV validation: ordering, duplicates, unknown types, length bounds
- Message encode/decode for all types
- Envelope handling of unknown types
- QuickCheck property tests for roundtrip invariants

## Dependencies

Added deepseq (for NFData instances) and tasty-quickcheck (for tests).

</content>
</entry>
<entry>
<id>af13f6a0e81dff9456beb7ac86271f7bfecca033</id>
<published>2026-01-25T05:55:51Z</published>
<updated>2026-01-25T05:55:51Z</updated>
<title type="text">feat: implement BOLT #1 message codec</title>
<link rel="alternate" type="text/html" href="commit/af13f6a0e81dff9456beb7ac86271f7bfecca033.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit af13f6a0e81dff9456beb7ac86271f7bfecca033
parent 1b7add76c3d13003e32a6e0166fd231624b47b0f
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 09:55:51 +0400

feat: implement BOLT #1 message codec

Implements encode/decode for all BOLT #1 message types per IMPL1-4:
- Core primitives (u16, u32, u64, BigSize with minimality checks)
- TLV record and stream types with BOLT #1 validation rules
- Message ADTs: init, error, warning, ping, pong, peer_storage,
  peer_storage_retrieval
- Message envelope encode/decode with optional extension TLV
- Unknown type handling: odd types ignored, even types fail

Tests include:
- BigSize vectors from Appendix A
- Unit tests for all message types
- Negative tests for invalid lengths and unknown even types
- Property tests for encode/decode roundtrips

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;

</content>
</entry>
<entry>
<id>1b7add76c3d13003e32a6e0166fd231624b47b0f</id>
<published>2026-01-25T05:27:43Z</published>
<updated>2026-01-25T05:27:43Z</updated>
<title type="text">init: ppad-bolt1 project skeleton</title>
<link rel="alternate" type="text/html" href="commit/1b7add76c3d13003e32a6e0166fd231624b47b0f.html" />
<author>
<name>Jared Tobin</name>
<email>jared@jtobin.io</email>
</author>
<content type="text">commit 1b7add76c3d13003e32a6e0166fd231624b47b0f
Author: Jared Tobin &lt;jared@jtobin.io&gt;
Date:   Sun, 25 Jan 2026 09:27:43 +0400

init: ppad-bolt1 project skeleton

Initial project setup for BOLT #1 (Lightning Network base protocol)
implementation.

Project structure:
- lib/Lightning/Protocol/BOLT1.hs - stub library module
- test/Main.hs - tasty test harness
- bench/{Main.hs,Weight.hs} - criterion/weigh benchmarks
- etc/01-messaging.md - BOLT #1 specification for reference
- flake.nix - nix flake with ppad-nixpkgs
- ppad-bolt1.cabal - cabal package definition

Co-Authored-By: Claude Opus 4.5 &lt;noreply@anthropic.com&gt;

</content>
</entry>
</feed>
