You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Update envelope notation paper with code fence tags and subject guidance
Add "envelope" language identifier to all code fence blocks for syntax
highlighting. Add new section documenting the use of UUID, null, and
'unknown' as envelope subjects for identified, unidentified, and
unknown-identity entities respectively.
Copy file name to clipboardExpand all lines: papers/bcr-2026-002-envelope-notation.md
+65-35Lines changed: 65 additions & 35 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,7 +21,7 @@ This document is intended to be read by humans and AI agents. It is *not* a form
21
21
22
22
An envelope is a *subject* with multiple *assertions*. Each assertion asserts a *fact* about the subject. Square brackets `[` and `]` denote the start and end of the assertions for a subject. There are no line terminators or commas between assertions.
23
23
24
-
```
24
+
```envelope
25
25
<subject> [
26
26
<assertion>
27
27
<assertion>
@@ -32,7 +32,7 @@ An envelope is a *subject* with multiple *assertions*. Each assertion asserts a
32
32
33
33
Assertions are composed of a *predicate* and an *object*, separated by a colon `:`.
A subject can have no assertions (a *bare subject*):
49
49
50
-
```
50
+
```envelope
51
51
<subject>
52
52
```
53
53
54
54
Brackets always contain one or more assertions. An envelope with no assertions *must* omit the brackets entirely.
55
55
56
56
An assertion can also stand alone (a *bare assertion*):
57
57
58
-
```
58
+
```envelope
59
59
<predicate>: <object>
60
60
```
61
61
62
62
An envelope can be *wrapped*. The wrapped subject *and* its assertions become the subject of the envelope. It is denoted by enclosing the entire subject and its assertions in curly braces `{` and `}`.
63
63
64
-
```
64
+
```envelope
65
65
{
66
66
<subject> [
67
67
<assertion>
@@ -72,7 +72,7 @@ An envelope can be *wrapped*. The wrapped subject *and* its assertions become th
72
72
73
73
This allows assertions to be placed on the entire wrapped envelope. Below, `inner-assertion`s are assertions about the *subject* of the inner envelope, while `outer-assertion`s are assertions about the *entire inner envelope*. This pattern is commonly used when signing.
74
74
75
-
```
75
+
```envelope
76
76
{
77
77
<subject> [
78
78
<inner-assertion>
@@ -95,15 +95,15 @@ Every *position* within an envelope is *also itself* an envelope. So every posit
95
95
96
96
Subject with an assertion (most common):
97
97
98
-
```
98
+
```envelope
99
99
<subject> [
100
100
<predicate>: <object>
101
101
]
102
102
```
103
103
104
104
Wrapped envelope with an assertion (common):
105
105
106
-
```
106
+
```envelope
107
107
{
108
108
<subject> [
109
109
<inner-assertion>
@@ -115,7 +115,7 @@ Wrapped envelope with an assertion (common):
115
115
116
116
Object with an assertion (common):
117
117
118
-
```
118
+
```envelope
119
119
<subject> [
120
120
<predicate>: <object> [
121
121
<object-assertion>
@@ -125,7 +125,7 @@ Object with an assertion (common):
125
125
126
126
Predicate with an assertion (rare):
127
127
128
-
```
128
+
```envelope
129
129
<subject> [
130
130
<predicate> [
131
131
<predicate-assertion>
@@ -136,7 +136,7 @@ Predicate with an assertion (rare):
136
136
137
137
Assertion with an assertion (less common):
138
138
139
-
```
139
+
```envelope
140
140
<subject> [
141
141
{
142
142
<predicate>: <object>
@@ -174,13 +174,13 @@ Because Envelope Notation is a human-readable format, the envelope formatter may
174
174
175
175
A bare subject that is a leaf displays just the leaf value. This is the notation for a simple but complete envelope:
176
176
177
-
```
177
+
```envelope
178
178
"Just a string"
179
179
```
180
180
181
181
Here `UUID` and `Date` are known tagged CBOR types, so they are displayed with their canonical names and formatted values:
For example, the known value `1` has the canonical name `isA`, and is used as a predicate to assert the type of a subject. By noticing what kinds of quotes are used, the reader can immediately see that `'isA'` is a known value and `"SomeType"` is a string:
196
196
197
-
```
197
+
```envelope
198
198
<subject> [
199
199
'isA': "SomeType"
200
200
]
201
201
```
202
202
203
203
If the envelope formatter encounters an *unknown* known value, it will display the known value's integer code point in single quotes:
204
204
205
-
```
205
+
```envelope
206
206
<subject> [
207
207
'9999': "No idea what's being asserted here"
208
208
]
@@ -214,14 +214,44 @@ Known value code points have been assigned to many common concepts, as well as t
214
214
215
215
Known value `0` represents the [Unit](https://grokipedia.com/page/Unit_type), which is a type as well as its sole inhabitant. It is used to denote not merely the *absence* of a value (that is what `null` is for), but to hold a position where there *can* be no information conveyed and it would be *invalid* to do so. It is displayed as empty single quotes `''`. The most common use of Unit is as the subject of an envelope entirely defined by its assertions:
216
216
217
-
```
217
+
```envelope
218
218
'' [
219
219
'isA': 'foaf:Person'
220
220
'foaf:firstName': "Alice"
221
221
'foaf:lastName': "Smith"
222
222
]
223
223
```
224
224
225
+
In the case where such a structure has a unique identifier for the referent, the subject may instead be a known value representing the unique identifier, e.g. a UUID, or XID:
226
+
227
+
```envelope
228
+
UUID(a25e5f24-33e2-41ba-b5c3-61c7d630620a) [
229
+
'isA': 'foaf:Person'
230
+
'foaf:firstName': "Carol"
231
+
'foaf:lastName': "Johnson"
232
+
]
233
+
```
234
+
235
+
Where a unique identifier is not available, `null` may be used as the subject to indicate the envelope refers an unidentified entity where the identifier may or may not exist:
236
+
237
+
```envelope
238
+
null [
239
+
'isA': 'foaf:Person'
240
+
'foaf:firstName': "Bob"
241
+
'foaf:lastName': "Jones"
242
+
]
243
+
```
244
+
245
+
The `'unknown'` known value is used to indicate that the identifier *must* exist, but is not known:
246
+
247
+
```envelope
248
+
'unknown' [
249
+
'isA': 'foaf:Person'
250
+
'foaf:firstName': "Eve"
251
+
'foaf:lastName': "Unknown"
252
+
]
253
+
```
254
+
225
255
## Obscuring
226
256
227
257
Envelopes may be *obscured* in three different ways: *elision*, *encryption*, and *compression*. The critical property is that even though the content may be obscured, the Merkle-like digest tree of the envelope remains intact, allowing integrity verification and selective disclosure.
@@ -234,61 +264,61 @@ In the examples below `<OBSCURED>` can appear as `ELIDED`, `ENCRYPTED`, or `COMP
234
264
235
265
No positions obscured:
236
266
237
-
```
267
+
```envelope
238
268
"Alice" [
239
269
'foaf:knows': "Bob"
240
270
]
241
271
```
242
272
243
273
Subject obscured:
244
274
245
-
```
275
+
```envelope
246
276
<OBSCURED> [
247
277
'foaf:knows': "Bob"
248
278
]
249
279
```
250
280
251
281
Predicate obscured:
252
282
253
-
```
283
+
```envelope
254
284
"Alice" [
255
285
<OBSCURED>: "Bob"
256
286
]
257
287
```
258
288
259
289
Object obscured:
260
290
261
-
```
291
+
```envelope
262
292
"Alice" [
263
293
'foaf:knows': <OBSCURED>
264
294
]
265
295
```
266
296
267
297
Predicate and object obscured:
268
298
269
-
```
299
+
```envelope
270
300
"Alice" [
271
301
<OBSCURED>: <OBSCURED>
272
302
]
273
303
```
274
304
275
305
Entire assertion obscured:
276
306
277
-
```
307
+
```envelope
278
308
"Alice" [
279
309
<OBSCURED>
280
310
]
281
311
```
282
312
283
313
Entire envelope obscured:
284
314
285
-
```
315
+
```envelope
286
316
<OBSCURED>
287
317
```
288
318
289
319
When more than one assertion has been obscured in the same way, they are grouped together for brevity. Here five assertions have been elided, but their digests remain separately verifiable:
290
320
291
-
```
321
+
```envelope
292
322
"Alice" [
293
323
ELIDED (5)
294
324
]
@@ -298,7 +328,7 @@ When more than one assertion has been obscured in the same way, they are grouped
298
328
299
329
In a Gordian Envelope, each assertion must have a unique digest. In other words, no two assertions can be identical. Because Envelope Notation can abbreviate values for readability, it may appear that duplicate assertions exist when they do not. For example, here are two assertions that *look* identical, but actually *must* have different byte strings for the objects:
300
330
301
-
```
331
+
```envelope
302
332
<subject> [
303
333
'key': Bytes(16)
304
334
'key': Bytes(16)
@@ -313,7 +343,7 @@ The important thing to remember is that in a Gordian Envelope, assertions are *u
313
343
314
344
Signatures are assertions. But as assertions assert facts about their subjects, an envelope like this would not sign the whole envelope, but only the subject.
315
345
316
-
```
346
+
```envelope
317
347
<subject> [
318
348
<inner-assertion>
319
349
'signed': Signature
@@ -322,7 +352,7 @@ Signatures are assertions. But as assertions assert facts about their subjects,
322
352
323
353
To sign the entire envelope, including its assertions, the common pattern is to *wrap* the envelope first, then place the signature assertion on the outer envelope:
324
354
325
-
```
355
+
```envelope
326
356
{
327
357
<subject> [
328
358
<inner-assertion>
@@ -338,7 +368,7 @@ The plaintext envelope is optionally signed, then symmetrically encrypted with t
338
368
339
369
Plaintext signed then wrapped:
340
370
341
-
```
371
+
```envelope
342
372
{
343
373
{
344
374
<subject> [
@@ -352,13 +382,13 @@ Plaintext signed then wrapped:
352
382
353
383
The subject (now the entire signed envelope) is then encrypted using the content key:
354
384
355
-
```
385
+
```envelope
356
386
ENCRYPTED
357
387
```
358
388
359
389
The encrypted envelope is then asserted for each recipient:
360
390
361
-
```
391
+
```envelope
362
392
ENCRYPTED [
363
393
'hasRecipient': SealedMessage
364
394
'hasRecipient': SealedMessage
@@ -369,7 +399,7 @@ ENCRYPTED [
369
399
370
400
A password may be used to symmetrically encrypt the content key. The `hasSecret` assertion contains an `EncryptedKey` object with the encrypted content key and necessary parameters.
371
401
372
-
```
402
+
```envelope
373
403
ENCRYPTED [
374
404
'hasSecret': EncryptedKey(Argon2id)
375
405
]
@@ -379,7 +409,7 @@ ENCRYPTED [
379
409
380
410
Before elision the assertion object is decorated with a salt assertion to prevent identical objects from producing identical digests.
381
411
382
-
```
412
+
```envelope
383
413
<subject> [
384
414
{
385
415
<predicate>: <object>
@@ -391,7 +421,7 @@ Before elision the assertion object is decorated with a salt assertion to preven
391
421
392
422
After elision the digest remains, but the salt prevents correlation.
393
423
394
-
```
424
+
```envelope
395
425
<subject> [
396
426
ELIDED
397
427
]
@@ -403,7 +433,7 @@ After elision the digest remains, but the salt prevents correlation.
403
433
404
434
Example: a cryptographic seed envelope with two attachments, each conforming to a different version of a seed attachment format, along with a name and note assertions:
405
435
406
-
```
436
+
```envelope
407
437
Bytes(16) [
408
438
'isA': 'Seed'
409
439
'attachment': {
@@ -443,7 +473,7 @@ Envelope notation uses some punctuation characters in ways that are overloaded b
0 commit comments