pub(crate) struct OutgoingJektSignatures {
request_id: String,
ts_secs: i64,
jekt_sig: Option<String>,
lan_sig: Option<String>,
source_channel: Option<String>,
channel_sig: Option<String>,
source_uid: Option<String>,
channel_sig_v2: Option<String>,
lan_sig_v2: Option<String>,
wan_sig: Option<String>,
wan_source_host: Option<String>,
}Expand description
Build the id/timestamp/host-signature/LAN-signature quadruple for an
outgoing jekt (SPEC_JEKT_TRUST_LAYER_COMPLETION_2026_08_13.md §2.2,
SPEC_JEKT_LAN_TIER_SIGNING_2026_08_15.md §2.3). Reads this process’s OWN
AGENTMUX_JEKT_KEY/AGENTMUX_LAN_KEY — injected at spawn alongside
AGENTMUX_AGENT_ID, into this agent’s env only, never any other
agent’s — and signs over the same (msgid, source_agent, target_agent,
ts_secs, message) material both schemes share.
Both signatures are computed unconditionally, regardless of which
delivery tier the message actually ends up taking — this process has no
reliable way to know that in advance (routing/forwarding is a
server-side decision, see
docs/specs/SPEC_JEKT_LAN_TIER_SIGNING_2026_08_15.md §3). Sending a
lan_sig alongside a message that’s actually delivered host or WAN
costs nothing — srv only ever consults lan_sig when it has
independently determined delivery_tier == "lan" (never trusting the
message body’s own claim), so an irrelevant signature is simply ignored.
Returns (request_id, ts_secs, jekt_sig, lan_sig). Either signature is
None — not an error — when its key is unavailable (an agent whose
.mcp.json predates this feature, or source_agent itself unresolved):
srv treats an absent signature as “unverified,” never as a reason to
fail delivery, so a missing key here must never block
SendMessage/Loop from sending.
The cross-channel signature (channel_sig,
SPEC_JEKT_CROSS_CHANNEL_TRUST_2026_09_02.md §D5) rides along on the
same terms as lan_sig: same AGENTMUX_LAN_KEY, but over a
domain-separated payload that also binds this process’s channel
(AGENTMUX_CHANNEL, injected into this env at spawn by
inject_jekt_signing_keys_into_mcp_json; defaults to stable exactly as
srv’s own registry writer does). srv only consults it once it has itself
labelled the delivery channel — a same-machine forward to a different
instance — so on every other tier it’s simply ignored.
Returned as a named struct rather than a tuple: the three signatures are
consecutive Option<String>s and a transposition at any of the call
sites would compile clean and silently mislabel trust on the receiver.
The WAN signature (wan_sig) rides along on exactly the
same terms as lan_sig, for the same reason: this process cannot know
which tier a send will take — it posts every send to the local reactive
endpoint and srv decides among local, cross-channel, LAN and cloud
afterwards. Computing it unconditionally is therefore the only
implementable shape, and an irrelevant signature costs nothing because srv
only consults wan_sig once it has itself determined the delivery is WAN.
It signs a domain-separated payload under this agent’s own
AGENTMUX_WAN_KEY, which is a different key from AGENTMUX_LAN_KEY.
Fields§
§request_id: String§ts_secs: i64§jekt_sig: Option<String>§lan_sig: Option<String>§source_channel: Option<String>§channel_sig: Option<String>§source_uid: Option<String>§channel_sig_v2: Option<String>§lan_sig_v2: Option<String>§wan_sig: Option<String>§wan_source_host: Option<String>Implementations§
Auto Trait Implementations§
impl Freeze for OutgoingJektSignatures
impl RefUnwindSafe for OutgoingJektSignatures
impl Send for OutgoingJektSignatures
impl Sync for OutgoingJektSignatures
impl Unpin for OutgoingJektSignatures
impl UnsafeUnpin for OutgoingJektSignatures
impl UnwindSafe for OutgoingJektSignatures
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.