*`ref_bytes` MUST be the canonical `ReferenceBytes` for some `Reference` value under `ENC/ASL1-CORE v1`,
*`ref_len` MUST be the exact length of `ref_bytes` (MUST be ≥ 2).
Decoders MUST:
* treat `ref_len < 2` as an encoding error, and
* decode `ref_bytes` using `decode_reference_core_v1`. Any failure in that decoding (including, when `HASH/ASL1` is implemented, a digest-length mismatch for a known `hash_id`) MUST be treated as an encoding error for `DagSchemeDescriptorBytes`.
* Optional `Reference` fields use:
```text
OptionalEncodedRef =
has_ref (u8)
[ EncodedRef ] // only if has_ref == 0x01
```
with:
*`has_ref = 0x00` → no value present (no `EncodedRef` follows),
*`has_ref = 0x01` → exactly one `EncodedRef` follows,
* other `has_ref` values are encoding errors.
---
## 3. Descriptor Logical Model
### 3.1 DagSchemeDescriptor (logical)
At the logical level, the DAG scheme descriptor is modeled as:
```text
DagSchemeDescriptor {
pel1_version: uint16
scheme_name: String // logical identifier, e.g. "PEL/PROGRAM-DAG/1"
// to a trace-profile descriptor (e.g. PEL/TRACE-DAG-DESC/1)
opreg_ref: optional Reference
// to a canonical operation-registry descriptor (e.g. OPREG/PEL1-KERNEL)
}
```
This structure is **logical**; the descriptor’s concrete bytes are defined in §4.
The `program_type_tag` / `program_enc_profile` pair tells engines **how to interpret Program Artifacts** for this scheme:
*`program_type_tag` ⇒ which `TypeTag` marks an Artifact as a DAG Program for this scheme;
*`program_enc_profile` ⇒ which Program encoding profile (specifically, `PEL_ENC_PROGRAM_DAG_V1` from `ENC/PEL-PROGRAM-DAG/1`) to use when decoding/encoding those Artifacts.
This pair is independent from the **ASL-level encoding profile** used for the descriptor Artifact itself, which is always `ASL_ENC_CORE_V1` when deriving `SchemeRef_DAG_1` (§5.2).
This document does not require engines to inspect all fields at runtime. In particular:
* engines that already know `SchemeRef_DAG_1`, `TYPE_TAG_PEL_PROGRAM_DAG_1`, and `PEL_ENC_PROGRAM_DAG_V1` MAY treat the descriptor as metadata; and
* the canonical binding to `PEL/PROGRAM-DAG/1` is via `SchemeRef_DAG_1` and the `program_type_tag` / `program_enc_profile` pair, not via `scheme_name` or the optional references.
### 3.2 Field semantics & invariants
For the **Amduat 2.0 baseline DAG scheme descriptor** (the one used to define `SchemeRef_DAG_1`) the following invariants apply:
*`pel1_version`:
* MUST be `1`.
* Indicates the descriptor is written against `PEL/1-CORE` version 1 semantics.
* Future PEL versions MAY introduce new descriptor formats, but MUST NOT change the meaning of `pel1_version = 1`.
*`scheme_name`:
* MUST be the UTF-8 string `"PEL/PROGRAM-DAG/1"`, compared byte-for-byte and case-sensitively.
* Serves as a human-readable identifier and sanity check.
* Changing `scheme_name` (while keeping other fields identical) changes the descriptor value and therefore its `Reference`.
*`program_type_tag`:
* MUST equal the `TypeTag` used for DAG Program Artifacts, symbolically:
```text
program_type_tag = TYPE_TAG_PEL_PROGRAM_DAG_1
```
* The concrete numeric `tag_id` is assigned by the TypeTag registry and is not restated here.
*`program_enc_profile`:
* MUST be the `EncodingProfileId` of `ENC/PEL-PROGRAM-DAG/1`, symbolically:
```text
program_enc_profile = PEL_ENC_PROGRAM_DAG_V1
```
* In the current encoding profile, this is `0x0101`, but this spec treats it symbolically; the numeric value comes from the encoding profile registry.
*`trace_profile_ref`:
* Optionally points at a descriptor Artifact that defines a canonical trace profile for this scheme (e.g. a future `PEL/TRACE-DAG-DESC/1`).
* For the **canonical Amduat 2.0 baseline descriptor used to define `SchemeRef_DAG_1`**, this field is **absent**:
```text
trace_profile_ref = None
```
* Future companion descriptors MAY set this field, but those will not be the descriptor used for `SchemeRef_DAG_1`.
*`opreg_ref`:
* Optionally points at a descriptor Artifact for the canonical operation registry for this scheme (e.g. `OPREG/PEL1-KERNEL`).
* For the **canonical Amduat 2.0 baseline descriptor used to define `SchemeRef_DAG_1`**, this field is **absent**:
```text
opreg_ref = None
```
* As with `trace_profile_ref`, future descriptors MAY set this field, but those will define distinct `SchemeRef` values, not `SchemeRef_DAG_1`.
### 3.3 Canonical descriptor value for the DAG scheme
Let:
```text
DagSchemeDescriptor_DAG_1 : DagSchemeDescriptor
```
denote the unique logical descriptor value that satisfies:
```text
DagSchemeDescriptor_DAG_1 {
pel1_version = 1
scheme_name = "PEL/PROGRAM-DAG/1"
program_type_tag = TYPE_TAG_PEL_PROGRAM_DAG_1
program_enc_profile = PEL_ENC_PROGRAM_DAG_V1
trace_profile_ref = None
opreg_ref = None
}
```
All Amduat 2.0 baseline components MUST agree on this logical value as “the” DAG scheme descriptor for binding `PEL/PROGRAM-DAG/1` to a `SchemeRef`.
Any descriptor with different logical contents (including differing optional fields) describes either:
* a different scheme, or
* a different profile or version of the DAG scheme,
and MUST NOT be used to derive `SchemeRef_DAG_1`.
Because the descriptor is carried in an ASL/1 Artifact and scheme references are content-addressed, any change to this descriptor (even in optional fields) yields a different `Reference`; `SchemeRef_DAG_1` is therefore permanently tied to exactly this v1 descriptor.
---
## 4. Descriptor Artifact & Encoding
### 4.1 Descriptor TypeTag
The DAG scheme descriptor is carried by an ASL/1 Artifact with a dedicated TypeTag:
```text
TYPE_TAG_PEL_SCHEME_DESC_1 : TypeTag
```
*`TYPE_TAG_PEL_SCHEME_DESC_1` is a symbolic constant for a `TypeTag.tag_id` assigned by the global `TypeTag` registry.
* This `TypeTag` MUST be used for the DAG scheme descriptor Artifact defined in this document.
* Other PEL scheme descriptors MAY reuse this `TypeTag` and the encoding in §4.2, but such reuse MUST be specified in their own descriptor documents.
The descriptor Artifact for the DAG scheme has the shape:
```text
DagSchemeDescriptorArtifact_DAG_1 : Artifact {
type_tag = TYPE_TAG_PEL_SCHEME_DESC_1
bytes = DagSchemeDescriptorBytes_DAG_1
}
```
where `DagSchemeDescriptorBytes_DAG_1` is the canonical encoding of `DagSchemeDescriptor_DAG_1` defined in §4.2.
This Artifact itself is encoded to `ArtifactBytes` using `ASL_ENC_CORE_V1` when deriving `SchemeRef_DAG_1` (§5.2). That use of `ASL_ENC_CORE_V1` is **independent** of the `program_enc_profile` field, which is about how Program Artifacts are encoded.
### 4.2 Descriptor encoding layout
The descriptor value `DagSchemeDescriptor` is encoded into `DagSchemeDescriptorBytes` using a small, fixed layout over primitive types:
```text
DagSchemeDescriptorBytes ::
pel1_version (u16)
scheme_name (Utf8String)
program_type_tag (u32) // TypeTag.tag_id
program_enc_profile (u16) // EncodingProfileId
has_trace_profile (u8)
[ trace_profile_ref (EncodedRef) ] // if has_trace_profile == 0x01
has_opreg_ref (u8)
[ opreg_ref (EncodedRef) ] // if has_opreg_ref == 0x01
```
Constraints:
*`pel1_version` MUST be `1` for descriptors governed by this document.
*`scheme_name` MUST be encoded as a `Utf8String` (§2.4).
*`program_type_tag` encodes `TypeTag.tag_id` for `TYPE_TAG_PEL_PROGRAM_DAG_1`.
*`program_enc_profile` encodes the `EncodingProfileId` for `PEL_ENC_PROGRAM_DAG_V1` as defined in `ENC/PEL-PROGRAM-DAG/1`.
*`has_trace_profile`:
*`0x00` → `trace_profile_ref` is absent; no bytes for it follow.
*`0x01` → `trace_profile_ref` is present and encoded as `EncodedRef`.
* Any other value is an encoding error.
*`has_opreg_ref`:
*`0x00` → `opreg_ref` is absent.
*`0x01` → `opreg_ref` is present and encoded as `EncodedRef`.
be the encoding and decoding functions for this profile.
**Encoding:**
Given a `DagSchemeDescriptor` value:
1. Emit `pel1_version (u16)`.
2. Emit `scheme_name` as `Utf8String`.
3. Emit `program_type_tag.tag_id` as `u32`.
4. Emit `program_enc_profile` as `u16`.
5. For `trace_profile_ref`:
* If absent:
* emit `has_trace_profile = 0x00`.
* If present:
* emit `has_trace_profile = 0x01`,
* emit `trace_profile_ref` as `EncodedRef` (u32 length + `ReferenceBytes`).
6. For `opreg_ref`:
* If absent:
* emit `has_opreg_ref = 0x00`.
* If present:
* emit `has_opreg_ref = 0x01`,
* emit `opreg_ref` as `EncodedRef`.
The concatenation of all emitted bytes is `DagSchemeDescriptorBytes`.
**Decoding:**
Given an `OctetString` known to contain exactly one `DagSchemeDescriptorBytes` value:
1. Read `pel1_version (u16)`.
* If `pel1_version != 1`, decoders that only implement this version MUST treat this as an encoding error. Future decoders MAY support additional versions but MUST NOT reinterpret `pel1_version = 1`.
2. Read `scheme_name` as `Utf8String` and validate UTF-8.
*`0x01` → read `trace_profile_ref` as `EncodedRef` and decode to `Reference`.
* other values → encoding error.
6. Read `has_opreg_ref (u8)`:
*`0x00` → `opreg_ref = None`.
*`0x01` → read `opreg_ref` as `EncodedRef` and decode to `Reference`.
* other values → encoding error.
7. If there are trailing bytes after successfully decoding all fields, decoders MAY treat this as an encoding error in contexts expecting a single `DagSchemeDescriptorBytes` value.
The mapping between `DagSchemeDescriptor` and `DagSchemeDescriptorBytes` defined here is the only encoding/decoding pair permitted by this profile.
### 4.4 Canonicality and injectivity
The mapping:
```text
DagSchemeDescriptor -> DagSchemeDescriptorBytes
```
defined above MUST be:
* **Injective** — distinct logical descriptor values MUST produce distinct byte strings.
* **Stable** — the same logical descriptor MUST always encode to the same bytes across implementations and time.
* **Streaming-friendly** — encoders and decoders MUST be implementable in a single forward pass; all length prefixes appear before their content.
In particular:
* Field ordering MUST NOT vary.
* No alternative encodings (e.g. different integer widths, string formats, or positions) are permitted.
*`EncodedRef` MUST always use canonical `ReferenceBytes` from `ENC/ASL1-CORE v1` (and therefore, when `HASH/ASL1` is present, inherit its digest-length consistency checks).
For the canonical DAG scheme, `DagSchemeDescriptor_DAG_1` encodes to a single, immutable `DagSchemeDescriptorBytes_DAG_1`. That byte sequence MUST NOT change once published.
### 4.5 Error handling (encoding layer)
Decoders for this profile MUST treat as **encoding errors** at the descriptor level:
1.**Unsupported `pel1_version`**
*`pel1_version != 1`.
2.**Invalid presence flags**
*`has_trace_profile` or `has_opreg_ref` not in `{ 0x00, 0x01 }`.
3.**Invalid `EncodedRef`**
*`ref_len < 2`, or
* insufficient bytes to read `ref_bytes`, or
*`ref_bytes` cannot be decoded as `ReferenceBytes` under `ENC/ASL1-CORE v1` (including digest-length mismatches for known `hash_id`s when `HASH/ASL1` is implemented).
4.**Invalid `Utf8String` for `scheme_name`**
*`scheme_name` bytes are not valid UTF-8.
5.**Truncation and over-long payloads**
* Not enough bytes to read anydeclared field.
* In contexts expecting a single descriptor value, additional trailing bytes after decoding all fields.
Mapping from these encoding errors to external error codes (e.g. `ERR_PEL_SCHEME_DESC_INVALID`) is implementation-specific.
---
## 5. Definition of `SchemeRef_DAG_1`
### 5.1 General derivation from the descriptor Artifact
Let `DagSchemeDescriptorArtifact` be any Artifact of the form:
```text
Artifact {
type_tag = TYPE_TAG_PEL_SCHEME_DESC_1
bytes = DagSchemeDescriptorBytes
}
```
such that `DagSchemeDescriptorBytes` decodes to some `DagSchemeDescriptor` value via `decode_dag_scheme_descriptor_v1`.
Given:
* encoding profile `P = ASL_ENC_CORE_V1`,
* hash algorithm `H` with `HashId = HID`,
the scheme reference for this descriptor under `(P, H)` is:
Other deployments MAY derive alternative scheme references from:
* the same descriptor Artifact but a different `(EncodingProfileId, HashId)` pair, or
* a different descriptor Artifact (e.g. one with additional optional references or different metadata).
Such configurations:
* are not the Amduat 2.0 baseline, and
* MUST NOT reuse the name `SchemeRef_DAG_1` for any scheme reference other than the one defined in §5.2.
Profiles MAY define their own symbolic names (e.g. `SchemeRef_DAG_1_PQ`) for alternate `(EncodingProfileId, HashId)` combinations, but those are outside the scope of this document.
---
## 6. Layering & Usage
### 6.1 Engine behavior
A PEL/1-CORE engine that claims support for the DAG scheme in the Amduat 2.0 baseline:
* MUST recognize `SchemeRef_DAG_1` (as defined in §5.2) as the scheme identifier corresponding to `PEL/PROGRAM-DAG/1`.
* MUST implement:
```text
Exec_s = Exec_DAG
```
when invoked with `scheme_ref = SchemeRef_DAG_1`.
* MUST treat Program Artifacts for this scheme as ASL/1 Artifacts whose `type_tag` equals the `program_type_tag` from the descriptor (i.e. `TYPE_TAG_PEL_PROGRAM_DAG_1`). The `program_enc_profile` field gives the encoding profile ID that engines use to select the appropriate Program encoding/decoding logic; in the Amduat 2.0 baseline this ID is `PEL_ENC_PROGRAM_DAG_V1` as defined in `ENC/PEL-PROGRAM-DAG/1`.
* MUST treat the descriptor Artifact as immutable metadata. Engines MAY bake in `SchemeRef_DAG_1` and the associated `TypeTag` and profile IDs at build time; they are not required to fetch or decode the descriptor on the execution hot path.
Nothing in this document requires engines to use `trace_profile_ref` or `opreg_ref` at runtime. Those fields exist so that tooling and profiles can discover related descriptors in a stable, content-addressed way.
### 6.2 Configuration and discovery
Tooling and configuration systems MAY use the descriptor to:
* discover:
* which `TypeTag` is used for DAG Programs,
* which encoding profile ID applies to those Programs,
* optional references to trace and operation-registry descriptors;
* populate engine configuration tables, e.g.:
```text
scheme_table[SchemeRef_DAG_1] = {
program_type_tag = TYPE_TAG_PEL_PROGRAM_DAG_1,
program_enc_profile = PEL_ENC_PROGRAM_DAG_V1,
trace_profile_ref = None,
opreg_ref = None,
}
```
This document:
* MUST NOT introduce any store-level behavior, TGK edge semantics, certification rules, fact semantics, or overlay semantics.
* ONLY binds PEL-level scheme semantics (`Exec_DAG`) to ASL-level values (`Artifact`, `TypeTag`, `Reference`).
---
## 7. Conformance
An implementation is **PEL/PROGRAM-DAG-DESC/1–conformant** if it satisfies all of:
1.**Descriptor encoding & decoding**
* Implements `encode_dag_scheme_descriptor_v1` / `decode_dag_scheme_descriptor_v1` as in §4.2–§4.3.
* Treats `pel1_version = 1` as the only supported version for this descriptor profile.
* Enforces presence flags and `EncodedRef` structure as defined in §2.4 and §4.5.
2.**Recognition of the descriptor Artifact**
* Recognizes `TYPE_TAG_PEL_SCHEME_DESC_1` as the PEL scheme descriptor tag for this document.
* For `type_tag = TYPE_TAG_PEL_SCHEME_DESC_1`, is able to decode `bytes` as `DagSchemeDescriptorBytes` and obtain a `DagSchemeDescriptor`.
* Recognizes `DagSchemeDescriptor_DAG_1` (per §3.3) as the canonical descriptor value for the DAG scheme in Amduat 2.0 (e.g. by comparing decoded fields).
3.**Derivation of `SchemeRef_DAG_1`**
* When configured with `ASL_ENC_CORE_V1` and `HASH-ASL1-256` (`HashId = 0x0001`), derives `SchemeRef_DAG_1` exactly as in §5.2 from `DagSchemeDescriptorArtifact_DAG_1`.
* Does not derive `SchemeRef_DAG_1` from any other Artifact or under any other `(EncodingProfileId, HashId)` pair.
4.**Scheme binding**
* For `SchemeRef = SchemeRef_DAG_1`, implements `Exec_s` as `Exec_DAG` per `PEL/PROGRAM-DAG/1`.
* Uses `program_type_tag` and `program_enc_profile` from the descriptor when interpreting Program Artifacts for this scheme (at build time or configuration time; not necessarily on every execution).
5.**Layering discipline**
* Does not introduce store, TGK, certificate, fact, or overlay semantics into the descriptor logic.
* Treats this document purely as a binding between:
* the PEL scheme (`PEL/PROGRAM-DAG/1`),
* its program representation (`TYPE_TAG_PEL_PROGRAM_DAG_1` + `PEL_ENC_PROGRAM_DAG_V1`),
* and an ASL/1 `SchemeRef` (`SchemeRef_DAG_1`).
Everything else — store wiring, TGK edges, receipts, facts, overlays, and domain semantics — is delegated to other specifications.
---
## 8. Version History
* **0.1.6 — 2025-11-16** — Marked `ENC/PEL-PROGRAM-DAG/1` as a normative dependency and clarified that `program_enc_profile` is specifically `PEL_ENC_PROGRAM_DAG_V1`.
* **0.1.5 — 2025-11-16** — Clarified the role of `program_enc_profile` vs `ASL_ENC_CORE_V1` and tightened wording around how Program Artifacts are interpreted.
* **0.1.4 — 2025-11-16** — Tightened decoding wording, clarified the uniqueness of the encoding/decoding pair, and polished streaming/injectivity language.
* **0.1.3 — 2025-11-16** — Clarified RFC 2119 usage, layering around program encoding, and tightened conformance wording.
* **0.1.2 — 2025-11-16** — Refined encoding error rules, clarified `TYPE_TAG_PEL_SCHEME_DESC_1` reuse, and described engine usage more explicitly.