amduat/tier1/enc-tgk1-edge-1.md
2025-12-20 11:32:17 +01:00

739 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ENC/TGK1-EDGE/1 — Canonical Encoding for TGK EdgeArtifacts
Status: Approved
Owner: Niklas Rydberg
Version: 0.1.0
SoT: Yes
Last Updated: 2025-11-16
Linked Phase Pack: N/A
Tags: [binary-minimalism, traceability]
<!-- Source: /amduat/docs/new/enc-tgk1-edge1.md | Canonical: /amduat/tier1/enc-tgk1-edge-1.md -->
**Document ID:** `ENC/TGK1-EDGE/1`
**Profile ID:** `TGK1_EDGE_ENC_V1 = 0x0201` (symbolic; concrete assignment lives in encoding-profile registry)
**Layer:** Edge Encoding Profile (on top of ASL/1-CORE + TGK/1-CORE)
**Depends on (normative):**
* `ASL/1-CORE v0.4.x` — value model (`Artifact`, `TypeTag`, `Reference`, `HashId`, identity model)
* `ENC/ASL1-CORE v1.x` — canonical encodings for `Artifact` and `Reference`
* `TGK/1-CORE v0.7.x` — trace graph kernel (`Node`, `EdgeBody`, `EdgeTypeId`, edgehood invariants)
**Integrates with (informative):**
* `HASH/ASL1 v0.2.x` — ASL1 hash family for `EdgeRef` identity
* `ASL/1-STORE v0.4.x` — content-addressable store holding EdgeArtifacts
* `SUBSTRATE/STACK-OVERVIEW v0.2.x` — stack layering discipline
* TGK type catalogs (e.g. `TGK/TYPES-CORE`) — `EdgeTypeId` semantics
* Future TGK profiles (`TGK/STORE/1`, `TGK/PROV/1`) that interpret edges
> The Profile ID `TGK1_EDGE_ENC_V1` is a configuration label.
> It is **not** embedded into edge payloads. Encoders and decoders select this encoding by context (type tag + profile configuration), not per value.
© 2025 Niklas Rydberg.
## License
Except where otherwise noted, this document (text and diagrams) is licensed under
the Creative Commons Attribution 4.0 International License (CC BY 4.0).
The identifier registries and mapping tables (e.g. TypeTag IDs, HashId
assignments, EdgeTypeId tables) are additionally made available under CC0 1.0
Universal (CC0) to enable unrestricted reuse in implementations and derivative
specifications.
Code examples in this document are provided under the Apache License 2.0 unless
explicitly stated otherwise. Test vectors, where present, are dedicated to the
public domain under CC0 1.0.
---
## 0. Overview
`ENC/TGK1-EDGE/1` defines the **canonical, streaming-friendly, injective binary encoding** of the `EdgeBody` structure from `TGK/1-CORE`:
```text
EdgeBody {
type: EdgeTypeId // uint32
from: Node[] // Node = Reference
to: Node[]
payload: Reference
}
```
and its embedding as TGK **EdgeArtifacts**:
```text
Artifact {
bytes = EdgeBytes // this profile
type_tag = TYPE_TAG_TGK1_EDGE_V1
}
```
where `EdgeBytes` is a single `OctetString` (sequence of bytes) used as `Artifact.bytes`.
Under this profile:
* `EdgeBytes` is the canonical representation of an `EdgeBody`.
* Edge identity is the ASL/1 `Reference` over the EdgeArtifact (`EdgeRef`), derived via `ENC/ASL1-CORE` + `HASH/ASL1`.
* The encoding is:
* **Injective** — distinct `EdgeBody` values → distinct `EdgeBytes`.
* **Deterministic & stable** — same `EdgeBody` → same `EdgeBytes` across implementations and time.
* **Streaming-friendly** — encoders, decoders, and hashers can operate in a single forward-only pass.
In line with `TGK/1-CORE`:
* Each EdgeArtifact encodes **exactly one** logical edge (one `EdgeBody`).
* All TGK edges are represented as ordinary ASL/1 Artifacts plus their ASL `Reference` identities; this profile introduces no additional identity or node/edge ID layer.
> **Non-goal:** This profile does **not** define what any particular `EdgeTypeId` “means”, nor how graphs are stored, indexed, or traversed. Those behaviors are defined by `TGK/1-CORE`, TGK type catalogs, and higher-layer profiles.
---
## 1. Scope & Layering
### 1.1 Purpose
This specification defines:
* The **binary layout** of:
* `EdgeBytes` — canonical encoding for `EdgeBody`.
* `EncodedRef` — an internal wrapper for embedding ASL `Reference`s.
* Canonical field ordering and integer widths.
* How `EdgeBytes` are bound into EdgeArtifacts and converted into `EdgeRef` identity.
It does **not** define:
* TGK graph semantics or provenance algorithms (`TGK/1-CORE`, `TGK/PROV/1`).
* Store or transport APIs (`ASL/1-STORE`, deployment profiles).
* Edge-type catalogs (`TGK/TYPES-*`) or policy.
### 1.2 Layering constraints
In line with `SUBSTRATE/STACK-OVERVIEW` and `TGK/1-CORE`:
* `ENC/TGK1-EDGE/1` is a **TGK edge-encoding profile**, not a kernel primitive.
* It MUST NOT:
* redefine `Artifact`, `Reference`, `HashId`, or `TypeTag` (from `ASL/1-CORE`);
* redefine `Node`, `EdgeBody`, or `EdgeTypeId` (from `TGK/1-CORE`);
* embed store, provenance, or policy semantics into its layout.
* It defines exactly one canonical encoding for `EdgeBody` values under the profile ID `TGK1_EDGE_ENC_V1`.
TGK/1-CORE sees this profile as providing a partial function:
```text
decode_edge_payload_TGK1_EDGE :
OctetString -> EdgeBody | error
```
that is:
* **partial** — may fail with an error for some inputs;
* **deterministic** — a pure function of its input bytes, with no dependence on environment or mutable state;
* **side-effect free** — decoding does not consult stores, catalogs, or policy.
Artifacts whose `type_tag` selects this profile use `decode_edge_payload_TGK1_EDGE` as their TGK edge decoder in the sense of `TGK/1-CORE §3.2`.
---
## 2. Conventions
### 2.1 RFC 2119 terms
The key words **MUST**, **MUST NOT**, **SHOULD**, **MAY**, etc. are to be interpreted as described in RFC 2119.
### 2.2 Integer encodings
All multi-byte integers are encoded as **big-endian** (network byte order), as in `ENC/ASL1-CORE`:
* `u8` — 1 byte
* `u16` — 2 bytes
* `u32` — 4 bytes
* `u64` — 8 bytes
Only fixed-width integers are used.
### 2.3 Lists
A list of values of some type `T` is encoded as:
```text
List<T> ::
count (u32)
element_0
element_1
...
element_{count-1}
```
* `count` is the number of elements (MAY be zero).
* Elements are encoded in order using the canonical encoding of `T`.
### 2.4 Embedded Reference (`EncodedRef`)
Within `EdgeBytes`, ASL/1 `Reference` values are embedded using a length-prefixed wrapper over canonical `ReferenceBytes` from `ENC/ASL1-CORE`:
```text
EncodedRef ::
ref_len (u32)
ref_bytes (byte[0..ref_len-1]) // canonical ReferenceBytes
```
Where:
* `ref_bytes` MUST be the canonical `ReferenceBytes` encoding of some `Reference` value under `ENC/ASL1-CORE v1.x`:
```text
ReferenceBytes ::
hash_id (u16)
digest (byte[...]) // remaining bytes in the frame
```
* `ref_len` MUST be the exact byte length of `ref_bytes` and MUST be ≥ 2.
Decoders MUST:
1. Read `ref_len (u32)`.
2. Read exactly `ref_len` bytes as `ref_bytes`.
3. Decode `ref_bytes` as `ReferenceBytes` per `ENC/ASL1-CORE v1.x`.
4. Reject encodings where:
* `ref_len < 2`, or
* `ref_bytes` is not a valid `ReferenceBytes` sequence (e.g. truncated or improperly framed in its context).
If the implementation also implements `HASH/ASL1` and recognizes the decoded `hash_id`, it MUST apply any length checks required by `ENC/ASL1-CORE` / `HASH/ASL1` for that `HashId` (e.g. fixed digest length). Failures MUST be treated as encoding/integrity errors.
`EncodedRef` is purely an internal framing wrapper for this profile; it introduces no additional semantics beyond “a `Reference` encoded canonically and length-prefixed so it can be embedded in larger structures”.
This pattern mirrors `EncodedRef` from `ENC/PEL-TRACE-DAG/1` for cross-profile consistency.
### 2.5 Encoding version field (`edge_version`)
`EdgeBytes` includes an `edge_version (u16)` field:
* For `TGK1_EDGE_ENC_V1`, encoders **MUST** always write `edge_version = 1`.
* Decoders for this profile:
* **MUST** accept `edge_version = 1`; and
* **MUST** treat any other value as “**not this encoding**” and fail decoding.
Within this profile, `edge_version` is a **guard word**, not an evolution mechanism:
* This document will never assign any other meaning than “constant value 1” to `edge_version` for `TGK1_EDGE_ENC_V1`.
* Values other than `1` simply indicate that the bytes are not an `EdgeBytes` value for this profile.
Any incompatible change to the `EdgeBytes` layout MUST be expressed as a **new encoding profile** (e.g. `TGK1_EDGE_ENC_V2` with its own Profile ID, and almost certainly a new `TypeTag`), not by reusing this profile with `edge_version = 2`.
Append-only extensions that would change the canonical mapping from `EdgeBody` to bytes are also out of scope for this profile; they belong in new profiles. Canonical `EdgeBody → EdgeBytes` mapping for `TGK1_EDGE_ENC_V1` is fixed and permanently tied to `edge_version = 1`.
---
## 3. Logical Model Reference (from TGK/1-CORE)
> **Source of truth:** `TGK/1-CORE`.
> This section is an informative restatement; in any conflict, `TGK/1-CORE` governs.
### 3.1 Node
```text
Node := Reference // ASL/1 Reference
```
Nodes are graph vertices identified solely by their `Reference` value.
### 3.2 EdgeTypeId
```text
EdgeTypeId = uint32
```
Semantics of particular `EdgeTypeId` values are defined by TGK type catalogs and profiles, not by this document.
### 3.3 EdgeBody
```text
EdgeBody {
type: EdgeTypeId
from: Node[] // ordered, MAY be empty
to: Node[] // ordered, MAY be empty
payload: Reference // always present
}
```
Relevant invariant from `TGK/1-CORE`:
> **TGK/EDGE-NONEMPTY-ENDPOINT/CORE/1**
> For a well-formed `EdgeBody`, at least one of `from` or `to` **MUST** be non-empty.
> An `EdgeBody` with both `from = []` and `to = []` is invalid and MUST NOT be produced or accepted as a TGK edge.
Other notes from `TGK/1-CORE`:
* Duplicates within `from` or `to` are allowed.
* `payload` may also appear in `from` or `to`.
* Semantics of such patterns, if any, are profile-specific.
`ENC/TGK1-EDGE/1` encodes exactly these fields and MUST NOT introduce additional logical data at the `EdgeBody` level.
---
## 4. EdgeBody Encoding
### 4.1 Overall layout: `EdgeBytes`
The canonical encoding of an `EdgeBody` under `TGK1_EDGE_ENC_V1` is a single self-contained byte sequence:
```text
EdgeBytes ::
edge_version (u16)
type_id (u32) // EdgeTypeId
from_count (u32)
from_nodes (EncodedRef[0..from_count-1])
to_count (u32)
to_nodes (EncodedRef[0..to_count-1])
payload_ref (EncodedRef)
```
`EdgeBytes` is treated as an indivisible frame. When embedded in larger structures or protocols, the enclosing layer is responsible for providing the frame boundaries (e.g. via a length-prefix or message framing).
Field roles:
1. **edge_version (u16)**
* Guard word for this encoding profile.
* For `TGK1_EDGE_ENC_V1`, encoders **MUST** set `edge_version = 1` for all values.
* Decoders for this profile:
* **MUST** accept `edge_version = 1`; and
* **MUST** treat any other value as “not a `TGK1_EDGE_ENC_V1` edge payload” and fail decoding.
`edge_version` is not a version knob for evolving `TGK1_EDGE_ENC_V1`; it is a constant sanity check to quickly reject mismatched bytes.
2. **type_id (u32)**
* Encodes `EdgeBody.type : EdgeTypeId`.
* The meaning of each `EdgeTypeId` value is external to this spec.
3. **from_count (u32)** and **from_nodes**
* `from_count` is the length of `EdgeBody.from`.
* `from_nodes` is a list of `from_count` `EncodedRef` entries, each encoding a `Node` (i.e. a `Reference`).
* Order MUST match the logical `from` list; duplicates are allowed; MAY be zero-length.
4. **to_count (u32)** and **to_nodes**
* `to_count` is the length of `EdgeBody.to`.
* `to_nodes` is a list of `to_count` `EncodedRef` entries.
* Order MUST match the logical `to` list; duplicates are allowed; MAY be zero-length.
5. **payload_ref (EncodedRef)**
* Encodes `EdgeBody.payload : Reference`.
* Always present and encoded as a single `EncodedRef`.
### 4.2 Encoding procedure (normative)
Let `E` be a logical `EdgeBody` value. The canonical encoding function:
```text
encode_edgebody_tgk1_v1 : EdgeBody -> EdgeBytes
```
is defined as:
1. Set `edge_version = 1`.
2. Emit `edge_version` as `u16`.
3. Emit `E.type` as `type_id (u32)`.
4. Let `from_count = len(E.from)`; emit `from_count (u32)`.
5. For each `Node` in `E.from` in order:
* Let `R` be that `Node` (an ASL `Reference` value).
* Encode `R` as canonical `ReferenceBytes` using `ENC/ASL1-CORE v1.x`.
* Wrap as `EncodedRef` (see §2.4) and append.
6. Let `to_count = len(E.to)`; emit `to_count (u32)`.
7. For each `Node` in `E.to` in order:
* Encode as `EncodedRef` as above and append.
8. Encode `E.payload` as canonical `ReferenceBytes`, wrap as `EncodedRef`, and append as `payload_ref`.
9. Enforce the TGK non-empty endpoint invariant at encoding time:
* If `from_count == 0` **and** `to_count == 0`, the encoder MUST fail and MUST NOT produce `EdgeBytes` for this `EdgeBody` under this profile.
> **TGK1-EDGE-NONEMPTY/ENC/1**
> Encoders for `TGK1_EDGE_ENC_V1` **MUST** reject any attempt to encode an `EdgeBody` with `from = []` and `to = []`.
> Such a value is not a well-formed TGK edge per `TGK/1-CORE` and MUST NOT be emitted as an EdgeArtifact payload.
### 4.3 Decoding procedure (normative)
Given a byte slice known to contain exactly one `EdgeBytes` frame under this profile, the canonical decoding function:
```text
decode_edgebody_tgk1_v1 : EdgeBytes -> EdgeBody | error
```
is defined as:
1. Read `edge_version (u16)`.
* If `edge_version != 1`, fail with an encoding error (e.g. “not `TGK1_EDGE_ENC_V1`”).
2. Read `type_id (u32)`.
3. Read `from_count (u32)`.
* For `i = 0 .. from_count-1`, read and decode one `EncodedRef` as a `Reference` and append to `from_nodes`.
4. Read `to_count (u32)`.
* For `j = 0 .. to_count-1`, read and decode one `EncodedRef` and append to `to_nodes`.
5. Read `payload_ref` as a single `EncodedRef` and decode to `payload : Reference`.
6. If `from_count == 0` **and** `to_count == 0`, fail with an encoding error:
* This violates `TGK/EDGE-NONEMPTY-ENDPOINT/CORE/1` and `TGK1-EDGE-NONEMPTY/ENC/1`.
7. If the decoding context expects an isolated `EdgeBytes` value:
* After step 5 (or 6), if any unread bytes remain in the slice, the decoder MUST treat this as an encoding error (trailing data).
8. Construct and return:
```text
EdgeBody {
type = EdgeTypeId(type_id)
from = from_nodes
to = to_nodes
payload = payload
}
```
Decoders MUST additionally treat as encoding errors:
* truncated sequences (insufficient bytes for any declared field or `EncodedRef`);
* invalid `EncodedRef` encodings (see §2.4);
* any integer reads that cannot be completed because the input ends early.
`decode_edgebody_tgk1_v1` MUST be deterministic and MUST NOT depend on any external configuration beyond:
* the bytes in the `EdgeBytes` frame; and
* the static definition of `ENC/ASL1-CORE v1.x` used to decode embedded `ReferenceBytes`.
Recognition of `type_id` values (as supported or not in a given ExecutionEnvironment) is handled by `TGK/1-CORE` and the local catalog. This profile always decodes the raw `EdgeBody` structure, regardless of whether the environment later chooses to treat it as an EdgeArtifact.
---
## 5. EdgeArtifact Binding & Profile Selection
### 5.1 EdgeArtifact shape
Under this profile, EdgeArtifacts MUST be ASL/1 Artifacts of the form:
```text
Artifact {
bytes = EdgeBytes
type_tag = TYPE_TAG_TGK1_EDGE_V1
}
```
Where:
* `TYPE_TAG_TGK1_EDGE_V1` is a `TypeTag` whose concrete `tag_id`:
* is assigned in the global TypeTag registry, and
* is included in the environments `EDGE_TAG_SET` when this profile is active.
ExecutionEnvironments that wish to treat such Artifacts as TGK edges MUST:
* include `TYPE_TAG_TGK1_EDGE_V1.tag_id` in their configured `EDGE_TAG_SET`; and
* register `TGK1_EDGE_ENC_V1` as the edge-encoding profile for that tag, so that `decode_edge_payload_TGK1_EDGE` is used for those Artifacts `bytes`.
This document treats `TYPE_TAG_TGK1_EDGE_V1` symbolically and does not assign a numeric `tag_id`.
### 5.2 Integration with TGK/1-COREs `decode_edge_payload_P`
For ExecutionEnvironments that activate `TGK1_EDGE_ENC_V1` for `TYPE_TAG_TGK1_EDGE_V1`, the corresponding `decode_edge_payload_P` function from `TGK/1-CORE §3.2` is:
```text
decode_edge_payload_TGK1_EDGE(bytes: OctetString) -> EdgeBody | error
```
defined by:
```text
decode_edgebody_tgk1_v1(bytes)
```
from §4.3.
Conformant implementations MUST:
* apply `decode_edge_payload_TGK1_EDGE` only to Artifacts whose `type_tag.tag_id` is configured to use this profile; and
* treat any decoding failure as “not a valid edge payload for this profile”.
Multi-profile behavior (e.g., co-existence with other edge encodings) is governed by `TGK/1-CORE §3.2`. In particular:
* If more than one active profile successfully decodes the same `Artifact.bytes`, all such profiles MUST decode to the same logical `EdgeBody` value.
* If two active profiles decode the same bytes to different `EdgeBody` values, the ExecutionEnvironment MUST NOT treat that Artifact as an EdgeArtifact until the conflict is resolved.
---
## 6. EdgeRef Identity via ASL/1-CORE
Given:
* `EdgeBytes` from §4;
* an `EdgeArtifact`:
```text
A_edge = Artifact {
bytes = EdgeBytes
type_tag = TYPE_TAG_TGK1_EDGE_V1
}
```
* `ENC/ASL1-CORE v1.x` for canonical `ArtifactBytes`;
* a hash algorithm `H` with `HashId = HID` from `HASH/ASL1`,
the canonical `EdgeRef : Reference` (the edge identity) is:
```text
ArtifactBytes = encode_artifact_core_v1(A_edge)
digest = H(ArtifactBytes)
EdgeRef = Reference { hash_id = HID, digest = digest }
```
This profile does not introduce any new identity scheme. Edge identity is entirely determined by:
* the ASL/1 Artifact identity model,
* the selected encoding profile (typically `ASL_ENC_CORE_V1`), and
* the selected hash algorithm (`HASH/ASL1`).
---
## 7. Canonicality & Injectivity
### 7.1 Injectivity
> **TGK1-EDGE-INJECTIVE/ENC/1**
> Under `TGK1_EDGE_ENC_V1`, the mapping:
>
> ```text
> EdgeBody -> EdgeBytes
> ```
>
> MUST be injective. That is, for any two `EdgeBody` values `E1` and `E2`:
>
> ```text
> E1 != E2 ⇒ encode_edgebody_tgk1_v1(E1) != encode_edgebody_tgk1_v1(E2)
> ```
This is ensured by:
* encoding all logical fields (`type`, `from`, `to`, `payload`);
* preserving list order exactly;
* using a fixed, explicit binary layout.
### 7.2 Stability
For the fixed profile `TGK1_EDGE_ENC_V1` (with the guard word `edge_version = 1`):
* The same logical `EdgeBody` MUST always encode to the same `EdgeBytes` across:
* implementations,
* platforms,
* executions,
* and time.
Encoders MUST NOT:
* reorder elements of `from` or `to`;
* alter integer widths or endianness;
* introduce alternative layouts for any field;
* use any `edge_version` other than `1`.
---
## 8. Error Handling (Encoding Layer)
Decoders for this profile MUST treat as **encoding errors** (to be surfaced as some error category at the API boundary):
1. **Guard word mismatch**
* `edge_version != 1`.
2. **Truncated fields**
* Not enough bytes to read any declared field (`u16`, `u32`, `EncodedRef`, list elements).
3. **Invalid `EncodedRef`**
* `ref_len < 2`; or
* `ref_bytes` is not a valid `ReferenceBytes` sequence per `ENC/ASL1-CORE v1.x`; or
* (when `HASH/ASL1` is implemented and `hash_id` is known) the digest length implied by `ref_bytes` does not match the canonical length for that `HashId`.
4. **Empty endpoints**
* `from_count == 0` **and** `to_count == 0` (violation of `TGK/EDGE-NONEMPTY-ENDPOINT/CORE/1`).
5. **Inconsistent list lengths**
* Fewer actual `EncodedRef` entries than indicated by `from_count` or `to_count`.
6. **Trailing data in isolated contexts**
* Additional bytes remaining after a full `EdgeBytes` value has been decoded, when the decoding context expects exactly one `EdgeBytes` frame.
Translating these into concrete error codes (e.g. `ERR_TGK1_EDGE_ENC_INVALID`) is implementation-specific, but MUST result in rejection of the payload as an `EdgeBytes` value under this profile.
Semantic errors about `EdgeTypeId` recognition or edge-type-specific constraints are handled by TGK catalogs and higher profiles, not at the encoding layer.
---
## 9. Streaming & Implementation Notes
Implementations MUST be able to encode and decode `EdgeBytes` in a **single forward-only pass**:
* All length prefixes (`from_count`, `to_count`, `ref_len`) precede their content.
* Decoders MUST NOT require backtracking to interpret the structure.
For large edges (many endpoints):
* Encoders MAY stream `EncodedRef` entries as they are generated.
* Decoders MAY stream `EncodedRef` entries to consumers or hashers as they are read.
Any such streaming strategy MUST be observationally equivalent to decoding the entire `EdgeBytes` into an `EdgeBody` in memory and MUST respect the canonical layout.
---
## 10. Conformance
An implementation is **ENC/TGK1-EDGE/1conformant** if, for `TGK1_EDGE_ENC_V1`, it:
1. **Implements canonical EdgeBody encoding/decoding**
* Implements `encode_edgebody_tgk1_v1` and `decode_edgebody_tgk1_v1` exactly as specified in §4.
* Always writes `edge_version = 1` when encoding.
* Accepts only `edge_version = 1` and treats any other value as “not this encoding”.
2. **Uses `EncodedRef` correctly**
* Embeds `Reference` values via `EncodedRef` as in §2.4.
* Uses canonical `ReferenceBytes` from `ENC/ASL1-CORE v1.x` when forming `ref_bytes`.
* Applies `HASH/ASL1` length checks for known `HashId`s when available.
3. **Enforces TGK invariants at the encoding layer**
* Rejects encodings with both `from` and `to` empty (`TGK1-EDGE-NONEMPTY/ENC/1`).
* Treats malformed payloads as encoding errors as per §8.
4. **Binds EdgeBytes into EdgeArtifacts correctly**
* When forming EdgeArtifacts, sets:
```text
Artifact.bytes = EdgeBytes
Artifact.type_tag = TYPE_TAG_TGK1_EDGE_V1
```
* Does not embed additional logical data into the Artifact beyond `EdgeBody` and `type_tag`.
5. **Derives EdgeRef identity via ASL/1-CORE**
* Uses `ENC/ASL1-CORE v1` and `HASH/ASL1` for identity, as in §6.
* Does not introduce alternative edge identity mechanisms at this layer.
6. **Integrates with TGK/1-CORE profile selection**
* Applies `decode_edge_payload_TGK1_EDGE` only to Artifacts whose `type_tag.tag_id` is configured for this profile.
* Respects multi-profile behavior rules from `TGK/1-CORE §3.2` when other edge encodings are also active.
7. **Preserves injectivity and stability**
* Distinct `EdgeBody` values always produce distinct `EdgeBytes`.
* The same `EdgeBody` always produces the same `EdgeBytes` under this profile.
Everything else — storage layout, access protocols, graph indexes, provenance algorithms, and edge-type semantics — is defined by `ASL/1-STORE`, `TGK/1-CORE`, TGK catalogs, and higher-layer profiles.
---
## 11. Informative Example (Sketch)
> Non-normative; values and hex are illustrative only.
Consider an edge:
```text
EdgeBody {
type = 0x00000010 // EDGE_EXECUTION (for example)
from = [N_prog, N_input]
to = [N_output]
payload = R_receipt
}
```
Where `N_prog`, `N_input`, `N_output`, and `R_receipt` are `Reference` values with canonical `ReferenceBytes`:
```text
Ref(N_prog) = ReferenceBytes(N_prog) // length = len_pg, bytes = bytes_pg
Ref(N_input) = ReferenceBytes(N_input) // length = len_in, bytes = bytes_in
Ref(N_output) = ReferenceBytes(N_output) // length = len_out, bytes = bytes_out
Ref(R_receipt) = ReferenceBytes(R_receipt) // length = len_rc, bytes = bytes_rc
```
Then `EdgeBytes` under this profile are:
```text
edge_version = 0001 ; u16 (guard word)
type_id = 00000010 ; u32
from_count = 00000002 ; 2 sources
from_nodes =
000000?? bytes_pg ... ; EncodedRef(N_prog)
000000?? bytes_in ... ; EncodedRef(N_input)
to_count = 00000001 ; 1 target
to_nodes =
000000?? bytes_out ... ; EncodedRef(N_output)
payload_ref =
000000?? bytes_rc ... ; EncodedRef(R_receipt)
```
Where each `EncodedRef(X)` is:
```text
ref_len(X) (u32) || ReferenceBytes(X)
```
These `EdgeBytes` become `Artifact.bytes` for an EdgeArtifact with `type_tag = TYPE_TAG_TGK1_EDGE_V1`. All conformant encoders MUST produce the same bytes for the same logical `EdgeBody`; all conformant decoders MUST reconstruct the same `EdgeBody` from those bytes.
---
**End of `ENC/TGK1-EDGE/1 v0.1.0 — Canonical Encoding for TGK EdgeArtifacts` (draft).**
---
## Document History
* **0.1.0 (2025-11-16):** Registered as Tier-1 spec and aligned to the Amduat 2.0 substrate baseline.