Files
alktunnels/docs/plans/003-correlation-miss-resolve.md
glm-5.3-flash 0ceecf582b docs: remove em dashes from repo prose and forbid them going forward
- Rewrote the remaining em dashes outside docs/reviews/ (preserved as
  historical record, matching the alktty precedent): tests/ (313),
  fuzz/ (34 plus one shell comment), tasks/ (671 plus 12 kept in
  fences), docs/research + sdd_process + plans (525 plus 25 in
  fences), docs/architecture/overview.md fence labels (13), README,
  CHANGELOG, AGENTS.md, fuzz/README.md (176), and the
  .opencode/agents prompts (110)
- Rewrote fenced content too: ASCII tree and module-map label
  separators, Rust snippet comments, and template placeholders; wire
  data, JSON/BAST examples, and transcripts survive verbatim
- Rewrote 6 assert/expect message literals in tests/ and 2 format
  strings in fuzz/shared/src; no test data changed
- Added Project Convention 18: no em dashes in prose (doc comments,
  markdown including docs/ and tasks/, agent prompts, commit
  messages); fence content rule, en-dash clause rule, and the
  no-spaced-hyphen prohibition follow alktty's convention 15

Follows 6b20924 (src doc comments) and cd0afe0 (docs/architecture).

Verification: cargo test (141 pass); cargo clippy --all-targets -D
warnings; cargo fmt --check; cargo doc --no-deps; wasm check and
clippy for wasm32-unknown-unknown with -D warnings; em dash grep over
the repo returns matches only in docs/reviews/
2026-11-03 14:12:46 +00:00

7.2 KiB

Plan: resolve review 003 (the correlation-miss arrival class)

