Specification ID
Spec ID:gs1-1.0.0Date: 2025-06-20
Status: Frozen (v1.0)
GS1 headers are NOT part of GLYPH canonicalization. GS1 is a stream framing protocol only.
Scope
GS1 is a stream framing protocol for transporting a sequence of GLYPH payloads over streaming transports (TCP, WebSocket, pipes, files, SSE).- GS1 does not modify GLYPH syntax or canonicalization
- A GS1 frame contains:
- A GS1 header (stream metadata)
- A payload that is valid GLYPH text (UTF-8 bytes)
- Canonicalization, schema validation, and patch semantics are properties of the payload, not GS1
Relationship to GLYPH
- A GS1 implementation MUST NOT require changes to the GLYPH parser
- The GS1 reader is a separate layer that outputs
payloadBytesto the normal GLYPH decoder
Terminology
| Term | Definition |
|---|---|
| Frame | One message in the stream (header + payload) |
| SID | Stream identifier (multiplex key) |
| SEQ | Per-SID sequence number (monotonic) |
| KIND | Semantic category of the payload |
| BASE | Optional state hash for patch safety |
| CRC | Optional CRC-32 checksum for integrity |
Frame Kinds
| Value | Name | Meaning | |------:|------|---------|| | 0 |doc | Snapshot or general GLYPH document/value |
| 1 | patch | GLYPH patch doc (@patch ... @end) |
| 2 | row | Single row value (streaming tabular data) |
| 3 | ui | UI event value (progress/log/artifact refs) |
| 4 | ack | Acknowledgement (usually no payload) |
| 5 | err | Error event (payload describes error) |
| 6 | ping | Keepalive / liveness check |
| 7 | pong | Ping response |
Implementations MUST accept unknown kinds and surface them as unknown(<byte>).
GS1-T (Text Framing)
GS1-T is the text-based wire format, suitable for SSE, WebSocket text frames, logs, and debugging.Frame Structure
Header Grammar
The header line starts with@frame{ and ends with }\n.
Inside {} is a space-separated or comma-separated list of key=value pairs.
Required keys:
| Key | Type | Description |
|---|---|---|
v | uint8 | Protocol version (MUST be 1) |
sid | uint64 | Stream identifier |
seq | uint64 | Sequence number (per-SID, monotonic) |
kind | string/uint8 | Frame kind (name or number) |
len | uint32 | Payload length in bytes |
| Key | Type | Description |
|---|---|---|
crc | string | CRC-32 of payload: crc32:<8hex> or <8hex> |
base | string | State hash: sha256:<64hex> |
final | bool | End-of-stream marker for this SID |
flags | uint8 | Bitmask (hex) |
Payload Reading Rule
Trailing Newline
- Writer MUST emit a trailing
\nafter payload - Reader SHOULD consume trailing
\nbut MUST accept EOF
Example Frame
GS1-B (Binary Framing)
GS1-B is reserved for future implementation. Binary header layout:- bit 0 (
0x01) =HAS_CRC - bit 1 (
0x02) =HAS_BASE - bit 2 (
0x04) =FINAL - bit 3 (
0x08) =COMPRESSED(reserved for GS1.1)
Integrity: CRC-32
Whencrc is present:
- Algorithm: CRC-32 IEEE (polynomial 0xEDB88320)
- Input: Payload bytes as transmitted
- Format:
crc=<8 lowercase hex digits>orcrc=crc32:<8hex>
Example
Patch Safety: BASE Hash
Whenbase is present:
- Algorithm: SHA-256
- Input:
CanonicalizeStrict(stateDoc)orCanonicalizeLoose(stateDoc) - Format:
base=sha256:<64 lowercase hex digits>
State Hash Definition
Patch Application Rule
Forkind=patch frames with base:
On mismatch, receiver SHOULD:
- Request a
docsnapshot, OR - Emit an
errframe, OR - Emit an
ackwith failure payload
Example
Ordering and Acknowledgement
SEQ Monotonicity
For eachsid:
seqMUST be monotonically increasing by 1- Receivers SHOULD detect gaps and handle appropriately
ACK Frames
kind=ackacknowledges receipt of(sid, seq)ackframes typically havelen=0ackwith payload may carry error/status details
FINAL Flag
final=trueindicates no more frames for thissid- Receiver may clean up per-SID state
Recommended Payload Schemas
These are non-normative examples. Actual payload schemas are application-defined.
UI Event
Error Event
Row Event
Payload is a single GLYPH value (struct/list) representing one row.Patch Event
Security Considerations
Implementations MUST enforce maximumlen (recommended: 64 MiB).
Conformance Checklist
A GS1 implementation is conformant if it:- ✓ Correctly reads/writes GS1-T frames per this spec
- ✓ Enforces
lenlimits - ✓ Verifies CRC-32 when present
- ✓ Parses
basehash correctly - ✓ Exposes
(sid, seq, kind, payloadBytes, base?, crc?)to caller - ✓ Does not require GLYPH parser changes
- ✓ Does not treat GS1 headers as part of GLYPH canonicalization
Test Vectors
Minimal Frame
Header:@frame{v=1 sid=0 seq=0 kind=doc len=2}Payload:
{}
Full frame:
Patch with CRC
Header:@frame{v=1 sid=1 seq=5 kind=patch len=24 crc=a1b2c3d4}Payload:
@patch\nset .x 1\n@end
UI Event
Header:@frame{v=1 sid=1 seq=10 kind=ui len=35}Payload:
UIEvent@(type "progress" pct 0.5)
ACK (no payload)
Header:@frame{v=1 sid=1 seq=10 kind=ack len=0}Payload: (empty)
Kind Name Mapping
For GS1-T,kind can be specified as name or number: