From 1cfb3638d1147d4569a059ba9f209aaa690be128 Mon Sep 17 00:00:00 2001 From: "glm-5.2" Date: Sun, 2 Aug 2026 06:38:15 +0000 Subject: [PATCH] Rebrand alknet-typedef to alktype in docs, crate name, and lib name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Renumber ADRs 095-102 to 001-008 and OQs 069-071 to 001-003, and update all cross-references (titles, body prose, file-path links, tables) across the 5 spec docs, README, open-questions index, and all 11 ADR/OQ files. Inline the ADR-009 door-type definition from the parent alknet project (broken cross-project reference). Rebrand prose: alknet-typedef -> alktype in headings, body text, dependency diagrams, and "additions" notes. Disambiguate the prior failed attempt at /workspace/@alkimiadev/alktype/ as "the @alkimiadev/alktype prototype" to distinguish it from this crate. Historical research citations (docs/research/*, /workspace/alknet-typedef-poc/) are kept as-is for provenance. Rename the crate in Cargo.toml ([package].name, [lib].name) and update the 11 use alknet_typedef::* imports across the 4 test files. Rebrand the crate-level doc comment in src/lib.rs. The TypeDef:* keyword strings, TypedefError/TypedefEngine identifiers, and other code-level references are unchanged — those are a separate code rebrand pass. Build, 295 tests, and clippy all pass clean. --- Cargo.lock | 2 +- Cargo.toml | 4 +- docs/architecture/README.md | 44 +++++++------- docs/architecture/data-access.md | 16 ++--- ...lktype-purpose-scope-jsonschema-engine.md} | 28 +++++---- ...002-two-layout-modes-packed-vs-aligned.md} | 8 +-- ...notations.md => 003-schema-annotations.md} | 8 +-- ...004-error-handling-validation-strategy.md} | 8 +-- ... => 005-int64-uint64-first-class-kinds.md} | 8 +-- ...inline-length-prefixed-in-aligned-mode.md} | 8 +-- ...ory.md => 007-packed-mode-read-factory.md} | 4 +- ...d => 008-reject-tunion-in-aligned-mode.md} | 8 +-- docs/architecture/layout-engine.md | 32 +++++----- docs/architecture/open-questions.md | 20 +++---- docs/architecture/overview.md | 60 +++++++++---------- ...ays-of-variable-length-element-structs.md} | 4 +- ...support.md => 002-no-std-alloc-support.md} | 4 +- ...03-builder-api-for-schema-construction.md} | 4 +- docs/architecture/schema-layer.md | 26 ++++---- docs/architecture/validation.md | 22 +++---- src/lib.rs | 2 +- tests/engine_integration.rs | 2 +- tests/error_paths.rs | 8 +-- tests/poc_roundtrip.rs | 6 +- tests/tunion_dispatch.rs | 8 +-- 25 files changed, 173 insertions(+), 171 deletions(-) rename docs/architecture/decisions/{095-alknet-typedef-purpose-scope-jsonschema-engine.md => 001-alktype-purpose-scope-jsonschema-engine.md} (88%) rename docs/architecture/decisions/{096-two-layout-modes-packed-vs-aligned.md => 002-two-layout-modes-packed-vs-aligned.md} (95%) rename docs/architecture/decisions/{097-schema-annotations.md => 003-schema-annotations.md} (97%) rename docs/architecture/decisions/{098-error-handling-validation-strategy.md => 004-error-handling-validation-strategy.md} (96%) rename docs/architecture/decisions/{099-int64-uint64-first-class-kinds.md => 005-int64-uint64-first-class-kinds.md} (95%) rename docs/architecture/decisions/{100-reject-non-final-inline-length-prefixed-in-aligned-mode.md => 006-reject-non-final-inline-length-prefixed-in-aligned-mode.md} (95%) rename docs/architecture/decisions/{101-packed-mode-read-factory.md => 007-packed-mode-read-factory.md} (97%) rename docs/architecture/decisions/{102-reject-tunion-in-aligned-mode.md => 008-reject-tunion-in-aligned-mode.md} (94%) rename docs/architecture/questions/{069-arrays-of-variable-length-element-structs.md => 001-arrays-of-variable-length-element-structs.md} (92%) rename docs/architecture/questions/{070-no-std-alloc-support.md => 002-no-std-alloc-support.md} (94%) rename docs/architecture/questions/{071-builder-api-for-schema-construction.md => 003-builder-api-for-schema-construction.md} (92%) diff --git a/Cargo.lock b/Cargo.lock index f3bc1fe..69f3a1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,7 +26,7 @@ dependencies = [ ] [[package]] -name = "alknet-typedef" +name = "alktype" version = "0.1.0" dependencies = [ "jsonschema", diff --git a/Cargo.toml b/Cargo.toml index c78ccea..098bff1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "alknet-typedef" +name = "alktype" version = "0.1.0" edition = "2021" license = "MIT OR Apache-2.0" @@ -7,7 +7,7 @@ description = "Binary struct engine: takes a JSON Schema with TypeDef:* custom k repository = "https://git.alk.dev/alkdev/alktype" [lib] -name = "alknet_typedef" +name = "alktype" [features] default = [] diff --git a/docs/architecture/README.md b/docs/architecture/README.md index bb5b3d9..ab934ab 100644 --- a/docs/architecture/README.md +++ b/docs/architecture/README.md @@ -3,7 +3,7 @@ status: draft last_updated: 2026-07-22 --- -# alknet-typedef +# alktype The binary struct engine: a small Rust crate that takes a JSON Schema with `TypeDef:*` custom keywords and produces an offset map, read/write @@ -24,22 +24,22 @@ format definition; the engine is generic. | ADR | Title | Relevance | |-----|-------|-----------| -| [095](decisions/095-alknet-typedef-purpose-scope-jsonschema-engine.md) | Purpose, Scope, and the jsonschema Engine | What the crate is/isn't; why jsonschema not a custom engine; "schema is the format" principle; scope boundaries | -| [096](decisions/096-two-layout-modes-packed-vs-aligned.md) | Two Layout Modes — Packed Sequential vs Aligned Static | The most important architectural finding; when to use each mode; `LayoutBuilder`/`SequentialReader` vs `OffsetMap` | -| [097](decisions/097-schema-annotations.md) | Schema Annotations — Endianness, Alignment, Encoding, TUnion Discriminators | Concrete JSON shapes for all schema-level annotations | -| [098](decisions/098-error-handling-validation-strategy.md) | Error Handling and Validation Strategy | `TypedefError` enum; load-time build, access-time check; field-path-carrying errors | -| [099](decisions/099-int64-uint64-first-class-kinds.md) | Int64/Uint64 as First-Class Kinds | 64-bit integers (SFTP offsets, metatensor data_offsets); JSON precision caveat | -| [100](decisions/100-reject-non-final-inline-length-prefixed-in-aligned-mode.md) | Reject Non-Final Inline Length-Prefixed Variable Fields in Aligned Mode | Prevents silent data corruption (inline variable data clobbering subsequent fields) | -| [101](decisions/101-packed-mode-read-factory.md) | Packed-Mode Read API — Engine as SequentialReader Factory | `engine.sequential_reader()` returns an owned reader, not a reference | -| [102](decisions/102-reject-tunion-in-aligned-mode.md) | Reject TUnion in Aligned Mode for v1 | Unions are the protocol pattern; aligned-mode union semantics were broken | +| [001](decisions/001-alktype-purpose-scope-jsonschema-engine.md) | Purpose, Scope, and the jsonschema Engine | What the crate is/isn't; why jsonschema not a custom engine; "schema is the format" principle; scope boundaries | +| [002](decisions/002-two-layout-modes-packed-vs-aligned.md) | Two Layout Modes — Packed Sequential vs Aligned Static | The most important architectural finding; when to use each mode; `LayoutBuilder`/`SequentialReader` vs `OffsetMap` | +| [003](decisions/003-schema-annotations.md) | Schema Annotations — Endianness, Alignment, Encoding, TUnion Discriminators | Concrete JSON shapes for all schema-level annotations | +| [004](decisions/004-error-handling-validation-strategy.md) | Error Handling and Validation Strategy | `TypedefError` enum; load-time build, access-time check; field-path-carrying errors | +| [005](decisions/005-int64-uint64-first-class-kinds.md) | Int64/Uint64 as First-Class Kinds | 64-bit integers (SFTP offsets, metatensor data_offsets); JSON precision caveat | +| [006](decisions/006-reject-non-final-inline-length-prefixed-in-aligned-mode.md) | Reject Non-Final Inline Length-Prefixed Variable Fields in Aligned Mode | Prevents silent data corruption (inline variable data clobbering subsequent fields) | +| [007](decisions/007-packed-mode-read-factory.md) | Packed-Mode Read API — Engine as SequentialReader Factory | `engine.sequential_reader()` returns an owned reader, not a reference | +| [008](decisions/008-reject-tunion-in-aligned-mode.md) | Reject TUnion in Aligned Mode for v1 | Unions are the protocol pattern; aligned-mode union semantics were broken | ## Relevant Open Questions | OQ | Title | Status | Relevance | |----|-------|--------|-----------| -| OQ-069 | Arrays of variable-length-element structs | deferred(scope) | Requires lazy walking logic; blocked on a concrete consumer that needs it | -| OQ-070 | `no_std` + `alloc` support | deferred(scope) | Target `std` for v1; blocked on an embedded use case | -| OQ-071 | Builder API for schema construction | deferred(scope) | Schemas are authored in TypeBox or hand-written JSON for v1; blocked on a concrete need | +| OQ-001 | Arrays of variable-length-element structs | deferred(scope) | Requires lazy walking logic; blocked on a concrete consumer that needs it | +| OQ-002 | `no_std` + `alloc` support | deferred(scope) | Target `std` for v1; blocked on an embedded use case | +| OQ-003 | Builder API for schema construction | deferred(scope) | Schemas are authored in TypeBox or hand-written JSON for v1; blocked on a concrete need | ## Key Design Principles @@ -47,53 +47,53 @@ format definition; the engine is generic. keywords is both the validation spec and the layout spec. No separate format definition, no separate parser, no separate validator. One schema, three uses: validate, compute offsets, access data. See - [overview.md](overview.md) and [ADR-095](decisions/095-alknet-typedef-purpose-scope-jsonschema-engine.md). + [overview.md](overview.md) and [ADR-001](decisions/001-alktype-purpose-scope-jsonschema-engine.md). 2. **jsonschema is the validation engine, not a custom engine.** The `jsonschema` crate (v0.46.5, Draft 2020-12) handles validation with custom keyword support. The novel code is the offset computation, not the validation. This eliminates ~14,000 lines of hand-rolled schema - engines (typebox-rs, alktype). See [schema-layer.md](schema-layer.md) - and [ADR-095](decisions/095-alknet-typedef-purpose-scope-jsonschema-engine.md). + engines (typebox-rs, the @alkimiadev/alktype prototype). See [schema-layer.md](schema-layer.md) + and [ADR-001](decisions/001-alktype-purpose-scope-jsonschema-engine.md). 3. **Two layout modes for two use cases.** Packed sequential (`LayoutBuilder`/`SequentialReader`) for protocol wire formats (SFTP, channels, TTY). Aligned static (`OffsetMap`) for mmap-friendly formats (metatensor). The consumer selects the mode; the schema is the same. See [layout-engine.md](layout-engine.md) and - [ADR-096](decisions/096-two-layout-modes-packed-vs-aligned.md). + [ADR-002](decisions/002-two-layout-modes-packed-vs-aligned.md). 4. **Variable-length types default to inline length-prefixing.** `[length: u32][data]` is the universal pattern used by channels, SFTP, TTY, and most binary protocols. Offset indirection (the metatensor blob tensor pattern) is opt-in via the `encoding` annotation. See [layout-engine.md](layout-engine.md) and - [ADR-097](decisions/097-schema-annotations.md). + [ADR-003](decisions/003-schema-annotations.md). 5. **TUnion supports both byte-offset and field-name discriminators.** Byte-offset for protocol dispatch (SFTP type bytes, call protocol event types). Field-name for the typedef.ts string pattern. See [data-access.md](data-access.md) and - [ADR-097](decisions/097-schema-annotations.md). + [ADR-003](decisions/003-schema-annotations.md). 6. **Endianness is per-schema, default little-endian.** The engine reads the `"endian"` annotation and byte-swaps accordingly. SFTP consumers specify `"endian": "big"`. See [layout-engine.md](layout-engine.md) - and [ADR-097](decisions/097-schema-annotations.md). + and [ADR-003](decisions/003-schema-annotations.md). 7. **Validation is opt-in, built once at load time.** The jsonschema validator is compiled once at schema load time. Access-time validation is a fast `is_valid()` check. High-throughput paths can skip validation; security-sensitive paths can validate every frame. See [validation.md](validation.md) and - [ADR-098](decisions/098-error-handling-validation-strategy.md). + [ADR-004](decisions/004-error-handling-validation-strategy.md). 8. **Not a serialization framework.** The typedef engine is not a general-purpose serde replacement. It operates on raw byte buffers at computed offsets — no intermediate `Value` tree, no reflection, no dynamic dispatch per field. For JSON data, use serde. For binary data with a known schema, use typedef. See [overview.md](overview.md) and - [ADR-095](decisions/095-alknet-typedef-purpose-scope-jsonschema-engine.md). + [ADR-001](decisions/001-alktype-purpose-scope-jsonschema-engine.md). ## References @@ -107,4 +107,4 @@ format definition; the engine is generic. - `/workspace/jsonschema/` — the jsonschema crate (v0.46.5, Draft 2020-12) - `/workspace/alknet-typedef-poc/` — the POC code (disposable) - `/workspace/@alkimiadev/typebox-rs/` — prior attempt, replaced by typedef -- `/workspace/@alkimiadev/alktype/` — prior attempt, replaced by typedef +- `/workspace/@alkimiadev/alktype/` — prior attempt (the @alkimiadev/alktype prototype, a handler-registry pattern; not to be confused with this crate, which reuses the name but is backed by the `jsonschema` crate) diff --git a/docs/architecture/data-access.md b/docs/architecture/data-access.md index be1c30a..be484c6 100644 --- a/docs/architecture/data-access.md +++ b/docs/architecture/data-access.md @@ -3,7 +3,7 @@ status: draft last_updated: 2026-07-22 --- -# alknet-typedef — Data Access +# alktype — Data Access The data access layer: read/write functions, TUnion dispatch, field paths, zero-copy access for fixed-size types, and length-prefix reading for @@ -79,7 +79,7 @@ impl TypedefEngine { pub fn write_field(&self, buffer: &mut [u8], field_path: &str, value: &FieldValue<'_>) -> Result<(), TypedefError>; - // Packed mode: returns an owned fresh SequentialReader (ADR-101). + // Packed mode: returns an owned fresh SequentialReader (ADR-007). // Each call returns a new reader with the cursor at position 0. // The consumer owns the reader and drives read_next/read_field/reset. pub fn sequential_reader(&self) -> Option; @@ -146,7 +146,7 @@ fn write_u32(buffer: &mut [u8], offset: usize, value: u32, ``` The engine applies endianness at access time based on the schema's -`"endian"` annotation (ADR-097). The offset computation is +`"endian"` annotation (ADR-003). The offset computation is endian-agnostic. The `read_array`/`write_array` helpers perform the bounds check and produce `TypedefError::Access` with the field path on failure. @@ -357,22 +357,22 @@ engine returns a slice of that region. ## Error Handling Read/write errors carry the field path for debugging. See -[ADR-098](decisions/098-error-handling-validation-strategy.md) and +[ADR-004](decisions/004-error-handling-validation-strategy.md) and [validation.md](validation.md) for the full error model. ## Design Decisions | Decision | ADR | Summary | |----------|-----|---------| -| Two layout modes | [ADR-096](decisions/096-two-layout-modes-packed-vs-aligned.md) | Determines whether offsets are fixed (OffsetMap) or sequential (SequentialReader) | -| Schema annotations | [ADR-097](decisions/097-schema-annotations.md) | Endianness, encoding, and TUnion discriminator shapes that control data access | -| Error handling | [ADR-098](decisions/098-error-handling-validation-strategy.md) | Field-path-carrying errors for read/write operations | +| Two layout modes | [ADR-002](decisions/002-two-layout-modes-packed-vs-aligned.md) | Determines whether offsets are fixed (OffsetMap) or sequential (SequentialReader) | +| Schema annotations | [ADR-003](decisions/003-schema-annotations.md) | Endianness, encoding, and TUnion discriminator shapes that control data access | +| Error handling | [ADR-004](decisions/004-error-handling-validation-strategy.md) | Field-path-carrying errors for read/write operations | ## Open Questions See [open-questions.md](open-questions.md) for full details. -- **OQ-069** (deferred(scope)): Arrays of variable-length-element structs +- **OQ-001** (deferred(scope)): Arrays of variable-length-element structs — affects the sequential walking logic for array access. ## References diff --git a/docs/architecture/decisions/095-alknet-typedef-purpose-scope-jsonschema-engine.md b/docs/architecture/decisions/001-alktype-purpose-scope-jsonschema-engine.md similarity index 88% rename from docs/architecture/decisions/095-alknet-typedef-purpose-scope-jsonschema-engine.md rename to docs/architecture/decisions/001-alktype-purpose-scope-jsonschema-engine.md index 93f1f5e..688a07f 100644 --- a/docs/architecture/decisions/095-alknet-typedef-purpose-scope-jsonschema-engine.md +++ b/docs/architecture/decisions/001-alktype-purpose-scope-jsonschema-engine.md @@ -1,4 +1,4 @@ -# ADR-095: alknet-typedef — Purpose, Scope, and the jsonschema Engine +# ADR-001: alktype — Purpose, Scope, and the jsonschema Engine ## Status Accepted @@ -37,9 +37,11 @@ Two prior attempts built their own jsonschema engines — the fatal flaw: - **typebox-rs** (`/workspace/@alkimiadev/typebox-rs/`, ~8,400 lines): a full 26-variant `SchemaKind` enum, a custom `Value` type with typed arrays, and a 912-line hand-written validator. -- **alktype** (`/workspace/@alkimiadev/alktype/`, ~5,600 lines): a - handler-registry pattern that also implements its own validation for - each type. +- **the @alkimiadev/alktype prototype** (`/workspace/@alkimiadev/alktype/`, + ~5,600 lines): a handler-registry pattern that also implements its own + validation for each type. (Not to be confused with this crate, which + reuses the name but is a fresh implementation backed by the `jsonschema` + crate rather than a hand-rolled engine.) The `jsonschema` crate (v0.46.5, Draft 2020-12) is already in the workspace at `/workspace/jsonschema/`. It handles validation with custom @@ -57,7 +59,7 @@ functions, and validation — all driven by the schema. ## Decision -**alknet-typedef is a small Rust crate that takes a JSON Schema with +**alktype is a small Rust crate that takes a JSON Schema with `TypeDef:*` custom keywords and produces three capabilities:** 1. **An offset map** — walks the schema, computes byte offsets for each @@ -94,16 +96,16 @@ JSON Schema wire format. **The crate targets `std` for v1.** The WASM target has `std` available via `wasm-bindgen`. If embedded use cases emerge, `no_std` + `alloc` can be added as a feature gate later — the engine's core (offset computation, -read/write) is already allocation-free. See OQ-070. + read/write) is already allocation-free. See OQ-002. ## Consequences ### Positive - **Eliminates ~14,000 lines of hand-rolled schema engines.** typebox-rs - and alktype are replaced by `jsonschema` + an offset map + ~50 lines of - custom keyword implementations. The codebase drops from "a port of - TypeBox" to "jsonschema + an offset map." + and the @alkimiadev/alktype prototype are replaced by `jsonschema` + an + offset map + ~50 lines of custom keyword implementations. The codebase + drops from "a port of TypeBox" to "jsonschema + an offset map." - **One schema, three uses.** The same JSON Schema validates, computes offsets, and drives data access. No separate format definition, parser, or validator per protocol. @@ -134,7 +136,7 @@ read/write) is already allocation-free. See OQ-070. small compile-time cost. - **Schema authoring is external.** Schemas are authored in TypeBox (JS) or hand-written JSON. The typedef engine consumes schemas; it does not - generate them. A builder API is deferred (OQ-071). + generate them. A builder API is deferred (OQ-003). ## Scope Boundaries (What This Is Not) @@ -166,8 +168,8 @@ read/write) is already allocation-free. See OQ-070. schema kinds (619 lines) - `/workspace/jsonschema/` — the jsonschema crate (v0.46.5, Draft 2020-12) - `/workspace/alknet-typedef-poc/` — the POC code (disposable) -- [ADR-096](096-two-layout-modes-packed-vs-aligned.md) — the two layout +- [ADR-002](002-two-layout-modes-packed-vs-aligned.md) — the two layout modes decision -- [ADR-097](097-schema-annotations.md) — schema annotation shapes -- [ADR-098](098-error-handling-validation-strategy.md) — error handling +- [ADR-003](003-schema-annotations.md) — schema annotation shapes +- [ADR-004](004-error-handling-validation-strategy.md) — error handling and validation strategy diff --git a/docs/architecture/decisions/096-two-layout-modes-packed-vs-aligned.md b/docs/architecture/decisions/002-two-layout-modes-packed-vs-aligned.md similarity index 95% rename from docs/architecture/decisions/096-two-layout-modes-packed-vs-aligned.md rename to docs/architecture/decisions/002-two-layout-modes-packed-vs-aligned.md index 7d1c85c..68fb82f 100644 --- a/docs/architecture/decisions/096-two-layout-modes-packed-vs-aligned.md +++ b/docs/architecture/decisions/002-two-layout-modes-packed-vs-aligned.md @@ -1,4 +1,4 @@ -# ADR-096: Two Layout Modes — Packed Sequential vs Aligned Static +# ADR-002: Two Layout Modes — Packed Sequential vs Aligned Static ## Status Accepted @@ -95,7 +95,7 @@ fields). Inline length-prefixing (`[length: u32][data]`) is the default for all variable-length types in both modes. This is the universal pattern used by channels, SFTP, TTY, and most binary protocols. Offset indirection is -opt-in via the `encoding` annotation (see ADR-097). +opt-in via the `encoding` annotation (see ADR-003). ## Consequences @@ -131,7 +131,7 @@ opt-in via the `encoding` annotation (see ADR-097). - `docs/research/alknet-typedef/findings.md` §"POC Results" — POC 1 (aligned OffsetMap) and POC 2 (packed LayoutBuilder/SequentialReader) -- [ADR-095](095-alknet-typedef-purpose-scope-jsonschema-engine.md) — +- [ADR-001](001-alktype-purpose-scope-jsonschema-engine.md) — purpose and scope -- [ADR-097](097-schema-annotations.md) — schema annotations including +- [ADR-003](003-schema-annotations.md) — schema annotations including the `encoding` field for variable-length types diff --git a/docs/architecture/decisions/097-schema-annotations.md b/docs/architecture/decisions/003-schema-annotations.md similarity index 97% rename from docs/architecture/decisions/097-schema-annotations.md rename to docs/architecture/decisions/003-schema-annotations.md index b9eb2ce..a78f387 100644 --- a/docs/architecture/decisions/097-schema-annotations.md +++ b/docs/architecture/decisions/003-schema-annotations.md @@ -1,4 +1,4 @@ -# ADR-097: Schema Annotations — Endianness, Alignment, Encoding, and TUnion Discriminators +# ADR-003: Schema Annotations — Endianness, Alignment, Encoding, and TUnion Discriminators ## Status Accepted @@ -65,7 +65,7 @@ struct-level.** - Default alignment (when no annotation is present): 1 for u8/bool, 2 for u16/i16, 4 for u32/i32/f32, 8 for u64/i64/f64, max field alignment for structs. -- Alignment is only meaningful in aligned static mode (ADR-096). In +- Alignment is only meaningful in aligned static mode (ADR-002). In packed sequential mode, alignment annotations are ignored — fields are packed with no padding. @@ -253,7 +253,7 @@ event types). Both work. - `docs/research/alknet-typedef/findings.md` §"Open Questions" — the annotation shape questions this ADR resolves -- [ADR-095](095-alknet-typedef-purpose-scope-jsonschema-engine.md) — +- [ADR-001](001-alktype-purpose-scope-jsonschema-engine.md) — purpose and scope -- [ADR-096](096-two-layout-modes-packed-vs-aligned.md) — the two layout +- [ADR-002](002-two-layout-modes-packed-vs-aligned.md) — the two layout modes (alignment only meaningful in aligned static mode) diff --git a/docs/architecture/decisions/098-error-handling-validation-strategy.md b/docs/architecture/decisions/004-error-handling-validation-strategy.md similarity index 96% rename from docs/architecture/decisions/098-error-handling-validation-strategy.md rename to docs/architecture/decisions/004-error-handling-validation-strategy.md index 0e3f35c..db7a723 100644 --- a/docs/architecture/decisions/098-error-handling-validation-strategy.md +++ b/docs/architecture/decisions/004-error-handling-validation-strategy.md @@ -1,4 +1,4 @@ -# ADR-098: Error Handling and Validation Strategy +# ADR-004: Error Handling and Validation Strategy ## Status Accepted @@ -150,8 +150,8 @@ you exactly which field failed and why. - `docs/research/alknet-typedef/findings.md` §"Open Questions" — error handling strategy question (OQ 8) -- [ADR-095](095-alknet-typedef-purpose-scope-jsonschema-engine.md) — +- [ADR-001](001-alktype-purpose-scope-jsonschema-engine.md) — purpose and scope -- [ADR-096](096-two-layout-modes-packed-vs-aligned.md) — the two layout +- [ADR-002](002-two-layout-modes-packed-vs-aligned.md) — the two layout modes -- [ADR-097](097-schema-annotations.md) — schema annotations +- [ADR-003](003-schema-annotations.md) — schema annotations diff --git a/docs/architecture/decisions/099-int64-uint64-first-class-kinds.md b/docs/architecture/decisions/005-int64-uint64-first-class-kinds.md similarity index 95% rename from docs/architecture/decisions/099-int64-uint64-first-class-kinds.md rename to docs/architecture/decisions/005-int64-uint64-first-class-kinds.md index 75d789c..30f6c3e 100644 --- a/docs/architecture/decisions/099-int64-uint64-first-class-kinds.md +++ b/docs/architecture/decisions/005-int64-uint64-first-class-kinds.md @@ -1,11 +1,11 @@ -# ADR-099: Int64/Uint64 as First-Class Kinds +# ADR-005: Int64/Uint64 as First-Class Kinds ## Status Accepted ## Context -The typedef engine's kind set (ADR-095, ADR-097) tops out at 32-bit +The typedef engine's kind set (ADR-001, ADR-003) tops out at 32-bit integers. The POC included `u64` read/write primitives, and the call-channels-unification research's own SFTP schema example uses `"TypeDef:Uint64"` for the `offset` field (`Read`/`Write` packets have @@ -108,7 +108,7 @@ The engine now has **19** first-class kinds (17 + Int64 + Uint64). the SFTP schema with `"offset": { "TypeDef:Uint64": true }` - `docs/research/alknet-typedef/findings.md` §"POC 1" — the POC included u64 read/write -- [ADR-095](095-alknet-typedef-purpose-scope-jsonschema-engine.md) — +- [ADR-001](001-alktype-purpose-scope-jsonschema-engine.md) — purpose and scope (the kind set) -- [ADR-097](097-schema-annotations.md) — schema annotations +- [ADR-003](003-schema-annotations.md) — schema annotations (endianness applies to the new kinds) \ No newline at end of file diff --git a/docs/architecture/decisions/100-reject-non-final-inline-length-prefixed-in-aligned-mode.md b/docs/architecture/decisions/006-reject-non-final-inline-length-prefixed-in-aligned-mode.md similarity index 95% rename from docs/architecture/decisions/100-reject-non-final-inline-length-prefixed-in-aligned-mode.md rename to docs/architecture/decisions/006-reject-non-final-inline-length-prefixed-in-aligned-mode.md index 41d5e9b..d36c3f9 100644 --- a/docs/architecture/decisions/100-reject-non-final-inline-length-prefixed-in-aligned-mode.md +++ b/docs/architecture/decisions/006-reject-non-final-inline-length-prefixed-in-aligned-mode.md @@ -1,11 +1,11 @@ -# ADR-100: Reject Non-Final Inline Length-Prefixed Variable Fields in Aligned Mode +# ADR-006: Reject Non-Final Inline Length-Prefixed Variable Fields in Aligned Mode ## Status Accepted ## Context -The aligned static layout mode (ADR-096) is designed for mmap-friendly +The aligned static layout mode (ADR-002) is designed for mmap-friendly formats: fields have fixed positions with natural alignment padding, enabling random access by field path without parsing preceding fields. @@ -102,9 +102,9 @@ not when writing data. ## References -- [ADR-096](096-two-layout-modes-packed-vs-aligned.md) — the two layout +- [ADR-002](002-two-layout-modes-packed-vs-aligned.md) — the two layout modes (aligned static mode's variable-length handling) -- [ADR-097](097-schema-annotations.md) — the three variable-length +- [ADR-003](003-schema-annotations.md) — the three variable-length encoding strategies (`maxLength`, `offset-indirect`, inline length-prefixing) - `../layout-engine.md` §"Variable-length diff --git a/docs/architecture/decisions/101-packed-mode-read-factory.md b/docs/architecture/decisions/007-packed-mode-read-factory.md similarity index 97% rename from docs/architecture/decisions/101-packed-mode-read-factory.md rename to docs/architecture/decisions/007-packed-mode-read-factory.md index bed66ff..8a493e8 100644 --- a/docs/architecture/decisions/101-packed-mode-read-factory.md +++ b/docs/architecture/decisions/007-packed-mode-read-factory.md @@ -1,4 +1,4 @@ -# ADR-101: Packed-Mode Read API — Engine as SequentialReader Factory +# ADR-007: Packed-Mode Read API — Engine as SequentialReader Factory ## Status Accepted @@ -97,7 +97,7 @@ compared to the cost of reading a buffer. ## References -- [ADR-096](096-two-layout-modes-packed-vs-aligned.md) — packed +- [ADR-002](002-two-layout-modes-packed-vs-aligned.md) — packed sequential mode (`SequentialReader` as the read-side) - `../data-access.md` §"Higher-level read/write" — the `SequentialReader` API \ No newline at end of file diff --git a/docs/architecture/decisions/102-reject-tunion-in-aligned-mode.md b/docs/architecture/decisions/008-reject-tunion-in-aligned-mode.md similarity index 94% rename from docs/architecture/decisions/102-reject-tunion-in-aligned-mode.md rename to docs/architecture/decisions/008-reject-tunion-in-aligned-mode.md index 0d084c8..6303343 100644 --- a/docs/architecture/decisions/102-reject-tunion-in-aligned-mode.md +++ b/docs/architecture/decisions/008-reject-tunion-in-aligned-mode.md @@ -1,11 +1,11 @@ -# ADR-102: Reject TUnion in Aligned Mode for v1 +# ADR-008: Reject TUnion in Aligned Mode for v1 ## Status Accepted ## Context -The aligned static layout mode (ADR-096) computes fixed byte positions +The aligned static layout mode (ADR-002) computes fixed byte positions for each field, enabling random access by field path. `TUnion` in aligned mode has three implementation problems: @@ -104,8 +104,8 @@ arrives, not speculatively now. ## References -- [ADR-096](096-two-layout-modes-packed-vs-aligned.md) — the two layout +- [ADR-002](002-two-layout-modes-packed-vs-aligned.md) — the two layout modes -- [ADR-097](097-schema-annotations.md) §4 — TUnion discriminators +- [ADR-003](003-schema-annotations.md) §4 — TUnion discriminators - `../layout-engine.md` §"TUnion" — aligned-mode union sizing \ No newline at end of file diff --git a/docs/architecture/layout-engine.md b/docs/architecture/layout-engine.md index 4855361..b16cf3c 100644 --- a/docs/architecture/layout-engine.md +++ b/docs/architecture/layout-engine.md @@ -3,7 +3,7 @@ status: draft last_updated: 2026-07-22 --- -# alknet-typedef — Layout Engine +# alktype — Layout Engine The layout engine: offset computation, the two layout modes (packed sequential vs aligned static), alignment, endianness, and variable-length @@ -14,7 +14,7 @@ JSON that computes byte positions for each field. The POCs surfaced that protocols and mmap-friendly formats need different layout strategies. This is the most important architectural finding — -decided in [ADR-096](decisions/096-two-layout-modes-packed-vs-aligned.md). +decided in [ADR-002](decisions/002-two-layout-modes-packed-vs-aligned.md). ### Mode 1: Packed sequential (protocol wire formats) @@ -114,7 +114,7 @@ with a `TypedefError::Offset` — the `OffsetMap` reserves only 4 bytes data inline, which would clobber subsequent fields. Non-final variable fields must use `maxLength` (fixed-size reservation) or `"encoding": "offset-indirect"`. See -[ADR-100](decisions/100-reject-non-final-inline-length-prefixed-in-aligned-mode.md). +[ADR-006](decisions/006-reject-non-final-inline-length-prefixed-in-aligned-mode.md). ## Offset Computation Algorithm @@ -142,7 +142,7 @@ its total size. **`TUnion`:** TUnion is supported in packed sequential mode only. In aligned static mode, `OffsetMap::compute` rejects `TUnion` fields with `TypedefError::Offset` — see -[ADR-102](decisions/102-reject-tunion-in-aligned-mode.md). Unions +[ADR-008](decisions/008-reject-tunion-in-aligned-mode.md). Unions are the protocol dispatch pattern (SFTP type bytes, call protocol event types); mmap-friendly formats use structs and arrays, not tagged unions. @@ -166,13 +166,13 @@ alignment padding in aligned mode). Element `i` starts at `array_offset + i × stride`. The array's total size is `count × stride`. **`TArray` of variable-length-element structs:** Deferred for v1 -(OQ-069). +(OQ-001). ### Variable-length types The typedef engine supports three strategies for variable-length types (see [schema-layer.md](schema-layer.md) §Variable-length types and -[ADR-097](decisions/097-schema-annotations.md) §3 for the full +[ADR-003](decisions/003-schema-annotations.md) §3 for the full annotation shapes). **Strategy 1: Inline length-prefixing (default).** @@ -211,7 +211,7 @@ path prefix. ### Endianness -Endianness is per-schema (ADR-097). The offset computation is +Endianness is per-schema (ADR-003). The offset computation is endian-agnostic — it computes byte positions, not byte values. The read/write functions apply endianness when converting between bytes and typed values. The engine reads the `"endian"` annotation from the schema @@ -252,7 +252,7 @@ returns `Some(&OffsetMap)` in aligned mode and `None` in packed mode; and `None` in aligned mode. `engine.sequential_reader()` returns `Option` (an owned fresh reader, not a reference — the reader has mutable cursor state that the consumer owns; see -[ADR-101](decisions/101-packed-mode-read-factory.md)) in packed +[ADR-007](decisions/007-packed-mode-read-factory.md)) in packed mode and `None` in aligned mode. See [validation.md](validation.md) §"The TypedefEngine struct" for the engine API. @@ -332,17 +332,17 @@ order (schema `properties` order, nested struct fields appearing inline). | Decision | ADR | Summary | |----------|-----|---------| -| Two layout modes | [ADR-096](decisions/096-two-layout-modes-packed-vs-aligned.md) | Packed sequential for protocols; aligned static for mmap formats | -| Schema annotations | [ADR-097](decisions/097-schema-annotations.md) | Endianness, alignment, encoding annotations that control layout behavior | -| Non-final inline variable fields | [ADR-100](decisions/100-reject-non-final-inline-length-prefixed-in-aligned-mode.md) | Rejected in aligned mode (would clobber subsequent fields); use `maxLength` or `offset-indirect` | -| Packed-mode read factory | [ADR-101](decisions/101-packed-mode-read-factory.md) | `engine.sequential_reader()` returns an owned fresh reader, not a reference | -| TUnion in aligned mode | [ADR-102](decisions/102-reject-tunion-in-aligned-mode.md) | Rejected for v1 (broken semantics; no current consumer needs it) | +| Two layout modes | [ADR-002](decisions/002-two-layout-modes-packed-vs-aligned.md) | Packed sequential for protocols; aligned static for mmap formats | +| Schema annotations | [ADR-003](decisions/003-schema-annotations.md) | Endianness, alignment, encoding annotations that control layout behavior | +| Non-final inline variable fields | [ADR-006](decisions/006-reject-non-final-inline-length-prefixed-in-aligned-mode.md) | Rejected in aligned mode (would clobber subsequent fields); use `maxLength` or `offset-indirect` | +| Packed-mode read factory | [ADR-007](decisions/007-packed-mode-read-factory.md) | `engine.sequential_reader()` returns an owned fresh reader, not a reference | +| TUnion in aligned mode | [ADR-008](decisions/008-reject-tunion-in-aligned-mode.md) | Rejected for v1 (broken semantics; no current consumer needs it) | ## Open Questions See [open-questions.md](open-questions.md) for full details. -- **OQ-069** (deferred(scope)): Arrays of variable-length-element structs +- **OQ-001** (deferred(scope)): Arrays of variable-length-element structs — requires lazy walking logic; blocked on a concrete consumer that needs it. @@ -350,9 +350,9 @@ See [open-questions.md](open-questions.md) for full details. - `docs/research/alknet-typedef/findings.md` §"POC Results" — POC 1 (aligned OffsetMap) and POC 2 (packed LayoutBuilder/SequentialReader) -- [ADR-096](decisions/096-two-layout-modes-packed-vs-aligned.md) — +- [ADR-002](decisions/002-two-layout-modes-packed-vs-aligned.md) — the two layout modes decision -- [ADR-097](decisions/097-schema-annotations.md) — schema +- [ADR-003](decisions/003-schema-annotations.md) — schema annotations - [schema-layer.md](schema-layer.md) — the 17 TypeDef kinds and their byte sizes diff --git a/docs/architecture/open-questions.md b/docs/architecture/open-questions.md index e5f38d5..5357d65 100644 --- a/docs/architecture/open-questions.md +++ b/docs/architecture/open-questions.md @@ -35,7 +35,7 @@ hub deployment because the hub dials workers" not "blocks the hub crate." This is the triage signal that makes the deferral's urgency visible. -Door type classifications follow ADR-009 — they describe **reversal cost** (how expensive it is to undo), not urgency: +Door type classifications describe **reversal cost** (how expensive it is to undo), not urgency: - **One-way door**: Reversal requires rewriting significant code or permanently closes a capability. Getting it wrong is expensive — requires ADR before implementation. - **Two-way door**: Reversal is cheap or additive. Getting it wrong is recoverable — decide, implement, revert if needed. @@ -47,19 +47,19 @@ Door type is separate from whether a decision is made. A two-way door is a decis | OQ | Title | Status | Door | Pri | |----|-------|--------|------|-----| -| [OQ-069](questions/069-arrays-of-variable-length-element-structs.md) | Arrays of Variable-Length-Element Structs | deferred(scope) | two | low | +| [OQ-001](questions/001-arrays-of-variable-length-element-structs.md) | Arrays of Variable-Length-Element Structs | deferred(scope) | two | low | ### Platform Support | OQ | Title | Status | Door | Pri | |----|-------|--------|------|-----| -| [OQ-070](questions/070-no-std-alloc-support.md) | `no_std` + `alloc` Support | deferred(scope) | two | low | +| [OQ-002](questions/002-no-std-alloc-support.md) | `no_std` + `alloc` Support | deferred(scope) | two | low | ### Schema Construction | OQ | Title | Status | Door | Pri | |----|-------|--------|------|-----| -| [OQ-071](questions/071-builder-api-for-schema-construction.md) | Builder API for Schema Construction | deferred(scope) | two | med | +| [OQ-003](questions/003-builder-api-for-schema-construction.md) | Builder API for Schema Construction | deferred(scope) | two | med | ## Deferred / Blocked @@ -69,7 +69,7 @@ blocking condition. They are not failures; they are scope management. This section exists so "what's currently blocking the architect" is answerable at a glance, not by filtering the tables above. -### OQ-069: Arrays of Variable-Length-Element Structs +### OQ-001: Arrays of Variable-Length-Element Structs - **Blocked on**: A concrete consumer that needs arrays of structs with variable-length fields, where the elements are interleaved @@ -80,9 +80,9 @@ answerable at a glance, not by filtering the tables above. pattern), not as an array of fixed-stride structs. Arrays of fixed-size structs are fully supported. - **Priority**: low -- **Full file**: [OQ-069](questions/069-arrays-of-variable-length-element-structs.md) +- **Full file**: [OQ-001](questions/001-arrays-of-variable-length-element-structs.md) -### OQ-070: `no_std` + `alloc` Support +### OQ-002: `no_std` + `alloc` Support - **Blocked on**: An embedded use case that requires `no_std` + `alloc` (e.g., a microcontroller running Rust without `std`). The WASM target @@ -90,9 +90,9 @@ answerable at a glance, not by filtering the tables above. computation, read/write) is already allocation-free; the `jsonschema` dependency is the only `alloc` consumer. - **Priority**: low -- **Full file**: [OQ-070](questions/070-no-std-alloc-support.md) +- **Full file**: [OQ-002](questions/002-no-std-alloc-support.md) -### OQ-071: Builder API for Schema Construction +### OQ-003: Builder API for Schema Construction - **Blocked on**: A concrete need for programmatic schema construction in Rust. The current consumers (SFTP, metatensor, binary call frames, @@ -101,4 +101,4 @@ answerable at a glance, not by filtering the tables above. produces the same JSON Schema structure — it would sit on top of the engine, not inside it. - **Priority**: medium -- **Full file**: [OQ-071](questions/071-builder-api-for-schema-construction.md) \ No newline at end of file +- **Full file**: [OQ-003](questions/003-builder-api-for-schema-construction.md) \ No newline at end of file diff --git a/docs/architecture/overview.md b/docs/architecture/overview.md index 94d5994..8357251 100644 --- a/docs/architecture/overview.md +++ b/docs/architecture/overview.md @@ -3,7 +3,7 @@ status: draft last_updated: 2026-07-22 --- -# alknet-typedef — Overview +# alktype — Overview The binary struct engine: a small Rust crate that takes a JSON Schema with `TypeDef:*` custom keywords and produces an offset map, read/write @@ -16,10 +16,10 @@ Component details are in the sibling documents. ## What -`alknet-typedef` is a library crate that consumes JSON Schemas annotated +`alktype` is a library crate that consumes JSON Schemas annotated with `TypeDef:*` custom keywords (the same kinds defined in TypeBox's `typedef.ts`, plus `TypeDef:Bytes`, `TypeDef:Int64`, and `TypeDef:Uint64` -as alknet-typedef additions) and produces three capabilities: +as alktype additions) and produces three capabilities: 1. **An offset map** — walks the schema, computes byte offsets for each field based on type sizes, field order, and alignment. @@ -36,18 +36,19 @@ each field. The custom keyword implementations are small (a few lines each, generated from shared macros — see [validation.md](validation.md)). The crate replaces two prior attempts that built their own jsonschema -engines — typebox-rs (~8,400 lines) and alktype (~5,600 lines) — with -`jsonschema` + an offset map + small custom keyword implementations. See -[ADR-095](decisions/095-alknet-typedef-purpose-scope-jsonschema-engine.md). +engines — typebox-rs (~8,400 lines) and the @alkimiadev/alktype prototype +(~5,600 lines) — with `jsonschema` + an offset map + small custom keyword +implementations. See +[ADR-001](decisions/001-alktype-purpose-scope-jsonschema-engine.md). ## Why -The crate's purpose is to be the binary struct engine for every alknet -component that reads or writes binary data at computed offsets. Instead -of per-protocol serde structs (russh-sftp's 29 packet types), per-handler -wire format code (TTY's 5-byte format parser), or per-format offset -computation (metatensor's tensor access), all of these become instances -of the same engine with different schemas. +The crate's purpose is to be a binary struct engine for components that +read or write binary data at computed offsets. Instead of per-protocol +serde structs (russh-sftp's 29 packet types), per-handler wire format +code (TTY's 5-byte format parser), or per-format offset computation +(metatensor's tensor access), all of these become instances of the same +engine with different schemas. The guiding insight: @@ -95,17 +96,16 @@ language-specific annotations. The schema is the ABI contract. ## Dependencies ``` -alknet-typedef +alktype ├── jsonschema (v0.46.5, Draft 2020-12) — validation engine, custom keyword support ├── serde_json (with preserve_order) — schema parsing; field order is load-bearing └── (no tokio, no platform deps) — WASM-clean by construction ``` -`alknet-typedef` is dependency-light: `jsonschema` + `serde_json` only. +`alktype` is dependency-light: `jsonschema` + `serde_json` only. No tokio, no platform deps. Compiles to `wasm32-unknown-unknown` for browser use. The `jsonschema` crate is already in the workspace at -`/workspace/jsonschema/` but not yet used by any alknet crate — typedef -is the first consumer. +`/workspace/jsonschema/` — alktype is its first consumer. `serde_json` requires the `preserve_order` feature because field order is load-bearing for binary layouts. The order of properties in the @@ -131,7 +131,7 @@ offsets, reads fields. Same result, no per-packet-type code. ## Scope Boundaries (What This Is Not) -These boundaries are decided in [ADR-095](decisions/095-alknet-typedef-purpose-scope-jsonschema-engine.md). +These boundaries are decided in [ADR-001](decisions/001-alktype-purpose-scope-jsonschema-engine.md). - **Not metatensor.** typedef is the binary struct *engine*. Metatensor is a *format* (8-byte header + JSON header + binary data) that uses the @@ -145,7 +145,7 @@ These boundaries are decided in [ADR-095](decisions/095-alknet-typedef-purpose-s - **Not a schema builder.** The typedef engine does not provide a fluent API for constructing schemas. Schemas are plain JSON — authored in TypeBox, generated by ujsx components, or hand-written. A builder API - is deferred (OQ-071). + is deferred (OQ-003). - **Not a serialization framework.** The typedef engine is not a general-purpose serde replacement. It operates on raw byte buffers at computed offsets — no intermediate `Value` tree, no reflection, no @@ -171,22 +171,22 @@ These boundaries are decided in [ADR-095](decisions/095-alknet-typedef-purpose-s | Decision | ADR | Summary | |----------|-----|---------| -| Purpose, scope, and the jsonschema engine | [ADR-095](decisions/095-alknet-typedef-purpose-scope-jsonschema-engine.md) | What the crate is/isn't; why jsonschema not a custom engine; "schema is the format" principle; scope boundaries | -| Two layout modes | [ADR-096](decisions/096-two-layout-modes-packed-vs-aligned.md) | Packed sequential (`LayoutBuilder`/`SequentialReader`) for protocols; aligned static (`OffsetMap`) for mmap formats | -| Schema annotations | [ADR-097](decisions/097-schema-annotations.md) | Endianness (schema-level, default LE), alignment (struct + field-level), encoding (length-prefixed vs offset-indirect), TUnion discriminators (byte-offset vs field-name) | -| Error handling and validation | [ADR-098](decisions/098-error-handling-validation-strategy.md) | `TypedefError` enum; load-time build, access-time check; field-path-carrying errors; jsonschema `ValidationError` wrapping | -| Int64/Uint64 kinds | [ADR-099](decisions/099-int64-uint64-first-class-kinds.md) | 64-bit integers as first-class kinds (SFTP offsets, metatensor data_offsets) | -| Non-final inline variable fields | [ADR-100](decisions/100-reject-non-final-inline-length-prefixed-in-aligned-mode.md) | Rejected in aligned mode (would clobber subsequent fields) | -| Packed-mode read factory | [ADR-101](decisions/101-packed-mode-read-factory.md) | `engine.sequential_reader()` returns an owned fresh reader | -| TUnion in aligned mode | [ADR-102](decisions/102-reject-tunion-in-aligned-mode.md) | Rejected for v1 (broken semantics; no current consumer needs it) | +| Purpose, scope, and the jsonschema engine | [ADR-001](decisions/001-alktype-purpose-scope-jsonschema-engine.md) | What the crate is/isn't; why jsonschema not a custom engine; "schema is the format" principle; scope boundaries | +| Two layout modes | [ADR-002](decisions/002-two-layout-modes-packed-vs-aligned.md) | Packed sequential (`LayoutBuilder`/`SequentialReader`) for protocols; aligned static (`OffsetMap`) for mmap formats | +| Schema annotations | [ADR-003](decisions/003-schema-annotations.md) | Endianness (schema-level, default LE), alignment (struct + field-level), encoding (length-prefixed vs offset-indirect), TUnion discriminators (byte-offset vs field-name) | +| Error handling and validation | [ADR-004](decisions/004-error-handling-validation-strategy.md) | `TypedefError` enum; load-time build, access-time check; field-path-carrying errors; jsonschema `ValidationError` wrapping | +| Int64/Uint64 kinds | [ADR-005](decisions/005-int64-uint64-first-class-kinds.md) | 64-bit integers as first-class kinds (SFTP offsets, metatensor data_offsets) | +| Non-final inline variable fields | [ADR-006](decisions/006-reject-non-final-inline-length-prefixed-in-aligned-mode.md) | Rejected in aligned mode (would clobber subsequent fields) | +| Packed-mode read factory | [ADR-007](decisions/007-packed-mode-read-factory.md) | `engine.sequential_reader()` returns an owned fresh reader | +| TUnion in aligned mode | [ADR-008](decisions/008-reject-tunion-in-aligned-mode.md) | Rejected for v1 (broken semantics; no current consumer needs it) | ## Open Questions See [open-questions.md](open-questions.md) for full details. -- **OQ-069** (deferred(scope)): Arrays of variable-length-element structs. -- **OQ-070** (deferred(scope)): `no_std` + `alloc` support. -- **OQ-071** (deferred(scope)): Builder API for schema construction. +- **OQ-001** (deferred(scope)): Arrays of variable-length-element structs. +- **OQ-002** (deferred(scope)): `no_std` + `alloc` support. +- **OQ-003** (deferred(scope)): Builder API for schema construction. ## References @@ -200,4 +200,4 @@ See [open-questions.md](open-questions.md) for full details. - `/workspace/jsonschema/` — the jsonschema crate (v0.46.5, Draft 2020-12) - `/workspace/alknet-typedef-poc/` — the POC code (disposable) - `/workspace/@alkimiadev/typebox-rs/` — prior attempt, replaced by typedef -- `/workspace/@alkimiadev/alktype/` — prior attempt, replaced by typedef +- `/workspace/@alkimiadev/alktype/` — prior attempt (the @alkimiadev/alktype prototype; not to be confused with this crate, which reuses the name but is backed by the `jsonschema` crate) diff --git a/docs/architecture/questions/069-arrays-of-variable-length-element-structs.md b/docs/architecture/questions/001-arrays-of-variable-length-element-structs.md similarity index 92% rename from docs/architecture/questions/069-arrays-of-variable-length-element-structs.md rename to docs/architecture/questions/001-arrays-of-variable-length-element-structs.md index c0a1a8c..bdde179 100644 --- a/docs/architecture/questions/069-arrays-of-variable-length-element-structs.md +++ b/docs/architecture/questions/001-arrays-of-variable-length-element-structs.md @@ -1,4 +1,4 @@ -# OQ-069: Arrays of variable-length-element structs +# OQ-001: Arrays of variable-length-element structs - **Origin**: [../layout-engine.md](../layout-engine.md), [../data-access.md](../data-access.md); @@ -17,4 +17,4 @@ walking of array elements, reading each element's length prefixes to find the next element's start) is understood but not needed by any current consumer. Arrays of fixed-size structs are fully supported. -- **Cross-references**: ADR-096, [layout-engine.md](../layout-engine.md) +- **Cross-references**: ADR-002, [layout-engine.md](../layout-engine.md) diff --git a/docs/architecture/questions/070-no-std-alloc-support.md b/docs/architecture/questions/002-no-std-alloc-support.md similarity index 94% rename from docs/architecture/questions/070-no-std-alloc-support.md rename to docs/architecture/questions/002-no-std-alloc-support.md index 3ae8618..2adf8f9 100644 --- a/docs/architecture/questions/070-no-std-alloc-support.md +++ b/docs/architecture/questions/002-no-std-alloc-support.md @@ -1,4 +1,4 @@ -# OQ-070: `no_std` + `alloc` support +# OQ-002: `no_std` + `alloc` support - **Origin**: [../overview.md](../overview.md); `docs/research/alknet-typedef/findings.md` §"Open Questions" (OQ 6) @@ -19,4 +19,4 @@ later. The engine's core (offset computation, read/write) is already allocation-free — it operates on `&[u8]` slices. The `jsonschema` dependency is the only `alloc` consumer. -- **Cross-references**: ADR-095 +- **Cross-references**: ADR-001 diff --git a/docs/architecture/questions/071-builder-api-for-schema-construction.md b/docs/architecture/questions/003-builder-api-for-schema-construction.md similarity index 92% rename from docs/architecture/questions/071-builder-api-for-schema-construction.md rename to docs/architecture/questions/003-builder-api-for-schema-construction.md index b0e1e8c..75df28e 100644 --- a/docs/architecture/questions/071-builder-api-for-schema-construction.md +++ b/docs/architecture/questions/003-builder-api-for-schema-construction.md @@ -1,4 +1,4 @@ -# OQ-071: Builder API for schema construction +# OQ-003: Builder API for schema construction - **Origin**: [../schema-layer.md](../schema-layer.md), [../overview.md](../overview.md); @@ -23,4 +23,4 @@ path is the primary interface for v1. A builder API would be a fluent Rust API that produces the same JSON Schema structure — it would sit on top of the engine, not inside it. -- **Cross-references**: ADR-095, [schema-layer.md](../schema-layer.md) +- **Cross-references**: ADR-001, [schema-layer.md](../schema-layer.md) diff --git a/docs/architecture/schema-layer.md b/docs/architecture/schema-layer.md index f77441c..bb57a0e 100644 --- a/docs/architecture/schema-layer.md +++ b/docs/architecture/schema-layer.md @@ -3,7 +3,7 @@ status: draft last_updated: 2026-07-22 --- -# alknet-typedef — Schema Layer +# alktype — Schema Layer The schema layer: the 19 `TypeDef:*` custom type kinds, their mapping to Rust types and byte sizes, the `jsonschema` custom keyword integration, @@ -40,11 +40,11 @@ encoding strategy (for variable-length types). | `TRecord` | `TypeDef:Record` | count-prefixed sequence of (key, value) pairs | variable | variable | | `TTimestamp` | `TypeDef:Timestamp` | length-prefixed RFC 3339 string | variable | variable | -`TypeDef:Int64` and `TypeDef:Uint64` are alknet-typedef additions — +`TypeDef:Int64` and `TypeDef:Uint64` are alktype additions — TypeBox's `typedef.ts` tops out at 32-bit integers. They are required by the primary POC targets: SFTP `Read`/`Write` packets have `offset: u64`, and metatensor `data_offsets` are `u64`. See -[ADR-099](decisions/099-int64-uint64-first-class-kinds.md). +[ADR-005](decisions/005-int64-uint64-first-class-kinds.md). ### The `TypeDefKind` enum @@ -106,7 +106,7 @@ number of variants (e.g., the call protocol's 5 event types); a `u32` index is compact, fixed-size, and sufficient for any realistic enum. The JSON representation (for validation) remains a string; the binary representation is the `u32` index. -The `u32` index follows the schema's endianness annotation (ADR-097), like +The `u32` index follows the schema's endianness annotation (ADR-003), like all other fixed-size types. In little-endian mode the index is `u32::from_le_bytes`; in big-endian mode it is `u32::from_be_bytes`. @@ -161,7 +161,7 @@ length prefixes and without reserving worst-case space. length-prefixing) otherwise. **Length prefix endianness:** The 4-byte length prefix (strategies 1 and 3) -respects the schema's `"endian"` annotation (ADR-097). In little-endian +respects the schema's `"endian"` annotation (ADR-003). In little-endian mode, the length is `u32::from_le_bytes`. In big-endian mode, the length is `u32::from_be_bytes`. This ensures SFTP consumers (big-endian) have consistent byte order for both field values and length prefixes. @@ -169,7 +169,7 @@ consistent byte order for both field values and length prefixes. **`TBytes`:** Raw bytes — no UTF-8 constraint. The payload is `&[u8]`. Otherwise identical to `TString` in layout (same three strategies). -**Design note:** `TypeDef:Bytes` is an alknet-typedef addition — it does +**Design note:** `TypeDef:Bytes` is an alktype addition — it does not exist in TypeBox's `typedef.ts` (which defines 16 kinds). It is included because raw byte arrays are a common binary protocol primitive (SFTP data payloads, channels payloads, tensor data) and are semantically @@ -360,7 +360,7 @@ a ujsx component, or hand-written. The schema is the interface. ## Schema Annotations Schema-level annotations control binary layout behavior. These are -decided in [ADR-097](decisions/097-schema-annotations.md). +decided in [ADR-003](decisions/003-schema-annotations.md). ### Endianness @@ -393,7 +393,7 @@ Both struct-level and field-level, with field-level overriding: - Default alignment: 1 for u8/i8/bool, 2 for u16/i16, 4 for u32/i32/f32/ enum, 8 for u64/i64/f64, 4 for variable-length (the u32 length prefix), 1 for struct/union/array. -- Only meaningful in aligned static mode (ADR-096). Ignored in packed +- Only meaningful in aligned static mode (ADR-002). Ignored in packed sequential mode. ### Variable-length encoding @@ -486,21 +486,21 @@ Mapping values may be either inline schemas or `$ref` pointers. Both work. | Decision | ADR | Summary | |----------|-----|---------| -| Schema annotations | [ADR-097](decisions/097-schema-annotations.md) | Concrete JSON shapes for endianness, alignment, encoding, and TUnion discriminators | -| Int64/Uint64 kinds | [ADR-099](decisions/099-int64-uint64-first-class-kinds.md) | 64-bit integers as first-class kinds (required by SFTP offsets and metatensor data_offsets) | -| Purpose and scope | [ADR-095](decisions/095-alknet-typedef-purpose-scope-jsonschema-engine.md) | Why jsonschema not a custom engine; "schema is the format" principle | +| Schema annotations | [ADR-003](decisions/003-schema-annotations.md) | Concrete JSON shapes for endianness, alignment, encoding, and TUnion discriminators | +| Int64/Uint64 kinds | [ADR-005](decisions/005-int64-uint64-first-class-kinds.md) | 64-bit integers as first-class kinds (required by SFTP offsets and metatensor data_offsets) | +| Purpose and scope | [ADR-001](decisions/001-alktype-purpose-scope-jsonschema-engine.md) | Why jsonschema not a custom engine; "schema is the format" principle | ## Open Questions See [open-questions.md](open-questions.md) for full details. -- **OQ-071** (deferred(scope)): Builder API for schema construction. +- **OQ-003** (deferred(scope)): Builder API for schema construction. ## References - `/workspace/@alkdev/typebox/example/typedef/typedef.ts` — the TypeBox schema kinds (619 lines) - `/workspace/jsonschema/` — the jsonschema crate (v0.46.5, Draft 2020-12) -- [ADR-097](decisions/097-schema-annotations.md) — schema +- [ADR-003](decisions/003-schema-annotations.md) — schema annotation shapes - [validation.md](validation.md) — custom keyword validator implementations diff --git a/docs/architecture/validation.md b/docs/architecture/validation.md index dc8251f..e308c13 100644 --- a/docs/architecture/validation.md +++ b/docs/architecture/validation.md @@ -3,7 +3,7 @@ status: draft last_updated: 2026-07-22 --- -# alknet-typedef — Validation +# alktype — Validation The validation layer: custom keyword validators for all 19 `TypeDef:*` kinds, the `TypedefError` enum, load-time vs access-time validation @@ -17,7 +17,7 @@ it registers custom keyword validators for each `TypeDef:*` kind and lets `jsonschema` handle the structural validation (object properties, required fields, array items, enum values). -The strategy is decided in [ADR-098](decisions/098-error-handling-validation-strategy.md): +The strategy is decided in [ADR-004](decisions/004-error-handling-validation-strategy.md): 1. **Load time:** Parse the schema JSON, build the layout engine, build the jsonschema validator. This is the `TypedefEngine::compile(schema)` constructor. @@ -50,7 +50,7 @@ process, not a single `validate(buffer)` call. ### The `TypedefEngine` struct The `TypedefEngine` is the compiled form of a schema. It supports both -layout modes (ADR-096) via an internal `Layout` enum: +layout modes (ADR-002) via an internal `Layout` enum: ```rust pub struct TypedefEngine { @@ -78,7 +78,7 @@ impl TypedefEngine { pub fn endian(&self) -> Endian; pub fn offset_map(&self) -> Option<&OffsetMap>; // Some in aligned mode pub fn layout_builder(&self) -> Option<&LayoutBuilder>; // Some in packed mode - pub fn sequential_reader(&self) -> Option; // owned fresh reader (ADR-101) + pub fn sequential_reader(&self) -> Option; // owned fresh reader (ADR-007) } ``` @@ -92,7 +92,7 @@ mode-agnostic (it operates on `Value`, not raw bytes). The `Layout::Packed` variant stores only the `LayoutBuilder` (write-side). The `SequentialReader` (read-side) is not stored — it has mutable cursor state that the consumer owns, so `sequential_reader()` constructs a fresh -reader on each call (ADR-101). +reader on each call (ADR-007). The `read_field`/`write_field` methods on `TypedefEngine` are the aligned-mode data-access API — see [data-access.md](data-access.md) @@ -219,7 +219,7 @@ example, a `TypeDef:Struct` validator can inspect the parent's A single `TypedefError` enum covers all error conditions across the engine's three phases (schema parsing, offset computation, read/write) -plus validation. Decided in [ADR-098](decisions/098-error-handling-validation-strategy.md). +plus validation. Decided in [ADR-004](decisions/004-error-handling-validation-strategy.md). ```rust pub enum TypedefError { @@ -314,20 +314,20 @@ representation first, then access the binary buffer. | Decision | ADR | Summary | |----------|-----|---------| -| Error handling and validation | [ADR-098](decisions/098-error-handling-validation-strategy.md) | `TypedefError` enum; load-time build, access-time check; field-path-carrying errors; jsonschema `ValidationError` wrapping | -| Purpose and scope | [ADR-095](decisions/095-alknet-typedef-purpose-scope-jsonschema-engine.md) | Why jsonschema not a custom engine | +| Error handling and validation | [ADR-004](decisions/004-error-handling-validation-strategy.md) | `TypedefError` enum; load-time build, access-time check; field-path-carrying errors; jsonschema `ValidationError` wrapping | +| Purpose and scope | [ADR-001](decisions/001-alktype-purpose-scope-jsonschema-engine.md) | Why jsonschema not a custom engine | ## Open Questions -None specific to validation. The three typedef OQs (OQ-069, OQ-070, -OQ-071) are about layout, platform support, and schema construction — +None specific to validation. The three typedef OQs (OQ-001, OQ-002, +OQ-003) are about layout, platform support, and schema construction — not validation. ## References - `docs/research/alknet-typedef/findings.md` §"Validation" — the POC's custom keyword validators for all 17 kinds -- [ADR-098](decisions/098-error-handling-validation-strategy.md) — +- [ADR-004](decisions/004-error-handling-validation-strategy.md) — error handling and validation strategy - [schema-layer.md](schema-layer.md) — the 17 TypeDef kinds that the validators check diff --git a/src/lib.rs b/src/lib.rs index 73eaaa8..df513a7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -//! alknet-typedef: The binary struct engine. +//! alktype: The binary struct engine. //! //! Takes a JSON Schema with `TypeDef:*` custom keywords and produces //! an offset map, read/write functions, and validation — all driven diff --git a/tests/engine_integration.rs b/tests/engine_integration.rs index 0694e81..8d6da58 100644 --- a/tests/engine_integration.rs +++ b/tests/engine_integration.rs @@ -5,7 +5,7 @@ //! `read_field` / `write_field` round-trip for the fixed-size primitive //! kinds and length-prefixed `String` / `Bytes`. -use alknet_typedef::*; +use alktype::*; use serde_json::json; fn mixed_fixed_struct_schema() -> serde_json::Value { diff --git a/tests/error_paths.rs b/tests/error_paths.rs index 00ab38a..469e4c0 100644 --- a/tests/error_paths.rs +++ b/tests/error_paths.rs @@ -1,4 +1,4 @@ -//! Error path integration tests for `alknet-typedef`. +//! Error path integration tests for `alktype`. //! //! Exercises the `TypedefError` variants across the crate: //! `Access` (buffer too short, invalid UTF-8, invalid boolean byte, @@ -6,9 +6,9 @@ //! malformed discriminator annotation), and `Offset` (missing //! variable-length field size in `LayoutBuilder::build`). -use alknet_typedef::data_access; -use alknet_typedef::tunion; -use alknet_typedef::*; +use alktype::data_access; +use alktype::tunion; +use alktype::*; use serde_json::json; use std::collections::HashMap; diff --git a/tests/poc_roundtrip.rs b/tests/poc_roundtrip.rs index 0e0cabf..c30fceb 100644 --- a/tests/poc_roundtrip.rs +++ b/tests/poc_roundtrip.rs @@ -8,9 +8,9 @@ //! reads them back, asserting both the values and (where applicable) //! the byte positions. -use alknet_typedef::data_access; -use alknet_typedef::tunion; -use alknet_typedef::*; +use alktype::data_access; +use alktype::tunion; +use alktype::*; use serde_json::json; use std::collections::HashMap; diff --git a/tests/tunion_dispatch.rs b/tests/tunion_dispatch.rs index 14cfbd4..e11e229 100644 --- a/tests/tunion_dispatch.rs +++ b/tests/tunion_dispatch.rs @@ -7,9 +7,9 @@ //! follows `$ref` pointers, and that `discriminator_size` reports the //! right fixed sizes. -use alknet_typedef::data_access; -use alknet_typedef::tunion; -use alknet_typedef::{Endian, TypedefError}; +use alktype::data_access; +use alktype::tunion; +use alktype::{Endian, TypedefError}; use serde_json::json; fn sftp_like_byte_union() -> serde_json::Value { @@ -318,6 +318,6 @@ fn resolve_variant_returns_schema_error_for_unknown_key() { #[test] fn parse_discriminator_missing_returns_schema_error() { let schema = json!({"TypeDef:Union": true}); - let err = alknet_typedef::parse_discriminator(&schema).unwrap_err(); + let err = alktype::parse_discriminator(&schema).unwrap_err(); assert!(matches!(err, TypedefError::Schema(_)), "got {err:?}"); }