amduat/tier1/dds.md
2026-01-17 11:18:00 +01:00

945 lines
50 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.

# AMDUAT-DDS — Detailed Design Specification
Status: Approved
Owner: Niklas Rydberg
Version: 0.5.0
SoT: Yes
Last Updated: 2025-11-11
Linked Phase Pack: PH01
Tags: [design, cas, composition]
<!-- Source: /amduat-api/tier1/dds.md | Canonical: /amduat/tier1/dds.md -->
**Document ID:** `AMDUAT-DDS`
**Layer:** L0.1 — Byte-level design (CAS + deterministic envelopes)
**Depends on (normative):**
* `AMDUAT-SRS` — behavioural requirements
* ADR-001 — CAS identity
* ADR-003 — canonical encoding discipline
* ADR-006 — deterministic error semantics
**Informative references:**
* ADR-015 — rejection governance
© 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.
> **Note (scope):**
> This DDS covers **Phase 01 (Kheper CAS)** byte semantics and, where necessary, the canonical **binary encodings** for higher deterministic layers (FCS/1, PCB1, FER/1, FCT/1).
> **Behavioural semantics live in SRS.** This document governs the **bytes**.
---
## 1 Content ID (CID)
**Rule.**
```
CID = algo_id || H("CAS:OBJ\0" || payload_bytes)
```
* `algo_id`: 1-byte or VARINT identifier (default `0x01` = SHA-256).
* `H`: selected hash over **exact payload bytes**.
* Domain separation prefix must be present verbatim: `"CAS:OBJ\0"`.
**Properties.**
* Deterministic: identical payload → identical CID.
* Implementation-independent (SRS NFR-001).
* Crypto-agile via `algo_id`.
**Errors.**
* `ERR_ALGO_UNSUPPORTED` when `algo_id` not registered.
* Empty payload is allowed and canonical.
---
## 2. Canonical Object Record (COR/1)
COR/1 is the **only** canonical import/export envelope for CAS objects. Exact bytes are consensus; on-disk layout is not.
### 2.1 Envelope Layout (exact bytes)
```
Header (7 bytes total):
MAGIC : 4 bytes = "CAS1" (0x43 0x41 0x53 0x31)
VERSION : 1 byte = 0x01
FLAGS : 1 byte = 0x00 (reserved; MUST be 0)
RSV : 1 byte = 0x00 (reserved; MUST be 0)
Body (strict TLV order; no padding):
0x10 algo_id (VARINT)
0x11 size (VARINT)
0x12 payload (BYTES; length == size)
```
**Notes**
* Fixed header invariants; any mismatch is rejection.
* No alignment/padding anywhere.
### 2.2 Tag Semantics
| Tag | Name | Type | Card. | Notes |
| ---: | ------- | ------ | ----: | ----------------------------------------------- |
| 0x10 | algo_id | VARINT | 1 | MUST equal algorithm used for the objects CID. |
| 0x11 | size | VARINT | 1 | **Minimal VARINT**; MUST equal payload length. |
| 0x12 | payload | BYTES | 1 | Raw bytes; never normalized. |
### 2.3 Canonicalization Rules (strict)
1. **Order & uniqueness:** `0x10`, `0x11`, `0x12`, each exactly once.
2. **VARINTS:** Unsigned LEB128 **minimal** form only.
3. **BYTES:** `VARINT(len) || len bytes`, with `len == size`.
4. **No extras:** No unknown tags, no trailing bytes.
5. **Header invariants:** `MAGIC="CAS1"`, `VERSION=0x01`, `FLAGS=RSV=0x00`.
6. **Policy domain:** `size ≤ max_object_size` when enforced (ICD/1 §3).
7. **Raw byte semantics** (SRS FR-010).
### 2.4 Decoder Validation Algorithm (normative)
1. Validate header ⇒ else `ERR_COR_HEADER_INVALID`.
2. Read `0x10` minimal VARINT ⇒ else `ERR_COR_TAG_ORDER` / `ERR_VARINT_NON_MINIMAL`.
3. Read `0x11` minimal VARINT ⇒ same error rules.
4. Read `0x12` BYTES (length minimal VARINT) ⇒ else `ERR_VARINT_NON_MINIMAL`.
5. Enforce `size == len(payload)``ERR_COR_LENGTH_MISMATCH` on failure.
6. Ensure **no trailing bytes**`ERR_TRAILING_BYTES`.
7. Recompute CID and compare ⇒ mismatch `ERR_CORRUPT_OBJECT`.
### 2.5 Consistency with CID (normative)
* **Export:** set `algo_id` to CID algorithm.
* **Import:** verify `algo_id` and hash component against expected CID.
* Mismatch ⇒ `ERR_ALGO_MISMATCH` / `ERR_CORRUPT_OBJECT`.
### 2.6 Round-Trip Identity
`import(COR/1) → export(CID)` MUST produce **byte-identical** envelope (SRS FR-005). Re-encoding is forbidden.
### 2.7 Rejection Matrix (normative)
| Violation | Example | Error |
| ------------------ | -------------------------------- | ------------------------- |
| Bad header | Wrong MAGIC/VERSION/FLAGS/RSV | `ERR_COR_HEADER_INVALID` |
| Unknown/extra tag | Any tag not 0x10/0x11/0x12 | `ERR_COR_UNKNOWN_TAG` |
| Out-of-order | `0x11` before `0x10` | `ERR_COR_TAG_ORDER` |
| Duplicate tag | Two `0x10` entries | `ERR_COR_DUPLICATE_TAG` |
| Non-minimal VARINT | Over-long algo/size/bytes length | `ERR_VARINT_NON_MINIMAL` |
| Length mismatch | `size != len(payload)` | `ERR_COR_LENGTH_MISMATCH` |
| Trailing bytes | Any bytes after payload | `ERR_TRAILING_BYTES` |
| Algo mismatch | `algo_id` conflicts with CID | `ERR_ALGO_MISMATCH` |
| Hash mismatch | Recomputed hash ≠ expected | `ERR_CORRUPT_OBJECT` |
---
## 3. Instance Descriptor (ICD/1)
ICD/1 publishes canonical instance configuration; its bytes are consensus.
### 3.1 Envelope
```
Header:
MAGIC : "ICD1"
VERSION : 0x01
TLV (strict order; minimal VARINTs; no duplicates):
0x20 algo_default (VARINT)
0x21 max_object_size (VARINT)
0x22 cor_version (VARINT) # 0x01 => COR/1 v1
0x23 gc_policy_id (VARINT; 0 if none)
0x24 impl_id (BYTES; optional build/impl descriptor CID)
```
### 3.2 Derived Identity
```
instance_id = SHA-256("CAS:ICD\0" || bytes(ICD/1))
```
**Rules:** Ordering/minimal VARINTs mirror COR/1. Exporters preserve canonical bytes; `instance_id` is stable.
---
## 4. Encodings
* **VARINT (unsigned LEB128)** — minimal form only; else `ERR_VARINT_NON_MINIMAL`.
* **BYTES** — `VARINT(length) || length bytes`.
* **Fixed-width integers** — big-endian if present.
* **No padding/alignment** in canonical encodings.
---
## 5. Algorithm Registry
**Default**
* `0x01` → SHA-256
**Reserved**
* `0x02` → SHA-512/256
* `0x03` → BLAKE3
**Policy**
* New entries require ADR + test vectors. Backward compatible by design.
---
## 6. Filesystem Considerations (Informative)
```
cas/
├─ sha256/
│ ├─ aa/.. # fan-out by CID prefix (implementation detail)
│ └─ ff/..
└─ amduat/
└─ <instance-id>/
├─ amduatcas
├─ sha256/.. # private runtime state; never a put() target
├─ interface/
│ └─ libamduatcas.current
├─ HEAD
└─ meta/
```
**Rule:** Public CAS API acts only on `cas/sha256/`. The per-instance subtree is private and MUST NOT receive `put()` writes.
---
## 7. Error Conditions & Higher-Layer Layouts (Normative)
### 7.1 COR/1 & ICD/1 Enforcement (codes)
* `ERR_COR_HEADER_INVALID`, `ERR_COR_UNKNOWN_TAG`, `ERR_COR_TAG_ORDER`, `ERR_COR_DUPLICATE_TAG`,
`ERR_COR_LENGTH_MISMATCH`, `ERR_VARINT_NON_MINIMAL`, `ERR_ALGO_UNSUPPORTED`,
`ERR_ALGO_MISMATCH`, `ERR_TRAILING_BYTES`, `ERR_CORRUPT_OBJECT`.
---
### 7.2 FCS/1 Descriptor Layout — v1-min (Normative)
> **Design principle:** *FCS/1 describes the deterministic execution recipe only.*
> Intent, roles, scope, authority, and registry policy are **not** encoded in FCS; they are captured at **certification time** in FCT/1.
Header: `MAGIC="FCS1" VERSION=0x01 FLAGS=RSV=0x00`
| Tag | Field | Type | Card. | Notes |
| ---: | ----------------- | ------ | ----: | ------------------------------------------ |
| 0x30 | `function_ptr` | CID | 1 | FPS/1 primitive or nested FCS/1 descriptor |
| 0x31 | `parameter_block` | CID | 1 | CID of PCB1 parameter block |
| 0x32 | `arity` | VARINT | 1 | Expected parameter slots |
**Validation rules**
1. Strict TLV order; duplicates/out-of-order → `ERR_FCS_TAG_ORDER`.
2. `parameter_block` MUST be valid PCB1 → `ERR_FCS_PARAMETER_FORMAT`.
3. `arity` MUST match slot count → `ERR_PCB_ARITY_MISMATCH`.
4. Descriptor graph MUST be acyclic → `ERR_FCS_CYCLE_DETECTED`.
5. **Any unknown or legacy governance tag** (`registry_policy 0x33`, `intent_vector 0x34`, `provenance_edge 0x35`, `notes 0x36`, or unregistered fields) → `ERR_FCS_UNKNOWN_TAG`. Such tags MUST never be tolerated in canonical streams.
---
### 7.3 PCB1 Parameter Blocks (Normative)
PCB1 payloads are COR/1 envelopes with header `MAGIC="PCB1"`, `VERSION=0x01`, `FLAGS=RSV=0x00`.
| Tag | Field | Type | Notes |
| ---: | --------------- | ----- | ----------------------------------------------------- |
| 0x50 | `slot_manifest` | BCF/1 | Canonical slot descriptors `{index,name,type,digest}` |
| 0x51 | `slot_data` | BYTES | Packed slot bytes respecting manifest order |
**Rules:**
Slots appear in ascending `index`. Numeric slots default to `0` when omitted.
Digest mismatches ⇒ `ERR_PCB_DIGEST_MISMATCH`. Non-deterministic ordering ⇒ `ERR_PCB_MANIFEST_ORDER`.
Arity mismatch vs FCS/1 ⇒ `ERR_PCB_ARITY_MISMATCH`.
---
### 7.4 **FER/1 Receipt Layout (Normative)**
FER/1 receipts reuse COR/1 framing with header `"FER1"` and are byte-deterministic.
**Strict TLV order (no padding):**
| Tag | Field | Type | Cardinality | Notes |
| ---- | --------------------- | ----------- | ----------- | ----- |
| 0x40 | `function_cid` | CID | 1 | Evaluated FCS/1 descriptor (must decode to v1-min). |
| 0x41 | `input_manifest` | CID | 1 | MUST decode to GS/1 BCF/1 set list (deduped, byte-lexicographic). |
| 0x42 | `environment` | CID | 1 | ICD/1 snapshot or PH03 environment capsule. |
| 0x43 | `evaluator_id` | BYTES | 1 | Stable evaluator identity (DID/descriptor CID). |
| 0x44 | `executor_set` | BCF/1 map | 1 | Map of executors → impl metadata (language/version/build); keys sorted. |
| 0x4F | `executor_fingerprint`| CID | 01 | SBOM/attestation CID feeding `run_id`; REQUIRED when `run_id` present. |
| 0x45 | `output_cid` | CID | 1 | Canonical output CID (single-output invariant). |
| 0x46 | `parity_vector` | BCF/1 list | 1 | Sorted by executor key; each entry carries `{executor, output, digest, sbom_cid}`. |
| 0x47 | `logs` | LIST<BCF/1> | 01 | Typed log capsules (`kind`, `cid`, `sha256`). |
| 0x51 | `determinism_level` | ENUM | 01 | `"D1_bit_exact"` (default) or `"D2_numeric_stable"`. |
| 0x50 | `rng_seed` | BYTES | 01 | 032 byte seed REQUIRED when determinism ≠ D1. |
| 0x52 | `limits` | BCF/1 map | 01 | Resource envelope (`cpu_ms`, `wall_ms`, `max_rss_kib`, `io_reads`, `io_writes`). |
| 0x48 | `started_at` | UINT64 | 1 | Epoch seconds (FR-020 start bound). |
| 0x49 | `completed_at` | UINT64 | 1 | Epoch seconds ≥ `started_at`. |
| 0x53 | `parent` | CID | 01 | Optional lineage pointer for follow-up runs. |
| 0x4A | `context` | BCF/1 map | 01 | Optional scheduling hooks (WT/1 ticket, TA/1 branch tip, notes ref). |
| 0x4B | `witnesses` | BCF/1 list | 01 | Optional observer descriptors / co-signers. |
| 0x4E | `run_id` | BYTES[32] | 01 | Deterministic dedup anchor (`H("AMDUAT:RUN\0" || function || manifest || env || fingerprint)`). |
| 0x4C | `signature` | BCF/1 map | 1 | Primary Ed25519 signature over `H("AMDUAT:FER\0" || canonical bytes)`. |
| 0x4D | `signature_ext` | BCF/1 list | 01 | Reserved slot for multi-sig / threshold proofs (future). |
**Validation:**
1. TLV order strict; unknown tags ⇒ `ERR_FER_TAG_ORDER` / `ERR_FER_UNKNOWN_TAG`.
2. `function_cid` must decode to valid FCS/1 ⇒ `ERR_FER_FUNCTION_MISMATCH` otherwise.
3. `input_manifest` MUST decode to GS/1 set list (deduped + byte-lexicographic). Violations ⇒ `ERR_FER_INPUT_MANIFEST_SHAPE`.
4. `executor_set` keys MUST be byte-lexicographic and align with `parity_vector` entries. Ordering mismatches ⇒ `ERR_IMPL_PARITY_ORDER`; missing executors or divergent outputs ⇒ `ERR_IMPL_PARITY`.
5. Each parity entry MUST declare `sbom_cid` referencing the executors mini-SBOM CID.
6. `determinism_level` defaults to `D1_bit_exact`; when set to any other value a 032 byte `rng_seed` is REQUIRED ⇒ `ERR_FER_RNG_REQUIRED`.
7. `limits` (when present) MUST supply non-negative integers for `cpu_ms`, `wall_ms`, `max_rss_kib`, `io_reads`, `io_writes`.
8. `logs` (when present) MUST contain objects with `kind ∈ {stderr, stdout, metrics, trace}`, `cid`, and `sha256` (both 32-byte hex strings).
9. `run_id` (when present) MUST equal `H("AMDUAT:RUN\0" || function_cid || manifest_cid || environment_cid || executor_fingerprint)`; missing fingerprint ⇒ `ERR_FER_UNKNOWN_TAG`.
10. `completed_at < started_at``ERR_FER_TIMESTAMP` (FR-020 envelope enforcement).
11. Signatures MUST verify against `H("AMDUAT:FER\0" || canonical bytes)` ⇒ failure ⇒ `ERR_FER_SIGNATURE`.
> **Manifest note:** `input_manifest` bytes MUST be the GS/1 canonical list; ingestion MUST reject producer-specific ordering.
> **Log capsule note:** `logs` entries bind `kind`, `cid`, and `sha256` together to avoid stdout/stderr hash confusion.
> **Dedup note:** `run_id` enables idempotent FER ingestion across registries while keeping the FER CID authoritative.
> **Provenance note:** FER/1 remains the exclusive home for run-time provenance and parity outcomes; governance stays in FCT/1.
> **Graph note:** Ingestors emit `realizes`, `produced_by`, `consumed_by`, and (optionally) `fulfills` edges based solely on FER content.
---
### 7.5 **FCT/1 Transaction Envelope (Normative)**
> **Design principle:** *FCT/1 is the canonical home for **intent**, **domain scope**, **roles/authority**, and **policy snapshot*** captured at certification/publication time.
FCT/1 serializes as ADR-003 BCF/1 map with canonical keys:
| Key | Type | Notes |
| --------------------- | ----------- | ------------------------------------------------------- |
| `fct.version` | UINT8 | MUST be `1` |
| `fct.registry_policy` | UINT8 | Publication policy snapshot (0=Open,1=Curated,2=Locked) |
| `fct.function` | CID | Certified FCS/1 descriptor |
| `fct.receipts` | LIST<CID> | One or more FER/1 CIDs |
| `fct.authority_role` | ENUM | ADR-010C role |
| `fct.domain_scope` | ENUM | ADR-010B scope |
| `fct.intent` | SET<ENUM> | ADR-010 intents |
| `fct.constraints` | LIST<BCF/1> | Optional constraint set |
| `fct.attestations` | LIST<BYTES> | Required when policy ≠ Open |
| `fct.timestamp` | UINT64 | Epoch seconds |
| `fct.publication` | CID | Optional ADR-007 digest |
**Validation:**
1. All receipts reference the same `function_cid` ⇒ else `ERR_FCT_RECEIPT_MISMATCH`.
2. If `registry_policy ≠ 0` then `attestations` **required**`ERR_FCT_ATTESTATION_REQUIRED`.
3. All signatures/attestations verify ⇒ `ERR_FCT_SIGNATURE` on failure.
4. Receipt timestamps must be monotonic ⇒ `ERR_FCT_TIMESTAMP`.
---
### 7.6 FPD/1 Publication Digest (Normative)
> **Design principle:** *Federation publishes exactly one deterministic digest per event (ADR-007, SRS FR-022).*
FPD/1 serializes as an ADR-003 BCF/1 map with canonical keys:
| Key | Type | Notes |
| --------------- | ---------- | --------------------------------------------------------------------- |
| `fpd.version` | UINT8 | MUST be `1`. |
| `fpd.members` | LIST<CID> | Deterministic, byte-lexicographic list of member artefact CIDs. |
| `fpd.parent` | CID (opt) | Previous FPD/1 digest for the domain publication chain (or `null`). |
| `fpd.timestamp` | UINT64 | Epoch seconds aligned with `fct.timestamp` monotonic ordering. |
| `fpd.digest` | CID | Canonical digest over `{FCT/1 bytes, FER/1 receipts, governance edges}`. |
**Construction:**
1. Normalize and sign the FCT/1 record (per §7.5) writing canonical bytes to the payload area (PA).
2. Collect referenced FER/1 receipts and governance edges (`certifies`, `attests`, `publishes`) as canonical byte arrays.
3. Build `fpd.members` as the byte-lexicographic list of CIDs for the certified FCT/1 record, every FER/1 receipt, and the edge batch capsule.
4. Hash the concatenated canonical payloads using the federation digest algorithm (default `CIDv1/BCF`). Persist the resulting bytes and record the CID in `fpd.digest`.
5. If a prior publication exists, set `fpd.parent` to the previous digest CID; otherwise omit.
6. Emit the FPD/1 map, persist alongside the FCT/1 payload under `/logs/ph03/evidence/fct/`, and update `fct.publication` with the FPD/1 CID.
**Validation:**
* `fpd.members` MUST include exactly one FCT/1 CID and the full set of FER/1 receipt CIDs referenced by that transaction.
* Recomputing the digest from the persisted canonical payloads MUST yield `fpd.digest`; mismatches ⇒ `ERR_FPD_DIGEST` (registered under ADR-006).
* `fpd.timestamp` MUST be ≥ the largest FER/1 `completed_at` and ≥ the prior `fpd.timestamp` when `fpd.parent` is present ⇒ violations raise `ERR_FPD_TIMESTAMP`.
* Graph emitters MUST log governance edges via `lib/g1-emitter/` using the canonical digests referenced above.
> **Graph note:** Publication surfaces emit `publishes(fct,fpd)` edges binding certification state to digest lineage for PH04 FLS/1 integration.
### 7.7 Error Surface Registration (consolidated)
All FCS/1, PCB1, FER/1, and FCT/1 errors map to ADR-006.
Additions since v0.3.0:
| Code | Meaning |
| --------------------- | -------------------------------------------------------------------------------------- |
| `ERR_FCS_UNKNOWN_TAG` | Descriptor contained a tag outside the v1-min set (`0x30-0x32`). Rejected per ADR-006. |
| `ERR_EXEC_TIMEOUT` | Executor exceeded deterministic time envelope (Maats Balance). |
| `ERR_IMPL_PARITY` | Executor outputs/parity metadata diverged (missing executor, mismatched `output_cid`). |
| `ERR_IMPL_PARITY_ORDER` | Parity vector ordering did not match the canonical executor ordering. |
| `ERR_FER_UNKNOWN_TAG` | FER/1 payload contained an unknown tag or cardinality violation. |
| `ERR_FER_INPUT_MANIFEST_SHAPE` | `input_manifest` failed GS/1 set decoding (not deduped or unsorted). |
| `ERR_FER_RNG_REQUIRED` | `determinism_level` demanded an `rng_seed` but none was provided. |
| `ERR_FPD_DIGEST` | Recomputed federation digest did not match `fpd.digest` (non-deterministic publication). |
| `ERR_FPD_TIMESTAMP` | Publication timestamp regressed relative to receipts or parent digest. |
| `ERR_FPD_PARENT_REQUIRED` | Policy-enforced lineage expected `fpd.parent` but none was provided. |
| `ERR_FPD_MEMBER_DUP` | Duplicate member CID detected in the canonical set ordering. |
| `ERR_WT_UNKNOWN_KEY` | WT/1 map contained a key outside the v1-min schema. |
| `ERR_WT_VERSION_UNSUPPORTED` | `wt.version` not equal to `1`. |
| `ERR_WT_INTENT_EMPTY` | `wt.intent` list empty. |
| `ERR_WT_INTENT_DUP` | Duplicate ADR-010 intents detected in `wt.intent`. |
| `ERR_WT_TIMESTAMP` | `wt.timestamp` regressed relative to the previous ticket from the same author. |
| `ERR_WT_SIGNATURE` | Signature validation over `"AMDUAT:WT\0"` failed. |
| `ERR_WT_KEY_UNBOUND` | Declared `wt.pubkey` is not authorized for `wt.author` via the predicate registry. |
| `ERR_WT_INTENT_UNREGISTERED` | `wt.intent` entry not registered in ADR-010 predicate registry. |
| `ERR_WT_SCOPE_UNAUTHORIZED` | Router policy rejected the declared domain scope. |
| `ERR_WT_PARENT_UNKNOWN` | Optional `wt.parent` reference could not be resolved. |
| `ERR_WT_PARENT_REQUIRED` | Policy required `wt.parent` but the field was omitted. |
| `ERR_SOS_UNKNOWN_KEY` | SOS/1 map contained a key outside the v1-min schema. |
| `ERR_SOS_VERSION_UNSUPPORTED` | `sos.version` not equal to `1`. |
| `ERR_SOS_PREDICATE_UNREGISTERED` | Overlay predicate not registered in the CRS predicate registry. |
| `ERR_SOS_POLICY_INCOMPATIBLE` | `sos.policy` outside `{0,1,2}` or disallowed for the deployment lane. |
| `ERR_SOS_SIGNATURE_INVALID` | Signature validation over `"AMDUAT:SOS\0"` failed. |
| `ERR_SOS_COMPAT_EVIDENCE_REQUIRED` | Compat overlays missing MPR/1 + IER/1 references. |
| `ERR_SOS_TIMESTAMP_REGRESSION` | Overlay timestamp regressed relative to policy baseline. |
### 7.8 FLS/1 and CRS/1 Byte Semantics
Phase 04 establishes deterministic linkage between FLS/1 envelopes and CRS/1 concept graphs. ADR-018 governs the linkage envelope; ADR-020 governs concept and relation payloads. CI harnesses (`tools/ci/run_vectors.py`, `tools/ci/gs_snapshot.py`) provide conformance evidence.
#### 7.8.1 FLS/1 Envelope TLVs (Draft)
> **Scope:** Draft wire image aligned with ADR-018 v0.5.0. Stewardship will finalize signature semantics alongside multi-surface publication work.
| Tag | Field | Type | Card. | Notes |
| ------ | -------------------- | ------ | ----- | ----- |
| `0x60` | `source_cid` | CID | 1 | Deterministic sender artefact/surface. |
| `0x61` | `target_cid` | CID | 1 | Deterministic recipient artefact/surface. |
| `0x62` | `payload_cid` | CID | 1 | Content payload (COR/1 capsule, CRS/1 concept, or CRR/1 relation). |
| `0x63` | `routing_policy_cid` | CID | 0-1 | Optional deterministic policy capsule. |
| `0x64` | `timestamp` | UINT64 | 0-1 | Optional bounded timing evidence (big-endian). |
| `0x65` | `signature` | BYTES | 0-1 | Optional Ed25519 signature with `"AMDUAT:FLS\0"` domain separator. |
**Envelope rules (draft):**
* Header MUST present `MAGIC="FLS1"`, `VERSION=0x01`, and zeroed `FLAGS/RSV` bytes.
* TLVs MUST appear in strictly increasing tag order. Duplicate tags ⇒ `ERR_FLS_DUPLICATE_TAG`; reordering ⇒ `ERR_FLS_TAG_ORDER`.
* Unknown tags are rejected until ADR updates extend this table (`ERR_FLS_UNKNOWN_TAG`).
* CID TLVs MUST present 32-byte payloads aligned with ADR-001 ⇒ `ERR_FLS_CID_LENGTH`.
* `timestamp` MUST be exactly eight bytes (UINT64, network byte order) ⇒ `ERR_FLS_TIMESTAMP_LENGTH`.
* `signature` MUST start with `"AMDUAT:FLS\0"` and carry a 64-byte Ed25519 signature ⇒ `ERR_FLS_SIGNATURE_DOMAIN` / `ERR_FLS_SIGNATURE_LENGTH`; failing Ed25519 verification raises `ERR_FLS_SIGNATURE`.
* When supplied, CRS payload bytes MUST hash to the declared `payload_cid` using `SHA-256("CAS:OBJ\0" || payload)``ERR_FLS_PAYLOAD_CID_MISMATCH`.
* CRS payload headers MUST match `CRS1` (concept) or `CRR1` (relation) when linkage metadata declares the type ⇒ `ERR_FLS_PAYLOAD_KIND`.
* Payloads MAY be CRS/1 concepts or CRR/1 relations; FLS/1 envelopes never mutate CRS graphs.
#### 7.8.2 CRS/1 Concept & Relation TLVs (Normative)
> **Scope:** Deterministic CRS/1 byte layout as ratified by ADR-020 v1.1.0. All TLVs
> use single-byte tags + single-byte lengths with fixed 32-byte payloads.
**Concept Header**`MAGIC="CRS1"`, `VERSION=0x01`, `FLAGS=0x00`, `RSV=0x00`.
| Tag | Field | Type | Card. | Notes |
| ------ | ------------------ | ---- | ----- | ----- |
| `0x40` | `description_cid` | CID | 1 | Canonical COR/1/BCF descriptor for the concept text/essence. |
| `0x41` | `relations_cid` | CID | 1 | Deterministic list CID of outbound relation CIDs. |
**Relation Header**`MAGIC="CRR1"`, `VERSION=0x01`, `FLAGS=0x00`, `RSV=0x00`.
| Tag | Field | Type | Card. | Notes |
| ------ | ----------------- | ---- | ----- | ----- |
| `0x42` | `source_cid` | CID | 1 | Originating Concept CID. |
| `0x43` | `target_cid` | CID | 1 | Destination Concept or artefact CID. |
| `0x44` | `predicate_cid` | CID | 1 | Registered predicate Concept CID. |
**Validation rules**
* Headers MUST match the values above; mismatches reject as malformed.
* TLVs MUST appear exactly once in the order listed. Missing or out-of-order
TLVs ⇒ `ERR_CRS_TAG_ORDER` (concept) or `ERR_CRR_TAG_ORDER` (relation).
* Duplicate relation tags ⇒ `ERR_CRR_DUPLICATE_TAG`.
* TLV payloads MUST be exactly 32 bytes ⇒ `ERR_CRS_LENGTH_MISMATCH` / `ERR_CRR_LENGTH_MISMATCH`.
* Unknown tags are rejected ⇒ `ERR_CRS_UNKNOWN_TAG` / `ERR_CRR_UNKNOWN_TAG`.
* `predicate_cid` MUST reference a CRS Concept (`ERR_CRR_PREDICATE_NOT_CONCEPT`). When a predicate taxonomy exists, predicates MUST declare `is_a → Predicate` (`ERR_CRR_PREDICATE_CLASS_MISSING`).
**Error mapping (ADR-006)**
| Code | Condition |
| ---- | --------- |
| `ERR_CRS_TAG_ORDER` | Concept TLVs missing, duplicated, or out of order. |
| `ERR_CRS_LENGTH_MISMATCH` | Concept TLV payload not exactly 32 bytes. |
| `ERR_CRS_UNKNOWN_TAG` | Concept TLV tag outside `0x400x41`. |
| `ERR_CRR_TAG_ORDER` | Relation TLVs missing, duplicated, or out of order. |
| `ERR_CRR_LENGTH_MISMATCH` | Relation TLV payload not exactly 32 bytes. |
| `ERR_CRR_UNKNOWN_TAG` | Relation TLV tag outside `0x420x44`. |
| `ERR_CRR_DUPLICATE_TAG` | Duplicate relation TLV encountered. |
| `ERR_CRR_PREDICATE_NOT_CONCEPT` | `predicate_cid` did not resolve to a CRS Concept. |
| `ERR_CRR_PREDICATE_CLASS_MISSING` | Predicate Concept missing `is_a → Predicate` taxonomy edge. |
**CID derivation**
```
concept_cid = SHA-256("CAS:OBJ\0" || bytes(CRS/1 concept record))
relation_cid = SHA-256("CAS:OBJ\0" || bytes(CRR/1 relation record))
```
Byte-identical records MUST yield identical CIDs; any mutation requires a new
record.
### 7.9 WT/1 Audited Ticket Intake (Normative)
WT/1 (ADR-023) captures auditable intent-to-change tickets as an ADR-003 BCF/1
map. Keys are UTF-8 strings sorted lexicographically; values use canonical BCF
types.
| Key | Type | Cardinality | Notes |
| -------------- | ----------------- | ----------- | ----- |
| `wt.version` | UINT8 | 1 | MUST equal `1`. |
| `wt.author` | CID (hex string) | 1 | CRS Concept or DID capsule representing the submitting actor. |
| `wt.scope` | CID (hex string) | 1 | ADR-010B domain scope concept CID. |
| `wt.intent` | LIST<STRING> | 1 | Non-empty ADR-010 intent identifiers; deduped and byte-lexicographically sorted. |
| `wt.payload` | CID (hex string) | 1 | CRS manifest, change plan, or opaque payload describing proposed work. |
| `wt.timestamp` | UINT64 | 1 | Epoch seconds; MUST be monotonic per `wt.author`. |
| `wt.pubkey` | BYTES[32] | 1 | Ed25519 public key used to verify `wt.signature`; MUST bind to `wt.author`. |
| `wt.signature` | BYTES[64] | 1 | Ed25519 signature over `H("AMDUAT:WT\0" || canonical_bytes_without_signature)`. |
| `wt.parent` | CID (hex string) | 01 | Optional lineage pointer to the previous WT/1 ticket for the same author. |
**Encoding rules**
1. `wt.intent` MUST be encoded as a list of unique UTF-8 strings sorted
lexicographically; duplicates ⇒ `ERR_WT_INTENT_DUP`; entries not registered in
ADR-010 ⇒ `ERR_WT_INTENT_UNREGISTERED`.
2. CIDs serialize as lowercase hex strings (32 bytes → 64 hex chars) matching
`SHA-256("CAS:OBJ\0" || payload)` outputs.
3. `wt.signature` is a 64-byte Ed25519 signature; `wt.pubkey` supplies the
32-byte verification key. The signature domain-separates with
`"AMDUAT:WT\0"` and excludes the `wt.signature` field from the canonical byte
stream hashed for verification.
**Validation**
1. Unknown keys ⇒ `ERR_WT_UNKNOWN_KEY`.
2. `wt.version != 1``ERR_WT_VERSION_UNSUPPORTED`.
3. Empty `wt.intent``ERR_WT_INTENT_EMPTY`.
4. `wt.timestamp` less than the prior accepted ticket for the same `wt.author`
`ERR_WT_TIMESTAMP`. When `wt.parent` is provided, its timestamp MUST NOT
exceed the child timestamp; violations ⇒ `ERR_WT_TIMESTAMP`.
5. Signature verification failure ⇒ `ERR_WT_SIGNATURE`.
6. Routers MUST verify `has_pubkey(wt.author, wt.pubkey)` (or registered
equivalent) ⇒ missing edge raises `ERR_WT_KEY_UNBOUND`.
7. Unknown ADR-010 intent ⇒ `ERR_WT_INTENT_UNREGISTERED`.
8. Router policy rejection of `wt.scope``ERR_WT_SCOPE_UNAUTHORIZED`.
9. Provided `wt.parent` that cannot be resolved ⇒ `ERR_WT_PARENT_UNKNOWN`.
10. Policy required lineage but omitted `wt.parent``ERR_WT_PARENT_REQUIRED`.
**Router integration**
* `POST /wt` (Protected Area) accepts WT/1 payloads, verifies signatures against
`wt.pubkey`, enforces ADR-010 intent membership, validates optional
`wt.parent` lineage, and rejects timestamp regressions.
* `GET /wt/:cid` returns canonical WT/1 bytes for replay.
* `GET /wt?after=<cid>&limit=<n>` paginates deterministically by CID
(byte-lexicographic). `after` is an exclusive bound; routers enforce
`1 ≤ limit ≤ Nmax` and MUST preserve stable replay windows.
* Responses MUST include canonical WT/1 bytes; no rewriting or reformatting is
permitted.
**Evidence & vectors**
* `/amduat/logs/ph04/evidence/wt1/PH04-EV-WT-001/summary.md` — validator run linking
router behaviour to vectors.
* `/amduat/vectors/ph04/wt1/` — fixtures `TV-WT-001…009` covering success,
unknown key, signature failure, timestamp regression, key unbound, intent
unregistered, parent timestamp inversion, scope policy rejection, and
unresolved parent lineage.
### 7.10 CT/1 Header (Normative)
CT/1 headers serialize as ADR-003 BCF/1 maps with fixed key ordering. Keys and
types:
| Key | Type | Notes |
| --------------------- | -------- | ----- |
| `ct.version` | `UINT8` | MUST equal `1`. |
| `ct.rcs_version` | `UINT8` | RCS/1 core schema version; MUST equal `1`. |
| `ct.topology` | `CID` | CRS/1 topology or manifest CID. |
| `ct.ac` | `CID` | AC/1 descriptor CID (ADR-028). |
| `ct.dtf` | `CID` | DTF/1 policy CID (ADR-028). |
| `ct.determinism_level`| `UINT8` | `0` = D1 (bit-exact), `1` = D2 (numeric stable). |
| `ct.kernel_cfg` | `CID` | Opaque kernel/tolerance configuration manifest. |
| `ct.tick` | `UINT64` | Monotonically increasing replay sequence number. |
| `ct.signature` | `BYTES` | 64-byte Ed25519 signature payload. |
**Validation**
1. BCF decode failures ⇒ `ERR_CT_MALFORMED`.
2. Key set/order mismatches ⇒ `ERR_CT_UNKNOWN_KEY`.
3. `ct.version` or `ct.rcs_version``1``ERR_CT_VERSION`.
4. `ct.determinism_level ∉ {0,1}``ERR_CT_DET_LEVEL`.
5. Non-canonical CID strings ⇒ `ERR_CT_CID`.
6. `ct.tick` outside `UINT64` range or non-monotone progression ⇒
`ERR_CT_FIELD_TYPE` / `ERR_CT_TICK`.
7. `ct.signature` length mismatch or Ed25519 verification failure ⇒
`ERR_CT_SIGNATURE`.
**Signature rules**
`ct.signature` signs `H("AMDUAT:CT\0" || canonical_bytes_without_signature)`. Public
keys are registered in the determinism catalogue (this section) and referenced by
`ct.kernel_cfg` as needed for tolerance disclosure.
**Evidence & vectors**
* `/amduat/tools/validate/ct1_validator.py` — validation helper covering CT/1,
AC/1, and DTF/1 schemas.
* `/amduat/vectors/ph05/ct1/` — fixtures `TV-CT1-001…004`, `TV-AC1-001…002`,
`TV-DTF1-001…002`.
* `/amduat/tools/ci/ct_replay.py` — replay harness producing
`/amduat/logs/ph05/evidence/ct1/PH05-EV-CT1-REPLAY-001/` (D1 parity + D2
tolerance runs).
### 7.11 SOS/1 Semantic Overlays (Normative)
SOS/1 (ADR-024) attaches typed overlays to CRS Concepts or Relations via an
ADR-003 BCF/1 map signed with the `"AMDUAT:SOS\0"` domain separator.
| Key | Type | Cardinality | Notes |
| -------------- | ------------ | ----------- | ----- |
| `sos.version` | UINT8 | 1 | MUST equal `1`. |
| `sos.subject` | CID (hex) | 1 | CRS Concept or Relation CID receiving the overlay. |
| `sos.predicate`| CID (hex) | 1 | Registered predicate concept describing overlay semantics. |
| `sos.value` | CID (hex) | 1 | Opaque payload (text capsule, BCF/1 manifest, etc.). |
| `sos.policy` | ENUM | 1 | `0=open`, `1=curated`, `2=compat`. |
| `sos.timestamp`| UINT64 | 1 | Epoch seconds when authored. |
| `sos.signature`| BYTES[64] | 1 | Ed25519 signature over `H("AMDUAT:SOS\0" || canonical_bytes_without_signature)`. |
**Validation**
1. Unknown keys ⇒ `ERR_SOS_UNKNOWN_KEY`.
2. `sos.version != 1``ERR_SOS_VERSION_UNSUPPORTED`.
3. `sos.predicate` MUST resolve to a registered CRS predicate ⇒
`ERR_SOS_PREDICATE_UNREGISTERED`.
4. `sos.policy` outside `{0,1,2}` or disallowed for deployment ⇒
`ERR_SOS_POLICY_INCOMPATIBLE`.
5. Epoch-second timestamps that regress relative to policy baseline MAY raise
`ERR_SOS_TIMESTAMP_REGRESSION`.
6. Signature verification failure ⇒ `ERR_SOS_SIGNATURE_INVALID`.
7. Compat overlays (`sos.policy = 2`) MUST reference MPR/1 + IER/1 artefacts in
certification evidence ⇒ missing references raise
`ERR_SOS_COMPAT_EVIDENCE_REQUIRED`.
**Router integration**
* `POST /sos` (Protected Area) validates predicate registry membership, policy
lane, timestamp discipline, and signatures.
* `GET /sos/:cid` returns canonical SOS/1 bytes for replay.
* `GET /sos?subject=<cid>&after=<cid?>&limit=<n>` paginates overlays
deterministically by CID with stable replay windows.
* Compat responses MUST surface referenced MPR/1 hashes and IER/1 fingerprints
for auditors.
**Evidence & vectors**
* `/amduat/logs/ph04/evidence/sos1/PH04-EV-SOS-001/summary.md` — validator run covering
`TV-SOS-001…006`.
* `/amduat/vectors/ph04/sos1/` — canonical overlay fixtures exercising success,
unregistered predicate, policy mismatch, signature failure, timestamp
regression, and compat evidence gaps.
### 7.12 MPR/1 Model Provenance (Normative)
MPR/1 (ADR-025 v1.0.0) captures canonical model fingerprint triples for compat
policy lanes.
| Key | Type | Cardinality | Notes |
| ------------------ | ------------ | ----------- | ----- |
| `mpr.version` | UINT8 | 1 | MUST equal `1`. |
| `mpr.model_hash` | HEX | 1 | Lowercase hex digest (≥64 chars) of model artefact. |
| `mpr.weights_hash` | HEX | 1 | Lowercase hex digest (≥64 chars) of weights bundle. |
| `mpr.tokenizer_hash` | HEX | 1 | Lowercase hex digest (≥64 chars) of tokenizer assets. |
| `mpr.build_info` | CID *(optional)* | 0..1 | Immutable build metadata capsule. |
| `mpr.signature` | BYTES[64] *(optional)* | 0..1 | Ed25519 signature over `"AMDUAT:MPR\0" || canonical_bytes_without_signature`. |
**Validation**
1. Unknown keys ⇒ `ERR_MPR_UNKNOWN_KEY`.
2. `mpr.version != 1``ERR_MPR_VERSION`.
3. Missing hash fields ⇒ `ERR_MPR_MISSING_FIELD`.
4. Hash fields not lowercase hex (≥64) ⇒ `ERR_MPR_HASH_FORMAT`; zero digests ⇒ `ERR_MPR_HASH_ZERO`.
5. `mpr.build_info` malformed ⇒ `ERR_MPR_BUILD_INFO`.
6. Signature verification failure ⇒ `ERR_MPR_SIGNATURE`.
**Evidence & vectors**
* `/amduat/logs/ph04/evidence/mpr1/PH04-EV-MPR-001/pass.jsonl` — validator harness (`python tools/ci/run_mpr_vectors.py`) covering `TV-MPR-001…003` with summary in `summary.md`.
* `/amduat/vectors/ph04/mpr1/` — fixtures exercising valid record, missing weights hash, and signature domain mismatch.
### 7.13 IER/1 Inference Evidence (Normative)
IER/1 (ADR-026 v1.0.0) binds FER/1 receipts to compat policy envelopes and MPR/1 fingerprints.
| Key | Type | Cardinality | Notes |
| ------------------------ | --------------- | ----------- | ----- |
| `ier.version` | UINT8 | 1 | MUST equal `1`. |
| `ier.fer_cid` | CID | 1 | Referenced FER/1 receipt. |
| `ier.executor_fingerprint` | CID | 1 | MUST equal linked MPR/1 CID. |
| `ier.determinism_level` | ENUM | 1 | FER/1 determinism indicator. |
| `ier.rng_seed` | HEX *(conditional)* | 0..1 | Required (hex) when determinism ≠ `D1`. |
| `ier.policy_cid` | CID | 1 | Compat policy capsule authorising run. |
| `ier.log_digest` | HEX | 1 | `H("AMDUAT:IER:LOG\0" || concat(log.sha256))`. |
| `ier.log_manifest` | MAP *(optional)* | 0..1 | Non-empty list of log entries with `sha256`. |
| `ier.attestations` | LIST<BYTES> *(optional)* | 0..1 | Policy attestations (Ed25519 signatures). |
**Validation**
1. Unknown keys ⇒ `ERR_IER_UNKNOWN_KEY`.
2. `ier.version != 1``ERR_IER_VERSION`.
3. Malformed CIDs ⇒ `ERR_IER_POLICY`.
4. `ier.executor_fingerprint` mismatch ⇒ `ERR_IER_FINGERPRINT`.
5. Missing RNG seed when determinism ≠ `D1``ERR_FER_RNG_REQUIRED`.
6. `ier.log_digest` mismatch or malformed manifest ⇒ `ERR_IER_LOG_HASH` / `ERR_IER_LOG_MANIFEST`.
7. Attestation payloads not raw bytes ⇒ `ERR_IER_MALFORMED`.
**Evidence & vectors**
* `/amduat/logs/ph04/evidence/ier1/PH04-EV-IER-001/pass.jsonl` — validator harness (`python tools/ci/run_ier_vectors.py`) covering `TV-IER-001…004` with manifest summary in `summary.md`.
* `/amduat/vectors/ph04/ier1/` — fixtures exercising success, missing RNG seed, fingerprint mismatch, and log digest mismatch.
---
## 8 Test Vectors & Conformance
### 8.1 COR/1 & ICD/1
* Payload → CID (algo `0x01`).
* COR/1 streams → CID and back (round-trip identity).
* ICD/1 → `instance_id`.
### 8.2 FCS/1 v1-min
* Positive: `{0x30,0x31,0x32}` only, strict order, valid PCB1, acyclic.
* Negative: any pre-v1-min tags (`0x33/0x34/0x35/0x36`) ⇒ reject per §7.2.
* Arity/PCB mismatch ⇒ `ERR_PCB_ARITY_MISMATCH`.
* Cycle ⇒ `ERR_FCS_CYCLE_DETECTED`.
* Negative: legacy tags (`0x33-0x36`) → `ERR_FCS_UNKNOWN_TAG` per §7.2.
### 8.3 FER/1
* Signed receipt with monotonic timestamps; verify signature, executor set ↔ parity alignment, and linkage to FCS/1.
* Negative: timestamp inversion ⇒ `ERR_FER_TIMESTAMP`; bad signature ⇒ `ERR_FER_SIGNATURE`.
* Negative: parity drift (mismatched executor keys or output digests) ⇒ `ERR_IMPL_PARITY`.
* Negative: unknown TLV tag/cardinality ⇒ `ERR_FER_UNKNOWN_TAG`.
### 8.4 FCT/1
* Multiple FER/1 receipts for same function; verify attestation coverage by policy.
* Negative: mismatched receipt function ⇒ `ERR_FCT_RECEIPT_MISMATCH`.
* Negative: missing attestation when policy ≠ Open ⇒ `ERR_FCT_ATTESTATION_REQUIRED`.
### 8.5 FPD/1
* Deterministic reconstruction of `fpd.digest` over `{FCT/1 bytes, FER/1 receipts, governance edge capsule}` on repeated runs.
* Negative: perturbation of member ordering ⇒ `ERR_FPD_DIGEST`.
* Negative: timestamp regression versus FER receipts or parent digest ⇒ `ERR_FPD_TIMESTAMP`.
**CI Requirements**
* Import/export **byte-identity** round-trip for COR/1/FCS/1/FER/1.
* Canonical TLV/BCF ordering across descriptors.
* Multi-platform reproducibility (≥3) including signature verification parity.
* Timing evidence captured per SRS FR-020 (deterministic envelope).
* Federation digest fixture verifies stable FPD/1 CID under `tools/ci/fct_publish_check.py`.
---
## 9. Security Considerations
* Domain separation strings MUST be exact.
* Hash **exact payload bytes**, never decoded structures.
* Canonical rejection prevents ambiguous encodings.
* Certification places policy/intent in signed FCT/1, not in execution recipes.
---
## 10. Change Management
* **Behavioural semantics are in SRS.**
* Changes here require ADR + CCP approval.
* Versioning follows semantic versioning of encodings.
* On approval, update IDX and SRS references accordingly.
---
## 11. ByteStore API & Persistence Discipline
ByteStore is the canonical persistence boundary layered over COR/1 and ICD/1.
Implementations **must** honour the behaviours in this section; deviations are
governed by ADR-030.
### 11.1 API Surface
| API | Signature | Behaviour | Error Surfaces (ADR-006) |
| -------------------- | ---------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------- |
| `put` | `(payload: bytes) → cid_hex` | Persist raw payload under CID derived from `H("CAS:OBJ\0" || payload)`. | `ERR_POLICY_SIZE`, `ERR_IDENTITY_MISMATCH` |
| `put_stream` | `(chunks: Iterable[bytes]) → cid_hex` | Deterministic chunked ingest; concatenated bytes hash to the same CID as `put`. | `ERR_STREAM_ORDER`, `ERR_STREAM_TRUNCATED` |
| `import_cor` | `(envelope: bytes) → cid_hex` | Validate COR/1, enforce policy, persist canonical envelope without re-encoding. | `ERR_POLICY_SIZE`, COR/1 decoder errors |
| `export_cor` | `(cid_hex: str) → envelope` | Return stored COR/1 bytes; must match the original import byte-for-byte. | `ERR_STORE_MISSING`, `ERR_IDENTITY_MISMATCH` |
| `get` | `(cid_hex: str) → bytes` | Return stored bytes (payload or COR envelope) exactly as persisted. | `ERR_STORE_MISSING` |
| `stat` | `(cid_hex: str) → {present: bool, size: int}` | Probe object presence and payload/envelope size without mutating state. | `ERR_STORE_MISSING` (absence reported via `present`) |
| `assert_area_isolation` | `(public_root: Path, secure_root: Path) → None` | Enforce SA/PA separation; raise if roots overlap or share ancestry. | `ERR_AREA_VIOLATION` |
### 11.2 Deterministic Identity
Canonical identity is derived per COR/1/SRS:
```
cid = algo_id || H("CAS:OBJ\0" || payload)
```
`algo_id` defaults to `0x01` (SHA-256). ByteStore **must** reuse the exact
domain separator and hash to remain compatible with CAS and DDS §1.
### 11.3 COR/1 Round-Trip Identity
`import_cor()` decodes the envelope, enforces policy (size ≤ ICD/1
`max_object_size`), and persists the canonical bytes. `export_cor()` returns the
exact stored envelope; re-encoding is forbidden. Derived CID **must** equal the
envelopes CID (DDS §2.5, SRS FR-BS-004).
### 11.4 Atomic fsync Ladder
All writes follow the deterministic ladder:
1. Write payload/envelope to a unique `.tmp-<suffix>` file in the shard.
2. `fsync(tmp)` to guarantee payload durability.
3. `rename(tmp, final)`.
4. `fsync(shard directory)` and then `fsync(ByteStore root)`.
Crash-window simulation is exposed via `AMDUAT_BYTESTORE_CRASH_STEP` (“before_rename”).
Implementations **must** honour the hook and leave PA consistent on recovery
(DDS §11.8; vectors TV-BS-005, evidence bundle PH05-EV-BS-001).
### 11.5 SA/PA Isolation & Pathing
Public area (PA) payloads live under case-stable two-level fan-out (`/aa/bb/cid…`).
Secure area (SA) metadata is held outside the PA tree. `assert_area_isolation()`
enforces:
* `public_root != secure_root`
* neither root is an ancestor of the other
Violations raise `ERR_AREA_VIOLATION` and **must** be surfaced by callers.
### 11.6 Chunked Ingest Determinism & Policy
`put_stream()` concatenates byte chunks in order, rejecting non-bytes input or
missing data. The resulting CID **must** equal `put(payload)` for the same
payload (SRS FR-BS-005). ByteStore enforces ICD/1 `max_object_size` prior to
persisting data; exceeding the limit raises `ERR_POLICY_SIZE`.
### 11.7 Error Mapping
| Condition | Error Code | Notes |
| ---------------------------------- | --------------------- | -------------------------------------------------------------- |
| Payload exceeds policy limit | `ERR_POLICY_SIZE` | ICD/1 `max_object_size` (ADR-006 policy lane). |
| Streaming chunk type/order invalid | `ERR_STREAM_ORDER` | Non-bytes or out-of-order chunks (deterministic rejection). |
| Streaming missing payload | `ERR_STREAM_TRUNCATED`| Zero-length stream without payload. |
| Stored bytes mismatch CID | `ERR_IDENTITY_MISMATCH` | Raised when existing bytes conflict with derived identity. |
| SA/PA overlap | `ERR_AREA_VIOLATION` | Shared roots or ancestry (secure/public crossing). |
| Crash-window hook triggered | `ERR_CRASH_SIMULATION`| Simulated crash prior to rename/fsync ladder completion. |
| Missing object | `ERR_STORE_MISSING` | Reported when an object path is absent. |
All other errors bubble from COR/1 decoding and map to existing ADR-006 codes
(see §2.7).
### 11.8 Conformance & Evidence
* Vectors: `/amduat/vectors/ph05/bytestore/` (`TV-BS-001…005`).
* Runner: `/amduat/tools/ci/bs_check.py` (dual-run determinism; emits JSONL).
* Evidence: `/amduat/logs/ph05/evidence/bytestore/PH05-EV-BS-001/` (runA/runB +
crash summary).
* Linked ADR: ADR-030 (ByteStore Persistence Contract).
---
## Appendix A — Surface Version Table
| Surface | Version | Notes |
| ------- | ------- | ----- |
| FCS/1 | v1-min | Execution-only descriptor (ADR-016); governance fields live in FCT/1. |
| FER/1 | v1.1 | Parity-first receipts with run_id dedup, executor fingerprints, typed logs, RNG envelope (ADR-017). |
| FCT/1 | v1.0 | Certification transactions binding policy/intent/attestations; publishes FER/1 receipts. |
| FPD/1 | v1.0 | Single-digest publication capsule linking FCT/1 and FER/1 sets. |
---
**End of DDS 0.5.0**
---
## Document History
* 0.2.1 (2025-10-26) — Updated Phase Pack references; byte semantics unchanged; ADR-012 no-normalization.
* 0.2.2 (2025-10-26) — Promoted PH01 design surfaces to Approved; synchronized anchors.
* 0.2.3 (2025-10-27) — Marked DDS scope as PH01-only and referenced FPS/1 surfaces.
* **0.2.4 (2025-11-14):** Added FCS/1 & PCB1 TLVs plus FER/1 receipt and FCT/1 transaction schemas with rejection mapping.
* **0.2.5 (2025-11-15):** Registered PCB1 header invariants and arity/cycle validation errors.
* **0.2.6 (2025-11-19):** Registered `ERR_EXEC_TIMEOUT` for deterministic timing envelope.
* **0.3.0 (2025-11-02):** Trimmed **FCS/1 to v1-min** (execution recipe only: `function_ptr`, `parameter_block`, `arity`). Moved **intent/roles/scope/policy** to **FCT/1**; clarified provenance lives in **FER/1**. Added rejection guidance for legacy FCS tags.
* **0.3.1 (2025-11-20):** Registered `ERR_FCS_UNKNOWN_TAG`; clarified that any legacy governance tag in FCS/1 is a hard rejection. No other layout changes.
* **0.3.2 (2025-11-21):** Adopted parity-first FER/1 TLVs (executor set, parity vector, context/witness hooks), registered `ERR_IMPL_PARITY` and `ERR_FER_UNKNOWN_TAG`, and refreshed conformance guidance.
* **0.3.3 (2025-11-22):** Added FPD/1 publication digest schema, registered federation digest/timestamp errors, and wired CI fixtures to deterministic publish checks.
* **0.3.5 (2025-11-07):** Added surface version table and aligned FER/1 v1.1 maintenance metadata for Phase 04 handoff.
* **0.3.6 (2025-11-08):** Seeded PH04 linkage & semantic placeholder section (DDS §7.8).
* **0.3.7 (2025-11-08):** Seeded FLS/1 placeholder TLV table aligned with ADR-018 v0.3.0.
* **0.3.8 (2025-11-08):** Registered FLS/1 TLV registry (0x600x65), error mapping, and conformance vectors aligned with ADR-018 v0.4.0.
* **0.3.9 (2025-11-09):** Locked CRS/1 concept/relation TLVs and registered FLS payload CID/type errors with conformance evidence.
* **0.4.0 (2025-11-08):** Promoted §7.8 FLS/1 & CRS/1 TLVs with error mapping and GS/1 snapshot evidence.
* **0.4.1 (2025-11-09):** Extended CRS predicate rules and mapped new validation errors
* **0.4.2 (2025-11-09):** Registered router error codes (`ERR_FLS_UNKNOWN_TAG`, `ERR_FLS_TAG_ORDER`, `ERR_FLS_SIGNATURE`) and FPD parent-policy errors with GS diff evidence pointer.
* **0.4.3 (2025-11-09):** Added WT/1 intake layout, validation errors, and router API integration (§7.9).
* **0.4.4 (2025-11-20):** Refined WT/1 (§7.9) with `wt.pubkey`, signature preimage exclusion, lineage/policy errors, and
expanded validator vector coverage.
* **0.4.6 (2025-11-22):** WT/1 and SOS/1 conformance evidence sealed via PH04-M4/M5 audit bundles.
* **0.4.5 (2025-11-21):** Registered SOS/1 overlays (§7.10) with compat evidence enforcement, aligned WT/1 error mapping (`ERR_WT_KEY_UNBOUND`, `ERR_WT_INTENT_UNREGISTERED`, `ERR_WT_PARENT_REQUIRED`), and expanded vector coverage to `TV-WT-001…009`.
* **0.4.7 (2025-11-23):** Documented MPR/1 and IER/1 schemas, error surfaces, and validator evidence for compat policy lane.
* **0.4.8 (2025-11-24):** Added §7.10 CT/1 header schema with error codes and renumbered downstream sections for PH05 replay.
* **0.5.0 (2025-11-11):** Added §11 ByteStore API & Persistence discipline covering API surface, fsync ladder, SA/PA isolation, streaming determinism, and ADR-006 error mapping.