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.
130 lines
6.4 KiB
Markdown
130 lines
6.4 KiB
Markdown
---
|
||
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). |