BP BitPads Protocol
BP BitPads Protocol

Implementation Guide · BitPads Protocol v2.0 / BitLedger v3.0

Mission
Manual

You have read the specs. Now build the encoder or decoder. This guide walks every algorithm step by step with real values throughout.

Every BitPads implementation starts at the same byte: Meta byte 1. Two paths diverge from there depending on whether you are producing frames or consuming them.

Path A
Encoder

Assemble BitPads frames from application data. Start at the Meta byte, determine mode, populate layers from innermost to outermost, compute CRC-15 last. Output is a byte sequence conforming to the wire format.

Sections: Value EncodingLayer 1Layer 2Layer 3

Path B
Decoder

Parse incoming BitPads bytes into structured records. Read the Meta byte first, branch on mode, traverse the fixed component sequence, validate cross-layer rules after each record.

Sections: Meta ByteState MachineLayer 3 Validation

Both paths
Common Ground

The Meta byte is the universal entry point. Both encoder and decoder must implement the full Meta byte interpretation table. All fields are positional — no schema lookup, no field identifiers. Know the position and you know the meaning.

Spec refs: BitPads v2 · BitLedger v3

Bit numbering convention. The spec numbers bits 1–8 from MSB (most significant) to LSB. Bit 1 is the high bit of each byte. Confirm your byte-manipulation code matches this convention before encoding any field. Reversal here corrupts every frame silently. See Common Pitfalls.

Entry Point — All Parsing Starts Here

Meta Byte Decoder

Every BitPads frame begins with Meta byte 1. Read exactly one byte. This byte fully determines what follows before you read a single additional bit. The first branch is on bit 1 — Wave or Record mode.

Bit Layout — Meta Byte 1

Meta Byte 1 — field map (all modes)
1 ? Mode
2 ? ACK/
SysCtx
3 ? Cont.
4 ? Treat/
Ignored
5 ? A/B/C
6 ? A/B/C
7 ? A/B/C
8 ? A/B/C
Mode / Control Content Field — Role A / B / C

Full Decision Tree

READ byte[0] ← Meta Byte 1 ├─ bit1 = 0 → WAVE MODE │ │ │ ├─ bit2 = 1 → ACK Request flagged │ │ (single byte alone = Pure Signal) │ │ │ ├─ bit3 = 1 → Fragment — accumulate bytes until bit3=0 │ │ │ ├─ bit4 = 0 → BASIC TREATMENT — Role A active │ │ │ │ │ ├─ bit5 = Priority flag (0=normal 1=elevated) │ │ ├─ bit6 = Cipher Active (0=plain 1=rolling codebook) │ │ ├─ bit7 = Extended Flags (0=none 1=ext byte follows) │ │ └─ bit8 = Profile Defined (0=standard 1=profile applies) │ │ │ └─ bit4 = 1 → CATEGORY MODE — Role B active │ │ │ └─ bits5-8 = 4-bit category code → see Wave category table below └─ bit1 = 1 → RECORD MODE ├─ bits5-8 = Role C expect flags: bit5=Value Present bit6=Time Present bit7=Task Present bit8=Note Present └─ READ byte[1] ← Meta Byte 2 (always follows in Record mode) ├─ bits1-4 = Archetype / sub-type by category ├─ bits5-6 = Time tier selector │ 00=none 01=T1 session offset │ 10=T1 external ref 11=T2 Time Block ├─ bit7 = Setup Byte Present (1=Setup byte precedes Value block) └─ bit8 = Signal Slot Presence 0 → proceed to Layer 1 directly 1 → READ Signal Slot Presence byte first, then proceed to Layer 1

Wave Category Table — bits 5-8 (Role B, bit4=1)

Code Category Layer 1? Structure
0000Plain ValueSession est.Setup byte (opt.) + Value block at tier
0001Simple MessageSession est.1-byte length prefix + content bytes
0010Status / LogSession est.Status code or length + log content
0011Command / RequestSession est.Task short form (1 byte) + optional ext
0100Basic RecordRequiredLayer 1 + opt. Layer 2 + value + opt. time
0101Transaction + MessageRequiredLayer 1 + Layer 2 + BL ctrl + value + note
0110Rich Log EntryRequiredLayer 1 + all four components
0111Priority AlertRequiredLayer 1 + value + task, priority override
1000Text StreamSessionStream-length prefix + UTF-8 bytes
1001Flag / Archetype StreamSessionStream-Open ctrl + length + packed flags
1010Variable Field StreamSessionStream-Open + length-prefixed fields
1011Binary BlobSessionLength prefix + raw binary
1100Compact CommandNoEnhancement grammar — upper 3=class, lower 5=code
1101Context DeclarationNoContext Declaration Block, 1–4 bytes
1110Telegraph EmulationSessionFull C0 Enhancement Grammar stream
1111Extended CategoryDependsNext byte = 8-bit extended category code

