Step 9 (convert tests to BAST format) was a no-op: steps 4-8 converted
the tests as they went. The only remaining reference in
src/tests was the intentional rejection test at
src/schema.rs:462 (asserting the old keyword form is rejected). Full
suite passes: 389 tests (312 lib + 77 integration).
Step 10 (sync architecture docs and ADRs):
Descriptive docs rewritten/updated for BAST:
- schema-layer.md: rewritten for the BAST parser (BastDoc/BastDef/
BastType typed tree, AlkTypeKind enum with to_bast_str/from_bast_str,
what was removed). Points at bast-format.md for the normative format.
- validation.md: rewritten for the two-validator model
(bast_validation for validate_bytes, standard jsonschema for
validate_json). Documents the repurposed build_validator, the
AlkTypeError::Validation uniform payload (D-BAST-009), and what is
removed.
- builder.md: updated all output examples to BAST JSON
(struct_() -> { kind: struct, fields: [...] }; object() -> standard
JSON Schema). Documents build_doc, count(), and the field-name union
fields requirement (D-BAST-005).
- overview.md: updated for BAST (what/why, schema-is-the-format table,
dependencies, architecture pointers, design decisions table).
- README.md (architecture index): updated document table, ADR table
(new ADR-BAST + ADR-VAL-SPLIT, superseded ADR-001), OQ table
(OQ-007/OQ-008 resolutions updated for BAST-native validator), and
key design principles (#1, #2, #7, #10 reworded for BAST).
- data-access.md: updated tunion function signatures to BastUnion and
the variant resolution to return BastType (resolve_typeref for refs).
- layout-engine.md: updated construct signatures
(LayoutBuilder::new(bast_doc, root_name), OffsetMap::compute(&doc),
SequentialReader::new(bast_doc, root_name)), the recursive-walk
description (BAST typed tree), and composite-kind headings
(TStruct/TUnion/TArray -> struct/union/array). Added D-BAST-004
note on array count requirement.
New ADRs:
- ADR-BAST (bast-bast-format.md): the BAST format, meta-schema,
//kind vocabulary, design principles, what is removed, the
enum index bounds bug fix. Supersedes ADR-001's format-specific
content; records D-BAST-001..009.
- ADR-VAL-SPLIT (val-split-two-validator-model.md): the two-validator
model (BAST-native for validate_bytes, standard jsonschema for
validate_json), the repurposed build_validator, the uniform
AlkTypeError::Validation payload. Refines ADR-004's validation
strategy and ADR-010's validation step; records D-BAST-006/007/009.
Amended ADRs (supersession/amendment notes added; original decision
text preserved as historical record):
- ADR-001: format-specific content superseded by ADR-BAST;
purpose/scope and schema-is-the-format principle retained.
- ADR-002: unchanged under the pivot; one-line note that the input
format changed but the modes didn't.
- ADR-003: annotation semantics retained; annotation location moved
to BAST type-level properties (amended by ADR-BAST).
- ADR-004: AlkTypeError enum retained (D-BAST-009); validation
strategy section refined by ADR-VAL-SPLIT.
- ADR-009: builder API surface retained; build() output format
amended to BAST / standard JSON Schema by ADR-BAST (D-BAST-008).
- ADR-010: validate_bytes two-step concept retained; validation step
amended to the BAST-native validator by ADR-VAL-SPLIT.
Other:
- Cargo.toml description: JSON Schema with AlkType:* custom keywords
-> BAST document.
- bast-pivot.md research record: status draft -> implemented, with a
pointer to the ADRs that superseded its decisions.
- bast-implementation.md plan: status draft -> complete, with a note
that step 9 was a no-op and step 10 is this commit.
- open-questions.md: OQ-006/OQ-007/OQ-008 resolutions updated for the
BAST-native validator.
- questions/008-unionvalidator-variant-dispatch.md: added a
post-BAST-pivot note pointing to the current bast_validation
implementation; v0.1.0 resolution text preserved as historical
record.
Verification:
- cargo test --release: 389 pass (312 lib + 77 integration)
- cargo clippy --all-targets -- -D warnings: clean
- cargo doc --no-deps: clean
- cross-reference check: every relative link in the new/updated docs
resolves (verified by script).
9.7 KiB
status, last_updated
| status | last_updated |
|---|---|
| draft | 2026-08-11 |
Open Questions
Each open question lives in its own file under questions/,
named NNN-slug.md (mirroring the ADR convention). This file is the index:
theme-grouped tables for scannability, plus a cross-theme
Open section (active investigation targets) and a
Deferred / Blocked section that surfaces the
safe-exit deferrals with their blocking conditions inline — so "what's
currently on the architect's desk" and "what's currently parked and why"
are each answerable at a glance.
Status values:
open— Needs to be resolved now. Has a clear path to resolution.resolved— Decided. The resolution is stated cleanly, without caveats about how it could be changed later.deferred(scope)— Cannot be resolved yet. The information is genuinely missing — a crate spec, POC result, or use case that doesn't exist yet. Has a concrete blocking condition. Not a failure — scope management.deferred(unclear)— Cannot be resolved yet. The pieces exist (decided in other ADRs, existing types, existing patterns) but the composition — how they fit together — isn't clear yet. Resolution requires investigation (work through examples, maybe POC), not waiting. Has a concrete investigation target and an impacts field. Not a failure — honest uncertainty in a poorly-defined problem space.partially resolved— Some aspects decided, others deferred or open.dissolved— The question was reframed out of existence (e.g., superseded by an ADR that retires the premise). Kept for reference.
Impacts field: Every unresolved OQ (open, deferred(scope),
deferred(unclear), partially resolved) should have an Impacts
field stating what it blocks downstream. Be specific: "blocks the first
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 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.
Door type is separate from whether a decision is made. A two-way door is a decision you make now and can revert later, not a decision to defer.
By Theme
Layout Engine
| OQ | Title | Status | Door | Pri |
|---|---|---|---|---|
| OQ-001 | Arrays of Variable-Length-Element Structs | deferred(scope) | two | low |
Platform Support
| OQ | Title | Status | Door | Pri |
|---|---|---|---|---|
| OQ-002 | no_std + alloc Support |
deferred(scope) | two | low |
Schema Construction
| OQ | Title | Status | Door | Pri |
|---|---|---|---|---|
| OQ-003 | Builder API for Schema Construction | resolved (ADR-009) | two | med |
| OQ-004 | Discriminator::Field name — &str or String |
resolved | two | low |
| OQ-006 | Builder spec Example 3 — wrap Union in a Struct |
resolved | two | low |
Validation
| OQ | Title | Status | Door | Pri |
|---|---|---|---|---|
| OQ-005 | Union materialization shape — byte-offset vs field-name consistency |
resolved | two | med |
| OQ-007 | Bytes materialization — lossy UTF-8 conversion |
resolved | one | med |
| OQ-008 | UnionValidator variant dispatch |
resolved | one | med |
Open
Active investigation targets — questions with a clear path to resolution that need to be worked through, not waited on. Each has a concrete investigation target. This section exists so "what's currently on the architect's desk" is answerable at a glance.
Note
: All v0.1.0 open questions (OQ-004, OQ-005, OQ-006, OQ-007, OQ-008) were resolved during the v0.1.0 POC round 2 (SFTP Packet
validate_bytesPOC). The resolutions are summarized below for traceability; see each OQ's full file for the decision rationale. The currently-parked OQs are OQ-001 and OQ-002 (see Deferred / Blocked below).
OQ-004: Discriminator::Field name — &str or String — RESOLVED
- Status: resolved.
String, for ownership simplicity (the builder consumesSelfon setters;&strwould require a lifetime parameter onDiscriminatorand transitively onSchema::union_). Implemented insrc/builder.rssince the initial v0.1.0 builder implementation. - Full file: OQ-004
OQ-005: Union materialization shape — RESOLVED
- Status: resolved. Both discriminator kinds return
{ "__discriminator": <value>, ...variant-fields }. The field-name path also had a real offset bug (returned start offset, not end) — fixed. Implemented insrc/materialize.rs. - Full file: OQ-005
OQ-006: Builder spec Example 3 — wrap Union in a Struct — RESOLVED
- Status: resolved. builder.md Example 3 now wraps
the
Unionin aSchema::struct_().field("payload", ...)and builds a complete BAST document viaDefinitions::build_doc. Matches the realistic SFTP wire shape and the engine's struct-at-root constraint (the root$defsentry must be astruct). - Full file: OQ-006
OQ-007: Bytes materialization — lossy UTF-8 conversion — RESOLVED
- Status: resolved. Array of u8: the materializer produces
Value::ArrayofValue::Number(one entry per byte, 0..=255) forbytesfields. The BAST-native validator (bast_validation::check_bytes) accepts bothValue::String(forvalidate_json-style inputs) andValue::Array(forvalidate_bytes).maxLength= max byte count. Implemented insrc/materialize.rsandsrc/bast_validation.rs. - Full file: OQ-007
OQ-008: UnionValidator variant dispatch — RESOLVED
- Status: resolved. Under the BAST pivot, the BAST-native validator
(
bast_validation::validate_union) reads__discriminator, looks up the variantBastTypein the union'smapping, and recurses into the variant's BAST definition viavalidate_typeref— enforcing every field constraint the variant declares (e.g.maxLengthon abytesfield inside a variant struct). Variant$refs resolve lazily viaBastDoc::resolve_typeref— noinline_union_variant_refscompile step (removed under BAST). No custom keywords, nojsonschemainvolvement on the bytes path. Implemented insrc/bast_validation.rsandsrc/bast.rs. See ADR-VAL-SPLIT. - Full file: OQ-008
Deferred / Blocked
The safe-exit visibility surface. These questions are parked because the information needed to resolve them does not exist yet — each has a concrete 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.
Note
: OQ-003 (Builder API) was resolved by ADR-009 in v0.1.0 and is retained below for traceability — it's marked RESOLVED, not deferred. The currently-parked OQs are OQ-001 and OQ-002.
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
(
[fixed_0][str_0][fixed_1][str_1]...) and the engine must walk sequentially rather than use a fixed stride. The SFTPNamepacket hasVec<File>whereFilecontains strings, but SFTP serializes this as a sequence of length-prefixed strings (the serdeSeqAccesspattern), not as an array of fixed-stride structs. Arrays of fixed-size structs are fully supported. - Priority: low
- Full file: OQ-001
OQ-002: no_std + alloc Support
- Blocked on: An embedded use case that requires
no_std+alloc(e.g., a microcontroller running Rust withoutstd). The WASM target hasstdavailable viawasm-bindgen. The engine's core (offset computation, read/write) is already allocation-free; thejsonschemadependency is the onlyallocconsumer. - Priority: low
- Full file: OQ-002
OQ-003: Builder API for Schema Construction — RESOLVED
- Status: resolved by ADR-009 in v0.1.0.
- Unblocking condition: alkcall — the merged
alknet-call+alknet-channelsextraction from@alkdev/alknet— is the concrete consumer that needs programmatic schema construction in Rust. It builds both binary-layout schemas (channels' 8-byte chunk header) and JSON payload schemas (OperationSpecinput/output/error schemas) at runtime. - Resolution: A fluent Rust builder producing
serde_json::Value, covering AlkType kinds and standard JSON Schema. Implemented insrc/builder.rs; spec in builder.md. See ADR-009. - Full file: OQ-003