phase 4: architecture docs + BAST schema + renumbered ADRs

Port the alknet-tty architecture docs into alktty and add the BAST
document for the alk/tty wire format. Docs-only; no Rust source
changes.

Spec docs (docs/architecture/, flat layout — single-crate repo):
- overview.md — crate purpose, two-carriage model, deps, ALPN,
  backend location map, feature gates
- tty-wire.md — 5-byte chunk codec, control channel split
  (STREAM_CTRL_IN=3 / STREAM_CTRL_OUT=4), sentinels
- tty-backend.md — TtyBackend trait, TtyHandle, TtyControl,
  REQ-TTY-01 (backends need not be natively async)
- tty-adapter.md — TtyAdapter, three-pump driver, exit-chunk
  ordering (ADR-004), cancel cleanup (ADR-005), access control
- tty-local.md — LocalTtyBackend (local feature module), PTY +
  pipe modes, REQ-TTY-02 (signal forwarding to process group)
- README.md — architecture index

ADRs (docs/architecture/decisions/, renumbered 001..008 from
alknet 052,053,054,055,056,057,077,093 in order):
- 001 wire format + two-carriage model (incl. Phase 7 control-
  channel split amendment)
- 002 TtyBackend trait + TtyHandle
- 003 local backend placement (records both the alknet sibling-
  crate decision and the alktty single-crate consolidation behind
  a local feature)
- 004 exit code on a control chunk
- 005 backend cleanup on session cancel
- 006 self-contained negotiation framing
- 007 tty inside channels (reversed by 008; kept for historical
  context with reversal notice)
- 008 channels pure channel multiplexing (reverses 007; TTY
  always uses its 5-byte format)

BAST document (docs/architecture/tty-bast.md):
- Normative JSON spec for the alk/tty wire format, conforming to
  the BAST meta-schema at https://alk.dev/bast/v1/schema
- 5-byte chunk header (struct, big-endian: stream_type uint8,
  length uint32) + StreamType enum (Stdin=0..CtrlOut=4)
- ControlMessage union (field-name discriminator on type:
  resize/signal/eof/exit) with documented deviation that on-wire
  control payloads are UTF-8 JSON, not BAST's binary union
  encoding
- NegotiationFrame (4-byte BE length + UTF-8 JSON body) +
  NegotiateRequest / TerminalParams JSON shapes
- StreamType enum deviation noted: on-wire uint8, not BAST's
  standard u32 enum index (chunk header is 5 bytes, not 8)
- alktty does not depend on alktype; the hand-rolled wire.rs is
  the runtime codec, the BAST is the human-readable contract

AGENTS.md: fixed the ADR mapping table to match the plan's 8-to-8
mapping (the previous table substituted ADR-050 for 054, relabeled
056 as control-message split, dropped 077, and added a new
control-split ADR at 006 — inconsistent with both the plan and the
prose). ADR-050 (dynamic resource ownership) is an alkcall/alknet-
core ADR, not tty-specific, and is not ported; the Phase 7 control
split stays as an amendment inside ADR-001, mirroring alknet.

Verification (all pass, no Rust source changed):
- cargo test (80 passed)
- cargo test --all-features (103 passed)
- cargo clippy --all-targets -- -D warnings (clean)
- cargo fmt --check (clean)
- cargo check --target wasm32-unknown-unknown (clean)
- cargo clippy --target wasm32-unknown-unknown -- -D warnings
  (clean)
- cargo doc --no-deps: 9 pre-existing intra-doc-link warnings in
  src/session.rs and src/channels.rs (untouched by this commit;
  not introduced here)
- BAST JSON parses; StreamType indices match wire.rs constants
  (0=Stdin..4=CtrlOut)
