feat(typedef): add implementation task decomposition (12 tasks, 7 generations)

Break the alknet-typedef architecture specs into atomic, dependency-ordered
implementation tasks covering crate init, error types, schema layer, data
access, both layout modes (aligned static + packed sequential), TUnion
dispatch, jsonschema custom keyword validators, TypedefEngine integration,
comprehensive tests, and a final review checkpoint.

Validated: 12 tasks, 0 cycles, 7 parallel generations.
This commit is contained in:
deepseek-v4-pro committed 2026-07-21 09:36:30 +00:00
1 parent dd232c3d47
commit db100f9849
12 files changed
+1996

No files matched your search

+145
View File
@@ -0,0 +1,145 @@
---
id: typedef/tunion
name: Implement TUnion discriminator dispatch for byte-offset and field-name discriminators
status: pending
depends_on: [typedef/schema-types, typedef/error-type, typedef/data-access]
scope: narrow
risk: medium
impact: component
level: implementation
---
## Description
Implement TUnion discriminator dispatch in `crates/alknet-typedef/src/tunion.rs`.
TUnion supports two discriminator kinds (ADR-097 §4): byte-offset (protocol dispatch,
e.g., SFTP type bytes) and field-name (typedef.ts string pattern).
Per [data-access.md](../../docs/architecture/crates/typedef/data-access.md) §"TUnion Dispatch"
and [schema-layer.md](../../docs/architecture/crates/typedef/schema-layer.md) §"TUnion discriminators".
### Target shape
```rust
/// The result of reading a TUnion discriminator.
#[derive(Debug, Clone)]
pub struct UnionDispatch {
/// The mapping key (stringified discriminator value).
pub key: String,
/// The byte offset where the variant struct starts.
pub variant_offset: usize,
/// The size of the discriminator in bytes.
pub discriminator_size: usize,
}
/// Read the discriminator value from a byte-offset TUnion.
/// The discriminator is a fixed-size integer at a known byte offset.
/// Returns the mapping key (as a string) and the variant struct offset.
///
/// This is the SFTP `Packet` enum pattern — byte 0 is the type byte,
/// bytes 1..N are the variant struct. The call protocol's event type
/// dispatch uses the same pattern.
pub fn read_byte_discriminator(
buffer: &[u8],
union_schema: &serde_json::Value,
endian: Endian,
) -> Result<UnionDispatch, TypedefError>;
/// Read the discriminator value from a field-name TUnion.
/// The discriminator is a named field within the struct — its offset
/// is computed like any other field. The consumer provides the
/// discriminator field's offset (from the OffsetMap or LayoutBuilder).
///
/// This is the typedef.ts `TUnion` pattern — the discriminator is a
/// field like any other, and the mapping keys are string values.
pub fn read_field_discriminator(
buffer: &[u8],
union_schema: &serde_json::Value,
disc_field_offset: usize,
endian: Endian,
) -> Result<UnionDispatch, TypedefError>;
/// Look up a variant schema from the union's mapping.
/// Returns the variant schema (resolving `$ref` if needed).
pub fn resolve_variant<'a>(
union_schema: &'a serde_json::Value,
key: &str,
) -> Result<&'a serde_json::Value, TypedefError>;
/// Get the discriminator size in bytes for a byte-offset discriminator.
pub fn discriminator_size(union_schema: &serde_json::Value) -> Result<usize, TypedefError>;
```
### Byte-offset discriminator
The discriminator is a fixed-size integer at a known byte offset. The mapping keys
are stringified integers (`"5"`, `"6"`, `"101"`).
Supported discriminator types: `TypeDef:Uint8` (1 byte), `TypeDef:Uint16` (2 bytes),
`TypeDef:Uint32` (4 bytes). The discriminator value is read using the appropriate
endian-aware read function from `data_access`.
The variant struct starts at `offset + discriminator_size`.
### Field-name discriminator
The discriminator is a named field within the struct. Its offset is computed like any
other field (by the `OffsetMap` or `LayoutBuilder`). The mapping keys are string
values matching the discriminator field's value.
The discriminator field's `TypeDef:*` kind determines how to read it:
- `TypeDef:String` → read a length-prefixed string
- `TypeDef:Uint8` → read a u8, stringify
- `TypeDef:Enum` → read a u32 index, map to string value from `"enum"` array
### Variant resolution
`resolve_variant()` looks up the mapping key in the union's `"mapping"` object.
Mapping values may be inline schemas or `$ref` pointers. `$ref` pointers are resolved
against the schema's `$defs` (the `$ref` normalization in `schema.rs` ensures they
are full JSON Pointer paths).
### What this does NOT include
- The offset computation for TUnion (that's in `offset_map.rs` and `layout_builder.rs`)
- The `TypedefEngine` struct (that's `engine.rs`)
## Acceptance Criteria
- [ ] `read_byte_discriminator()` reads discriminator at known byte offset
- [ ] Supports `TypeDef:Uint8`, `TypeDef:Uint16`, `TypeDef:Uint32` discriminator types
- [ ] Discriminator value read with correct endianness
- [ ] Returns mapping key as string (e.g., `"5"` for SFTP Read packet)
- [ ] Returns correct `variant_offset` (offset + discriminator_size)
- [ ] `read_field_discriminator()` reads discriminator from named field at given offset
- [ ] Supports `TypeDef:String`, `TypeDef:Uint8`, `TypeDef:Enum` discriminator field types
- [ ] `resolve_variant()` looks up mapping key and returns variant schema
- [ ] `resolve_variant()` resolves `$ref` pointers to `$defs`
- [ ] `resolve_variant()` returns `TypedefError::Schema` for unknown mapping keys
- [ ] `discriminator_size()` returns correct size for each discriminator type
- [ ] Returns `TypedefError::Access` for buffer-too-short
- [ ] Returns `TypedefError::Schema` for malformed discriminator annotations
- [ ] No `unwrap()` or `expect()` on error paths
- [ ] All public functions have doc comments
- [ ] `cargo check -p alknet-typedef` succeeds
- [ ] `cargo clippy -p alknet-typedef` succeeds with no warnings
- [ ] `cargo build --workspace` still succeeds
## References
- docs/architecture/crates/typedef/data-access.md — TUnion dispatch section
- docs/architecture/crates/typedef/schema-layer.md — TUnion discriminators section
- docs/architecture/decisions/097-schema-annotations.md — ADR-097 §4 (TUnion discriminators)
- /workspace/alknet-typedef-poc/src/lib.rs — POC reference (parse_union_discriminator, read_union_discriminator)
## Notes
> This is a focused module for TUnion discriminator dispatch. The two discriminator
> kinds cover both protocol dispatch (SFTP type bytes, call protocol event types) and
> the typedef.ts string pattern. The mapping keys are always strings — integer
> discriminator values are stringified. The POC 2's `parse_union_discriminator` and
> `read_union_discriminator` functions are good references.
## Summary
> To be filled on completion