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

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
implementation/door-udp
implementation/local-backend-producer
implementation/composed-accept
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:

  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

  • The full -D story (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_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).