- 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 Follows6b20924(src doc comments) andcd0afe0(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/
7.5 KiB
id, name, status, depends_on, scope, risk, impact, level, tags
| id | name | status | depends_on | scope | risk | impact | level | tags | |||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| tunnels/corrmiss-adr | ADR: the forwarded op's establishment phase + the correlation-miss vocabulary (resolves review 003's decisions) | completed | narrow | medium | phase | implementation |
|
Description
Land the ADR ink for the settled decisions in
docs/plans/003-correlation-miss-resolve.md §Decisions (1-4): the
forwarded op's serving side gains an establishment phase; a stale/
missing listen token fails the open as a typed channel:open_failed
(rewriting plan decision 2: the wire vocabulary already pins
unknown_resource, so no wire-vocabulary extension and no
reason-class ADR); the residual post-open decline (the narrow
establisher-pass/handler-miss race) keeps teardown-at-birth and adopts
correlation-miss as the canonical event name with alkssh's level
posture (assembly-side declines at debug; the producer-side generic
arm keeps warn now carrying a typed reason instead of a prose one).
Also record the tri-vocabulary history the decision retires:
alkssh correlation-miss (debug, decline_arrival), alksocks prose
("forwarded open with no waiting session", warn,
src/composed/mod.rs:497), alktunnels handler_error-class generic
arm (warn, the bind-first accept loop's failed-open branch); review
003's situation section plus the plan's §Verified findings are the
primary sources for it.
Doc-only change; no code in this task.
Shape to decide while writing (the plan's "ADR-008 amendment
(or a small successor ADR)" choice)
Recommendation: an Amendment 2 to ADR-008. This amends the forwarded op's serving shape exactly as §3 pins it (that section's sentence "no establisher: the forwarded channel needs no establishment; its data plane starts immediately" is the text being amended), the wire vocabulary is unextended, and the amendment keeps the whole forwarded-op decision record in one ADR. Take a small successor ADR instead only if the amendment balloons (e.g. it forces restating §4/§5 wholesale). Whichever shape: mark the amended §3 sentence, cross-link the plan and review 003, keep the existing ADR text's amendment style (the landed Amendment 1 is the format precedent).
The invariants the ADR must pin
- The gate is injected: the protocol crate cannot hold the assembly's
correlation map; the establisher's check is an assembly-provided
closure the crate wraps into the alkcall
OpenEstablisherdance (the plan's W1 decision; assemblies must not hand-roll the alkcall establisher plumbing). - The gate rides
register_openable_with_establisher(alkcall 0.10.0, verified): establisher failure → typedchannel:open_failedwithdetails.reason; "never a phantom channel" is ADR-049's posture. The forwarded op currently rides the phantom-shaped serving side (establisher-less everywhere), and this closes it for the miss class. unknown_resourceis reused as-is (the waiting session IS a resource that is gone), sodetails.reason's wire vocabulary is NOT extended.- The scope gate (
tunnel:forwarded) precedes the establisher; pin the order (the registry runs the ACL before the open op's establishment phase; alkcall's open-op wrapper order). - The residual post-open race keeps teardown-at-birth (the fallback
shape, which is ADR-008 §3's opener-half posture, unchanged), and
its event
name is
correlation-missatdebug(assembly-side; the protocol crate's built-in handler holds no map, so the name is the assemblies' convention this ADR records, not code this crate runs). - Additive-only surface: the base
register_tunnel_forwarded_openableshape stays for compatibility; the establisher variant is the recommended posture (new assemblies take it by default posture).
Acceptance Criteria
- Amendment 2 to ADR-008 (or the successor ADR) lands under
docs/architecture/decisions/, covering all four §Decisions and the tri-vocabulary history - The amended/superseded §3 sentence is marked, not silently replaced
- Wire-vocabulary non-extension is explicit (
unknown_resourcereused;wire.md§The Open Ops untouched; state that) - Status block of
docs/reviews/003-correlation-miss-arrival-class-alkssh-input.mdis NOT updated here (the doc-sync task owns it; this task is the ADR itself) - No code changes; doc build clean (
cargo doc --no-depsclean is NOT required for pure docs/ edits; verify md renders coherently instead)
References
- docs/plans/003-correlation-miss-resolve.md §Decisions, §Verified findings, §W1 (this task is the ADR bullet of W1)
- docs/reviews/003-correlation-miss-arrival-class-alkssh-input.md
- docs/architecture/decisions/008-listen-metadata-forwarded-op.md §3 (the serving shape being amended; Amendment 1 is the format precedent)
- docs/architecture/wire.md §The Open Ops (the pinned
details.reasonvocabulary, unextended) - alkcall ADR-049 (the establisher posture being extended to the
forwarded op's serving side); alkcall 0.10.0
register_openable_with_establisher(verified present)
Notes
- Shape chosen: Amendment 2 to ADR-008 (the recommendation held: it did not balloon, and §4/§5 needed no restating).
- Before writing, verified the ground against the shipped sources:
alkcall 0.10.1
EstablishmentError(variantsDialFailed/UnknownResource/ResourceShortage/HandlerError;.reason()mapsUnknownResource → "unknown_resource", operations.rs:592-596) andregister_openable_with_establisher(operations.rs:761); the open-op wrapper order (policy.check_open, the ACL, then allocate → establisher → handler, operations.rs:1085-1103) pins the "scope gate precedes the establisher" invariant. Cargo.toml pinsalkcall = "0.10.1", so the ADR says "0.10.x, verified present". - The amended §3 sentence (lines 187-196, the serving-shape bullet) is marked inline with "amended by Amendment 2"; the pre-amendment posture is recorded, not replaced (the Amendment 1 style).
- Deliberately NOT touched:
wire.md(the amendment states itsdetails.reasonvocabulary is unextended; the one serving-shape prose line ("no establisher" under §The Forwarded Op) syncs with the API task per the amendment's note) and review 003's status block (doc-sync task owns it).
Summary
Amendment 2 landed at
docs/architecture/decisions/008-listen-metadata-forwarded-op.md
(2026-11-03): the forwarded op's serving side gains an establishment
phase: an assembly-provided gate closure (over
TunnelForwardedParams) the crate wraps into the alkcall
OpenEstablisher dance via register_openable_with_establisher,
with failures mapped to EstablishmentError::UnknownResource so a
stale/missing listen token is a typed
channel:open_failed/unknown_resource before any channel is born.
unknown_resource is reused as-is; the wire vocabulary is unextended
and wire.md is untouched. Gate order pinned (tunnel:forwarded ACL
precedes the establisher); the residual post-open race keeps
teardown-at-birth with the canonical assembly-side name
correlation-miss at debug (producer-side generic arm stays warn
with the typed reason); the base
register_tunnel_forwarded_openable stays, the establisher variant
is the recommended default posture; the wire delta of the amendment
is empty. The tri-vocabulary history (alkssh correlation-miss
debug, alksocks prose warn, alktunnels handler_error-class generic
warn + the fabric-side silence) is recorded with sources. Doc-only;
no code changes.