Wave category 1100/1101/1110 engage the Enhancement Sub-Protocol. See Enhancement Grammar for the full C0 byte structure. In these categories every content byte carries 3 flag bits (P/A/C) in its upper 3 bits and 5 content bits in its lower 5.

Algorithm

Value Encoding Algorithm

All values encode as whole integers using the formula N = A × 2S + r. No floating point anywhere. Every integer from 0 to 33,554,431 is reachable without gaps. Rounding, when it occurs, is always explicit — two flag bits declare direction.

N = A × 2S + r
N = stored integer in the value block
A = upper (25−S) bits = floor(N / 2S)
S = Optimal Split from Layer 2 (default 8)
r = lower S bits = N mod 2S
Real Value = (N × Scaling Factor) / 10Decimal Position

Encoder Algorithm — Step by Step

  1. Determine the target real value V (e.g. $4.53). Obtain SF (Scaling Factor) and D (Decimal Position) from Layer 2 batch context.
  2. Compute raw stored integer: R = V × 10D / SF. Example: V=4.53, SF=1, D=2 → R = 4.53 × 100 / 1 = 453.
  3. Check if R is a whole integer. If yes: set N = R, bit 26 = 0, bit 27 = 0 (exact). Skip to step 6.
  4. Rounding required. Choose direction by account type: Liability/Tax → round up (ceiling). Asset/Income → round down (floor). General → round to nearest. Set N = floor(R) or ceil(R). Set bit 26 = 1. Set bit 27 = 0 (down) or 1 (up).
  5. Range check: if N > 33,554,431, increase SF to next power of 10 and return to step 2.
  6. Obtain Optimal Split S from Layer 2 (default S=8). Compute: A = floor(N / 2S), r = N mod 2S. Pack A into upper bits, r into lower bits of value block.

Worked Example — $4.53 at SF×1, D=2, S=8

── ENCODER: $4.53 ────────────────────────────
Target V $4.53
SF, D, S ×1, D=2, S=8
──────────────────────────────────────────────
Step 1 R = 4.53 × 100 / 1 = 453
Step 2 453 is whole integer → exact
Bit 26 0 (exact)
Bit 27 0 (must be 0 when bit26=0)
──────────────────────────────────────────────
N 453
A = ⌊453/256⌋1 → stored in bits 1-17
r = 453 mod 256197 → stored in bits 18-25
──────────────────────────────────────────────
Decode check N = 1×256 + 197 = 453
Real Value 453 × 1 / 100 = $4.53 ✓ exact

Value Tier Reference

Tier Setup bits 1-2 Block bits Max N Max at SF×1, D=2 When to use
T1 00 8 bits 255 $2.55 Status codes, deep space IoT, single-byte values
T2 01 16 bits 65,535 $655.35 Small sensor values, local measurements
T3 10 (DEFAULT) 24 bits 16,777,215 $167,772.15 General purpose — default when no Setup byte present
T4 11 32 bits 4,294,967,295 $42,949,672.95 Large assets, high-volume physical quantities
Value Encoder — N = A × 2S + r

Session Header

Layer 1 — 8 Bytes

Layer 1 is transmitted once at session open. It carries sender identity, domain, permissions, session defaults, and a CRC-15 checksum over bits 1–49. CRC is computed AFTER all other fields are populated.

Bit 1 SOH Always 1
Bit 2 Wire Ver 0=v1 current
Bits 3-4 Domain 00=Financial
Bits 5-8 Permissions R/W/C/Proxy
Bit 9 Split Order 0=Mulcand first
Bits 10-11 ID Split 00=Flat 32-bit
Bit 12 Enh. Flag 0=off 1=C0 on
Bits 13-44 Sender ID 32-bit flat/split
Bits 45-49 Sub-Entity 5-bit (0-31)
Bits 50-64 CRC-15 x^15+x+1

