Batch 1 of the Phase 1 decomposition: the default, wasm-clean crate (producer + consumer + wire + seams + params/errors), per the architecture spec set (ADRs 001-013) and the three POCs' validated shapes. The assembly layer (local/composed providers, front doors) is batch 2, decomposed after review-protocol-core opens. - foundation: crate-deps (alkcall 0.8.0 first consumption), wire-codec (the ASSOCIATE frame + the joint bound), seam-types (the three ADR-004 seams), params-errors (the one-way-door surface) - harness: duplex transport + identities + in-process seams (the alkcall 0.8.0 establishment surface proven before the producer) - verticals: producer/consumer splits per command (CONNECT, ASSOCIATE, BIND) — each POC's scope, producer tasks test via the raw RFC client, consumer tasks e2e through the harness - closing: integration suite (three-command regression, teardown matrix, identity matrix, docs sync) + review-protocol-core (the batch gate) taskgraph: 8 generations, no cycles, risk path 2.55 (no high-risk tasks). Also records the wire.md/bast.md len=0 residue (payload-level F-2 is the operative invariant) as a doc-sync deliverable of the wire-codec task. Verification: cargo test (76 passed), fmt clean; taskgraph validate/cycles/parallel/critical clean.
5.2 KiB
5.2 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) | pending |
|
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— the serving side allocates; 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 — 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) — 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 — 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
To be filled by implementation agent
Summary
To be filled on completion