Files
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/core-test-harness Core: integration test harness (duplex transport + identities + in-process seams) completed
implementation/core-seam-types
implementation/core-params-errors
moderate medium phase implementation

Description

Build tests/harness.rs, the producer↔consumer wiring over a tokio::io::duplex carrying the channels 8-byte chunk format, so every subsequent core task tests end-to-end without the local feature. This is the alkcall-0.8.0-first-consumption task: the POCs ran 0.7.1; the harness proves the 0.8.0 establishment surface (register_openable_with_establisher, Establishment, ChannelClient::open_channel) works for this crate's shape before the producer task builds on it. Template: /workspace/@alkdev/alktunnels/tests/harness.rs (the sibling's harness, same topology, adapted to this crate's seams).

Topology (the alktunnels harness shape):

  • producer (connect side of the channels connection; runs ChannelClient::from_connection_with_serving): serves the socks5 open op + generic channel ops on its serving registry. Its manager allocates the channel IDs (ChannelSide::Connect, since the serving side allocates and the initiator adopts).
  • consumer (accept side): the ChannelsAdapter + capturing install hook. The hook captures the consumer's channel-0 CallConnection and ChannelManager.
  • The POC #1 wiring requirement is load-bearing here (producer.md §Harness wiring requirement): the accept-side install hook must call channel0_conn.set_identity(resolved) before building the CallConnection; without it, scope-gated opens fail closed with FORBIDDEN "authentication required" (correct behavior, implicit wiring). The harness makes the requirement explicit and tested.

