- git row: a second exec on a served git channel answers channel_failure inline — the serve rides on, no second serving path; race-free by construction (advertisement drained, serve parked at the gated list_refs) - tty rows: the pipe row (second exec) and the shell row (second shell request) — the same inline decline shape, channel still usable - the rows assert the decline event's exact request vocabulary (class request, reason channel-not-held, route git/pipe/absent, debug level, self-describing build) — the class's vocabulary coverage - tests/common/event_capture.rs: the observe-suite's capture convention shared across the mapping binaries - test-only: no production change; the guard held its documented shape in every featured build (verified default / git / session / session,git / tunnel / sftp / --all-features) Verified: cargo test (+ per-feature + --all-features) all green · cargo clippy --all-targets -- -D warnings ✓ · cargo clippy --all-features --all-targets -- -D warnings ✓ · cargo fmt --check ✓ · cargo doc --no-deps 0 warnings · taskgraph validate ✓ (35 tasks)
5.7 KiB
id, name, status, depends_on, scope, risk, impact, level
| id | name | status | depends_on | scope | risk | impact | level | |
|---|---|---|---|---|---|---|---|---|
| w4-channel-not-held-rows | Wave 4 — channel-not-held guard wire rows (wave-3 gate booked item 2) | completed |
|
narrow | low | component | implementation |
Description
Close the wave-3 gate's booked finding item 2
(review-wave-3 §Booked findings): the channel-not-held guard
lacks wire test rows. The guard is a documented decline class on
all three rows (git / tty pipe / shell) — a second exec (or request)
on an already-served channel — constructible on the wire, but no row
asserts it in any build. mapping.md's every-row-tested-in-every-build
convention names it contract territory; the fail-closed invariant is
contract on both sides of every feature (AGENTS.md convention 5).
Test-only task — no production code change expected (if landing the rows exposes a guard gap, stop and book it for the gate rather than silently widening scope):
- Wire rows through the harness, per build (the per-build cfg-pinned module convention): a second exec on a served git channel → the channel-not-held decline; the same on the tty pipe row and the shell row — the decline class asserted in every build that carries the row (featured builds carry the serving rows; the decline-class rows ride the same per-build matrix the dispatch tests use).
- The rows observe the decline's wire shape + the tracing event
vocabulary (the
w3-decline-tracingclass/reason fields — the rows double as the vocabulary's coverage for this class). - Depends on
w4-git-exit-closeonly to keeptests/git_mapping.rssingle-writer (the hardening lands first; these rows land into the settled file).
Acceptance Criteria
- Wire rows for the channel-not-held decline class on all three rows (git / tty pipe / shell), per build, through the harness
- The rows assert the wire shape + the tracing event class/reason
- No production code change (no guard gap exposed — nothing to book; the guard's shape held on the wire in every featured build)
cargo test(+ per-feature +--all-features), clippy ×2 (-D warnings), fmt,cargo doc --no-depspass
References
- tasks/implementation/review-wave-3.md §Booked findings item 2
- docs/architecture/mapping.md (the request-level table — the channel-not-held class; the every-row-tested convention)
- tests/git_mapping.rs, tests/tty_mapping.rs, tests/dispatch_core.rs (the per-build matrix convention the rows join), src/observe.rs (the event vocabulary the rows assert)
Notes
- Test-only, as planned — no production change; no guard gap surfaced (the landing verified the guard's documented shape on the wire in every build that carries each row).
- Rows landed (one per served row, each with the inline-decline
wire shape —
channel_failurewhile the first serving path rides on — plus the channel-stays-usable witness and the tracing event's exact request-decline vocabularysrc/observe.rscarries):tests/git_mapping.rs(cfggit): a second exec on a served git channel — the decline event carriesexec_route = "git", and the declined re-exec never spawns a second serving path (the doubles' resolve count stays at one). Race-free by construction: the advertisement drains first and the serve parks at the doubles' gatedlist_refsbehind it, so the wire is quiescent for the decline.tests/tty_mapping.rs(cfgsession), two rows: the pipe row (second exec on a served pipe channel — event carriesexec_route = "pipe") and the shell row (second shell request on a served shell channel — the event carries noexec_routefield, pinning the absent-field shape on the wire). The exit-Noneshim script keeps the serve live and the wire quiescent.
- The per-build matrix: the rows join the cfg-pinned convention —
git-build rows run in every build carrying
git, session rows in every build carryingsession(verified across default /git/session/session,git/tunnel/sftp/--all-features). - Shared capture helper:
tests/common/event_capture.rs(new) — the observe-suite's recorded hand-rolled global-subscriber convention shared across the mapping binaries;await_eventfield-matching (parallel rows never order against each other) and the exact-field-set assertion (assert_request_decline) — the rows double as this class's vocabulary coverage, including thedebuglevel and the build self-description. - No
dispatch_core.rsrows added — that binary builds no seam, so its git row declines at the config gate before the store-take; the guard is unreachable there (the reference names the per-build convention the rows join, which the mapping binaries carry).
Summary
The channel-not-held guard's wire rows landed on all three served
rows: second_exec_on_a_served_git_channel_declines_channel_not_held
(tests/git_mapping.rs), and the pipe/shell pair
(tests/tty_mapping.rs) — each pinning the inline decline shape
(channel_failure, no close, the first serve rides on, the channel
stays usable, no second serving path) plus the decline event's exact
vocabulary (class request, reason channel-not-held, route
git/pipe/absent, debug level, self-describing build). No
production change was needed — the guard held its documented shape in
every featured build. tests/common/event_capture.rs shares the
observe-suite's capture convention across the mapping binaries.
Verified: full suite + per-feature builds (default, git, session,
session,git, tunnel, sftp) + --all-features all green;
clippy ×2 (-D warnings), cargo fmt --check, cargo doc --no-deps
clean.