Renames the written-usage rule into practice across the contract surface: docs/ (architecture, research, plans, sdd), tasks/ (all 43 task files, taskgraph validate passes), AGENTS.md, README.md, CHANGELOG.md, and the .opencode/agents/ prompts. Every replacement is a sense-preserving rewrite (colons, semicolons, commas, parentheses, sentence splits, varied), never a mechanical swap; no spaced hyphens were substituted. Enum fields, frontmatter, tables, wire data, and cited identifiers survive verbatim; en dashes inside numeric ranges keep their meaning. Verification: taskgraph validate (43 tasks), repo grep clean (single exempt hit: the verification command's own search pattern in AGENTS.md), cargo test, clippy --all-targets -D warnings, fmt --check, doc all green.
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, so no production code change is 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, with 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, and 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, so 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, hence 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, whose 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, with the event carryingexec_route = "pipe") and the shell row (second shell request on a served shell channel, whose 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) with 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), and the rows double as this class's vocabulary coverage, including thedebuglevel and the build self-description. - No
dispatch_core.rsrows added, because 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, and 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.