Files
alksocks/tasks/implementation/assembly-integration-suite.md
glm-5.3-flash e196ed43e3 docs: remove em dashes from repo prose and forbid them going forward
- 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
2026-11-03 19:31:53 +00:00

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).