CRC-15 Encoding Algorithm

The CRC-15 covers bits 1–49 (the 49-bit session payload). Generator polynomial: G = x15 + x + 1 = 0x8003. At the encoder side, compute the remainder, then embed in bits 50–64.

── CRC-15 ENCODER ────────────────────────────────────────────
Input P = bits 1-49 (49-bit session payload)
──────────────────────────────────────────────────────────────
Step 1: Append 15 zero bits
W = P[1..49] + 000000000000000 // W is now 64 bits
 
Step 2: XOR shift loop — one iteration per payload bit
for i = 1 to 49:
if leading bit of W == 1:
W = W XOR (G << (64 - 15 - i)) // align polynomial
W = W << 1
 
Step 3: Extract remainder
R = final 15 bits of W
 
Step 4: Pack into frame
transmit: bits[1..49] followed by R[0..14]
total: 64 bits = 8 bytes = Layer 1 complete
──────────────────────────────────────────────────────────────
DECODER: run CRC-15 over all 64 received bits using same polynomial.
Result == 0x0000 → session accepted
Result != 0x0000 → NACK, session rejected, request retransmission

Worked Example — Layer 1 Construction

── LAYER 1 EXAMPLE: Sender ID 0x00291847 ─────────────────────
SOH 1 // always 1, self-framing
Wire Ver 0 // current wire format v1
Domain 00 // Financial
Permissions 1111 // Read+Write+Correct+Proxy all set
Split Order 0 // Multiplicand first
ID Split 00 // Flat 32-bit Node ID
Enh. Flag 0 // No C0 Enhancement this session
Sender ID 0000 0000 0010 1001 0001 1000 0100 0111 // 0x00291847
Sub-Entity 00100 // sub-entity 4
──────────────────────────────────────────────────────────────
Payload bits 49 bits assembled (bits 1-49)
CRC-15 resultcomputed over 49-bit payload, polynomial 0x8003
CRC example 011 0100 1011 0001 // 15 bits embedded at bits 50-64
──────────────────────────────────────────────────────────────
Final hex 80 F0 01 48 C2 1C 06 B1 // 8 bytes = Layer 1 complete

v2.0 change: Layer 1 bit 12 is now the Session Enhancement Flag (was Opposing Convention in v1). When bit 12 = 1, a Session Configuration Extension byte follows Layer 1 before any content. It carries Nesting Level Code, Opposing Convention, Compound Mode Active, and BL Block Optional flags.

Session Config Extension Byte (when bit 12 = 1)

BitsFieldValuesMeaning
1-2Nesting Level Code00–1100=Flat only. 01=Depth 2. 10=Depth 4. 11=Extended (ext byte follows).
3Opposing Convention0/10=Opposing inferred. 1=Always transmitted explicitly in extension byte.
4Compound Mode Active0/10=Off. 1=1111 continuation markers valid this session.
5BL Block Optional0/10=Accounting block always present. 1=Optional per record.
6-8Reserved111Transmit as 1.

Batch Header

Layer 2 — 6 Bytes (48 bits)

Layer 2 establishes the decoding context for an entire batch. Every record in the batch inherits SF, D, and currency without re-stating them. Transmitted once before the first record in each batch.

Bits 1-2 TX Type 01=Pre-conv
Bits 3-9 Scale Factor 7-bit index
Bits 10-13 Opt. Split 0-15 (def=8)
Bits 14-16 Dec. Position 010=D=2
Bit 17 Enquiry Bell 0/1
Bit 18 ACK Bell 0/1
Bits 19-22 Group Sep 4-bit group ID
Bits 23-27 Record Sep 5-bit rec ID
Bits 28-30 File Sep 3-bit file ID
Bits 31-35 Entity ID 5-bit
Bits 36-41 Currency 6-bit code
Bits 42-45 Rounding Bal 4-bit signed
Bits 46-47 Compound Pfx 00-11
Bit 48 Reserved Always 1

Encoding Example — USD, D=2, SF×1, Batch 1

