amduat-api/tier1/srs.md

519 lines
26 KiB
Markdown
Raw Normal View History

2026-01-17 00:07:10 +01:00
# AMDUAT-SRS — Detailed Requirements Specification
Status: Approved | Owner: Niklas Rydberg | Version: 0.4.0 | Last Updated: 2025-11-11 | SoT: Yes
Tags: [requirements, cas, kheper]
> **Purpose:** Capture normative behavioural requirements for Phase PH01 (Kheper) and beyond. Long-lived semantics live here (not in Phase Packs).
---
## 1. Objectives (from Tier-0 Charter; elaborated)
* Deterministic addressing: identical payload bytes **MUST** yield identical CIDs.
* Immutability: new bytes → new CID; objects MUST NOT be mutated in place.
* Integrity by design: `verify()` MUST detect corruption; zero false positives.
* Instance isolation: storage layout and runtime state are implementation detail.
* Binary canonical substrate: COR/1 is the normative import/export envelope.
* Instance identity: ICD/1 defines stable `instance_id` for future transaction bindings.
* Crypto agility: default SHA-256; algorithm IDs extensible.
* Minimal tooling: reference CLI (`amduatcas`) and C library.
* Conformance: golden vectors and cross-impl CI enforce byte-identity.
---
## 2. Scope (Behavioural)
### 2.1 In Scope
* Local, single-node Content-Addressable Storage (CAS)
* Deterministic hashing with domain separation
* Canonical envelopes (COR/1) and instance descriptor (ICD/1)
* CRUD-adjacent operations: put/get/stat/exists/verify
* Import/export of canonical bytestreams
* Optional listing/gc semantics
### 2.2 Out of Scope (for PH01)
* Networking, replication, consensus
* Multi-object transactions
* Semantic/provenance graphing
* Encryption/ACLs (layer externally)
---
## 3. Functional Requirements
### FR-001 Deterministic CID Production
Given identical payload bytes and algo_id, the CID **MUST** match across compliant implementations.
### FR-002 Immutability
Objects **MUST NOT** be mutated; new payload → new CID.
### FR-003 Idempotent Put
Concurrent `put()` of identical payload MUST yield one canonical object; object integrity preserved.
### FR-004 Verification
`verify(CID)` MUST recompute the CID and detect corruption; zero false positives.
### FR-005 Import/Export Canonicality
Importing COR/1 and then exporting it MUST yield byte-identical bytestreams.
### FR-006 Size Validation
`get()` MUST validate payload length according to COR/1.
### FR-007 Optional Verify-on-Read Policy
Policy MAY require verify for cold reads; MUST NOT corrupt payload if disabled.
### FR-008 Canonical Rejection
CAS decoders MUST reject:
* out-of-order TLV tags
* duplicate TLV tags
* extraneous tags
* trailing bytes
* malformed or over-long VARINT encodings
* payload length mismatches
Rejection MUST be deterministic and symbolic.
### FR-009 Concurrency Discipline
Concurrent `put()` operations for identical payloads MUST NOT yield divergent COR/1 envelopes. Only one canonical envelope may result.
### FR-010 Raw Byte Semantics
CAS MUST operate strictly over exact payload bytes. No normalization (newline, whitespace, UTF-8 interpretation, or Unicode equivalence) SHALL occur.
### FR-011 Filesystem Independence
Consensus behaviour MUST NOT depend on:
* directory entry ordering
* timestamp metadata
* filesystem case sensitivity
* locale or regional configuration
### FR-012 Deterministic Failure
Malformed objects MUST be rejected. CAS MUST NOT auto-repair or normalize COR/1 envelopes.
### FR-013 Resource Boundaries
Resource exhaustion (disk full, allocation failure) MUST fail atomically and leave no partial objects visible.
### FR-014 FCS/1 Descriptor Determinism (v1-min)
Composite and custom functions MUST be expressed as canonical **FCS/1** descriptors that contain **only the execution recipe**:
`function_ptr`, `parameter_block (PCB1)`, and `arity`.
Identical descriptors SHALL hash to identical CIDs and MUST remain immutable after publication. **No policy/intent/notes** appear in FCS/1.
### FR-015 Registry Determinism (Descriptor Admission)
Functional registries MUST admit **only canonical FCS/1 descriptors** (per FR-014) and enforce descriptor validation (TLV order, PCB1 arity, acyclicity).
Registries MUST NOT infer or embed policy/intent into descriptors; publication governance is handled at certification time (FR-017).
### FR-016 Evaluation Receipt Integrity (FER/1)
Every execution of a composite function under curated or locked policies MUST emit a **FER/1** receipt. The receipt SHALL encode, in canonical TLV order, at least the following evidence:
1. `function_cid` → evaluated FCS/1 descriptor (v1-min) preserving CIP indirection.
2. `input_manifest` → GS/1 BCF/1 set of consumed input CIDs (deduped and byte-lexicographic).
3. `environment` → ICD/1 (or PH03 env capsule) snapshot pinning toolchain/runtime state.
4. `evaluator_id` → stable evaluator identity bytes.
5. `executor_set` → implementations that executed the recipe, keyed in canonical byte order.
6. `parity_vector` → per-executor digests with matching `executor` ordering, shared `output` (`== output_cid`), and `sbom_cid` entries.
7. `executor_fingerprint` + `run_id` → optional SBOM fingerprint CID and deterministic dedup hash (`H("AMDUAT:RUN\0" || function || manifest || env || fingerprint)`).
8. `logs` → typed evidence capsules binding `kind`, `cid`, and `sha256` for stdout/stderr/metrics traces.
9. `limits` → declared execution envelope (`cpu_ms`, `wall_ms`, `max_rss_kib`, `io_reads`, `io_writes`).
10. `determinism_level` / `rng_seed` → declared determinism class (`D1_bit_exact` default, `D2_numeric_stable` requires a 032 byte seed).
11. `output_cid` → single canonical output CID for the run.
12. `started_at` / `completed_at` → epoch-second timestamps satisfying FR-020 bounds.
13. `signature` → Ed25519 metadata verifying `H("AMDUAT:FER\0" || canonical bytes)`.
Receipts MAY include optional `logs` (typed capsules), `context`, `witnesses`, `parent`, and `signature_ext` TLVs but MUST NOT leak policy/intent (those belong to FCT/1).
From Phase 04 onwards, governance and runtime layers MUST require FER/1 v1.1 receipts; ER/1 artefacts remain valid only as historical evidence and SHALL NOT satisfy FR-016 compliance gates.
Parity discipline is mandatory: unsorted executor keys or mismatched parity orderings SHALL raise `ERR_IMPL_PARITY_ORDER`; divergent outputs or missing executors SHALL raise `ERR_IMPL_PARITY`. Unknown TLVs or cardinality violations SHALL raise `ERR_FER_UNKNOWN_TAG`. GS/1 manifest violations emit `ERR_FER_INPUT_MANIFEST_SHAPE`; missing RNG seed when determinism ≠ D1 emits `ERR_FER_RNG_REQUIRED`. All signatures MUST verify against the domain-separated hash (`ERR_FER_SIGNATURE` on failure).
### FR-017 Certification Transactions (FCT/1: Policy & Intent)
Certification events MUST be recorded as **FCT/1** transactions that aggregate one or more FER/1 receipts and bind **registry policy, intent, domain scope, and authority role**.
Transactions MUST include attestations whenever `registry_policy != 0` and SHALL expose publication pointers when federated.
**All intent/scope/role/authority metadata lives in FCT/1 (not in FCS/1).**
### FR-BS-001 ByteStore Deterministic Identity
ByteStore SHALL derive CIDs using the canonical CAS domain separator: `CID = algo || H("CAS:OBJ\0" || payload)`.
The derived CID returned by `put()` and `import_cor()` MUST match the CID embedded in COR/1 envelopes and SHALL remain stable across runs, implementations, and ingest modes (DDS §11.2; ADR-030).
### FR-BS-002 Atomic Durability Ladder
ByteStore persistence MUST follow the atomic write ladder: write → `fsync(tmp)``rename``fsync(shard)``fsync(root)`.
Crash-window simulations triggered via `AMDUAT_BYTESTORE_CRASH_STEP` MUST leave the public area consistent upon recovery, with no visible partial objects (DDS §11.4; ADR-030; evidence PH05-EV-BS-001).
### FR-BS-003 Secure/Public Area Isolation
ByteStore SHALL enforce SA/PA isolation such that public payload roots and secure state roots are disjoint and non-overlapping.
Violations MUST raise `ERR_AREA_VIOLATION` and SHALL be surfaced to callers (DDS §11.5; ADR-030).
### FR-BS-004 COR/1 Round-Trip Identity
Importing COR/1 bytes via ByteStore and exporting the same CID MUST yield a byte-identical envelope.
Any mismatch between stored bytes and derived CID SHALL raise `ERR_IDENTITY_MISMATCH` (DDS §11.3; ADR-030).
### FR-BS-005 Streaming Determinism & Policy Enforcement
Chunked ingestion (`put_stream`) MUST produce the same CID as single-shot `put` for equivalent payloads and reject non-bytes or missing data with deterministic errors (`ERR_STREAM_ORDER`, `ERR_STREAM_TRUNCATED`).
ByteStore SHALL enforce ICD/1 `max_object_size` for all ingest paths, raising `ERR_POLICY_SIZE` when exceeded (DDS §11.611.7; ADR-030).
### FR-022 Federation Publication Digest (FPD/1)
Every publish event emerging from an FCT/1 certification MUST emit exactly one **FPD/1** digest satisfying ADR-007 single-digest guarantees.
The digest SHALL canonically hash the certified FCT/1 record, all attested FER/1 receipts, and the emitted governance edges (`certifies`, `attests`, `publishes`).
Implementations MUST persist the FPD/1 bytes alongside the FCT/1 payload under `/logs/ph03/evidence/fct/` (or successor evidence path) and reference the resulting CID from `fct.publication`.
Repeated invocations over identical inputs SHALL reproduce the same digest; mismatches SHALL be treated as certification failures.
### FR-018 Provenance Enforcement
Caching or replay layers MUST validate FER/1 receipts and FCT/1 transactions before serving composite outputs. Serving uncertified artefacts when policy requires certification is forbidden.
### FR-019 Transaction Envelope Rejection
Systems MUST reject FER/1 or FCT/1 envelopes whose CID lineage does not match the referenced FCS/1 descriptor, whose timestamps are non-monotonic, or whose signatures/attestations fail verification.
### FR-020 Deterministic Execution Envelope
| ID | Statement | Verification | Notes |
| --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| **FR-020 — Deterministic Execution Envelope** | Each executor SHALL complete within a bounded deterministic time envelope (default 5 s). Execution time SHALL be measured and logged as evidence. Non-termination SHALL yield symbolic error `ERR_EXEC_TIMEOUT`. | Verified via CI parity harness and evidence file `/logs/ph03/evidence/<date>-execution-times.jsonl`. | Implements Maats Balance principle. Tags: [deterministic-timing, evidence, maat-balance]. |
### FR-021 Acyclic Composition
FCS/1 descriptors referencing FPS/1 primitives, PCB1 parameter blocks, or nested FCS/1 descriptors MUST form an acyclic graph.
Registries SHALL reject submissions introducing self-references or cycles and emit `ERR_FCS_CYCLE_DETECTED` or
`ERR_PCB_ARITY_MISMATCH` when arity metadata conflicts with PCB1 manifests.
### FR-028 Concept-Native Domain Materialization
Federated domain manifests SHALL be materialized exclusively from CRS Concepts
and Relations. Given a DomainNode Concept, registries MUST traverse
`hasManifest``ManifestEntry` Concepts, extract `entryName` and
`entryChildVersion` relations, dedupe the `(name, version)` set, and compute the
GS/1 domain state deterministically. Duplicated pairs trigger `ERR_DG_DUP_ENTRY`;
missing relations trigger `ERR_DG_ENTRY_INCOMPLETE`; self references or
ancestor loops raise `ERR_DG_CYCLE`. Evidence: `tools/ci/dg_snapshot.py`
`logs/ph04/evidence/dg1/PH04-EV-DG-001/`.
Operational linkage: router listings (`GET /links`) MUST return entries sorted
lexicographically by `fls_cid` and treat `since` query parameters as exclusive
lower bounds, ensuring deterministic replay of linkage events.
### FR-029 Publication Recursion Discipline
Publication Concepts SHALL declare their supporting FPD/1 digest, GS/1 cover
state, endorsed member FPD CIDs, and optional lineage parent using CRS
relations (`covers`, `endorses`, `parent`). Validators MUST recompute GS/1 from
the FPD payload, enforce duplicate-free membership, and detect recursive
cycles (`ERR_FPD_CYCLE`). Timestamp regressions raise `ERR_FPD_TIMESTAMP`; state
mismatches raise `ERR_PUB_STATE_MISMATCH`. Evidence: `tools/ci/pub_validate.py`
`logs/ph04/evidence/pub1/PH04-EV-PUB-001/`.
Operational linkage: non-genesis publications SHOULD enable the parent-required
policy, supplying `fpd.parent` and guaranteeing strictly monotonic
`fpd.timestamp` to align with ADR-019 v1.2.1 and PH04 parent-policy harnesses.
### FR-030 Predicate Concepts
Every CRR/1 relation predicate MUST resolve to a CRS Concept. When the
taxonomy defines a `Predicate` Concept, predicate entries SHALL expose an
`is_a` edge into that class. Missing predicate Concepts raise
`ERR_CRR_PREDICATE_NOT_CONCEPT`; missing taxonomy membership raises
`ERR_CRR_PREDICATE_CLASS_MISSING`. Evidence: CRS validator vectors and
`logs/ph04/evidence/crs1/PH04-EV-CRS-001.md`.
Operational linkage: FPD feed endpoints SHALL implement stateless, content-anchored pagination over parent-chained publications. `GET /feed/fpd` MUST traverse the publishers current tip toward genesis until either the caller-provided `limit` is satisfied or the supplied `since` CID is encountered; identical `publisher_id`, `since`, and `limit` inputs SHALL yield identical CID sequences. Detail lookups (`GET /feed/fpd/:cid`) SHALL expose publisher, members, parent, and state metadata without server-side session state. Evidence: `tools/ci/feeds_check.py``/amduat/logs/ph04/evidence/feeds/PH04-EV-FEEDS-001/pass.jsonl`.
### FR-031 Authority Anchoring via CRS & FPD
Publishing authorities SHALL represent identities as CRS Concepts linked via
`owns` and `hasRole` relations to key material and governance roles. Signatures
remain confined to FCT/1 and FPD/1 surfaces; CRS layers stay unsigned. FLS/1
transport MAY carry Concept or Relation payloads but MUST NOT mutate them and
MUST perform payload-kind checks when requested (`--check-crs-payload`).
Operational linkage: FLS router deployments SHALL expose `POST /fls`,
`GET /fls/:cid`, `GET /links`, `GET /healthz`, and `GET /readyz` endpoints and
enforce SA/PA separation (`ERR_AREA_VIOLATION` if misconfigured) so that public
ingest never mutates state areas directly. Audited ticket intake SHALL be
implemented via WT/1 (ADR-023) with:
* `POST /wt` (Protected Area) accepting WT/1 BCF/1 payloads, validating
`has_pubkey(wt.author, wt.pubkey)` (or registered equivalent), verifying
signatures over `H("AMDUAT:WT\0" || canonical_bytes_without_signature)`,
enforcing registered ADR-010 intents (deduped + byte-lexicographically
sorted), ensuring monotonic `wt.timestamp` per `wt.author`, and optionally
chaining `wt.parent` lineage. Violations yield `ERR_WT_SIGNATURE`,
`ERR_WT_KEY_UNBOUND`, `ERR_WT_INTENT_UNREGISTERED`, `ERR_WT_INTENT_DUP`,
`ERR_WT_INTENT_EMPTY`, `ERR_WT_TIMESTAMP`, `ERR_WT_PARENT_UNKNOWN`, or
`ERR_WT_PARENT_REQUIRED`. Router policy MUST surface scope denials as
`ERR_WT_SCOPE_UNAUTHORIZED` and log the governing policy capsule.
* `GET /wt/:cid` returning the canonical WT/1 bytes for any accepted ticket.
* Deterministic pagination (`GET /wt?after=<cid>&limit=<n>`) that emits WT/1
entries in byte-lexicographic CID order with stable page boundaries. The
`after` parameter is an exclusive bound and routers SHALL enforce
`1 ≤ limit ≤ Nmax` to guarantee replay stability.
Evidence: `/amduat/logs/ph04/evidence/wt1/PH04-EV-WT-001/summary.md` captures the
validator run over vectors `TV-WT-001…009`, ensuring unknown keys, signature
failures, timestamp regressions (including parent inversions), unbound keys,
unregistered intents, policy rejections, and unresolved parents reject as
specified.
Compat overlays SHALL reference ADR-025 MPR/1 provenance capsules and ADR-026
IER/1 inference evidence when operating in policy lane `compat`. Routers MUST
validate that `executor_fingerprint` equals the supplied MPR/1 CID, enforce
`determinism_level` plus `rng_seed` (raising `ERR_FER_RNG_REQUIRED` when
omitted), and verify log digests via the IER/1 manifest before accepting
overlays (`ERR_IER_LOG_HASH`/`ERR_IER_LOG_MANIFEST`). Evidence surfaces
`/amduat/logs/ph04/evidence/mpr1/PH04-EV-MPR-001/pass.jsonl` and
`/amduat/logs/ph04/evidence/ier1/PH04-EV-IER-001/pass.jsonl` prove vector
coverage `TV-MPR-001…003` (hash triple, missing weights, signature domain) and
`TV-IER-001…004` (ok, missing seed, fingerprint mismatch, log digest mismatch)
respectively with scenario summaries in accompanying `summary.md` files.
### FR-032 CT/1 Deterministic Replay (D1)
Given identical AC/1 + DTF/1 + topology inputs, executing the runtime twice in
isolation MUST produce byte-identical CT/1 snapshots (header and payload) with
matching CIDs whenever `ct.determinism_level = 0`. Evidence:
`tools/ci/ct_replay.py` (`runA`/`runB`) →
`/amduat/logs/ph05/evidence/ct1/PH05-EV-CT1-REPLAY-001/`.
### FR-033 CT/1 Numeric Stability (D2)
When `ct.determinism_level = 1`, numeric observables MAY diverge, but the
maximum absolute delta MUST remain within the tolerance documented by
`ct.kernel_cfg`. Evidence: `tools/ci/ct_replay.py` D2 replay outputs and kernel
configuration manifests in the same evidence set.
### FR-034 CT/1 Header Integrity
CT/1 headers MUST follow ADR-027: canonical BCF/1 key ordering, rejection of
unknown keys, monotonic `ct.tick`, canonical `cid:` formatting for topology and
AC/1/DTF/1 pointers (ADR-028), and Ed25519 signatures over
`H("AMDUAT:CT\0" || canonical_bytes_without_signature)`. Evidence:
`tools/validate/ct1_validator.py` with vectors
`/amduat/vectors/ph05/ct1/TV-CT1-001…004` and AC/DTF fixtures
`TV-AC1-001…002`, `TV-DTF1-001…002`.
---
## 4. Non-Functional Requirements
### NFR-001 Determinism
Platform/language differences MUST NOT affect CID.
### NFR-002 Performance
Put/get latency MUST remain within configured OPS budgets.
### NFR-003 Reliability
CAS operations MUST be atomic; partial writes MUST NOT be visible.
### NFR-004 Portability
Implementations MUST operate on common filesystems.
### NFR-005 Security Posture
Domain separation strings MUST be applied for all hashed surfaces.
### 4.3 Future Scope Alignment (Informative)
Phase 02 introduces deterministic transformation primitives (**FPS/1**) extending the Kheper CAS model defined herein.
See `/amduat/arc/adrs/adr-015.md` and `/amduat/tier1/fps.md` for details.
No behavioural changes apply retroactively to PH01 surfaces.
---
## 5. Data Model (Behavioural View)
* CAS objects identified strictly by CID.
* COR/1 envelope provides size, payload, algo_id.
* ICD/1 descriptor provides instance configuration.
> See DDS §2 (COR/1) and §3 (ICD/1) for normative byte layouts.
---
## 6. API Semantics
### `put(payload_bytes, algo_id=default) → CID`
* Compute CID using domain separation: `CID = algo_id || H("CAS:OBJ\0" || payload_bytes)`
* If CID exists: return existing CID (idempotent)
* If absent: write canonical COR/1 envelope atomically
* Reject on size limit breach, malformed payload, non-canonical COR/1, I/O errors
* Writes MUST be atomic: temp file → fsync → rename → fsync parent dir
### `get(CID) → payload_bytes`
* Retrieve raw payload bytes
* MUST validate canonical COR/1 envelope
* Implementation MAY verify hash on read by policy
* Reject on missing object, hash mismatch
### `exists(CID) → bool`
* Return true if object is present and canonical
### `stat(CID) → { present, size, algo_id }`
* MUST return canonical metadata
### `verify(CID) → { ok|error, expected:CID, actual:CID }`
* Recompute CID from canonical bytes
* MUST detect corruption and reject non-canonical encodings
### `import(stream_COR1) → CID`
* Validate canonical TLV ordering
* Reject duplicate tags, extraneous tags, malformed VARINTs
* MUST round-trip to identical CID
### `export(CID) → stream_COR1`
* Emit canonical envelope; re-encoding MUST preserve canonical bytes
### Deterministic Errors
Errors MUST be emitted as stable symbolic codes including but not limited to:
* `E_CID_NOT_FOUND`
* `E_CORRUPT_OBJECT`
* `E_CANONICALITY_VIOLATION`
* `E_IO_FAILURE`
---
## 7. Success Criteria
* Byte-for-byte CID agreement (≥ 3 platforms)
* Zero false positives in `verify()`
* Idempotent concurrent `put()`
* COR/1 import/export round-trips cleanly
---
## 8. GC Semantics (Behavioural)
* Reachability from configured roots
* Dry-run mode MUST NOT delete
* Removal MUST be atomic per object
---
## 9. Acceptance Criteria (Phase Exit)
* Golden vectors published
* Cross-impl CI passing
* COR/1 and ICD/1 documented in DDS
* Security posture validated by SEC
---
## 10. Traceability
* Requirements link to tests/defects in Phase Packs
* ADRs reference affected FR/NFR IDs
---
## 11. Future Phases
* Multi-object transactions bind to `instance_id`
* Provenance graph consumes COR/1 metadata
---
## 12. Functional Primitive Surface (FPS/1)
> Defines the canonical deterministic operations over canonical payloads.
> Each primitive produces exactly one payload and one CID.
| Primitive | Signature | Description | Determinism / Errors |
| ------------- | ------------------------------ | ------------------------------------------- | ---------------------------------------------- |
| `put` | `(payload_bytes) → CID` | Canonical write, atomic fsync ladder. | ADR-006 `ERR_IO_FAILURE`, `ERR_NORMALIZATION`. |
| `get` | `(CID) → payload_bytes` | Fetch canonical bytes. | `ERR_CID_NOT_FOUND`. |
| `slice` | `(CID, offset, length) → CID` | Extract contiguous bytes. | `ERR_SLICE_RANGE`. |
| `concatenate` | `([CID₁,…,CIDₙ]) → CID` | Sequential join of payloads. | `ERR_EMPTY_INPUTS`. |
| `reverse` | `(CID, level) → CID` | Reverse payload order (bit/byte/word/long). | `ERR_REV_ALIGNMENT`, `ERR_INVALID_LEVEL`. |
| `splice` | `(CID_a, offset, CID_b) → CID` | Insert payload b into a at offset. | `ERR_SPLICE_RANGE`. |
**Determinism:** identical inputs → identical outputs.
**Immutability:** inputs never mutated.
**Closure:** outputs valid for reuse as inputs to any primitive.
**Error handling:** all symbolic per ADR-006.
---
## Appendix A — Surface Version Table
| Surface | Version | Notes |
| ------- | ------- | ----- |
| FCS/1 | v1-min | Canonical execution descriptors; governance captured in FCT/1. |
| FER/1 | v1.1 | Receipts enforce parity-first evidence, run_id dedup, typed logs, and RNG discipline (ADR-017). |
| FCT/1 | v1.0 | Certification transactions binding policy/intent/attestations with FER/1 sets. |
| FPD/1 | v1.0 | Publication digest linking FCT/1 to FER/1 receipts for federation replay. |
---
## Document History
* 0.2.1 (2025-10-26) — Phase Pack pointer updated; no semantic changes; archival preserves historical lineage per ADR-002.
* 0.2.2 (2025-10-26) — Promoted PH01 baseline to Approved; synchronized Phase Pack §1 anchors and closure snapshot.
* 0.2.3 (2025-10-27) — Added future scope alignment note pointing to FPS/1 and ADR-015; PH01 semantics remain unchanged.
* **0.2.4 (2025-11-14):** Added FR-014FR-019 for FCS/1 composition, FER/1 receipts, and FCT/1 certification policies.
* **0.2.5 (2025-11-15):** Added FR-021 (formerly FR-020) enforcing acyclic FCS/1 composition and PCB1 arity validation.
* **0.2.6 (2025-11-19):** Registered FR-020 Deterministic Execution Envelope (Maats Balance) with timing evidence tags.
* **0.3.0 (2025-11-02):** Trimmed FCS/1 to execution-only (v1-min) under FR-014/FR-015; moved policy/intent/scope/role/authority to FCT/1 (FR-017); clarified registry admission behaviour and kept FER/1 unchanged.
* **0.3.1 (2025-11-21):** Updated FR-016 to require parity-first FER/1 receipts with executor sets, parity vectors, and FR-020 aligned timestamps.
* **0.3.2 (2025-11-22):** Registered FR-022 Federation Publication Digest (FPD/1) requirement tying FCT/1 publications to single-digest evidence and canonical logging.
* **0.3.4 (2025-11-07):** Recorded FER/1 v1.1 requirement for Phase 04 and added surface version table.
* **0.3.5 (2025-11-08):** Registered PH04 linkage & semantic placeholder requirements (FR-028…031).
* **0.3.6 (2025-11-09):** Promoted FR-028…031 to normative linkage requirements with CRS/1 validator enforcement.
* **0.3.7 (2025-11-08):** Finalized FR-028…031 with CRS/1 immutability, GS/1 linkage, and certification coverage.
* **0.3.8 (2025-11-09):** Promoted FR-028…FR-031 for concept-native domain and publication validation.
* **0.3.9 (2025-11-09):** Documented operational linkage: router endpoints, deterministic `/links`, and parent-required publish policy guidance.
* **0.3.10 (2025-11-11):** Registered FR-030 stateless, content-anchored FPD feed pagination requirement.
* **0.3.11 (2025-11-09):** Extended FR-031 with WT/1 intake endpoints, validation, and evidence log references.
* **0.3.12 (2025-11-20):** Tightened FR-031 with `wt.pubkey` bindings, signature preimage exclusion, lineage/policy errors, and
expanded WT/1 vector evidence coverage.
* **0.3.13 (2025-11-21):** Updated FR-031 for `has_pubkey` bindings (`ERR_WT_KEY_UNBOUND`), intent registry enforcement (`ERR_WT_INTENT_UNREGISTERED`), lineage policy rejection (`ERR_WT_PARENT_REQUIRED`), and expanded WT/1 vectors `TV-WT-001…009`.
* **0.3.14 (2025-11-22):** WT/1 intake and SOS/1 compat overlays proven with PH04-M4/M5 audit evidence.
* **0.3.15 (2025-11-22):** Recorded ADR-025/026 compat path requirements and evidence anchors for FR-031.
* **0.3.16 (2025-11-23):** Compat lane now enforces ADR-025/026 validators (MPR/1 hash triple, IER/1 replay) with updated evidence surfaces.
* **0.3.17 (2025-11-24):** Added FR-032FR-034 for CT/1 replay determinism, numeric stability, and header integrity (ADR-027/028).
* **0.4.0 (2025-11-11):** Added FR-BS-001…005 for ByteStore identity, atomic durability, SA/PA isolation, COR round-trip, and streaming determinism linked to DDS §11 / ADR-030.