Files
glm-5.3-flash f4b5f896b4 docs: sweep em dashes from all markdown prose
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.
2026-11-04 20:28:00 +00:00

130 lines
6.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: w4-tty-coverage
name: "Wave 4: tty coverage minors (wave-3 gate booked item 3)"
status: completed
depends_on: [w4-channel-not-held-rows]
scope: narrow
risk: low
impact: component
level: implementation
---
## Description
Close the wave-3 gate's booked finding item 3
(`review-wave-3` §Booked findings, "minors, one ticket's worth"):
- **The `channel_close`-fired per-channel cancel path is
unexercised on the wire**; only the teardown signal is. Land the
wire row: a channel closing (client-side close on a served tty
row) fires the per-channel cancel path (the cap release + the
per-channel state teardown observed, the disjoint release sites
the gate verified per row, now wire-witnessed for this path).
- **The Closed/Break no-exit-chunk close shape has no wire row**, so
land the row(s): a session ending via the Closed/Break close shape
emits **no exit chunk** (the derivation contract's close-shape
class, the absent-report posture pinned, not just the happy
paths).
- **The tty stdout `write_all` carries no deadline**, recorded as a
**known limit only** (module docs): backpressure is bounded, liveness
is covered by the inactivity timeout; no code change (the gate's
recorded disposition, since a deadline here is a behavior change, not a
coverage minor).
Depends on `w4-channel-not-held-rows` to keep `tests/tty_mapping.rs`
single-writer (that task's rows land first; these land into the
settled file).
## Acceptance Criteria
- [x] Wire row: the `channel_close`-fired per-channel cancel path
(cap release + state teardown observed on the wire)
- [x] Wire row(s): the Closed/Break no-exit-chunk close shape
- [x] The stdout `write_all` no-deadline limit recorded in module
docs (no code change)
- [x] `cargo test` (+ per-feature + `--all-features`), clippy ×2
(`-D warnings`), fmt, `cargo doc --no-deps` pass
## References
- tasks/implementation/review-wave-3.md §Booked findings item 3
- docs/architecture/mapping.md §The exit derivation contract (the
close-shape classes; the PTY-path rule-5 limit, the docs-posture
template), src/tty_map.rs, src/channel_cap.rs (the release sites
the rows witness)
- tests/tty_mapping.rs (the per-build matrix the rows join)
## Notes
- **Test + module-docs only, as planned**, hence no production code
change;
the shapes held on the wire exactly as documented.
- **`channel_close`-fired cancel path**, namely
`a_client_close_on_a_served_row_fires_the_per_channel_cancel_and_releases_the_cap`
(`tests/tty_mapping.rs`, cfg `session`): a served pipe row under a
cap of 1; a second open is refused (`AdministrativelyProhibited`,
the admission held), the client then closes the served channel, and
the row witnesses (a) the per-channel state teardown, with the
shim's
kill-on-drop witness fires (the bridge surface's cancel → the
serving task aborts the alktty session), polled *before* unmount so
it is the `channel_close` site, not the teardown; (b) no exit report
fabricated on the wire (plain close / channel end); (c) the serving
path's ended lifecycle event; (d) the **cap release**, with the next
open admits and routes (release site 1, disjoint from the
bridge-failure and arrival sites).
- **Closed/Break no-exit-chunk close shape**, namely
`a_bridge_end_without_an_exit_chunk_reports_nothing_and_closes_plain`
(same file): the shape is constructed deterministically through the
real path: the shim's stdout carries a payload beyond alktty's own
`MAX_CHUNK_LEN` wire bound; alktty's `ChunkWriter` rejects it
locally, its drainer shuts the write half down, and the bridge's
next read is EOF (`BridgeFrame::Closed`) with the scripted exit
(`Some(0)`) never forwarded. The row pins: the in-bounds chunk rode
first, the end is a plain close, **no exit-status/exit-signal ever
rides** (the absent-report posture, neither 0 nor 255), the session
truly served (an allocation happened, so this is the close shape,
not a decline), and the ended lifecycle event landed.
- **Break's classification row**, which pins
`clean_ends_classify_closed_and_oversized_lengths_classify_break`
(`src/tty_map.rs` test mod): Break is **unreachable on the wire**
through alktty's own validated `ChunkWriter` (an oversized chunk
fails local validation → the drainer break → the read sees EOF,
exactly the Closed row's construction; a non-EOF duplex read error
has no wire-constructible producer at this pin, and the
serving-path body of Closed/Break is one arm). So the family's
*serving* outcome is wire-witnessed by the Closed row, and the
frame-level `Break` classification (bounds-checked, never an
oversized read) is pinned at the frame layer by the unit row,
recorded here as the reason one wire row + one unit row cover the
"row(s)".
- **The stdout `write_all` no-deadline limit**, recorded in
`src/tty_map.rs`'s module docs (§the translation bridge): the gate's
recorded disposition verbatim; backpressure bounded, liveness
covered by the inactivity timeout, a deadline would be a behavior
change, not a coverage minor. No code change.
- A `session_with_limits` / `session_config(limits)` driver variant
was added to the binary (the cap row's ceiling of 1); `session_with`
delegates unchanged.
## Summary
The wave-3 gate's booked item 3 is closed: the `channel_close`-fired
per-channel cancel path is now wire-witnessed (a served pipe row under
a cap of 1: the refused over-cap open pins the admission, the client
close pins the cancel, with the kill-on-drop witness firing before any
teardown, no exit report is fabricated, the ended lifecycle event
lands, and the succeeding re-open pins the cap release from the
established-channel-close release site); the Closed/Break
no-exit-chunk close shape landed its wire row (constructed through
the real path via an oversized shim chunk dying at alktty's own
`ChunkWriter` validation: EOF without an exit chunk → plain close,
nothing fabricated, the scripted exit never forwarded) plus the
frame-level Break classification row (Break is wire-unreachable
through alktty's validated writer at this pin, as recorded); and the
stdout `write_all` no-deadline limit is recorded in the module docs
per the gate's disposition. No production code change. Verified:
`cargo test` (default, `session`, `session,git`, `git`, `tunnel`,
`sftp`, `--all-features`, with the tty rows' 5×-repeat flake check
included), clippy ×2 (`-D warnings`), `cargo fmt --check`,
`cargo doc --no-deps` 0 warnings, `taskgraph validate` ✓ (35 tasks).