Envelopes
The envelope packages encrypted data so another BitPlan reader can open it. It provides framing and public decryption parameters; encryption protects the plan inside it. Anything that can read a 1Sat Ordinal and talk to a BRC-100 wallet can implement the format.
Where it lives
Content type is application/x-bitplan. Cleartext MAP on chain is three fields: { "app": "bitplan", "type": "plan", "enc": "1" }. Titles, descriptions, and git provenance stay inside the ciphertext.
Versioning
The first publish inscribes a 1-satoshi output. Later publishes spend that satoshi back to you with a new envelope. The origin (genesis outpoint) is the draft's identity. Only the wallet holding the coin can publish the next version.
Binary layout
Multi-byte integers are little-endian. A reader must reject anything whose magic is not BPLN, whose version it does not implement, whose header size overruns the buffer, or that carries no ciphertext.
| Field | Size | Value |
|---|---|---|
| magic | 4 bytes | ASCII BPLN |
| version | 1 byte | 0x01 private / 0x02 shared |
| header size | 4 bytes | uint32-LE length of the header JSON |
| header | varies | UTF-8 JSON |
| ciphertext | rest | private ciphertext, or shared payload followed by wrapped keys |
Private
The header names the fixed [2, "bitplan"]protocol and keyID. The wallet derives the encryption key internally and encrypts the complete plan with counterparty: "self". The keyID is a public derivation label, not key material.
Security properties
AES-GCM provides confidentiality and tamper detection. The wallet will fail on the wrong protocol, keyID, counterparty, or ciphertext. A shared payload includes a SHA-256 commitment to its canonical header. It detects changes made without the document key. The envelope does not prove authorship by itself; the ordinal's origin and transaction chain do that.