Status: W1 landed (2026-11-03), covering ADR-008 Amendment 2, the …_with_establisher surface, the gate tests, and the review/checkpoint

  • doc sync done. W2 (alkssh) / W3 (alksocks) are open: sibling-repo sessions, unticked until those repos land. Resolution of docs/reviews/003-correlation-miss-arrival-class-alkssh-input.md (also kept: it records the tri-vocabulary decision's ground), including the verification caveats found in this session (see §Verified findings, which extend the review and do not contradict it).

Verified findings (the ground the plan stands on)

The review's claims held under code verification. Two additions sharpen the resolution scope:

  • A third vocabulary variant. alksocks (src/composed/mod.rs:497) logs the same miss class as prose at warn ("forwarded open with no waiting session"). So the family names the stale-token miss three ways: alkssh correlation-miss (debug), alksocks prose (warn), alktunnels handler_error-class generic arm (warn, call-plane failures only).
  • The in-session miss is fully silent on the fabric side. The forwarded op is served establisher-less everywhere (alkssh, alksocks, and this crate's own built-in shape), so an in-session correlation miss (route removed while the fabric connection lives) succeeds at the call plane, declines post-open in the assembly, and the producer-side pump EOFs with no log at all. The generic arm (src/producer.rs:838-854) only fires for the connection-gone/NOT_FOUND/ACL-refused subclass.
  • All three are the phantom-channel shape, i.e. the ADR-049 posture exception ("a refused open is a typed call error, never a phantom channel") that the forwarded op's serving side currently rides.

Decisions (settled this session, pending ADR ink)

  1. Route the miss through an establisher: the serving side gains an establisher variant so a no-route token returns a typed channel:open_failed before the channel is born. The residual post-open decline (a token missing between establisher pass and handler run, a narrow race) keeps teardown-at-birth as the fallback shape.
  2. Reuse unknown_resource as the typed reason for a stale/missing token. The waiting session is a resource that is gone; the wire vocabulary (wire.md §The Open Ops, details.reason ∈) already pins it. No wire-vocabulary extension, no reason-class ADR (framing option 2's "new class" question is moot).
  3. Adopt correlation-miss as the canonical event name for the residual post-open decline class (alkssh's shipped vocabulary wins, as it is published); alksocks' prose variant retires. Level posture: assembly-side declines at debug; the producer-side generic arm stays warn (it now carries a typed reason instead of a prose one).
  4. Scope of the change is additive-only in this crate: a new registration surface for the forwarded op. The base register_tunnel_forwarded_openable shape stays (compatibility + assemblies that prefer the post-open shape); the establisher variant is the recommended shape and new assemblies take it by default posture.

Work items

W1 (alktunnels): ADR + additive API (this repo; ~1 session)

  • ADR-008 amendment (or a small successor ADR): the forwarded op's serving side gains an establishment phase; misses are typed failures (decision 1-4 above), the residual post-open decline keeps the correlation-miss name. Also record the tri-vocabulary history the decision retires (review 003 + this plan).
  • API: an establisher variant for the forwarded-op serving half. The protocol cannot hold the assembly's correlation map, so the establisher's check is injected. Candidate shape (a W1 design decision to finalize): a small assembly gate closure ((TunnelForwardedParams) -> Result<(), TunnelEstablishError>) that the crate wraps into the alkcall OpenEstablisher dance, plus register_tunnel_forwarded_openable_with_establisher(core, on_registry, auth, gate, handler). Assemblies must not hand-roll the alkcall establisher plumbing.
  • Tests: miss at the gate → channel:open_failed with reason unknown_resource, no channel allocated; gate-pass → existing serving flow unchanged; the residual race shape (gate passes, route gone at handler time) still reaps cleanly; scope gate unchanged (tunnel:forwarded, runs before the establisher; pin the order).
  • Update the in-code docs that describe the miss as assembly-side-only (make_forwarded_op_handler doc, Register…forwarded doc).

W2 (alkssh): adopt the establisher (dedicated session; alkssh repo)

  • Move pump_forwarded_arrival's route lookup into the new gate (the ListenRouter lookup becomes the establisher's check); the residual handler keeps decline_arrival("correlation-miss", …) for the narrow post-open race only.
  • Verify the fabric-side silence fix: a stale-token arrival now fails the open (alkssh-side typed error; producer-side generic arm fires with a parseable reason), so the race window no longer produces a zero-signal pump.
  • Fold alkssh's em-dash doc cleanup into its release for this change ("cleanup rides the code-update release"; the user-owned task, out of this plan).

W3 (alksocks): adopt the establisher (dedicated session; alksocks repo)

  • Move CorrelationRegistry lookup into the new gate; retire the prose warn (the miss becomes a typed failure at the open; residual logging aligns to correlation-miss at debug).
  • Fold alksocks' em-dash doc cleanup into its release for this change (user-owned, out of this plan).

Ordering

W1 → {W2, W3} (the dependent waves can run in parallel; each is its own session). Em-dash cleanup rides each repo's release for its wave and is otherwise out of scope here.

Acceptance criteria (plan level)

  • W1: ADR landed; …_with_establisher surface landed; tests green (cargo test, clippy --all-targets -D warnings, fmt, wasm check; --all-features as far as features exist today); review 003 status updated to resolved (W1 absorbed; W2/W3 pointed).
  • W2: alkssh serves the gate shape; stale-token arrival produces a typed call-plane failure; residual class named correlation-miss at debug; alkssh release includes its doc cleanup.
  • W3: alksocks serves the gate shape; prose variant retired; residual logging aligned; release includes its doc cleanup.
  • The family names the class one way in its event surface; composed -R traces read coherently end to end.

References

  • docs/reviews/003-correlation-miss-arrival-class-alkssh-input.md (the ask; this plan resolves it)
  • docs/architecture/decisions/008-listen-metadata-forwarded-op.md §3 (the serving shape this amends); alkcall ADR-049 (the establisher posture being extended); docs/architecture/wire.md §The Open Ops (the pinned details.reason vocabulary, unextended by this plan)
  • src/producer.rs (the generic arm; the forwarded-op serving half); alkssh src/tunnel_map.rs (pump_forwarded_arrival, ListenRouter); alksocks src/composed/mod.rs (make_forwarded_handler, CorrelationRegistry)
  • alkssh docs/plans/implementation.md ("Still booked with their owners" (the booking this filing unblocks)