Skip to content

feat(channels): show observed path hash sizes - #128

Closed
dborup wants to merge 1 commit into
masterfrom
codex/observed-path-hash-size
Closed

dborup wants to merge 1 commit into
masterfrom
codex/observed-path-hash-size

Conversation

@dborup

@dborup dborup commented Sep 28, 2026

Copy link
Copy Markdown
Owner

Summary

  • show the path-hash width actually observed in relayed channel-message paths
  • aggregate 1-, 2-, and 3-byte evidence across every observation of the same transmission
  • preserve that evidence across cold/chunk loads, live WebSocket updates, REST refreshes, cache deduplication, and client-side decryption
  • render no badge when the evidence is empty, malformed, mixed within one path, unsupported, or direct/zero-hop

This is related to Kpa-clawbot#2089, but deliberately does not derive the value from the first-ingested raw frame. One content hash can be observed on different routes, so the implementation reports only what CoreScope has actually seen in non-empty observation.path_json values. It does not claim to know the sender's permanent configuration.

User-facing contract

  • one width: Observed path hash: 2-byte
  • several widths: Mixed path hashes: 1/2-byte
  • no usable relayed-path evidence: no badge

The tooltip states that direct zero-hop copies provide no hash-size evidence and that the label is not proof of a permanent sender setting.

Implementation notes

  • No schema change, migration, backfill, new SQL query, or configuration/customizer field.
  • The existing channel-message observation scan accumulates a three-bit mask; the hot-path parser is zero-allocation.
  • StoreTx uses one byte of existing padding and remains 320 bytes on 64-bit builds.
  • Work remains O(number of observations already being read), with O(1) work per observation.
  • The legacy content-hash migration's collision path now unions this evidence across all same-content in-memory rows, including collisions split across batches. It intentionally does not change that migration's existing index/cardinality semantics.
  • REST channel rows expose observedPathHashSizes; packet/WebSocket shapes expose observed_path_hash_sizes.
  • The browser normalizes both spellings and monotonically unions evidence, so a delayed REST response cannot erase richer live evidence.

Verification

Fresh on the final working tree:

  • focused Go tests, normal and -race
  • full cmd/server test suite
  • full cmd/ingestor test suite
  • go vet, gofmt, and git diff --check
  • collision regressions for same-batch, cross-batch, three-row, and already-current survivors
  • new frontend unit suite: 11/11, including legacy-cache and same-timestamp evidence enrichment
  • new Playwright regression: 7/7, including 375 px mobile and injection-shaped input
  • existing channel WS/REST race regression: 5/5
  • existing channel fluid-layout regression: 11/11
  • relevant channel merge, ping-bot, escaping, layout, and CSS-variable suites
  • ESLint for public/channels.js
  • whole-file XSS sink check for public/channels.js
  • YAML parse and fork-guard tests; workflow triggers, permissions, jobs, dependencies, and side-effect guards are unchanged

The broad test-frontend-helpers.js suite still has its two pre-existing favStar failures; this change does not touch that code or suppress those failures.

Known limitation

MeshCore flood packets encode a hash width even when the route contains zero hops. This implementation intentionally leaves zero-hop/direct observations unknown, because CoreScope did not observe an actual relayed hop whose token width can serve as path evidence. That keeps the label conservative and independent of the first frame retained for a deduplicated transmission.

The existing content-hash migration has a separate legacy issue: after a duplicate collision, deleted rows can remain in several in-memory indexes until restart. This PR explicitly characterizes that behavior and does not rewrite those indexes; it only keeps the new evidence union consistent on every retained copy. A full atomic PacketStore duplicate merge belongs in a separate issue/PR.

An independent review found and drove fixes for client-decrypt cache enrichment and multi-row cross-batch collision evidence, then approved the final diff with no remaining feature blockers.

No staging, production, deployment, or upstream write was performed for this PR.

dborup commented Sep 29, 2026

Copy link
Copy Markdown
Owner Author

Superseded by #131 — same change re-committed with the project identity; branch kept.


Generated by Claude Code

@dborup dborup closed this Sep 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant