- 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/core-test-harness | Core: integration test harness (duplex transport + identities + in-process seams) | completed |
|
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-0CallConnectionandChannelManager. - 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 theCallConnection; without it, scope-gated opens fail closed withFORBIDDEN "authentication required"(correct behavior, implicit wiring). The harness makes the requirement explicit and tested.
Deliverables:
- Identities:
consumer_identity()(socks5:openonly),bind_identity()(socks5:bindonly, the command-gate probe),both_scopes_identity()(both grants, explicitly and never implied, ADR-006), plus aTestIdProviderresolving them (the alktunnels harness shape). - In-process seam closures (no sockets; the protocol layer is
substrate-agnostic, so the harness dials in-process):
echo_dial(): aDialFnreturning duplex-halves wired to an in-process echo server (the POC #1 shape); plusrefusing_dial()(a failing dial for the refusal-mapping tests).echo_egress(): anEgressFactorywhose egress echoes datagrams back (the POC #2 shape, readiness-contract-clean: parks on a channelrecv(),Pendingwhen nothing is ready).echo_accept(): aBindAcceptFactorywhose accept resolves immediately with in-process halves (the POC #5 shape); plus a failing variant.
- The producer registration helper: a
spawn_producer(...)function wiringregister_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. - 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). - 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_overshape 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_identityin the install hook; a scope-less identity getsFORBIDDEN(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
localfeature, no sockets; everything in-process cargo testgreen; 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_identityrequirement) - 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 onetokio::io::duplexcarrying 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 (theChannelsAdapter+ capturing install hook; the hook captures the consumer's channel-0CallConnection+ChannelManager).- The load-bearing POC #1 wiring requirement is explicit and tested:
the hook calls
channel0_conn.set_identity(resolved)before building theCallConnection; the transport identity is set on the dialing (producer) connection beforefrom_connection_with_serving(CF-005 (b) primary path). The scope-less identity test asserts theFORBIDDENcode and that no channel survives on either side (fail-closed). - Identities:
consumer_identity()(socks5:openonly),bind_identity()(socks5:bindonly),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 throughpump_bidi, the producer data (echo-per-dial, exercised throughpump_bidi, the producer data plane's shape),refusing_dial(err)(variant-preserving per-call reconstruction, as the seam errors are notClone),echo_egress()(aChanEgresswhosenext_replyparks onmpsc::UnboundedReceiver::recv():Pendingwhen 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_PORT2121; the accept future resolves immediately with echo-pipe halves),refusing_accept_factory(err)(pre-reply#1) andrefusing_accept(err)(post-reply#1). register_socks5_openable_minimal+socks5_session_establisher: the producer-side wiring helper over alkcall 0.8.0'sChannelCore::register_openable_with_establisher(spec fromsocks5_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 anIdentityWitness, asserted end-to-end in the smoke test.RegisterMode(MinimalConnect(dial)/NoSocks5) controls whatwire_withregisters 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'saccept_no_auth→read_command→ CONNECT-only dispatch → the injectedDialFn→reply_success→pump_bidiinline, 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 viaTargetAddr::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 onconsumer_manager(the alktunnelswire_with+open_reverse_channelshape) rather thanChannelClient::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_channelremains the consumer-session surface for the consumer task's session types. - The harness is
tests/harness.rsonly (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 provesnext_replyparks, never a hotOk(None)) /refusing_egress,echo_accept(immediate resolve + echo) /refusing_accept_factory/refusing_accept(two-stage refusal shapes, mapping-table-verified throughto_reply_error()). - The producer registration helper (
register_socks5_openable_minimalsocks5_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 anyAsyncRead + 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.