5 Commits
Author SHA1 Message Date
glm-5.3-flash e95459c425 feat: alkcall 0.8.0 adoption — bump to 0.5.0
- BREAKING (ecosystem-coordination): alkcall bumped to 0.8.0. No type
  alktty touches changed shape (ChannelCore/openable machinery,
  OpenEstablisher/OpenHandler/Establishment/ChannelPlan,
  ChannelClient::open_channel, ChannelOpenError::CallFailed are
  identical to 0.7.1); the new reply-projection / relay / hub-leg
  surfaces are additive and alktty exercises none of them. alktty's own
  open op is the standard-shape name channels/tty/sub, so the new
  flavor-form discovery path stays on the byte-stable standard
  derivation, and with no establisher reply-fields configured the open
  reply is byte-identical to pre-0.8.0. The minor bump is for
  downstream lockstep, since alktty's public signatures reference
  alkcall types.
- Verification counts unchanged from the 0.7.1 baseline (113 default /
  156 all-features); the adoption required no source change in alktty.

Verification:
- cargo test: 113 passed (default), 156 passed (--all-features)
- cargo clippy --all-targets -- -D warnings: clean
- cargo fmt --check: clean
- cargo doc --no-deps: clean
- cargo check/clippy --target wasm32-unknown-unknown -D warnings: clean
- cargo publish --dry-run --allow-dirty: clean
2026-09-18 13:55:53 +00:00
glm-5.3-flash d14941ffb1 chore: bump to 0.4.1, changelog for the MSRV floor raise (1.85 -> 1.88)
Verification: 113 default / 156 all-features tests on stable (1.94) and
on a real 1.88 toolchain, clippy (all-targets) clean, fmt clean, doc
clean, wasm32 check + clippy clean, publish dry-run OK.
2026-09-10 02:55:11 +00:00
glm-5.3-flash 01e94914c1 chore: raise rust-version floor to 1.88
The 1.85 claim is now false at the dependency level: the lockfile pins
alkcall 0.7.x, and alkcall 0.7.1 raised its MSRV floor to 1.88, so no
1.85 toolchain can resolve this dependency graph regardless of what
Cargo.toml declares. Raising the floor keeps the claim honest and
aligns with the ecosystem floor (noq's 1.88, matching the QUIC path;
iroh sits above at 1.91). alktty's own code is 1.85-clean (verified:
cargo check under 1.85 passes with the pre-bump lockfile) — the raise
is dependency-driven only, so no clippy fixes are needed.

- Cargo.toml: rust-version 1.85 -> 1.88 (version-line bump deferred to
  release time)

Verification:
- 1.88: cargo test --locked (113 default / 156 all-features pass),
  clippy --all-targets -D warnings
- stable 1.94: test --locked, clippy --all-targets -D warnings,
  fmt, doc --no-deps, wasm32-unknown-unknown check + clippy clean
2026-09-10 02:53:33 +00:00
glm-5.3-flash 32809af840 docs: fill changelog version link refs (0.4.0/0.3.0/0.2.0) 2026-09-07 18:07:13 +00:00
glm-5.3-flash 67cf253621 feat: alkcall 0.7.0 adoption (CF-006 identity alignment) — bump to 0.4.0
- BREAKING (ecosystem-coordination): alkcall bumped to 0.7.0. No type
  alktty touches changed shape (OpenEstablisher/OpenHandler/
  Establishment/ChannelPlan identical to 0.6.0); the minor bump is for
  downstream lockstep, since alktty's public signatures reference
  alkcall types.
- CF-006 alignment: the channels establisher and pump handler now take
  their identity from the per-call auth (alkcall 0.7 derives the
  dispatch-resolved opener — the same identity view the registry's ACL
  gate checked) instead of the captured install-time override.
  Behavior-identical in the per-connection-registry deployment; the
  ownership check and the ACL gate see the same subject in every
  deployment. make_tty_establisher / make_tty_open_handler drop their
  captured-identity parameter (both private).

