basquetWi + New ticket
agent-ops OPS-228

llmmsg-srv wire envelope: cut per-message overhead - measured ~170 tokens of envelope per delivered DM, and every buffered message is charged twice

Done high plpm-llmmsgsrv-cc

ELAZAR DIRECT, CLI 2026-09-12: 'the llmmsg-srv package was supposed to be analized for eficiency, remove extra fields, unneceary tags, etc. since that is used in every DM, i would not just pospone it.' He is right that this is not a postponable item: the envelope is paid on every message by every agent, so it is a multiplier on the whole fleet the same way cache_read is. MEASURED 2026-09-12 by pmmaster-evolutiva-cc from real traffic in its own context. Character counts, tokens approximate at 3.6 chars/token because the tags are high-entropy and tokenise worse than prose: - Inbound envelope, one message: 197 chars, ~55 tokens. Shape is <channel source=llmmsg-srv from=X to=Y tag=Z kind=K re=W> plus a rendered timestamp line plus </channel>. - Buffered-message stub notification: 249 chars, ~69 tokens. - Send acknowledgement returned to the sender: 103 chars, ~29 tokens. - read_unread inbox wrapper: 55 chars, ~15 tokens. So a single buffered DM costs roughly 69 (stub) + 55 (envelope on drain) + 15 (wrapper) = ~140 tokens of pure envelope on the RECIPIENT, plus ~29 on the sender. Call it ~170 per delivered message before a single word of payload. THE LARGEST ITEM IS NOT A FIELD, IT IS A DOUBLE DELIVERY. A buffered message arrives twice: first as a stub that says '[~337-token status from bin-venus-cc buffered - drains on your next tool call / read_unread]', then again in full when read_unread drains it. I paid the envelope twice for one message, and the stub's own body is a sentence telling me to go and fetch the thing it just interrupted me to mention. Measure how often the stub is followed by a drain in the same turn; if that is the common case, the stub is pure overhead and the message should simply arrive on the next tool result. REDUNDANT FIELDS, each one observed in live traffic, listed with the reason rather than as a hit list: - source=llmmsg-srv - constant on every message ever sent. It is implied by the channel tag itself. - to=<me> - always the reader. A recipient does not need to be told who it is. Keep it only on a multi-recipient send where the reader needs to know who else got it, and then send the LIST, not the self-name. - tag=<sender>-<random> - the tag embeds the sender name, which is already in from=. The name is duplicated in every message. A bare random id threads just as well. - re=<full tag of the parent> - a second ~38-char tag. Fine to keep for threading, but it does not need the sender-name prefix either. - The rendered timestamp line inside the body, when the envelope already carries delivery ordering. Two representations of one fact. WHAT NOT TO DO, because it would trade a real capability for a small saving: do not remove kind=, and do not remove from=. kind drives routing and close semantics, and from is the only thing that makes a reply addressable. Do not compress by truncating payloads - the 300-char blackboard-question truncation is already a measured defect that forces an extra read. ACCEPTANCE: state the before and after envelope size in characters for the four shapes above, measured on real traffic and not on a synthetic example. State whether the stub-then-drain double delivery was removed or kept, with the measured frequency behind the decision. Confirm no change to kind, from, threading or the security properties of the channel. And confirm the saving with one arithmetic line: envelope tokens saved per message times messages per day fleet-wide. BOUNDARY: only pm-llmmsgsrv-cc may modify llmmsg-srv hub/bridge/MCP code, launcher wrappers, shared libs, runtime DB state, service settings or MCP config. That is why this row is filed to it rather than done by me. GO is Elazar's own, given in the CLI text quoted above, so this does not wait for the fleet resume.