── LAYER 2: USD · SF×1 · D=2 · Batch 1 ─────────────────────
TX Type 01 // Pre-converted (bit1-2)
Scale Factor 000 0000 // index 0 = ×1 (bits 3-9)
Optimal Split1000 // 8 bits for multiplier (bits 10-13)
Dec. Position010 // D=2, standard retail/banking (bits 14-16)
Enquiry Bell 0 // no ACK request
ACK Bell 0 // no ACK confirmation
Group Sep 0001 // group 1 (bits 19-22)
Record Sep 00001 // record group 1 (bits 23-27)
File Sep 001 // file 1 (bits 28-30)
Entity ID 00100 // sub-entity 4 (bits 31-35)
Currency 000001 // USD = code 1 (bits 36-41)
Rounding Bal 0000 // exactly balanced (bits 42-45)
Compound Pfx 00 // no compound records in batch
Reserved 1 // always 1 (bit 48)
──────────────────────────────────────────────────────────────
Raw bits 01 0000000 1000 010 0 0 0001 00001 001 00100 000001 0000 00 1
Hex 40 10 84 08 04 81 // 6 bytes = Layer 2 complete
Precision Step = $0.01 · Max = $335,544.31 · Currency: USD

Rounding Balance — Sign-Magnitude Encoding

Bits 42-45 track net rounding for the batch. High bit = sign (0=rounded up, 1=rounded down). Lower 3 bits = magnitude in minimum precision units. 0000 = exactly balanced. 1000 = escape — magnitude exceeds 7, see batch-close control record.

The precision unit is always SF / 10D. At SF×1, D=2: precision unit = $0.01.

Transaction Record

Layer 3 — The 40-Bit Record

Five bytes. Both sides of a double-entry transaction. Three independent error detection mechanisms operate on every record without a separate checksum field.

Bits 1-17 Multiplicand A 17 bits, 0-131071
Bits 18-25 Multiplier r 8 bits, 0-255
Bit 26 Rounding 0=exact
Bit 27 Round Dir 0=down 1=up
Bit 28 Split Order 0=session def
Bit 29 Direction 0=In 1=Out
Bit 30 Status 0=Paid 1=Debt
Bit 31 Dr/Cr 0=Cr 1=Dr
Bit 32 Qty Present 0=flat 1=split
Bits 33-36 Acct Pair 0000-1111
Bit 37 BL Dir = bit 29
Bit 38 BL Status = bit 30
Bit 39 Complete 0=full 1=part
Bit 40 Ext Flag 0=done 1=ext

Cross-Layer Validation Rules

These rules provide two of the three independent error detection signals on every record. Any violation means the record is malformed — reject before posting.

Rule 1 — Direction Mirror
bit29 (Set A) Direction flag
bit37 (BL) Direction flag
 
MUST be equal:
if record[29] != record[37]:
raise ProtocolError('direction mismatch')
Rule 2 — Status Mirror
bit30 (Set A) Status flag
bit38 (BL) Status flag
 
MUST be equal:
if record[30] != record[38]:
raise ProtocolError('status mismatch')
── CROSS-LAYER VALIDATION — FULL PSEUDOCODE ──────────────────
Rule 1: direction mirror
if record[29] != record[37]: PROTOCOL ERROR — record rejected
 
Rule 2: status mirror
if record[30] != record[38]: PROTOCOL ERROR — record rejected
 
Rule 3: rounding state validity
if record[26] == 0 and record[27] == 1:
PROTOCOL ERROR — state 01 is structurally invalid
do not post to ledger
──────────────────────────────────────────────────────────────
All three rules pass → record valid, proceed to conservation check

Conservation Invariant Check

Run after completing each batch (when batch-end flag is set). The sum of all signed flows must equal zero. A batch that fails this check is invalid — it may contain phantom flows, missing records, or duplicates.

── CONSERVATION CHECK — PER BATCH ───────────────────────────
batch_balance = 0
 
for each record in batch:
N = decode_value(record) // apply A, S, r formula
real_val = (N × SF) / 10^D
 
if record[29] == 0: // Direction = In (Plus)
batch_balance += real_val
else: // Direction = Out (Minus)
batch_balance -= real_val
 
if record[39] == 0 and is_batch_end:
break // batch closed
 
Account for rounding balance from Layer 2 bits 42-45
batch_balance += rounding_balance_from_L2
 
