Files
alkssh/tasks/implementation/w3-seam-config.md
T
glm-5.3-flash d1f755f2d9 docs(tasks): decompose wave 3 — the server mappings
Six implementation tasks + the gate under tasks/implementation/,
chained sequentially (the mappings replace stubs in the same Handler
impl and share the decline-matrix test binaries):

- w3-seam-config: the serve-config's per-feature seam handles
  (alktty backends/ownership/selector; the alkgit quartet/pipeline/
  push-options flag) + the optional sibling deps — wave 3's first
  course correction to the wave-1 config surface
- w3-decline-tracing: the wave-2 gate's booked finding — the
  decline/serve-path tracing vocabulary, landed before the mappings
- w3-git-mapping: the full exec grammar replaces the wave-2 probe +
  the serve_duplex_resolved dispatch + the store-and-take handoff
- w3-tty-session: the translation bridge + the exit-derivation
  contract (rules 1-6, the signum table)
- w3-tunnel-direct: the route-1 bridge (accept only after the fabric
  open succeeds) + set_identity propagation + the capacity-across-
  fabric-window mechanics
- w3-tunnel-listen: the -R listen flow + the forwarded-tcpip data
  leg (the POC-untested leg; the stop-and-book provision)
- review-wave-3: the gate

The plan carries the wave-3 decomposition record with four
interpretations flagged for the gate (the serve-config course
correction, the already-discharged server-side sftp bullet, the
w3-tunnel-listen open mechanics, the booked-items' wave-3 homes).
taskgraph validate: 26 tasks, clean.

Sibling pins verified against crates.io at decomposition time:
alktty 0.8.1 / alkgit 0.1.0 / alktunnels 0.4.1 / alkcall 0.10.1.
2026-10-28 12:32:13 +00:00

4.6 KiB

id, name, status, depends_on, scope, risk, impact, level
id name status depends_on scope risk impact level
w3-seam-config Wave 3 — serve-config seam handles (alktty/alkgit per-feature) pending
review-wave-2
w1-config
narrow low component implementation

Description

Extend [crate::ServeConfig] with the per-feature family-seam handles the wave-3 mappings consume. This is wave 3's first course correction to the wave-1 config surface — the assembly-supplied composition inputs were never carried (mapping.md's seam-entries table names them inside the seam signatures; the wave-1 config bullet pre-dates that reading), and the mappings cannot call drive_session[_pre_negotiated] / serve_duplex_resolved without them. Landing them here, before the mapping tasks, keeps the un-set-declines posture structural and the review surface unified:

  • The session seam handle (feature-gated), unset → the session rows decline even with the feature on (the decline matrix's "an unset field declines its row though the feature is on" note, config-driven). Contents, per alktty 0.8.1's actual drive_session[_pre_negotiated] signature — decide the exact final shape (flat Option fields vs an Option-struct per seam; record):
    • the alktty backends map (Arc<HashMap<String, Arc<dyn TtyBackend>>> — assembled by the assembly; alkssh never touches a real backend, the local shapes stay alktty-side);
    • the backend selector — the NegotiateRequest.backend string alkssh writes (assembly-supplied, never wire-derived; decide and record);
    • the ownership provider Option<Arc<dyn alkcall::core::ownership::OwnershipProvider>> (an alkcall type — no new dep; pass-through to drive_session_pre_negotiated, family ACL layer riding along).
  • The git seam handle (feature-gated), unset → the git rows decline even with the feature on. Contents, per alkgit 0.1.0's serve_duplex_resolved signature: the four backend traits (GitRegistry / GitRefs / GitPackGen / GitPackIngest), the caller-owned server-wide pipeline: Arc<tokio::sync::Semaphore>, and push_options_negotiated: bool (the assembler's config flag; false in the v1 default).
  • Manifest (the wave-1 rule: per-feature sibling deps land with their first consuming wave — the config fields consume them first, so they are not dead entries): optional deps alktty = "0.8.1", alkgit = "0.1.0" wired feature-to-dep (session = ["dep:alktty"], git = ["dep:alkgit"]) so a git-build never compiles alktty and vice versa; verify the pins against crates.io before committing (verified at decomposition: 0.8.1 / 0.1.0, both over the shared alkcall 0.10 req → 0.10.1; MSRVs 1.88 ≤ our 1.89; MIT OR Apache-2.0). alktunnels is NOT landed here — the config carries no alktunnels types beyond the already-landed Arc<ChannelClient>; its optional dep lands with its first consuming code (w3-tunnel-direct).

No construction-time validation (the unset-declines contract lives in the type shape, checked at request time by the mappings); the tunnel handle stays Option<Arc<ChannelClient>> as landed; Debug impls and the config module docs updated (the direction list now states what each seam handle carries).

Acceptance Criteria

  • ServeConfig gains the feature-gated seam handles (the final shape decided and recorded); unset → the owned rows decline, structurally carried, no construction-time validation
  • The optional deps + dep: feature wiring land with crates.io pins verified; a git-build never compiles alktty and vice versa (no code path outside the cfg gate touches the types)
  • The none-build's ServeConfig::new shape is unchanged; feature-gated fields absent from featureless builds
  • Tests: the per-feature construction shapes, the unset-declines-preserved rows, the Debug posture
  • cargo test, cargo clippy --all-targets -- -D warnings, cargo clippy --all-features --all-targets -- -D warnings, cargo fmt --check, cargo doc --no-deps pass

References

  • docs/plans/implementation.md §Wave 1 (config bullet), §Wave 3
  • docs/architecture/mapping.md §The seams (the signature shapes), §Session-channel dispatch (the unset note), §Decline matrix
  • docs/architecture/decisions/002-russh-pin.md (the manifest rule), docs/architecture/decisions/003-feature-graph.md (the feature graph)
  • alktty 0.8.1: src/adapter.rs:205-241 (drive_session[ _pre_negotiated]), src/negotiation.rs:64-92 (NegotiateRequest)
  • alkgit 0.1.0: src/duplex.rs:1412-1426 (serve_duplex_resolved), src/backend.rs:31-162 (the four traits)

Notes

To be filled at implementation time.