- 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
11 KiB
id, name, status, depends_on, scope, risk, impact, level
| id | name | status | depends_on | scope | risk | impact | level | |||
|---|---|---|---|---|---|---|---|---|---|---|
| implementation/assembly-integration-suite | Assembly: the cross-cutting integration suite + docs sync | completed |
|
moderate | medium | phase | 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:
- Cross-cutting integration tests (
tests/assembly-integration.rs):- The full
-Dstory end to end: a vanilla tun2proxy-shaped client → the cred-bearing TCP door → the channels-native session → the producer withlocalproviders → 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 composedwasm checks green (thelocalfeature is non-wasm by design; verify it fails to build on wasm, the alktty posture, and record the observed error in Notes).
- The full
- Docs sync (the architecture-sync check):
docs/architecture/README.mdCurrent State + the doc statuses reflect the landed assembly layer (the "nolocal/composedcode exists yet" lines updated).lib.rscrate 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).
- 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), andcargo doc --no-deps(docs changed).
Acceptance Criteria
- The full
-Dstory (vanilla client → door → session → producer → real target) pinned end to end for all three commands - The composed variant set pinned end to end (all three commands)
- Mixed assembly (doors + channels-native + composed) concurrent on one producer (pinned)
- The assembly teardown matrix pinned (door disconnects, idle bounds, fresh-session-after-teardown)
- All four verification targets green (default, all-features, wasm default, wasm composed)
- 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_replyreturned the association-endErr("all tunnel relays ended") on a fresh association too: the lazy table starts withlive_relays == 0, so the producer's datagram stage (which parks onnext_replywhen 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'sAssociateSession(open → the stage parks → the first datagram) did. Fix: anever_openedflag; the ended-relayErrfires only once at least one tunnel existed and every relay has ended; a never-opened table parks (the readiness contract'sPending, the channel branch governs). The landed spec wording (producer.md: "Pendingwhen nothing is ready") already stated the correct contract; the implementation was the divergent side. Regression-pinned intests/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::wraptakes the client's channel-0CallConnectiononce (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'sserve_socks5_overlikewise 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).
- The cred-bearing door's
- 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.rsintotests/harness.rs(single-sourced;composed-accept.rsconsumes 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:directtunnel:forwarded+socks5:open+socks5:bind) is new.
- The wasm gate, observed:
cargo check --features local --target wasm32-unknown-unknownfails as designed (the alktty posture); the first error iserror: This wasm target is unsupported by mio. If using Tokio, disable the net feature.(mio v1.2.3, viatokio/netwhichlocalenables), followed by the miosysmodule's unresolved imports (crate::sys::IoSourceState,crate::sys::tcp,Selector,event). Both default and--features composedwasm checks are green. - The
-Dstory's door wiring: the cred-bearing TCP door + the UDP door each take their ownChannelClient(two connections to the one registration); the tests'DoorTokenProviderresolves the mappeddoor--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_overover thelocalprovider 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):
- The full
-Dstory (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
localproviders 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).
- the UDP door against one producer registration with the
- The composed story (
composed_story_...): the producer withcomposed::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 realbound+ the realpeer+ the pass-through plane); all three commands, all live. - 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).
- 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).
- The producer's own front door (
ProducerDoor) drives all three commands through one door + one registration (the-Dstory's other half; the faithful-RFC BIND variant). - The
-Ddomain-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).