if batch_balance != 0:
BATCH INVALID — conservation violation
send NACK, reject batch, flag for investigation
else:
BATCH VALID — conservation confirmed
──────────────────────────────────────────────────────────────
Note: check is per-batch, not per-record.
Do not check after each individual record.

Full BitLedger Frame Example — $100.00 USD Debit, Account Pair 0001

── LAYER 3 RECORD: $100.00 USD Debit, Op Expense/Liability ──
Target $100.00 SF=×1 D=2 S=8
N 10000
A = ⌊10000/256⌋39
r = 10000 mod 25616
Decode check 39×256 + 16 = 10000 → $100.00 exact
──────────────────────────────────────────────────────────────
Bits 1-17 0 0000 0000 0010 0111 // A=39
Bits 18-25 0001 0000 // r=16
Bit 26 0 // exact
Bit 27 0 // must be 0 when bit26=0
Bit 28 0 // follow session split order
Bit 29 1 // Out (Debit disbursement)
Bit 30 1 // Debt (accrued, not yet settled)
Bit 31 1 // Debit side
Bit 32 0 // flat value, qty implicit=1
──────────────────────────────────────────────────────────────
Bits 33-36 0001 // Acct pair: Op Expense / Liability
Bit 37 1 // Out — must match bit29 ✓
Bit 38 1 // Debt — must match bit30 ✓
Bit 39 0 // Full, transaction complete
Bit 40 0 // no extension byte
──────────────────────────────────────────────────────────────
Record hex 00 27 10 0E 03 // 5 bytes = Layer 3 complete
Journal DEBIT Op Expense $100.00 / CREDIT Accounts Payable $100.00

Parser

Decoder State Machine

The decoder is a deterministic state machine. State transitions are driven exclusively by the bytes read and the flags previously set. No lookahead. No ambiguity. Each state reads a fixed number of bytes or derives the count from previously read flags.

State
Bytes
Action / Transition
INIT
0
Idle. Await any byte. If byte = 0x01 (SOH leading 1-bit) → unconditionally open Layer 1 read. Otherwise → read as Meta byte 1. → META1
META1
1
Decode bit1. If bit1=0 → Wave mode, read category or Role A flags, branch per category. Standalone = WAVE_COMPLETE. If bit1=1 → Record mode. → META2_EXPECT
META2_EXPECT
1
Read Meta byte 2. Decode bits1-4 (archetype/sub-type), bits5-6 (time tier), bit7 (Setup byte present), bit8 (Signal Slot Presence). → META2
META2
0
Branch: if Meta2 bit8=1 → read 1 Signal Slot Presence byte, store P4-P8 flags. If bit8=0 → skip. → L1_EXPECT
L1_EXPECT
8
Read 64 bits (8 bytes) for Layer 1. Run CRC-15 over all 64 bits. If CRC ≠ 0x0000 → NACK, session rejected. If CRC = 0x0000 → valid. Store Sender ID, domain, permissions, session defaults, Enhancement Flag (bit12). → L1
L1
0
Branch: if L1 bit12=1 (Enhancement active) → read Session Config Extension byte, store nesting, opposing, compound, BL-optional flags. If nesting code=11 → read Nesting Declaration Extension. If Meta1 bit2=1 → read System Context Extension block. → L2_EXPECT
L2_EXPECT
6
Read 48 bits (6 bytes) for Layer 2 batch header. Store SF, Optimal Split, DP, separators, Entity ID, currency, rounding balance, compound prefix. → L2
L2
0
SF, DP, Optimal Split stored. Batch context established. If compound prefix ≠ 00 → enter compound-aware mode. → L3_EXPECT
L3_EXPECT
5
Read 40 bits (5 bytes) for Layer 3 record. → L3
L3
0
Decode value block (N = A×2S+r). Check rounding state (bits 26-27). Run cross-layer validation (bit29=bit37, bit30=bit38). Update batch balance. If bits 33-36 = 1111 → COMPOUND_CONTINUATION. If bit40=1 → read extension byte(s). → RECORD_COMPLETE or COMPOUND_CONTINUATION
COMPOUND_CONTINUATION
5
Linked record. Bits 37-38 carry sub-type (00=standard, 01=correction, 10=reversal, 11=cross-batch). Bit39=1 → more continuations follow, read another L3. Bit39=0 → compound closed. → RECORD_COMPLETE
RECORD_COMPLETE
0
If batch-end flag set (control record type 010 or record count met) → run conservation check (batch_balance = 0?). If valid → post records to ledger. → L3_EXPECT (next record) or INIT
WAVE_COMPLETE
0
Wave frame consumed. Process per category (value, message, command, stream, etc.). If bit3=1 in prior Meta byte → accumulate next fragment until bit3=0. → INIT

Enhancement signal slots. When Layer 1 bit 12 = 1 (Enhancement active), the state machine inserts C0 Enhancement reads at each declared signal slot position. P4 = before Value block, P5 = after Value block, P6 = after Time field, P7 = after Task block, P8 = after Note block. Session-layer slots P1-P3 appear at session open. Batch-layer slots P9-P11 appear at batch open/close. See Enhancement Grammar for full slot map.

C0 Enhancement Grammar

Enhancement Decoder

When Layer 1 bit 12 = 1 and the Signal Slot Presence byte declares one or more slots active, the decoder encounters enhanced C0 bytes at the declared positions. Each enhanced C0 byte carries a 3-bit flag matrix in its upper 3 bits and a 5-bit C0 code identity in its lower 5 bits.

Enhanced C0 Byte Structure

Enhanced C0 Byte — upper 3 bits = flags, lower 5 = C0 identity
1 P Priority
2 A ACK Req
3 C Cont.
4 C0 Code
5 C0 Code
6 C0 Code
7 C0 Code
8 C0 Code
Enhancement flags (P/A/C) C0 code identity (5 bits, 0-31)

Enhancement Decode Algorithm

  1. Determine the byte is at a declared signal slot position (P4-P8 per Signal Slot Presence byte, or P1-P3/P9-P13 for session/batch/stream positions when bit12=1).
  2. Read the byte. Extract upper 3 bits: P (bit1) = Priority flag, A (bit2) = Acknowledge Request, C (bit3) = Continuation flag.
  3. Extract lower 5 bits (bits 4-8): this is the C0 code identity (0-31). Look up in the agreed control table. 29 unconditional codes always map to the same controls. 4 conditional codes are context-dependent.
  4. If P=1: process this signal at elevated priority before lower-priority pending items. If A=1: queue an ACK signal to be sent at the corresponding response slot.
  5. Route to the appropriate handler for the decoded C0 control (e.g. SOH, STX, ETX, BEL, SO, SI, EM, SUB, FS, GS, RS, US, etc.).
  6. If C=1 (Continuation flag set): read the next byte as another enhanced C0 signal at the same slot position. Repeat from step 2. If C=0: slot consumption complete, resume normal frame parsing.
── ENHANCED C0 DECODE EXAMPLE ─────────────────────────────
Byte at P5 0xC5 = 1100 0101
Upper 3 bits 1 1 0 // P=1 (Priority), A=1 (ACK req), C=0 (no more)
Lower 5 bits 0 0101 // C0 code 5 = ENQ (Enquire)
──────────────────────────────────────────────────────────
P flag 1 → elevated priority, process first
A flag 1 → ACK required — queue response signal
C flag 0 → slot done, return to normal parsing
C0 code 5 ENQ → route to Enquire handler

Implementation Warnings

Common Pitfalls

The following mistakes recur in first-time implementations. Each has a single correct resolution. Click any row to expand.

Pitfall Symptom
CRITICALBit ordering reversed — MSB/LSB confusion All frames decode incorrectly. Mode always wrong.
The Problem

The spec numbers bits 1–8 from MSB (most significant) to LSB (least significant). Bit 1 is the high bit. Many implementors default to LSB-first numbering, which silently reverses every field.

The Fix

Pure Signal 0x40 = 0100 0000. Bit 1 (MSB) = 0 (Wave mode). Bit 2 = 1 (ACK Request). Write a single-byte decoder that produces this interpretation. If it does, your bit ordering is correct. If not, reverse your extraction mask.

CRITICALCRC-15 computed over wrong byte range All sessions rejected at receiver. CRC never validates.
The Problem

CRC-15 covers the 49-bit session payload (bits 1–49 of Layer 1). It does NOT cover Layer 2 or Layer 3 independently. A common mistake is computing CRC over the full frame or over only the first byte.

The Fix

