docs(architecture): OQ-10 resolved as a decided mapping contract; tracker statements made accurate
- OQ-10 resolved: alkssh derives SSH exit-signal from the alktty exit chunk's negative code (−N = signal N, pipe path) server-side; −1 (alktty's could-not-determine sentinel) → exit-status(255), never a signal claim; core_dumped never asserted in v1; no alktty wire change - new verified backend finding recorded: portable-pty 0.9 reduces PTY-mode signal termination to a plain exit code 1 (signal number unrecoverable through its trait surface) — faithful exit-signal on the PTY row is an alktty/portable-pty upstream ask, not an alkssh one - research docs (poc-3 §D.2, pocs.md, mapping-table rows) restated accurately instead of carrying inline correction scaffolding Verification: cargo doc --no-deps earlier this session (docs-only change)
This commit is contained in:
1 parent
9217a8b3cf
commit
1a40bfb498
5 files changed
+64
-64
No files matched your search
@@ -75,8 +75,8 @@ the served listen flow is implementation-phase contract-test territory.*
|
|||||||
| `window_change_request` | resize control (POC-3 §D.1: live resize proven) |
|
| `window_change_request` | resize control (POC-3 §D.1: live resize proven) |
|
||||||
| `signal` | signal control (alktty names verbatim); PTY mode reaches the process group, pipe mode is pid-only (backend semantics, recorded in OQ-10) |
|
| `signal` | signal control (alktty names verbatim); PTY mode reaches the process group, pipe mode is pid-only (backend semantics, recorded in OQ-10) |
|
||||||
| data / `extended_data(1)` | the translation bridge (rows table) |
|
| data / `extended_data(1)` | the translation bridge (rows table) |
|
||||||
| `exit_status` | from the alktty exit chunk — sent **before** close, from the spawned task via `Session::handle()` (POC-3 §D: proven both legs) |
|
| `exit_status` | from the alktty exit chunk — sent **before** close, from the spawned task via `Session::handle()` (POC-3 §D: proven both legs). `−1` (alktty's could-not-determine sentinel — alktty ADR-004 §4) → `exit-status(255)`, never a signal claim |
|
||||||
| `exit_signal` | only for signal-terminated exits; derived from the exit chunk's negative code — `−N` = terminated by signal N on Unix (alktty ADR-004's documented convention). Details pending OQ-10: the `−1` wait-failure/SIGHUP collision, core-dumped (discarded by alktty; likely never asserted in v1), non-Unix shift |
|
| `exit_signal` | signal-terminated exits on the **pipe** path: the exit chunk's negative code is the signal — `−N` → name via a Unix signal-number→name table (OQ-10 resolved; POC-3 §D.2 observed `−15` → `exit-signal("TERM")` live). `core_dumped` always `false` (v1 — alktty discards `ExitStatus::core_dumped()`). **PTY path**: signal-terminated children arrive as a plain code 1 (portable-pty's exit surface; the signal number is unrecoverable there today) → `exit-status(1)` — faithful `exit-signal` on the PTY row is an alktty-backend/portable-pty ask, upstream |
|
||||||
|
|
||||||
## The structural constraint: spawn-and-return
|
## The structural constraint: spawn-and-return
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ under `--all-features`.
|
|||||||
|
|
||||||
- **OQ-08** (shell convention — status: open): blocks this doc's
|
- **OQ-08** (shell convention — status: open): blocks this doc's
|
||||||
`shell_request`/`NegotiateRequest.cmd` row detail.
|
`shell_request`/`NegotiateRequest.cmd` row detail.
|
||||||
- **OQ-10** (exit-signal derivation details — status: open, **premise corrected**): the negative code *is* the signal identity by alktty's documented convention, so no chunk widening is justified by default (the upstream option's gate and consequence analysis are recorded there). This blocks only the `exit_signal` row's derivation detail — the `−1` disposition, core-dumped assertion, non-Unix note.
|
- ~~OQ-10~~ (exit-signal derivation — resolved: the negative code is the signal encoding on the pipe path; the PTY path's signal-identity loss is recorded upstream, alktty-side).
|
||||||
- **OQ-11** (streamlocal platform decline shape — status: open).
|
- **OQ-11** (streamlocal platform decline shape — status: open).
|
||||||
- ~~OQ-02~~ (dispatch composition — resolved by ADR-006, as amended).
|
- ~~OQ-02~~ (dispatch composition — resolved by ADR-006, as amended).
|
||||||
|
|
||||||
|
|||||||
@@ -94,24 +94,19 @@ alkcall trackers have their own OQ spaces).
|
|||||||
- **Blocked on**: a concrete consumer use case requiring wire-supplied environment variables.
|
- **Blocked on**: a concrete consumer use case requiring wire-supplied environment variables.
|
||||||
- **Resolution**: Not yet decidable — no use case; decline stands.
|
- **Resolution**: Not yet decidable — no use case; decline stands.
|
||||||
|
|
||||||
### OQ-10: ~~"The alktty exit chunk carries no signal identity — widen the chunk or map by assembly policy"~~ — premise corrected; re-scoped
|
### OQ-10: ~~SSH `exit-signal` fidelity over the alktty exit-code convention~~ — resolved
|
||||||
|
|
||||||
- **Origin**: [poc-3-mapping-bakeoff.md](../research/poc-3-mapping-bakeoff.md) §D.2, `mapping-table.md` (exit_signal row). **Premise corrected 2026-10-27**: the POC's "signal-identity gap" framing was an incorrect assumption, surfaced during review; the incorrect assumption is documented here, not silently edited.
|
- **Origin**: `mapping-table.md` (exit_signal row), [poc-3-mapping-bakeoff.md](../research/poc-3-mapping-bakeoff.md) §D.2
|
||||||
- **Status**: open — re-scoped to the SSH-fidelity derivation details; the detail decision lands during `mapping.md`
|
- **Status**: resolved — the alkssh mapping contract is decided (below, and in `mapping.md`'s exit rows). The PTY-path fidelity limit recorded in point 4 is an alktty-backend/portable-pty matter and belongs in their trackers; alkssh adapts automatically with no contract change if the convention ever holds on that path.
|
||||||
- **Priority**: medium
|
- **Resolution**: alkssh adds nothing to the alktty wire — the exit chunk is alktty's contract (`{"type":"exit","code":N}` on ctrl-out, exit-chunk-is-last — alktty ADR-004, ported from alknet ADR-055) — and derives all SSH fidelity from the code the chunk already carries:
|
||||||
- **The incorrect assumption, explicitly**: the OQ seed treated the exit chunk's lack of a signal *name* as a design gap, with "alktty widens the chunk" as a co-equal candidate casually offered ("filed as an ask"). Both halves were wrong.
|
|
||||||
- **The chunk does carry signal identity.** The negative exit code *is* the signal encoding, by a deliberate documented one-way convention (alktty ADR-004 decision 1, ported from alknet ADR-055; implemented in alktty `src/local/pipe.rs::exit_code_from` — on Unix, `ExitStatus::signal() → -sig`). The rationale is tty/pty-ground: the backend reaps a Unix wait-status, and the negative-code encoding preserves exactly that ground truth across every backend behind a single `exit_code → i32` API. The OQ's claim "carries no signal identity" overstated an *information-preserving* encoding as an absence.
|
1. **The negative code is the signal encoding on the pipe path.** alktty's pipe backend maps Unix `ExitStatus` signal termination to `−N` (`pipe.rs::exit_code_from`, `ExitStatusExt::signal() → -sig`; the alknet ADR-055 convention). POC-3 stage D observed it live on the wire: signal TERM → `−15` → SSH `exit-signal("TERM")` via the cloned `Session::handle()`.
|
||||||
- **Upstream widening is not a justified candidate by default.** It is not a wire-only tweak: widening `ControlMessage::Exit`'s shape is a one-way-surface change every ctrl-out consumer parses; the backend API (`TtyHandle.exit_code → i32`, shared by every backend) would have to widen with it — changing how every backend reaps and reports; and the negative-code convention is shared with alknet's docker-carriage lineage (alknet ADR-055). "It would be easier for alkssh" is not a tty/pty-grounded justification; alkssh cannot shift alktty's contract for its own fidelity convenience, and will not silently work around the wire either.
|
2. **Name derivation is alkssh server-side work, not a wire change**: `−N` → the SSH `exit-signal` name from a Unix signal-number→name table (signal semantics belong to the serving platform, where the backend reaps). `core_dumped` is always `false` in v1 — alktty discards `ExitStatus::core_dumped()`, so nothing better is knowable from the chunk; no error message rides.
|
||||||
- **The tty/pty conventions alkssh consumes, never repurposes**: the exit control chunk (JSON, never zero-length, "exit chunk is last" invariant) and the data-plane sentinels (zero-length stdin = client EOF — the form alkssh's SSH-EOF translation uses; zero-length stdout = stdout-drained). Both have tty/pty rationale in alktty's ADR-004/`tty-wire.md`; they are upstream decisions, not alkssh levers.
|
3. **`−1` is never a signal claim.** Per alktty ADR-004 §4, `−1` is the backend could-not-determine sentinel — it collides with a real SIGHUP termination (signal 1). Alkssh renders `−1` as `exit-status(255)` (OpenSSH's conventional failure value): fabricating `exit-signal("HUP")` for a wait failure would invent a signal that never happened. The SIGHUP information loss inside the sentinel is alktty's documented edge — alktty's additive `exit_error` control type is its own extension seam if it ever becomes load-bearing.
|
||||||
- **What is genuinely missing** (the re-scoped open detail — all alkssh mapping-contract territory):
|
4. **PTY path — the real fidelity limit, backend-side.** portable-pty 0.9 converts a signal-terminated child's wait status with `code = status.code().unwrap_or(1)` → **1**, keeping the signal only in a separate humanized (`strsignal`) string field that alktty's PTY waiter discards (`pty.rs` reads `exit_code()` only; the number is unrecoverable through portable-pty 0.9's trait surface). So a signal-killed PTY session arrives as a plain exit 1 → alkssh maps `exit-status(1)`; faithful `exit-signal` for the `session`/PTY row needs the PTY backend to conform to alktty's own negative-code convention — an alktty/portable-pty ask with tty/pty-grounded justification, not an alkssh convenience ask.
|
||||||
1. **Name derivation**: SSH `exit-signal` requires a name; `−N → name` is alkssh server-side work (a Unix signal table — signal semantics belong to the server's platform, where the backend reaps).
|
5. **Non-Unix**: no signal termination; `−1` is the only negative that can appear → rule 3.
|
||||||
2. **Core-dumped**: alktty discards `ExitStatus::core_dumped()`; SSH's `exit-signal` carries a bool. Currently unrecoverable — disposition decided during `mapping.md` (likely direction: never asserted, v1).
|
6. **Pipe-mode pid-only vs PTY process-group signal scope** is backend semantics, not a mapping change — recorded as a fidelity note on `mapping.md`'s `signal` row.
|
||||||
3. **The `−1` collision** (pre-existing, documented in alktty ADR-004's consequences): `−1` is the backend wait-failure sentinel, colliding with a real SIGHUP termination. The SSH mapping must pick a disposition (`exit-status` with an opaque value, no exit request, or a diagnostic band). alktty has an *additive* escape (`exit_error` message type) recorded in its own ADR — an upstream improvement, not an alkssh ask by default.
|
- **Cross-references**: OQ-08, [mapping.md](mapping.md) (`exit_signal`, `exit_status`, `signal` rows), alktty ADR-004 / alknet ADR-055
|
||||||
4. **Non-Unix platforms**: the negative-code convention is `#[cfg(unix)]`; Windows backends report `code()` only (signal termination essentially does not occur) — the mapping detail records the graceful shift.
|
|
||||||
5. **Pipe-mode pid-only vs PTY process-group signal scope** (carried from the POC): backend semantics, not a mapping change — a fidelity note on the `signal` row.
|
|
||||||
- **Impacts**: blocks the `exit-signal` fidelity detail in `mapping.md` only; no upstream ask stands by default.
|
|
||||||
- **Resolution**: pending. Direction fixed: alkssh derives exit-signal fidelity from the existing wire (the documented negative-code convention). Decide the derivation details (−1 disposition, core-dumped assertion, non-Unix note) when writing `mapping.md`; record them as an ADR-006 amendment or a dedicated ADR. Any *upstream* widening of the exit chunk would require its own alktty ADR with the full consequence analysis above of the tty/pty rationale — that gate is stated here so it cannot be skipped.
|
|
||||||
- **Cross-references**: OQ-08, [mapping.md](mapping.md) (`exit_signal`, `signal` rows), alktty ADR-004 / `tty-wire.md` (alktty repo), alknet ADR-055
|
|
||||||
|
|
||||||
### OQ-11: `direct-streamlocal` platform surface — compile-time or runtime decline shape?
|
### OQ-11: `direct-streamlocal` platform surface — compile-time or runtime decline shape?
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ request-level extras.
|
|||||||
|
|
||||||
| SSH channel type | Vanilla use | Feature (candidate) | Family seam | Notes |
|
| SSH channel type | Vanilla use | Feature (candidate) | Family seam | Notes |
|
||||||
|---|---|---|---|---|
|
|---|---|---|---|---|
|
||||||
| `session` → `pty_request`+`shell_request` | `ssh host` interactive shell | `session` | alktty producer: `NegotiateRequest` constructed locally → `drive_session` (or pre-allocated variant) | `pty_request` args → `TerminalParamsWire` (term/cols/rows/pixels; SSH modes → `modes` JSON reserved); shell case needs a cmd convention (OQ); PTY mode merges stderr into stdout (kernel PTY). **[POC-3 corrected]** the data-plane mapping is a *translation bridge*, not a byte pump: alktty's plane is chunk-framed both directions (stdin/stdout/stderr + CTRL_IN/CTRL_OUT chunks), so alkssh encodes SSH data→stdin chunks and decodes stdout→data, stderr→extended_data, exit chunk→exit-status/exit-signal. New OQ: the exit chunk carries no signal identity (negative code only). **[Corrected 2026-10-27]** the negative code *is* the signal encoding (alktty ADR-004); the OQ is about server-side derivation details, not chunk widening
|
| `session` → `pty_request`+`shell_request` | `ssh host` interactive shell | `session` | alktty producer: `NegotiateRequest` constructed locally → `drive_session` (or pre-allocated variant) | `pty_request` args → `TerminalParamsWire` (term/cols/rows/pixels; SSH modes → `modes` JSON reserved); shell case needs a cmd convention (OQ); PTY mode merges stderr into stdout (kernel PTY). **[POC-3 corrected]** the data-plane mapping is a *translation bridge*, not a byte pump: alktty's plane is chunk-framed both directions (stdin/stdout/stderr + CTRL_IN/CTRL_OUT chunks), so alkssh encodes SSH data→stdin chunks and decodes stdout→data, stderr→extended_data, exit chunk→exit-status/exit-signal. The exit chunk encodes pipe-path signal termination as the negative code `−N` (alktty ADR-004's convention — `pipe.rs::exit_code_from`); the PTY path reduces signal termination to a plain exit code (portable-pty's exit surface), so PTY-mode `exit-signal` fidelity is an alktty-backend question |
|
||||||
| `session` → `exec_request` (non-git command) | `ssh host "cmd"` | `session` | alktty pipe mode: `terminal: None`, separate stderr | stderr flows back as SSH `extended_data` code 1 — only valid without PTY |
|
| `session` → `exec_request` (non-git command) | `ssh host "cmd"` | `session` | alktty pipe mode: `terminal: None`, separate stderr | stderr flows back as SSH `extended_data` code 1 — only valid without PTY |
|
||||||
| `session` → `exec_request`/`subsystem_request` git | `git push/clone ssh://` | `git` | alkgit: parse command → `Service` + repo (same grammar as `preamble.rs`, without `\0host=`) → `serve_duplex_resolved(repo_id, identity, service, duplex, ...)` | Process-mode dialect is correct (SSH supplies service+repo out of band; server speaks first = advertisement). **[POC-3 corrected]** git over SSH is exec-only: a `subsystem` request carries the service *name* but no repo id, so even a git-service subsystem must decline — vanilla git always executes `git-upload-pack '/repo'`. POC-3: vanilla clone/push/second-push through the published seam + substrate composition, exit-status in both directions |
|
| `session` → `exec_request`/`subsystem_request` git | `git push/clone ssh://` | `git` | alkgit: parse command → `Service` + repo (same grammar as `preamble.rs`, without `\0host=`) → `serve_duplex_resolved(repo_id, identity, service, duplex, ...)` | Process-mode dialect is correct (SSH supplies service+repo out of band; server speaks first = advertisement). **[POC-3 corrected]** git over SSH is exec-only: a `subsystem` request carries the service *name* but no repo id, so even a git-service subsystem must decline — vanilla git always executes `git-upload-pack '/repo'`. POC-3: vanilla clone/push/second-push through the published seam + substrate composition, exit-status in both directions |
|
||||||
| `session` → SOCKS5-in-channel | (n/a — retired) | ~~`dynamic-forward`~~ **retired (ADR-003 §1a)** | was alksocks: `serve_socks5_over` | **Post-architecture retirement:** no consumer is ever the family-native client shape this row served. Vanilla `ssh -D` does SOCKS client-side and opens plain `direct-tcpip` (POC-3 correction 2 → the `tunnel` row); the family `-D` behavior is a *client-local* alksocks door over the alkssh client's `direct-tcpip` opens (assembly composition). POC-3 stage B remains the evidence that SOCKS-in-channel is feasible if a family client ever wants a remote SOCKS door (back via explicit ADR). **[ADR-003 amended]** |
|
| `session` → SOCKS5-in-channel | (n/a — retired) | ~~`dynamic-forward`~~ **retired (ADR-003 §1a)** | was alksocks: `serve_socks5_over` | **Post-architecture retirement:** no consumer is ever the family-native client shape this row served. Vanilla `ssh -D` does SOCKS client-side and opens plain `direct-tcpip` (POC-3 correction 2 → the `tunnel` row); the family `-D` behavior is a *client-local* alksocks door over the alkssh client's `direct-tcpip` opens (assembly composition). POC-3 stage B remains the evidence that SOCKS-in-channel is feasible if a family client ever wants a remote SOCKS door (back via explicit ADR). **[ADR-003 amended]** |
|
||||||
@@ -90,8 +90,8 @@ spec detail deferred to phase 1.
|
|||||||
| `window_change_request` | `TtyControlHandle::resize(cols, rows, pixel_w, pixel_h)` |
|
| `window_change_request` | `TtyControlHandle::resize(cols, rows, pixel_w, pixel_h)` |
|
||||||
| `signal` | `TtyControlHandle::signal(name)` (alktty's `signal_from_name` accepts the HUP/INT/TERM/... names verbatim) |
|
| `signal` | `TtyControlHandle::signal(name)` (alktty's `signal_from_name` accepts the HUP/INT/TERM/... names verbatim) |
|
||||||
| data / `extended_data(1)` | channel duplex in/out; stderr only meaningful in pipe mode (PTY merges) |
|
| data / `extended_data(1)` | channel duplex in/out; stderr only meaningful in pipe mode (PTY merges) |
|
||||||
| `exit_status` | from `TtyHandle.exit_code` (`TtySession.wait()` semantics: i32; negative = signal-terminated) — alkssh sends the SSH `exit-status` request before channel close (POC-3: proven both directions via the cloned `Session::handle()` from the spawned serving task) |
|
| `exit_status` | from `TtyHandle.exit_code` (`TtySession.wait()` semantics: i32; negative = signal-terminated on the pipe path — `pipe.rs::exit_code_from` maps Unix `ExitStatus::signal()` to `−sig`; the PTY path reduces signal termination to a plain exit code, see the exit_signal row) — alkssh sends the SSH `exit-status` request before channel close (POC-3: proven both directions via the cloned `Session::handle()` from the spawned serving task); `−1` (alktty's could-not-determine sentinel, alktty ADR-004 §4) → `exit-status(255)` |
|
||||||
| `exit_signal` | Only reachable in signal-termination cases; mapped from the same exit-code path (OQ: exact encoding). **[POC-3]** the alktty exit chunk is `{"type":"exit","code":N}` — a negative code implies signal termination but carries no *name*, so the faithful `exit-signal` mapping needs alktty to widen the chunk or an assembly-policy default. **[Corrected 2026-10-27]** the "needs widening" premise was wrong: the negative code *is* the documented signal encoding (alktty ADR-004, ported from alknet ADR-055; `pipe.rs::exit_code_from` — Unix `ExitStatus::signal() → -sig`), so the name is derivable server-side by alkssh; no chunk change is justified by default. The genuine gaps (core-dumped discarded, the `−1` wait-failure/SIGHUP collision, non-Unix) are alkssh mapping-contract details — alkssh OQ-10 |
|
| `exit_signal` | derived server-side from the exit chunk's negative code — `−N` → name via a Unix signal-number→name table; `core_dumped` never asserted (alktty discards `ExitStatus::core_dumped()`); no chunk change is needed or proposed (the encoding is alktty's documented contract, alknet ADR-055 lineage). POC-3 observed `−15` → `exit-signal("TERM")` live on the pipe path. PTY path: portable-pty 0.9's `ExitStatus` conversion yields `code = status.code().unwrap_or(1)` (**1**) for signal-terminated children, keeping the signal only in a separate humanized (`strsignal`) string field alktty's waiter discards — faithful `exit-signal` on the PTY row needs the alktty backend to conform to its own ADR convention (upstream ask: alktty/portable-pty trackers; the alkssh contract adapts automatically) |
|
||||||
|
|
||||||
## Data-plane / limits contract
|
## Data-plane / limits contract
|
||||||
|
|
||||||
|
|||||||
@@ -266,37 +266,41 @@ against a **real PTY** (`LocalTtyBackend` over portable-pty):
|
|||||||
(parse-then-route: the git parse is the `git` feature's gate) —
|
(parse-then-route: the git parse is the `git` feature's gate) —
|
||||||
the feature-split failure matrix holds in this build too.
|
the feature-split failure matrix holds in this build too.
|
||||||
|
|
||||||
### 2. The signal-identity gap (new OQ)
|
### 2. Signal/exit fidelity over the alktty exit-code convention
|
||||||
|
|
||||||
The exit chunk is `{"type":"exit","code":N}` — a negative code says
|
The exit chunk is `{"type":"exit","code":N}` (alktty ADR-004, ported
|
||||||
*signal-terminated* but **carries no signal name**. The adapter cannot
|
from alknet ADR-055). Findings of this stage, verified against the
|
||||||
map SSH `exit-signal` faithfully from the chunk alone (the POC's check
|
published sources:
|
||||||
asserts TERM because the *request* was TERM, not because the chunk
|
|
||||||
said so). Options for the ADR: alktty widens the exit chunk with the
|
|
||||||
signal name, or alkssh fixes the exit-signal name by assembly policy.
|
|
||||||
Also recorded: pipe-mode signals are **pid-only** (a SIGTERM to `sh -c
|
|
||||||
"sleep 60"` leaves the orphaned `sleep` holding the stdout pipe — no
|
|
||||||
exit chunk until the whole group dies); PTY-mode signals reach the
|
|
||||||
process group (correct terminal semantics). The signal row's fidelity
|
|
||||||
therefore depends on the tty/pipe mode split the table already notes.
|
|
||||||
|
|
||||||
**[Corrected 2026-10-27]** The "signal-identity gap" framing above was
|
- **Pipe path — the negative code is the signal encoding.** Pipe-mode
|
||||||
an incorrect assumption, surfaced during review and now corrected in
|
signal-terminated children arrive as the negative signal number
|
||||||
the alkssh tracker (OQ-10). The exit chunk's negative code *is* the
|
verbatim from std's `ExitStatusExt` (`pipe.rs::exit_code_from` maps
|
||||||
signal identity, by alktty's documented one-way convention (alktty
|
`ExitStatus::signal()` to `−sig`; the alknet ADR-055 convention).
|
||||||
ADR-004 decision 1, ported from alknet ADR-055;
|
So SSH `exit-signal` needs no wire change: the adapter's check
|
||||||
`src/local/pipe.rs::exit_code_from` maps Unix `ExitStatus::signal()`
|
mapped `−15` → `exit-signal("TERM")` — the name derivation is a
|
||||||
to `-sig`) — the tty/pty ground truth (a reaped wait-status,
|
server-side number→name table lookup, not an alktty ask.
|
||||||
preserved across one backend-wide `exit_code → i32` API), not an
|
- **PTY path — the signal number does not survive the backend.**
|
||||||
absence. The signal *name* is derivable server-side by alkssh, so
|
portable-pty 0.9's `ExitStatus` conversion records
|
||||||
"alktty widens the chunk" is not a justified default candidate: it
|
`code = status.code().unwrap_or(1)` → **1** for signal-terminated
|
||||||
would change `ControlMessage::Exit`'s one-way parsed shape, force the
|
children, keeping the signal only in a separate humanized
|
||||||
backend-wide API to widen, and ripple the alknet ADR-055 lineage — an
|
(`strsignal`-text) string field that alktty's PTY waiter discards
|
||||||
alktty ADR with explicit justification, only if a fidelity failure
|
(`pty.rs` reads `exit_code()` only; the number is unrecoverable
|
||||||
demands it. The genuine gaps — core-dumped (discarded), the `−1`
|
through portable-pty 0.9's trait surface). Alktty's own PTY signal
|
||||||
wait-failure/SIGHUP collision (pre-existing, documented in alktty
|
tests assert `code != 0`, never the encoding. Consequence: faithful
|
||||||
ADR-004 with an additive `exit_error` escape), and non-Unix semantics
|
`exit-signal` for signal-killed PTY sessions needs the alktty
|
||||||
— are alkssh mapping-contract details.
|
backend to conform to its own ADR's negative-code convention — an
|
||||||
|
alktty/portable-pty ask with tty/pty-grounded justification (upstream
|
||||||
|
trackers; the alkssh mapping adapts automatically, no hedge needed).
|
||||||
|
- **The `−1` sentinel** (backend wait failure) collides with a real
|
||||||
|
SIGHUP termination (signal 1) — documented in alktty ADR-004 §4,
|
||||||
|
with an additive `exit_error` control type as its recorded extension
|
||||||
|
seam. Alkssh renders `−1` as `exit-status(255)` — it fabricates no
|
||||||
|
signal for a wait failure.
|
||||||
|
- **Pipe-mode signals are pid-only** (a SIGTERM to `sh -c "sleep 60"`
|
||||||
|
leaves the orphaned `sleep` holding the stdout pipe — no exit chunk
|
||||||
|
until the whole group dies); PTY-mode signals reach the process
|
||||||
|
group (correct terminal semantics). The signal row's fidelity
|
||||||
|
depends on the tty/pipe mode split the table already notes.
|
||||||
|
|
||||||
### 3. Client-visible mechanics (russh 0.64 API facts from this stage)
|
### 3. Client-visible mechanics (russh 0.64 API facts from this stage)
|
||||||
|
|
||||||
@@ -334,7 +338,7 @@ ADR-004 with an additive `exit_error` escape), and non-Unix semantics
|
|||||||
per bridged route.
|
per bridged route.
|
||||||
- "stage D may surface PTY-merge stderr surprises that reshape the
|
- "stage D may surface PTY-merge stderr surprises that reshape the
|
||||||
request-level mapping rows" — partially: no surprises in the
|
request-level mapping rows" — partially: no surprises in the
|
||||||
PTY/pipe split, but the **signal-identity gap** and the
|
PTY/pipe split, but the **signal/exit-fidelity details** and the
|
||||||
**translation-bridge shape** (two adapters, not a pump) do reshape
|
**translation-bridge shape** (two adapters, not a pump) do reshape
|
||||||
the session row's implementation notes.
|
the session row's implementation notes.
|
||||||
|
|
||||||
@@ -350,16 +354,19 @@ ADR-004 with an additive `exit_error` escape), and non-Unix semantics
|
|||||||
family-native clients; vanilla `-D` rides the `tunnel` row.
|
family-native clients; vanilla `-D` rides the `tunnel` row.
|
||||||
3. `mapping-table.md` session/pty row implementation notes: the
|
3. `mapping-table.md` session/pty row implementation notes: the
|
||||||
alktty bridge is a **translation bridge** (chunk framing both
|
alktty bridge is a **translation bridge** (chunk framing both
|
||||||
directions), not a byte pump; plus the exit-chunk signal-identity
|
directions), not a byte pump; plus the exit/signal fidelity
|
||||||
gap above.
|
findings above (pipe-path `−N` encoding holds; PTY path reduces
|
||||||
|
signal termination to a plain code — portable-pty's exit surface).
|
||||||
|
|
||||||
## OQ seeds carried forward
|
## OQ seeds carried forward
|
||||||
|
|
||||||
1. Session-channel dispatch shape for SOCKS (first-byte sniff vs
|
1. Session-channel dispatch shape for SOCKS (first-byte sniff vs
|
||||||
in-band preamble vs exec marker; the detect window's bound).
|
in-band preamble vs exec marker; the detect window's bound).
|
||||||
2. Exit-chunk signal identity (alktty exit chunk widening vs
|
2. Exit/signal fidelity over the alktty exit-code convention (the
|
||||||
assembly-policy mapping; pipe-mode pid-only vs PTY process-group
|
`−N` encoding holds on the pipe path — name derivation is
|
||||||
scope).
|
server-side; the PTY path's signal-identity loss is an
|
||||||
|
alktty/portable-pty matter; pipe-mode pid-only vs PTY
|
||||||
|
process-group scope).
|
||||||
3. Shell command convention (already seeded; the POC's stand-in —
|
3. Shell command convention (already seeded; the POC's stand-in —
|
||||||
`bash` for shell, `sh -c <cmd>` for exec — is an explicit assembly
|
`bash` for shell, `sh -c <cmd>` for exec — is an explicit assembly
|
||||||
policy, not wire-derived).
|
policy, not wire-derived).
|
||||||
|
|||||||
@@ -138,12 +138,10 @@ forms). russh server loopback + vanilla clients; per stage:
|
|||||||
original plan was unnecessary — stage D completed 13/13 and produced
|
original plan was unnecessary — stage D completed 13/13 and produced
|
||||||
the load-bearing session-row corrections: the alktty bridge is a
|
the load-bearing session-row corrections: the alktty bridge is a
|
||||||
**translation bridge** (chunk framing both directions, not a byte
|
**translation bridge** (chunk framing both directions, not a byte
|
||||||
pump) and the alktty exit chunk carries no signal identity
|
pump) and the exit/signal findings over the alktty exit-code
|
||||||
(`poc-3-mapping-bakeoff.md` §Stage D). [Corrected 2026-10-27: the
|
convention (pipe-path signal termination rides the negative code
|
||||||
"no signal identity" claim overstated the gap — the exit chunk's
|
`−N`; the PTY path reduces signal termination to a plain exit
|
||||||
negative code *is* the documented signal encoding (alktty ADR-004);
|
code — `poc-3-mapping-bakeoff.md` §D.2).
|
||||||
see `poc-3-mapping-bakeoff.md` §D.2's correction and alkssh
|
|
||||||
OQ-10.]
|
|
||||||
|
|
||||||
**Validates:** the one-seam-per-mapping hypothesis; the parse-then-
|
**Validates:** the one-seam-per-mapping hypothesis; the parse-then-
|
||||||
route dispatch; stderr semantics in pipe vs PTY mode; EOF/close/signal
|
route dispatch; stderr semantics in pipe vs PTY mode; EOF/close/signal
|
||||||
|
|||||||
Reference in new issue
Block a user