- all markdown cross-reference links resolve
This commit is contained in:
2026-08-17 10:52:26 +00:00
parent 712e7ae071
commit b3f50d1836
17 changed files with 5165 additions and 46 deletions
+63 -17
View File
@@ -1,6 +1,8 @@
# Project Setup Plan
Status: draft (revised 2026-08-17 to reflect landed upstream changes)
Status: draft (revised 2026-08-17 to reflect landed upstream changes;
Phase 4 landed 2026-08-17 — architecture docs + BAST schema +
renumbered ADRs)
Last updated: 2026-08-17
## Overview
@@ -415,32 +417,76 @@ operation spec — the registry runs the ACL before the wrapper, so the
`local` feature in `src/lib.rs`:
`#[cfg(feature = "local")] pub mod local;`
### Phase 4: Architecture docs + BAST schema
### Phase 4: Architecture docs + BAST schema — landed 2026-08-17
1. Port the 5 spec docs from `alknet/docs/architecture/crates/tty/`
1. Ported the 5 spec docs from `alknet/docs/architecture/crates/tty/`
into `docs/architecture/` (flat layout, not the `crates/tty/`
subpath — this is a single-crate repo now):
`tty-wire.md`, `tty-backend.md`, `tty-adapter.md`, `tty-local.md`,
plus an `overview.md` index.
2. Port relevant ADRs (052, 053, 054, 055, 056, 057, 077, 093) —
renumber into alktty's ADR range (001..008), update cross-references
(`alknet/tty` → `alk/tty`, `alknet-tty-local` → `alktty`'s `local`
feature, `alknet-core` → `alkcall::core`).
3. Write `docs/architecture/tty-bast.md` — the BAST JSON document for
the `alk/tty` wire format. Covers:
`overview.md` (the crate overview; the alknet `README.md` index is
ported as `docs/architecture/README.md`), `tty-wire.md`,
`tty-backend.md`, `tty-adapter.md`, `tty-local.md`. Each is renamed
`alknet-tty` → `alktty`, `alknet/tty` → `alk/tty`, `alknet-core` →
`alkcall::core`, `alknet-call` → `alkcall`, `alknet-tty-local`
alktty's `local` feature module, and cross-references to alknet
ADRs are renumbered to alktty's ADR range (001..008).
2. Ported the 8 alknet ADRs (052, 053, 054, 055, 056, 057, 077, 093)
into `docs/architecture/decisions/` renumbered 001..008 in order:
- [001](../architecture/decisions/001-wire-format-and-two-carriage.md)
← alknet ADR-052 — wire format + two-carriage model (incl. the
Phase 7 control-channel split amendment)
- [002](../architecture/decisions/002-ttybackend-trait-and-ttyhandle.md)
← alknet ADR-053 — `TtyBackend` trait + `TtyHandle`
- [003](../architecture/decisions/003-local-backend-placement.md)
← alknet ADR-054 — local backend placement (records both the
alknet sibling-crate decision and the alktty single-crate
consolidation behind a `local` feature)
- [004](../architecture/decisions/004-exit-code-on-control-chunk.md)
← alknet ADR-055 — exit code on a control chunk
- [005](../architecture/decisions/005-backend-cleanup-on-session-cancel.md)
← alknet ADR-056 — backend cleanup on session cancel
- [006](../architecture/decisions/006-negotiation-framing-self-contained.md)
← alknet ADR-057 — self-contained negotiation framing
- [007](../architecture/decisions/007-tty-inside-channels.md)
← alknet ADR-077 — TTY inside channels (reversed by 008; kept for
historical context with its reversal notice pointing to 008)
- [008](../architecture/decisions/008-channels-pure-channel-multiplexing.md)
← alknet ADR-093 — channels pure channel multiplexing (reverses
007; TTY always uses its 5-byte format)
3. Wrote
[`docs/architecture/tty-bast.md`](../architecture/tty-bast.md) —
the BAST (Binary Abstract Syntax Tree) document for the `alk/tty`
wire format. Conforms to the BAST meta-schema at
`https://alk.dev/bast/v1/schema`; validatable by any JSON Schema
Draft 2020-12 validator. Covers:
- The 5-byte chunk header (`struct` with `endian: "big"`:
`stream_type: uint8`, `length: uint32`).
- The four stream-type channels as an `enum` (`Stdin=0`,
- The five stream-type channels as an `enum` (`Stdin=0`,
`Stdout=1`, `Stderr=2`, `CtrlIn=3`, `CtrlOut=4`).
- The control-message `union` (field-name discriminator on `type`:
`resize`, `signal`, `eof`, `exit`).
`resize`, `signal`, `eof`, `exit`) with the documented deviation
that on-wire control payloads are UTF-8 JSON, not BAST's binary
union encoding.
- The negotiation frame as a separate `struct` (4-byte BE length
prefix + UTF-8 JSON `NegotiateRequest` body) — annotated as
out-of-band for the chunk codec but documented for completeness.
- Conforms to the BAST meta-schema at
`https://alk.dev/bast/v1/schema`; validatable by any JSON Schema
Draft 2020-12 validator.
4. Write `docs/architecture/README.md` index.
- The `StreamType` enum's documented deviation: on-wire encoding is
`uint8` (1 byte), not BAST's standard `u32` enum index (4 bytes)
— the chunk header is 5 bytes, not 8.
4. Wrote [`docs/architecture/README.md`](../architecture/README.md) —
the architecture index: documents table, ADR table (with alknet
origin numbers and port status), key design principles, open
questions, and references.
The ADR mapping follows the plan's 8-to-8 list (ADR-052→001, 053→002,
054→003, 055→004, 056→005, 057→006, 077→007, 093→008). ADR-050
(dynamic resource ownership) is an alkcall/alknet-core ADR, not
tty-specific, and is not ported into alktty's ADR range; the
access-control work that declares against the ADR-050 model is
described in `tty-adapter.md` and the ADR-001/002 ported docs, which
reference ADR-050 by its alknet number. The Phase 7 control-channel
split (`STREAM_CTRL_IN` = 3, `STREAM_CTRL_OUT` = 4) is an amendment
inside ADR-001, mirroring alknet (it was not a standalone ADR there
either). `AGENTS.md` was updated to match this mapping.
### Phase 5: Tests