Compute CRC-15 over exactly bits 1–49 of Layer 1 (SOH through Sub-Entity ID). Embed the 15-bit remainder at bits 50–64. Decoder: run the same CRC over all 64 bits — a correct frame produces remainder 0x0000.

HIGHCompound mode without session permission 1111 account pair triggers decode errors. Records corrupted.
The Problem

Account pair 1111 is the compound continuation marker. You cannot use it unless Compound Mode Active is set in the Session Config Extension byte (bit 4) AND the Layer 2 Compound Prefix is non-00 for the current batch. Both must be active.

The Fix

At session open, set Session Enhancement Flag (bit 12 = 1) and include Session Config Extension with bit 4 = 1. At batch open, set Compound Prefix to 01, 10, or 11 as appropriate. Only then is 1111 valid in Layer 3 records.

HIGHConservation check run after each record All multi-record batches flagged as invalid. False positives.
The Problem

The conservation invariant (sum of all signed flows = 0) is a batch-level invariant, not a per-record invariant. Checking it after each record will always fail for batches with more than one record.

The Fix

Accumulate the running batch balance across all records. Run the conservation check exactly once — at batch close (batch-end flag from control record type 010 or batch record count met). Only then check batch_balance == 0.

MEDIUMRounding balance in Layer 2 not carried across records Batches with rounded values fail conservation check despite correct encoding.
The Problem

Layer 2 bits 42-45 encode the net rounding balance for the batch in sign-magnitude form. When records are rounded, the accumulated rounding delta is declared here. A decoder that ignores this field will see a non-zero batch balance even for a correctly encoded rounded batch.

The Fix

Decode the 4-bit rounding balance (high bit = sign: 0=rounded up, 1=rounded down; lower 3 bits = magnitude in precision units). Add this to the batch balance before the conservation check. Code 1000 = escape — read the full value from the batch-close control record payload.

MEDIUMSignal Slot Presence byte assumed always present Decoder reads Layer 1 one byte late. All subsequent fields corrupted.
The Problem

The Signal Slot Presence byte (Meta byte 2 bit 8) is CONDITIONAL. It only appears when Meta byte 2 bit 8 = 1. The most common case is bit 8 = 0, in which case the byte is absent and the sequence proceeds directly from Meta byte 2 to Layer 1.

The Fix

Always read Meta byte 2 bit 8 first. If bit 8 = 0: proceed directly to Layer 1. If bit 8 = 1: read exactly one Signal Slot Presence byte, decode P4-P8 flags (bits 1-5), then proceed to Layer 1. Never assume the byte is present.

LOWWave mode vs Record mode misidentified Frames parsed in wrong mode. Garbled output for all frame types.
The Problem

Mode is determined by bit 1 of Meta byte 1 only. No other byte, no preamble, no frame length prefix indicates mode. Do not infer mode from byte count, context, or any other field.

The Fix

Read bit 1 of the first byte. 0 = Wave mode. 1 = Record mode. Apply this branch unconditionally before reading any other field. Do not cache mode across frames — read it fresh from every new Meta byte 1.

Verification

Test Vectors

Known-good byte sequences for implementation verification. An encoder producing these exact byte sequences, and a decoder consuming them and producing the stated interpretation, is conformant for the covered cases.

Vector 1 — Pure Signal (1 byte)

── PURE SIGNAL ──────────────────────────────────────────────
Hex 40
Binary 0100 0000
────────────────────────────────────────────────────────────
Byte 0 0x40
bit1 0 = Wave mode
bit2 1 = ACK Request
bit3 0 = Complete (no continuation)
bit4 0 = Basic treatment, Role A active
bits5-8 0000 = no priority, plain, no ext, standard
────────────────────────────────────────────────────────────
Meaning I am here. Acknowledge me.
Response ACK control record 0x31
Total bytes 1

Vector 2 — Minimal Wave (4 bytes — anonymous value $4.53)

── MINIMAL WAVE — $4.53 SF×1 D=2 ───────────────────────────
Hex 0F 00 01 C5
Binary 0000 1111 00000000 00000001 11000101
────────────────────────────────────────────────────────────
Byte 0: 0x0F bit1=0 Wave, bit2=0 no ACK, bit3=0 complete,
bit4=1 Category mode → bits5-8 = 0000 Plain Value
Byte 1: 0x00 Setup byte: tier=00 (T1 explicit), SF=00 (×1), D=01 (D=2)
(in this example tier 3 default, byte signals defaults)
Bytes 2-3 Value block Tier 3 (24-bit): A=1, r=197
A bits 00000000 00000001 = 1
r bits 11000101 = 197
────────────────────────────────────────────────────────────
Decode N = 1×256 + 197 = 453
Real Value $4.53 (453 × 1 / 100)
Total bytes 4

