- Rewrote em dash prose across the whole tree outside docs/reviews/ (the historical reviews stay verbatim, matching the alktunnels and alktty precedent): src doc comments and inline comments (587), docs/architecture (319), docs/research + sdd_process (484), tests (361), tasks (899), fuzz (28), README/CHANGELOG/Cargo.toml (77), AGENTS.md (85), and the .opencode/agents prompts (109) - Fenced content follows the precedent: comments, ASCII-diagram label separators, and template placeholders rewritten; wire data, JSON/BAST documents, byte diagrams, and transcripts survive verbatim; assert, expect, panic, error-display, and format message literals rewritten as prose; no code, fixture, or test data change - src/rfc1928/LICENSE: the two dashes in alksocks' own provenance header rewritten; the MIT legal text untouched - AGENTS.md adds Project Convention 18: no em dashes in prose; varied restructure, no spaced-hyphen substitutes, fenced prose rule, en dash numeric ranges exempt, docs/reviews/ exempt from the greps - tasks/*.md frontmatter: the name values rewritten by the sweep are now quoted (a raw colon inside an unquoted YAML scalar parsed as null); taskgraph validate reports 37 tasks, no issues Verification: cargo test; cargo clippy --all-targets -D warnings; cargo fmt --check; cargo doc --no-deps; fuzz corpus replay (cargo test --manifest-path fuzz/shared/Cargo.toml); wasm check and clippy for wasm32-unknown-unknown with -D warnings; em dash grep over the repo returns matches only in docs/reviews/ and the bast.md BAST JSON data fence
203 lines
11 KiB
Markdown
203 lines
11 KiB
Markdown
---
|
|
id: implementation/assembly-integration-suite
|
|
name: "Assembly: the cross-cutting integration suite + docs sync"
|
|
status: completed
|
|
depends_on: [implementation/door-udp, implementation/local-backend-producer, implementation/composed-accept]
|
|
scope: moderate
|
|
risk: medium
|
|
impact: phase
|
|
level: implementation
|
|
---
|
|
|
|
## Description
|
|
|
|
The batch-2 closing task (the core-integration-suite's assembly-layer
|
|
analogue): the cross-cutting suite that pins the whole assembly
|
|
story, plus the docs sync that records what landed. The per-component
|
|
tasks own their verticals; this task owns the compositions and the
|
|
spec-vs-implementation reconciliation.
|
|
|
|
Deliverables:
|
|
|
|
1. **Cross-cutting integration tests** (`tests/assembly-integration.rs`):
|
|
- **The full `-D` story end to end**: a vanilla tun2proxy-shaped
|
|
client → the cred-bearing TCP door → the channels-native
|
|
session → the producer with `local` providers → real echo
|
|
targets: CONNECT + UDP (the RFC-header'd datagram through the
|
|
UDP door) + BIND (the vanilla BIND conversation through the
|
|
door) all through one door process against one producer
|
|
registration (the one-registration-three-commands regression,
|
|
now through the doors).
|
|
- **The composed story end to end**: the producer with
|
|
`composed::direct_egress` + `composed::bindfirst_accept`:
|
|
CONNECT through the direct op, ASSOCIATE through the lazy
|
|
table, BIND through the bind-first listener (the ADR-008
|
|
composed variant set, all three commands).
|
|
- **Mixed assembly**: one producer registration serving
|
|
channels-native sessions AND door clients AND composed seams
|
|
concurrently (the producer/consumer-roles-not-sides posture;
|
|
both shapes on one connection).
|
|
- **Teardown matrix, assembly edition**: door-client disconnect
|
|
tears the association/channel down (no leaks; the channel
|
|
count witnesses); the idle bounds fire; fresh sessions succeed
|
|
immediately after each teardown (no connection poisoning).
|
|
- **The wasm gates re-verified**: default + `--features composed`
|
|
wasm checks green (the `local` feature is non-wasm by design;
|
|
verify it *fails* to build on wasm, the alktty posture, and
|
|
record the observed error in Notes).
|
|
2. **Docs sync** (the architecture-sync check):
|
|
- `docs/architecture/README.md` Current State + the doc statuses
|
|
reflect the landed assembly layer (the "no `local`/`composed`
|
|
code exists yet" lines updated).
|
|
- `lib.rs` crate docs updated (the "not yet present" paragraph;
|
|
the doors/providers are landed now).
|
|
- Any spec drift the implementation surfaced reconciled in the
|
|
same change, never silently diverged (the batch-1 discipline).
|
|
3. **Full verification sweep** (the batch gate's input):
|
|
`cargo test`, `cargo test --all-features`, clippy
|
|
`--all-targets --all-features -- -D warnings`, `cargo fmt
|
|
--check`, both wasm checks (default + composed), and `cargo doc
|
|
--no-deps` (docs changed).
|
|
|
|
## Acceptance Criteria
|
|
|
|
- [x] The full `-D` story (vanilla client → door → session →
|
|
producer → real target) pinned end to end for all three
|
|
commands
|
|
- [x] The composed variant set pinned end to end (all three commands)
|
|
- [x] Mixed assembly (doors + channels-native + composed) concurrent
|
|
on one producer (pinned)
|
|
- [x] The assembly teardown matrix pinned (door disconnects, idle
|
|
bounds, fresh-session-after-teardown)
|
|
- [x] All four verification targets green (default, all-features,
|
|
wasm default, wasm composed)
|
|
- [x] Docs synced (README Current State, lib.rs crate docs, any
|
|
drift reconciled)
|
|
|
|
## References
|
|
|
|
- docs/architecture/overview.md (the feature gates + module map;
|
|
the landed-shape check), consumer.md §The Front Doors, producer.md
|
|
§Producer-Side Local Backend, §Wiring
|
|
- docs/architecture/decisions/005/007/008/009/014
|
|
- The batch-1 precedent: `tests/core-integration.rs` (the suite
|
|
shape), `tasks/implementation/core-integration-suite.md` (the
|
|
task shape)
|
|
|
|
## Notes
|
|
|
|
> Filled by the implementation agent (2026-09-25).
|
|
|
|
- **The spec drift the implementation surfaced (one real drift,
|
|
reconciled in `src/composed/mod.rs`):** `ComposedEgress::next_reply`
|
|
returned the association-end `Err` ("all tunnel relays ended") on a
|
|
*fresh* association too: the lazy table starts with `live_relays ==
|
|
0`, so the producer's datagram stage (which parks on `next_reply`
|
|
when no datagram has arrived) ended every quiescent association at
|
|
birth. The composed-egress suite drove the egress send-first and
|
|
never hit it; the assembly suite's `AssociateSession` (open → the
|
|
stage parks → the first datagram) did. Fix: an `ever_opened` flag;
|
|
the ended-relay `Err` fires only once at least one tunnel existed
|
|
and every relay has ended; a never-opened table parks (the readiness
|
|
contract's `Pending`, the channel branch governs). The landed spec
|
|
wording (producer.md: "`Pending` when nothing is ready") already
|
|
stated the correct contract; the implementation was the divergent
|
|
side. Regression-pinned in `tests/composed-egress.rs`
|
|
(`fresh_association_parks_before_any_tunnel_is_opened`).
|
|
- **Two assembly-shape findings recorded in the tests (not code
|
|
changes; the landed contracts are correct):**
|
|
- The cred-bearing door's `TokenClient::wrap` takes the client's
|
|
channel-0 `CallConnection` once (the door-only contract,
|
|
door-tcp's Notes); the UDP door's association (and any other
|
|
consumption shape) rides its own channels connection to the same
|
|
producer registration. The suite pins the assembly story as "one
|
|
registration, many connections" (consumer.md reconciled).
|
|
- The RFC conversation is **one command per connection** at every
|
|
door shape (the cred-bearing TCP door's RFC half consumes the
|
|
greeting + one command; the producer-side `ProducerDoor`'s
|
|
`serve_socks5_over` likewise serves one command per accepted
|
|
socket; a second command's bytes ride the first session's data
|
|
plane). The vanilla one-command-per-connection shape is pinned by
|
|
the suite's structure (each command opens its own door
|
|
connection).
|
|
- **Harness consolidation (review 002 N-5's discipline):** the
|
|
composed-accept machinery the assembly suite also consumes (the
|
|
test bind, the accept queue + loop, the channel-set probe, the
|
|
identities) moved from `tests/composed-accept.rs` into
|
|
`tests/harness.rs` (single-sourced; `composed-accept.rs` consumes
|
|
the same shapes via the harness re-exports (its test bodies are
|
|
unchanged in behavior). The five-gate composed identity
|
|
(`composed_full_opener_identity`: `tunnel:open` + `tunnel:direct`
|
|
+ `tunnel:forwarded` + `socks5:open` + `socks5:bind`) is new.
|
|
- **The wasm gate, observed**: `cargo check --features local --target
|
|
wasm32-unknown-unknown` fails as designed (the alktty posture);
|
|
the first error is `error: This wasm target is unsupported by mio.
|
|
If using Tokio, disable the net feature.` (mio v1.2.3, via
|
|
`tokio/net` which `local` enables), followed by the mio `sys`
|
|
module's unresolved imports (`crate::sys::IoSourceState`,
|
|
`crate::sys::tcp`, `Selector`, `event`). Both default and
|
|
`--features composed` wasm checks are green.
|
|
- **The `-D` story's door wiring**: the cred-bearing TCP door + the
|
|
UDP door each take their own `ChannelClient` (two connections to
|
|
the one registration); the tests' `DoorTokenProvider` resolves the
|
|
mapped `door-`-prefixed identity ids (the same producer-side
|
|
resolution policy shape the door-tcp suite pins). The producer-door
|
|
test drives the producer's own front door (`ProducerDoor` →
|
|
`serve_socks5_over` over the `local` provider set) through all
|
|
three commands.
|
|
|
|
## Summary
|
|
|
|
> Filled on completion (2026-09-25).
|
|
|
|
Landed the batch-2 closing task: `tests/assembly-integration.rs`,
|
|
seven cross-cutting integration tests pinning the whole assembly layer
|
|
end to end (feature `local` + `composed`):
|
|
|
|
1. **The full `-D` story** (`full_dash_d_story_...`): a vanilla
|
|
tun2proxy-shaped client through the cred-bearing RFC 1929 TCP door
|
|
+ the UDP door against one producer registration with the `local`
|
|
providers and real echo targets: CONNECT + BIND (the app server
|
|
dials the advertised address; reply#2 carries the real peer) +
|
|
ASSOCIATE (the RFC-header'd datagram through the relay socket)
|
|
live simultaneously, each exercised mid-life of the others, the
|
|
door-client disconnect ending only its own sessions, fresh
|
|
sessions succeeding after (no connection poisoning).
|
|
2. **The composed story** (`composed_story_...`): the producer with
|
|
`composed::direct_egress` + `composed::bindfirst_accept` + a real
|
|
TCP dial: CONNECT, ASSOCIATE (the lazy table; the direct-op dial
|
|
count witnesses the lazy open), BIND (the real `bound` + the real
|
|
`peer` + the pass-through plane); all three commands, all live.
|
|
3. **Mixed assembly, twice**: channels-native sessions + door clients
|
|
concurrent on one registration (the doors on their own
|
|
connections), and composed seams beside channels-native sessions
|
|
(the composed suite's producer; teardowns end only their own
|
|
sessions; the channel-set probe after the settle).
|
|
4. **The teardown matrix, assembly edition**: the UDP door's idle
|
|
bound fires on the vanished door client, the association's channel
|
|
reaps (the channel count witnesses), a fresh association succeeds
|
|
immediately (no connection poisoning).
|
|
5. **The producer's own front door** (`ProducerDoor`) drives all
|
|
three commands through one door + one registration (the `-D`
|
|
story's other half; the faithful-RFC BIND variant).
|
|
6. **The `-D` domain-target pin**: a domain-form CONNECT through the
|
|
NoAuth raw-pipe door resolves at the producer's seam (ADR-012).
|
|
|
|
The reconciled drift: `ComposedEgress`'s never-opened-table association
|
|
end (fixed in `src/composed/mod.rs`, the `ever_opened` guard;
|
|
regression-pinned in `tests/composed-egress.rs`). Docs synced:
|
|
`README.md` Current State (the assembly layer landed; both suites
|
|
named), `lib.rs` crate docs (the assembly-layer paragraph + both
|
|
suites named), `consumer.md` §Door variants (the `TokenClient`
|
|
door-only contract + one-command-per-connection posture reconciled,
|
|
the drift the suite surfaced, recorded in Notes). Harness: the
|
|
composed-accept machinery single-sourced into `tests/harness.rs` (the
|
|
N-5 discipline).
|
|
|
|
Verification: `cargo test` (375 green across 12 targets), `cargo test
|
|
--all-features` (615 green), `cargo clippy --all-targets -- -D
|
|
warnings` + `cargo clippy --all-targets --all-features -- -D warnings`
|
|
clean, `cargo fmt --check` clean, `cargo doc --no-deps` clean (0
|
|
warnings), both wasm checks green (default + `--features composed`,
|
|
check + clippy), and the `local`-on-wasm build failure observed +
|
|
recorded (the alktty posture: mio's unsupported-wasm error). |