feat(filter): expose payload.destHash + payload.srcHash in filter autocomplete (#1774) (#1775)

Resolves #1774.

## What

Adds `payload.destHash` and `payload.srcHash` to the filter autocomplete
suggestions array in `public/packet-filter.js`.

## Why

The decoder already emits `destHash` and `srcHash` JSON keys for `REQ` /
`RESPONSE` / `TXT_MSG` / `PATH` / `ANON_REQ` packets (see
`cmd/ingestor/decoder.go`), and the generic `payload.*` accessor in the
filter language (`packet-filter.js:296-308`) already evaluates these
fields correctly — i.e. `payload.destHash == "2f"` has always worked.
The gap was purely autocomplete + docs: the two names were missing from
the `FIELDS` (SUGGESTIONS) array, so operators discovering filters via
the suggestion popup couldn't find them.

Per the triage on #1774, the canonical names match the decoder's
serialization (`destHash` / `srcHash`), not the reporter's proposed
`dest` / `src` — so the filter token agrees with the raw-JSON view and
the packet detail's `Dest Hash (1B)` label.

## Tests

- Red commit (`test-packet-filter.js`): asserts
`filter('payload.destHash == "2f"')` matches a fake REQ packet AND that
`FIELDS` contains entries named `payload.destHash` / `payload.srcHash`.
Fails on the FIELDS assertion only (filter() already works).
- Green commit: adds the two entries. All 83 packet-filter tests pass.

## Scope

Single-file change in `public/packet-filter.js` (+2 lines) + 23 lines of
test coverage. No decoder changes, no backend changes, no API signature
changes.

Fixes #1774.

---------

Co-authored-by: clawbot <bot@corescope>
This commit is contained in:
Kpa-clawbotandclawbot authored and GitHub committed 2026-06-21 20:52:09 -07:00
1 parent 72d451221c
commit b3b8bec5ec
2 files changed
+25

No files matched your search

+2
View File
@@ -459,6 +459,8 @@
{ name: 'payload.flags.repeater', desc: 'Decoded payload: advert flag (repeater role)' },
{ name: 'payload.flags.room', desc: 'Decoded payload: advert flag (room server)' },
{ name: 'payload.flags.hasLocation', desc: 'Decoded payload: advert has location' },
{ name: 'payload.destHash', desc: 'Decoded payload: destination hash byte (1B hex, REQ/RESPONSE/TXT_MSG/PATH/ANON_REQ)' },
{ name: 'payload.srcHash', desc: 'Decoded payload: source hash byte (1B hex, REQ/RESPONSE/TXT_MSG/PATH/ANON_REQ)' },
{ name: 'code1', desc: 'Transport route Code1 (hex, e.g. AABB) — present on TRANSPORT_FLOOD/DIRECT' },
{ name: 'code2', desc: 'Transport route Code2 (hex, e.g. CCDD) — present on TRANSPORT_FLOOD/DIRECT' },
];
+23
View File
@@ -232,5 +232,28 @@ test('observer_iata and iata appear in suggest field list', () => {
assert(names.indexOf('iata') !== -1, 'iata in FIELDS');
});
// --- Issue #1774: payload.destHash / payload.srcHash filterable + in suggestions ---
const reqPkt = {
route_type: 1, payload_type: 0, // REQ
hash: 'deadbeef', raw_hex: '0000',
decoded_json: JSON.stringify({ destHash: '2f', srcHash: '0b' }),
};
test('#1774: payload.destHash filters REQ by destination hash byte', () => {
assert(PF.compile('payload.destHash == "2f"').filter(reqPkt));
assert(!PF.compile('payload.destHash == "ff"').filter(reqPkt));
});
test('#1774: payload.srcHash filters REQ by source hash byte', () => {
assert(PF.compile('payload.srcHash == "0b"').filter(reqPkt));
assert(!PF.compile('payload.srcHash == "ff"').filter(reqPkt));
});
test('#1774: payload.destHash listed in FIELDS suggestions', () => {
const names = PF.FIELDS.map(f => f.name);
assert(names.indexOf('payload.destHash') !== -1, 'payload.destHash missing from FIELDS');
});
test('#1774: payload.srcHash listed in FIELDS suggestions', () => {
const names = PF.FIELDS.map(f => f.name);
assert(names.indexOf('payload.srcHash') !== -1, 'payload.srcHash missing from FIELDS');
});
console.log(`\n=== Results: ${pass} passed, ${fail} failed ===`);
process.exit(fail > 0 ? 1 : 0);