docs(plan): resolve review 003 — the correlation-miss arrival class

Plan for the review-003 resolution: route the forwarded-op correlation
miss through an establisher (typed unknown_resource failure, the
ADR-049 posture extended), adopt alkssh's correlation-miss as the
canonical event name for the residual decline, and align the family
(alkssh + alksocks waves). Adds the session's verification findings:
the alksocks prose variant (third vocabulary) and the fully-silent
in-session miss on the fabric side.

Verified: cargo fmt --check, cargo test (13 suites ok), clippy
--all-targets -D warnings (native + wasm32). Docs-only change.
This commit is contained in:
glm-5.3-flash committed 2026-11-03 07:56:08 +00:00
1 parent ec52a9620d
commit bd8a82b4c4
1 file changed
+138
+138
View File
@@ -0,0 +1,138 @@
# Plan — resolve review 003: the correlation-miss arrival class
Status: planned (2026-11-03). Resolution of
`docs/reviews/003-correlation-miss-arrival-class-alkssh-input.md`,
including the verification caveats found in this session (see §Verified
findings — they extend the review, 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 — 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 —
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) — 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)