You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
analytics(hash-stats): break down path hash sizes by payload type and channel #146
Extend Analytics → Hash Stats with a breakdown of the 1/2/3-byte path hash distribution per payload type (and, for channel messages, per channel), so it is visible how far each kind of traffic has moved to multi-byte hashes (e.g. chat vs. adverts).
Background
computeAnalyticsHashSizes (cmd/server/store.go, around line 8313) already reads the path byte (bits 7–6 of the path-length byte in raw_hex) for every transmission and returns total, distribution, distributionByRepeaters, hourly, topHops and multiByteNodes, with region/area filtering.
feat(channels): show observed path hash sizes #131 added an observation-based width for channel messages only. It is in-memory only, GRP_TXT only, gives nothing for zero-hop floods, and "mixed" widths did not occur on staging (0 of 516 messages). It is therefore not a good analytics source; this issue uses the path byte, which Hash Stats already parses and which also covers zero-hop floods (see the firmware notes in Kpa-clawbot/CoreScope#2089).
Proposal
Server (same loop, no new query, no schema change):
Count distribution per payload type: {payloadType → {1,2,3}} using the firmware type names already used elsewhere (ADVERT, GRP_TXT, TXT_MSG, REQ, …).
For GRP_TXT, count per channel key: the stored channel_hash (decrypted name such as #name, or enc_XX when not decrypted). Keep only the top N channels by message count (N = 20 initially) and fold the rest into other, so the result stays bounded.
Respect the existing region/area filters and caching/recompute behaviour of the Hash Stats endpoint.
Add the new fields as named Go structs with explicit JSON tags (AGENTS.md: no new map[string]interface{} in response builders), e.g. distributionByPayloadType and grpTxtByChannel. Existing fields stay unchanged.
Frontend (public/analytics.js, Hash Stats tab):
A compact table (or stacked bars) with one row per payload type: count and share of 1/2/3-byte.
A second table for the top channels, with the same columns.
Colours via existing CSS variables/badges (badge-hash-N); all names escaped.
Per-type and per-channel counts sum to the overall distribution for the same filter (test).
Unknown/reserved size bits and packets without a path byte are excluded exactly as today.
Region and area filters apply to the new fields (test).
Per-channel map is bounded (top N + other); N is a named constant, noted for the customizer later (AGENTS.md rule 8).
Work stays O(1) extra per transmission in the existing loop; include a benchmark or timing for the recompute on a realistic store (AGENTS.md rule 0).
Unit tests for the server aggregation and the frontend rendering (including escaping of channel names); Playwright check of the tab at desktop and mobile width.
Summary
Extend Analytics → Hash Stats with a breakdown of the 1/2/3-byte path hash distribution per payload type (and, for channel messages, per channel), so it is visible how far each kind of traffic has moved to multi-byte hashes (e.g. chat vs. adverts).
Background
computeAnalyticsHashSizes(cmd/server/store.go, around line 8313) already reads the path byte (bits 7–6 of the path-length byte inraw_hex) for every transmission and returnstotal,distribution,distributionByRepeaters,hourly,topHopsandmultiByteNodes, with region/area filtering.Kpa-clawbot/CoreScope#2089).Proposal
Server (same loop, no new query, no schema change):
distributionper payload type:{payloadType → {1,2,3}}using the firmware type names already used elsewhere (ADVERT, GRP_TXT, TXT_MSG, REQ, …).channel_hash(decrypted name such as#name, orenc_XXwhen not decrypted). Keep only the top N channels by message count (N = 20 initially) and fold the rest intoother, so the result stays bounded.map[string]interface{}in response builders), e.g.distributionByPayloadTypeandgrpTxtByChannel. Existing fields stay unchanged.Frontend (
public/analytics.js, Hash Stats tab):badge-hash-N); all names escaped.#/analytics?tab=hashsizes§ion=…).Acceptance criteria
distributionfor the same filter (test).other); N is a named constant, noted for the customizer later (AGENTS.md rule 8).docs/api-spec.mdupdated.Non-goals