Deliverables:

  1. Identities: consumer_identity() (socks5:open only), bind_identity() (socks5:bind only, the command-gate probe), both_scopes_identity() (both grants, explicitly and never implied, ADR-006), plus a TestIdProvider resolving them (the alktunnels harness shape).
  2. In-process seam closures (no sockets; the protocol layer is substrate-agnostic, so the harness dials in-process):
    • echo_dial(): a DialFn returning duplex-halves wired to an in-process echo server (the POC #1 shape); plus refusing_dial() (a failing dial for the refusal-mapping tests).
    • echo_egress(): an EgressFactory whose egress echoes datagrams back (the POC #2 shape, readiness-contract-clean: parks on a channel recv(), Pending when nothing is ready).
    • echo_accept(): a BindAcceptFactory whose accept resolves immediately with in-process halves (the POC #5 shape); plus a failing variant.
  3. The producer registration helper: a spawn_producer(...) function wiring register_socks5_openable (or its task-6 successor) with the harness seams, the single place the producer-side wiring lives, so the per-command tasks only write tests.
  4. A raw RFC client helper: a hand-rolled minimal RFC 1928 client over any AsyncRead + AsyncWrite (greeting → method selection → command with target → reply read) following the differential suite's established pattern, so producer tasks test without depending on the consumer session types (which land later).
  5. One smoke test proving the full loop: harness up → producer registered → consumer opens a channel → raw RFC CONNECT conversation → echo round-trip. (This test needs a minimal CONNECT producer path; if the producer task hasn't landed, stub the handler with the POC #1 serve_socks5_over shape inline in the harness, and the producer task then replaces it. Alternatively sequence this task to land immediately before the producer task and let the smoke test be the producer task's first test; the implementer's judgment; the acceptance bar is the harness compiling with the identities + seams + helpers tested.)

Acceptance Criteria

  • Harness topology works over alkcall 0.8.0 (the establishment surface consumed successfully; the first-consumption risk retired)
  • Identity wiring explicit: set_identity in the install hook; a scope-less identity gets FORBIDDEN (fails closed), tested
  • All three identities + all in-process seam closures unit-tested
  • The raw RFC client helper round-trips a greeting + command + reply against a hand-rolled server over a duplex
  • No local feature, no sockets; everything in-process
  • cargo test green; clippy/fmt clean; both wasm checks clean (the harness is dev-only; verify it stays out of the wasm build)

References

  • Template: /workspace/@alkdev/alktunnels/tests/harness.rs (the topology + identity shapes)
  • POC harnesses: /workspace/alksocks-connect-poc/src/harness.rs, /workspace/alksocks-udp-poc/src/harness.rs, /workspace/alksocks-bind-poc/src/harness.rs
  • docs/architecture/producer.md §Harness wiring requirement (the set_identity requirement)
  • docs/architecture/decisions/006-access-control.md (the scope identities)

Notes

Filled by the implementation agent (2026-09-23).

  • tests/harness.rs: the producer↔consumer wiring over one tokio::io::duplex carrying the channels 8-byte chunk format, in the task's topology: producer = connect side (ChannelClient::from_connection_with_serving; its manager allocates the odd channel IDs), consumer = accept side (the ChannelsAdapter + capturing install hook; the hook captures the consumer's channel-0 CallConnection + ChannelManager).
  • The load-bearing POC #1 wiring requirement is explicit and tested: the hook calls channel0_conn.set_identity(resolved) before building the CallConnection; the transport identity is set on the dialing (producer) connection before from_connection_with_serving (CF-005 (b) primary path). The scope-less identity test asserts the FORBIDDEN code and that no channel survives on either side (fail-closed).
  • Identities: consumer_identity() (socks5:open only), bind_identity() (socks5:bind only), both_scopes_identity() (both, explicit, per ADR-006), TestIdProvider + TEST_AUTH_TOKEN (the token-resolver path, unit-tested both directions).
  • In-process seams (no sockets, no local): echo_dial() (echo-per-dial, exercised through pump_bidi, the producer data (echo-per-dial, exercised through pump_bidi, the producer data plane's shape), refusing_dial(err) (variant-preserving per-call reconstruction, as the seam errors are not Clone), echo_egress() (a ChanEgress whose next_reply parks on mpsc::UnboundedReceiver::recv(): Pending when idle, with the readiness contract verified with a 50ms timeout probe), refusing_egress(err), echo_accept() (reply#1 advertises a static in-process BND.ADDR, ECHO_BIND_PORT 2121; the accept future resolves immediately with echo-pipe halves), refusing_accept_factory(err) (pre-reply#1) and refusing_accept(err) (post-reply#1).
  • register_socks5_openable_minimal + socks5_session_establisher: the producer-side wiring helper over alkcall 0.8.0's ChannelCore::register_openable_with_establisher (spec from socks5_open_spec(), Establishment::default() for a session gate only; the dial is in-stream). The establisher witnesses the per-call opener identity id (CF-006) into an IdentityWitness, asserted end-to-end in the smoke test.
  • RegisterMode (MinimalConnect(dial) / NoSocks5) controls what wire_with registers post-hoc (W2) on the producer's serving registry; generic channel ops always register.
  • The smoke test's producer path is the minimal CONNECT stand-in (make_minimal_connect_handler → serve_connect_minimal: the forked typestate's accept_no_auth → read_command → CONNECT-only dispatch → the injected DialFn → reply_success → pump_bidi inline, R-02). The producer task replaces this; the registration shape (spec/establisher/handler/auth/timeout) stays.
  • RawRfcClient<S>: hand-rolled greeting (05 01 00 → 05 00) + request encoder (all three commands, all address forms via TargetAddr::to_be_bytes()) + reply reader (v4/v6/domain BND.ADDR forms; returns (code, addr_bytes)). Round-trip-tested against a hand-rolled byte-level server over a duplex, success + refusal reply codes; the harness is producer-independent (no consumer session types).
  • Wire note: the smoke test calls the open op via consumer_call.call(OP_SOCKS5_OPEN, Socks5Params::as_json()) and adopts on consumer_manager (the alktunnels wire_with + open_reverse_channel shape) rather than ChannelClient::open_channel: in this topology the open op is served by the producer's registry and reached from the accept side's channel-0 call surface; open_channel remains the consumer-session surface for the consumer task's session types.
  • The harness is tests/harness.rs only (dev-only), verified out of the wasm build by the targeted checks below.

Summary

Filled on completion (2026-09-23).

Built tests/harness.rs, the integration test harness: the producer↔consumer topology over one tokio::io::duplex (producer = connect side/serving; consumer = accept side/adapter + capturing hook), the alkcall 0.8.0 establishment surface consumed for the first time by this crate (register_openable_with_establisher, Establishment::default, the consumer-side call + adopt dance), and the first-consumption risk retired with 14 green tests.

  • The three identities + TestIdProvider (all unit-tested).
  • All in-process seam closures: echo_dial/refusing_dial (variant- preserving), echo_egress (readiness contract verified: a 50ms timeout probe proves next_reply parks, never a hot Ok(None)) / refusing_egress, echo_accept (immediate resolve + echo) / refusing_accept_factory / refusing_accept (two-stage refusal shapes, mapping-table-verified through to_reply_error()).
  • The producer registration helper (register_socks5_openable_minimal
    • socks5_session_establisher + RegisterMode), the single place the producer-side wiring lives; the CF-006 identity witness rides it and is asserted.
  • RawRfcClient: the raw RFC 1928 client helper over any AsyncRead + AsyncWrite, round-tripped against a hand-rolled byte-level server (success + refusal replies).
  • The smoke test: harness up → producer registered → consumer open + adopt → raw RFC CONNECT → echo round-trip through pump_bidi, with the establisher witness asserted mid-flight. Plus the fail-closed probe (scope-less identity → FORBIDDEN, no channel anywhere) and the odd-ID allocation/adopt sanity probe.

Verification: cargo test (127 green: 76 lib + 14 harness + 37 rfc1928-differential), cargo test --all-features green, cargo clippy --all-targets -- -D warnings clean, cargo fmt --check clean, cargo doc --no-deps zero warnings, both wasm checks (cargo check + cargo clippy on wasm32-unknown-unknown) clean, and the harness stays out of the wasm build.