6.5 Values

Every value has one wire form, and the field's type names it. A payload is one MessagePack map with string keys (PSPK §2).

6.5.1 Types #

ValueWire formType
PrincipalA binary SID (PCDS)bin.sid
GUIDThe 16-byte binary GUID (PCDS)bin.guid
LUIDUnsigned integeruint.luid
ACEThe binary ACE (PCDS)bin.ace
Point in timeUnsigned integer, nanoseconds since the Unix epochuint.time
DurationUnsigned integer, nanosecondsuint.duration
Size in bytesUnsigned integeruint.bytes
Access maskUnsigned integeruint.mask
FlagsUnsigned integeruint.flags
Integrity levelUnsigned integer, the integrity RIDuint.integrity
Error numberSigned integer, negativeint.errno
BooleanMessagePack booleanbool
EnumerationString, kebab-casestr.enum
Numeric enumerationUnsigned integeruint.enum
PathStringstr.path
IP addressString, in the textual form for its familystr.ip
DigestBinarybin
TextStringstr
Other integerUnsigned or signed integeruint, int

An emitter MUST encode a value in the wire form of its field's type. A consumer MUST NOT accept a different form as the same value: a SID written as an SDDL string is not a bin.sid.

Enumerations are symbolic. An enumeration is a kebab-case string naming the value, wrong-type rather than 2. A uint.enum is permitted only where the numbers are fixed by another specification or an external standard — an impersonation level, an address family — and a consumer renders it by name. Every enumeration declares its values in its fragment, or names the reason-code family it draws them from, and states whether the set is closed (§6.10). A consumer that meets a value of an open enumeration it does not know MUST treat it as a value rather than an error, and SHOULD show it as written.

Masks need their kind. A uint.mask is decoded against the table for the kind of thing it applies to, which the same record names in object.kind. An event that carries a uint.mask field MUST carry object.kind.

6.5.2 What an emitter does not write #

  • An absent value. A field with no value is omitted: the key is not written. An emitter MUST NOT write nil, an empty string or zero to mean "none".
  • The header again. An emitter MUST NOT repeat in its payload a value the header already carries: the time, the sequence, or the emitter's token and process GUIDs (§6.4).
  • A name beside a SID. A principal is carried as its SID only. An emitter MUST NOT carry a principal's name in a field; resolving a SID to a name is a consumer's convenience, done when the record is read.
  • Units in a name. The type carries the unit. A duration is operation.duration, never operation.duration-ns.
  • Debugging output. A string value MUST NOT be the output of a language's debug formatter. Its format is not stable and no consumer can rely on it.

6.5.3 Departures from the shared conventions #

This chapter departs from the data conventions of the Conventions book §3.3 on two points:

  • Timestamps are unsigned integers counting nanoseconds since the Unix epoch, not RFC 3339 strings. The record header already carries time this way (PSPK §2), and one form for every time in a record lets a consumer compare them directly.
  • Digests are carried as binary, not lowercase hexadecimal. A consumer renders them as hexadecimal for display.

Edit this page