Vector 3 — Minimal Record with Layer 1 (13 bytes)

── MINIMAL RECORD — Meta×2 + Layer 1 + Tier 3 Value ─────────
Hex 80 00 80 F0 01 48 C2 1C 06 B1 00 27 10
── BYTE MAP ─────────────────────────────────────────────────
Byte 0: 0x80 Meta byte 1: bit1=1 Record, bits5-8=0000 no components
Byte 1: 0x00 Meta byte 2: no archetype, no time, no setup, no slots
Bytes 2-9 Layer 1 (8 bytes):
80 SOH=1, ver=0, domain=00 (fin), perms=1111
F0 split=0, ID-split=00, enh=0, SenderID high
01 48 C2 Sender ID mid/low bytes (= 0x00291847 partial)
1C Sub-entity ID (5 bits) + CRC-15 high bits
06 B1 CRC-15 low bytes
Bytes 10-12 Layer 3 value block (3 bytes = Tier 3 default):
00 27 10 N = 39×256 + 16 = 10000 → $100.00 at SF×1 D=2
────────────────────────────────────────────────────────────
Total bytes 13 (minimum full record)

Vector 4 — Full BitLedger Frame (22 bytes — $100.00 USD Debit, account pair 0001)

── FULL BITLEDGER FRAME — $100.00 USD DEBIT ─────────────────
Total hex 80 00 80 F0 01 48 C2 1C 06 B1 40 10 84 08 04 81 00 27 10 0E 03 00
── FRAME LAYOUT ─────────────────────────────────────────────
Bytes 0-1 80 00 Meta bytes 1 & 2
Meta1 0x80 Record mode, Value Present (bit5=1), no other components
Meta2 0x00 No archetype, D=2 (default), no setup byte, no slots
────────────────────────────────────────────────────────────
Bytes 2-9 80 F0 01 48 C2 1C 06 B1 Layer 1 (8 bytes)
SOH+domain SOH=1, Financial domain, Perms=RWCP, Flat 32-bit ID
Sender ID 0x00291847
Sub-entity 4
CRC-15 valid (zero remainder on full 64-bit block)
────────────────────────────────────────────────────────────
Bytes 10-15 40 10 84 08 04 81 Layer 2 (6 bytes)
TX Type 01 Pre-converted
SF ×1 (index 0)
Opt. Split 8 (default)
Dec. Pos D=2 (standard banking)
Currency USD (code 1)
Rounding 0000 (exactly balanced)
Compound 00 (no compound records)
────────────────────────────────────────────────────────────
Bytes 16-20 00 27 10 0E 03 Layer 3 (5 bytes)
A=39, r=16 N = 39×256+16 = 10000 → $100.00 exact
bit26=0 Exact (no rounding)
bit29=1 Direction Out (Debit)
bit30=1 Status Debt (accrued)
bit31=1 Debit side
bits33-36 0001 = Op Expense / Liability
bit37=1 Out — matches bit29 ✓ (Rule 1 pass)
bit38=1 Debt — matches bit30 ✓ (Rule 2 pass)
bit39=0 Full — transaction complete
bit40=0 No extension byte
Byte 21 00 Padding / frame end marker
────────────────────────────────────────────────────────────
Journal DEBIT Op Expense $100.00 / CREDIT Accounts Payable $100.00
Status Accrued, not yet settled
Validation All 3 cross-layer rules pass · Conservation: $100 out = $100 in
Total bytes 22 (minimum full BitLedger frame in BitPads)

Validating your implementation. A correct encoder produces the exact hex sequences above for the stated inputs. A correct decoder consumes them and produces the stated interpretation. If your byte sequence differs, check: (1) bit ordering — MSB first, (2) CRC-15 polynomial 0x8003 over bits 1-49, (3) value formula N=A×2S+r with default S=8, (4) cross-layer bit mirroring (bit29=bit37, bit30=bit38).