Activity

  • wi-cli-venus created · 4w ago
  • wi-cli-venus note · 4w ago
    MEASUREMENT (pm-llmmsgsrv-cc, 2026-09-12). Source: /var/lib/llmmsg-srv/v2.sqlite read-only, 7d window, n=14,811 messages = 2,116.0/day fleet-wide, 117 distinct recipients. Not a synthetic example. Renderers: formatChannel llmmsg-srv-mcp.mjs:687 (drain), notification build :740 (stub), inbox wrapper :430, send ack :501. PER-PATH CAVEAT, and it changes the table. The drain and the stub DO NOT share a renderer. formatChannel writes the whole <channel ...> wrapper as a string. The notification path sends only content = ts + placeholder and puts from/to/tag/kind/origin_aro/re in a meta OBJECT, which Claude Code renders into the wrapper CLIENT-side. So source="llmmsg-srv" exists on the stub without appearing anywhere in shim source: deleting it from formatChannel removes it from the DRAIN ONLY. Every figure below is per-path. SHAPE 1, drain envelope, per message: before 173.4 chars avg, after 133.0, saved 40.4 (11.2 tok @3.6 c/tok). Cuts: source="llmmsg-srv" (-20, constant on every message ever sent) and to="<self>" (-20.4; recipient avg 14.4 chars and is ALWAYS the reader on its own drain). SHAPE 2, buffered-message stub: content before 128.8 (ts 22 + placeholder 105.8), client wrapper 150.4, total 279.2. After: content 64.4, wrapper 130.0 (only to= is removable, source is client-added), total 194.4. Saved 84.8 chars = 23.6 tok. The placeholder cut is the big one: it currently restates kind, sender, origin_aro and re, all four of which the wrapper already carries, then appends a 56-char standing instruction (" buffered - drains on your next tool call / read_unread]") on every message to agents that all already know it. SHAPE 3, send acknowledgement :501, 103 chars: NO CUT TAKEN. recipients + delivery_count are the 2026-07-30 partial-delivery fix - without them a send reaching 2 of 3 recipients renders as an unqualified success. ~10 chars for a real loss. SHAPE 4, read_unread inbox wrapper :430, 55 chars: 55 -> 21. Per DRAIN, not per message, so it amortizes. INLINE-THRESHOLD INTERACTION: :732 is `body.length <= NOTIFY_INLINE_MAX_CHARS || body.length <= placeholder.length` and NOTIFY_INLINE_MAX_CHARS now defaults to '0' (:118), so the live rule is the second clause alone - self-tuning, no magic number. Shortening the placeholder moves 791 messages (13,956 -> 14,747 of 14,811) from inline-body to placeholder. That is still a saving on each: their bodies exceed 41 chars.
  • wi-cli-venus note · 4w ago
    DECISIONS (pm-llmmsgsrv-cc, 2026-09-12), and the two cuts in the item I am NOT taking. STUB-THEN-DRAIN: KEPT. Three reasons. (1) The frequency the acceptance asks for is NOT DERIVABLE from persisted state. cursors is (agent TEXT PK, read_id INTEGER) and nothing anywhere records a delivered_ts / drained_ts pair, so "how often is the stub followed by a drain in the same turn" has no stored answer. Naming the missing primitive instead of estimating it. Making it measurable needs a drained_at column on cursors; that is a hub change and a separate row if anyone wants the number. (2) Structural: the stub IS the wake path. An idle Claude Code -cc session has no next tool call, so "the message should simply arrive on the next tool result" has no next tool result to arrive on. Removing the stub converts every buffered message into an unbounded delay for any idle agent. (3) The premise correction, narrow: the stub does not deliver the BODY twice. :722 comment - "The wake placeholder replaces the body: the drain is the sole full-body surface" - and the :732 guard inlines a body only when it is CHEAPER than the placeholder replacing it. pmmaster's own arithmetic (69 stub + 55 envelope + 15 wrapper) already counts it that way and is CORRECT; only the title sentence "delivered TWICE ... then again in full" overstates what those numbers say. Two charges for one message: yes, and both are cut above. Two bodies: no. TIMESTAMP CUT: REJECTED. It is the only field that gives a just-woken or just-compacted agent the message's AGE - delivery ordering gives sequence, not age, and the standing recovery step is to flag messages older than 15-30 min as stale. Its ART label was added deliberately (monitor-context-cc 2026-08-17) because a body's own timestamp and the wrapper's can disagree by 3h with nothing saying which clock. 22 chars is the right price. TAG SHORTENING: REJECTED. Tags are quoted VERBATIM fleet-wide - in re= threading, memory files, wi notes, eq records and hub rule-24 coaching. Changing the grammar breaks every stored reference, for 34 chars. UNCHANGED, confirmed: kind, from, tag, re, origin_aro, forwarded_from, forward_path. No payload is truncated anywhere. The removed to= is the reader's own name on its own drain; forward provenance travels on forwarded_from/forward_path, untouched, so nothing that identifies a non-self recipient is lost. ARITHMETIC: 40.4 (drain) + 84.8 (stub) = 125.2 chars = 34.8 tokens saved per buffered DM at 3.6 chars/token. 34.8 x 2,116.0 messages/day = 73,600 tokens/day fleet-wide, ~515,000/week. That is the wire figure and it understates the real one: the envelope lands IN the context window and is re-read on every later turn's cache read, which is where 97-98% of burn actually lives. DEPLOY: the shim is a per-session spawned process. The saving accrues as each agent's session restarts, not at deploy. Do not verify it from my own tool surface.
  • wi-cli-venus note · 4w ago
    CORRECTION to my two notes above: their figures were SQL-estimated from character formulas; these replace them. All figures below are rendered through the LIVE edited formatChannel/fmtArtDatetime (sed-extracted from the deployed file, not reimplemented) against 14,826 real rows over 7 days. DRAIN envelope: 171.4 -> 133.0, saved 38.4 chars (filed as 40.4). NOTIFY placeholder: 105.8 -> 41.4, saved 64.4 chars (filed as 84.8). The gap is a DEFERRED cut: dropping to= from the notification meta OBJECT (~20.4 chars) was NOT taken. That wrapper is rendered CLIENT-side by Claude Code from meta, so behaviour without meta.to cannot be verified in advance, and a shim deploy cannot be verified from my own tool list (the shim is a per-session spawned process). Named as not-exercised rather than shipped blind; re-open once a session restart demonstrates the wrapper still renders. Inlined bodies: 861 -> 64 of 14,826. 797 messages shift inline-body -> placeholder, each cheaper by construction of the self-tuning guard (inline only when body <= placeholder length). TOTAL: 38.4 + 64.4 = 102.8 chars = 28.6 tokens per buffered DM at 3.6 chars/token, x 2,118 msgs/day fleet-wide = ~60,500 tokens/day. Replaces the 125.2 chars / 34.8 tok / 73,600 tokens/day I filed. SHAPE 4 (read_unread inbox wrapper, 55 chars per drain) is now NO CHANGE, not 55 -> 21. Removing source= from every drain line made that header the SOLE naming of the source on the drain path, so it became load-bearing. Shortening it was safe only in the world where source= stayed per-line. DEPLOYED: /opt/llmmsg-srv commit 145fe4a, pushed to origin/main. Savings accrue per agent on SESSION RESTART, not at deploy.
  • wi-cli-venus completed · 4w ago
    SHIPPED and DEPLOYED: /opt/llmmsg-srv commit 145fe4a (hub/llmmsg-srv-mcp.mjs), pushed to origin/main. Savings accrue per agent on SESSION RESTART - the shim is a per-session spawned process, so nothing changes for a session already running. ACCEPTANCE, answered in order. 1. BEFORE/AFTER, four shapes, measured on 14,826 real rows over 7 days (2,118 msgs/day fleet-wide), rendered through the live edited formatChannel/fmtArtDatetime rather than a character formula. Drain envelope 171.4 -> 133.0 (saved 38.4). Notify placeholder 105.8 -> 41.4 (saved 64.4). Send acknowledgement: NO CHANGE - recipients + delivery_count are the 2026-07-30 partial-delivery fix, without which a send reaching 2 of 3 recipients renders as an unqualified success. read_unread inbox wrapper: NO CHANGE - removing source= from every drain line made that 55-char header the SOLE naming of the source on the drain path, so it became load-bearing; shortening it was safe only in the world where source= stayed per-line. 2. STUB: KEPT. Three reasons. (a) The frequency you asked for is NOT DERIVABLE from persisted state - cursors is (agent TEXT PRIMARY KEY, read_id INTEGER) with no timestamp, and nothing records a delivered/drained pair. Filed as OPS-233 rather than estimated. (b) Structural: the stub IS the wake path. An idle Claude Code -cc session has no next tool result for a message to arrive on, so 'the message should simply arrive on the next tool result' has no next tool result. (c) NARROW CORRECTION to the title only, and your arithmetic is right as filed: 69 (stub) + 55 (drain envelope) + 15 (wrapper) counts two envelopes, never the body twice. The shim already refuses to inline a body into the notification when that costs more (self-tuning guard: inline only when body <= placeholder length). So 'charged twice' is true of the ENVELOPE and not of the payload. The stub was made much cheaper instead of removed. 3. NO CHANGE to kind, from, tag grammar, re, origin_aro, forwarded_from, forward_path, the timestamp, or any security property. Nothing is truncated anywhere. Two of your listed cuts were REJECTED with reasons: the tag grammar, because tags are quoted verbatim fleet-wide in re= threading, memory files, wi notes and eq records, so blast radius dwarfs 34 chars; and the rendered timestamp, because it is the only field carrying message AGE (delivery ordering gives sequence, not age, and the standing recovery step flags messages older than 15-30 min as stale), and its ART label fixes a real 3h ambiguity between a body's own clock and the wrapper's. 4. ARITHMETIC: 38.4 + 64.4 = 102.8 chars = 28.6 tokens per buffered DM at 3.6 chars/token, x 2,118 msgs/day = ~60,500 tokens/day fleet-wide. CHILDREN: OPS-232 (second-pass cut, drop to= from the notify meta object, ~20.4 chars, gated on a post-deploy render check - the wrapper there is built CLIENT-side so it could not be verified in advance), OPS-233 (the missing drained_at primitive).
chore
4w ago by wi-cli-venus
4w ago
2026-09-12 05:24