Verification:
- cargo test: 113 passed (default), 156 passed (--all-features)
- cargo clippy --all-targets -- -D warnings: clean
- cargo fmt --check: clean
- cargo doc --no-deps: clean
- cargo check/clippy --target wasm32-unknown-unknown -D warnings: clean
- cargo publish --dry-run --allow-dirty: clean
2026-09-07 17:57:36 +00:00
4 changed files with 115 additions and 26 deletions

No files matched your search

+90
View File
@@ -4,6 +4,91 @@ All notable changes to this crate are documented here. The format is
based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
this crate adheres to [Semantic Versioning](https://semver.org/).
## [0.5.0] - 2026-09-18
The alkcall 0.8.0 adoption: a dependency bump only — no source change
in alktty. alkcall 0.8.0 landed review 008's remediation (the
establisher reply projection, flavor-form open-op ids in discovery, the
in-tree `ChannelRelay` + `HubLegImports`/`HubLegTemplate`) plus a
post-landing hardening sweep; all new surfaces are additive on the
call-plane JSON and the registry seams, and the channels data plane is
untouched. The wire format, the direct-ALPN path, the `TtyBackend`
trait, and alktty's public API surface are unchanged.
### Changed
- **BREAKING (ecosystem-coordination) — `alkcall` bumped to 0.8.0.**
alkcall 0.8.0 changed no type that alktty touches: the open-op
machinery alktty registers through (`ChannelCore`/
`register_openable_with_establisher`/`OpenEstablisher`/`OpenHandler`
/`Establishment`/`ChannelPlan`, `ChannelClient::open_channel`,
`ChannelOpenError::CallFailed`) is shape-identical to 0.7.1 — the
new `open_channel_with_reply` / reply-field / relay / hub-leg
surfaces are additive and alktty exercises none of them. alktty's
own open op is the standard-shape name `channels/tty/sub`, so the
new flavor-form `channel_open_alpn` discovery path stays on the
byte-stable standard derivation, and with no establisher
reply-fields configured the open reply is byte-identical to
pre-0.8.0. alktty's public signatures reference alkcall types, so
downstream crates must now unify on alkcall 0.8.0. Minor bump per
the 0.x ecosystem-coordination rule.
- **`alkcall` requirement updated to `0.8.0`; lockfile bumped from
0.7.1 to 0.8.0.** Verification counts are unchanged from the 0.7.1
baseline (113 default / 156 all-features) — the adoption required no
source change in alktty.
## [0.4.1] - 2026-09-10
The MSRV floor becomes honest: `rust-version` raises from 1.85 to
1.88. The 1.85 claim was already false at the dependency level — the
lockfile pins `alkcall 0.7.x`, and alkcall 0.7.1 raised its MSRV floor
to 1.88 (the ecosystem MSRV audit: noq's 1.88 matching the QUIC path;
iroh sits above at 1.91), so no 1.85 toolchain could build 0.4.0
regardless of what Cargo.toml declares. The raise breaks no downstream
that could build the crate before. No API or wire-format change;
downstreams on caret requirements pick this up on their next `cargo
update`.
### Changed
- **`rust-version` 1.85 → 1.88.** Verified on a real 1.88 toolchain
(full test suite, clippy). alktty's own code is 1.85-clean —
`cargo check` under a 1.85 toolchain passes with the pre-bump
lockfile — so the raise is dependency-driven only and needed no
clippy fixes. Behavior-identical.
- **`alkcall` requirement updated to `0.7.1`; lockfile bumped from
0.7.0 to 0.7.1.** Version-requirement-only (0.7.x is already the
resolved family); alkcall 0.7.1 changed no type alktty touches.
## [0.4.0] - 2026-09-07
The alkcall 0.7.0 adoption (the connect-side caller-identity seam,
CF-005/006/007): a dependency bump plus one behavior-alignment change
on the channels path. The wire format, the direct-ALPN path, the
`TtyBackend` trait, and the public API surface are unchanged.
### Changed
- **BREAKING (ecosystem-coordination) — `alkcall` bumped to 0.7.0.**
alkcall 0.7.0 changed no type that alktty touches
(`OpenEstablisher`/`OpenHandler`/`Establishment`/`ChannelPlan` are
identical to 0.6.0; alktty never constructs `ServingConfig`), but
alktty's public signatures reference alkcall types, so downstream
crates must now unify on alkcall 0.7.0. Minor bump per the 0.x
ecosystem-coordination rule.
- **The channels establisher and pump handler take their identity
from the per-call `auth` (CF-006 alignment).** `register_openable`
no longer captures the install-time identity and overrides the
establisher/handler `auth.identity` with it — post-alkcall-0.7 the
per-call context already carries the dispatch-resolved opener (the
same identity view the registry's ACL gate checked; the end client,
not the hub, on hub-forwarded opens). Behavior-identical in the
per-connection-registry deployment (install-time identity was the
caller's); the ownership check and the ACL gate now see the same
subject in every deployment. Two factory parameters dropped
(`make_tty_establisher`/`make_tty_open_handler` are private; no
public-surface change).
## [0.3.0] - 2026-09-07
The alkcall 0.6.0 adoption (review 007 R-01 — the `Establishment`
@@ -236,4 +321,9 @@ alknet mono-repo.
the client→backend pump is aborted at session end instead of
lingering until the client disconnects.
[0.5.0]: https://git.alk.dev/alkdev/alktty/releases/tag/v0.5.0
[0.4.1]: https://git.alk.dev/alkdev/alktty/releases/tag/v0.4.1
[0.4.0]: https://git.alk.dev/alkdev/alktty/releases/tag/v0.4.0
[0.3.0]: https://git.alk.dev/alkdev/alktty/releases/tag/v0.3.0
[0.2.0]: https://git.alk.dev/alkdev/alktty/releases/tag/v0.2.0
[0.1.0]: https://git.alk.dev/alkdev/alktty/releases/tag/v0.1.0
Generated
+3 -3
View File
@@ -27,9 +27,9 @@ dependencies = [
[[package]]
name = "alkcall"
version = "0.6.0"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a44500900b82904d2a870e444051fc041a042e42ff7190803bbc5b3973f4feeb"
checksum = "8695d47cee5b5a5fe68471f04a505bc257a7e7ed9e64d827de33ff83adf4db12"
dependencies = [
"async-trait",
"bytes",
@@ -48,7 +48,7 @@ dependencies = [
[[package]]
name = "alktty"
version = "0.3.0"
version = "0.5.0"
dependencies = [
"alkcall",
"async-trait",
+3 -3
View File
@@ -1,8 +1,8 @@
[package]
name = "alktty"
version = "0.3.0"
version = "0.5.0"
edition = "2021"
rust-version = "1.85"
rust-version = "1.88"
license = "MIT OR Apache-2.0"
description = "Terminal session protocol: wire format, TtyBackend trait, TtyAdapter, and typed consumer client. Producer/consumer protocol crate on top of alkcall channels."
repository = "https://git.alk.dev/alkdev/alktty"
@@ -25,7 +25,7 @@ default = []
local = ["dep:portable-pty", "dep:tokio-util", "tokio/process", "tokio/rt-multi-thread"]
[dependencies]
alkcall = "0.6.0"
alkcall = "0.8.0"
# Minimal, wasm-clean tokio features. `local` adds `process` +
# `rt-multi-thread` (non-wasm). Do NOT use `features = ["full"]` — it
# pulls in `signal`/`fs`/`net` which break `wasm32-unknown-unknown`.
+19 -20
View File
@@ -98,10 +98,12 @@ pub const TTY_ALPN: &str = "alk/tty";
/// the entry point (here by the registry's `AccessControl`), the
/// ownership check is enforced once at the backend-selection point.
///
/// `auth` is the peer's `AuthContext`, captured at
/// `install_channel_zero` time and closed over by the wrapper so the
/// `TtyOpenHandler` receives it without the wrapper having to reach
/// into `OperationContext` for it (per the ADR-047 §4 amendment).
/// `auth` is the peer's `AuthContext`, the install-time context passed
/// through to `register_openable_with_establisher`. The establisher
/// and pump handler read their identity from the per-call context
/// alkcall derives (alkcall 0.7, CF-006 corollary) — the
/// dispatch-resolved opener, the same view the registry's ACL gate
/// checked.
///
/// # Errors
///
@@ -117,8 +119,8 @@ pub fn register_openable(
auth: AuthContext,
) -> Result<(), String> {
let spec = tty_open_spec();
let establisher = make_tty_establisher(Arc::clone(&backends), ownership, auth.identity.clone());
let open_handler = make_tty_open_handler(backends, auth.identity.clone());
let establisher = make_tty_establisher(Arc::clone(&backends), ownership);
let open_handler = make_tty_open_handler(backends);
core.register_openable_with_establisher(
spec,
Some(establisher),
@@ -239,11 +241,12 @@ pub fn tty_open_spec() -> OperationSpec {
/// returned.
///
/// The `tty:open` scope gate is NOT checked here — the registry's
/// `AccessControl` enforced it before the establisher ran (the
/// identity view the registry checked, resolved from the connection,
/// is the authoritative one; the establisher-side identity is only
/// the ownership-check subject — the same split as the old
/// handler-side check).
/// `AccessControl` enforced it before the establisher ran. The
/// establisher's `auth` is the per-call context (alkcall 0.7, CF-006
/// corollary): its identity is the dispatch-resolved opener — the same
/// identity view the registry's ACL gate checked — and is the
/// ownership-check subject (the same split as the old handler-side
/// check).
///
/// Mapping into the ADR-049 reason vocabulary (no new codes — the
/// vocabulary is alkcall's one-way wire surface):
@@ -275,12 +278,11 @@ pub fn tty_open_spec() -> OperationSpec {
fn make_tty_establisher(
backends: Arc<HashMap<String, Arc<dyn TtyBackend>>>,
ownership: Option<Arc<dyn OwnershipProvider>>,
identity: Option<alkcall::core::auth::Identity>,
) -> OpenEstablisher {
Arc::new(move |input: Value, auth: AuthContext| {
let backends = Arc::clone(&backends);
let ownership = ownership.clone();
let identity = identity.clone().or_else(|| auth.identity.clone());
let identity = auth.identity.clone();
Box::pin(async move {
let req: NegotiateRequest = match serde_json::from_value(input) {
Ok(r) => r,
@@ -388,17 +390,14 @@ impl AllocatedHandle {
///
/// The `tty:open` scope gate is enforced by the registry's `AccessControl`
/// before this handler runs — the handler does not re-check it.
fn make_tty_open_handler(
backends: Arc<HashMap<String, Arc<dyn TtyBackend>>>,
identity: Option<alkcall::core::auth::Identity>,
) -> OpenHandler {
fn make_tty_open_handler(backends: Arc<HashMap<String, Arc<dyn TtyBackend>>>) -> OpenHandler {
Arc::new(
move |input: Value,
plan: Option<ChannelPlan>,
channel_conn: Connection,
auth: AuthContext| {
let backends = Arc::clone(&backends);
let identity = identity.clone().or_else(|| auth.identity.clone());
let identity = auth.identity.clone();
tokio::spawn(async move {
let req: NegotiateRequest = match serde_json::from_value(input) {
@@ -523,7 +522,7 @@ mod tests {
let mut backends: HashMap<String, Arc<dyn TtyBackend>> = HashMap::new();
backends.insert("mock".to_string(), Arc::new(MockBackend::with_exit_code(0)));
let handler = make_tty_open_handler(Arc::new(backends), None);
let handler = make_tty_open_handler(Arc::new(backends));
let task = handler(
serde_json::json!({
@@ -577,7 +576,7 @@ mod tests {
ownership: Option<Arc<dyn OwnershipProvider>>,
input: Value,
) -> Result<Establishment, EstablishmentError> {
let establisher = make_tty_establisher(backends, ownership, None);
let establisher = make_tty_establisher(backends, ownership);
establisher(input, AuthContext::anonymous(b"test")).await
}