Skip to content

v1.3.42.1 -- One FilterBar, URL state, header search

argosVersion 1.3.42.0 -> 1.3.42.1. Frontend release (review doc item 8) shipped inside the v1.3.42.0 drift window: no change to logs, rollup or bouncer backend. The two backend changes are read-side and small. Planning: docs/planning/v1.3.42.1-filterbar-phase0.md.

What ships

  • Filters live in the URL. useUrlFilters(schema) + FilterBar (frontend/src/hooks, frontend/src/components): every list or aggregate page reads its range, filters, tab and page from the URL (validated, defaults filled), writes keystrokes with replace and range / select / tab / page changes with push, so a link, a reload and the browser's back button reproduce the view. Text fields debounce 300 ms; a filter edit goes back to the first page. One vocabulary everywhere: range, host_id, ip, country, scenario, q, source, status, method, path, origin, scope, type, tab, page / offset, limit.
  • Pages: Logs (every incoming param honoured, ip maps to the existing remote_ip filter instead of a q LIKE over raw, host select, debounce, offset reset), Dashboard (one range and the host in the URL; its links into Logs carry ip= / status= and range=24h), Threats (six filters and page in the URL, q mapped to search), Security (tab, Banned IPs and Activity filters, Scenarios q), AppSec (range instead of a one-shot window), Notifications (tab, History range / status / event type), Hosts (q over domain and target group), Backup and Certificates (tab).
  • Header search: paste an IP, CIDR, domain, scenario or text; the client classifies it and, on Enter or after 500 ms idle with 3+ characters (never per keystroke, AbortController on edit), fans out to existing endpoints: decisions (live), Logs (last 24 h), hosts, whitelist, scenarios, WAF alerts (24 h top lists). Every section names its window and total and links to the owning page with the filter applied. / focuses the input, Esc closes.
  • Logs with a deleted host: a link with a host_id that no longer exists degrades to "all hosts" with a notice instead of an empty list.
  • GET /api/security/countries omits the cidrs arrays unless ?cidrs=1 (Settings renders counts only): 1,704 bytes for 8 countries on the demo, about 770 KB before on prod.
  • Range translation in one place: lib/filters.ts maps range to the dashboard range, the AppSec window and the from ISO the logs and deliveries endpoints take, with npm run test:lib (node:test on the compiled library, no new dependency) covering the translations, the URL round-trip and the classifier. v1.3.42.2 removes the translation in one commit.

Verified on the demo (rc image)

scripts/capture/run-demo.sh before (1.3.42.0) and after (rc): same 27 surfaces, same 4 skips, no failures. Extra captures with a plain Playwright script (deep links, URL round trip, header search):

check result
/logs?ip=203.0.113&range=24h&source=caddy_access page opens filtered (every row 203.0.113.x, 24 h, source set)
/logs?source=caddy_access&status=403,429&range=24h (the Dashboard "Blocked" card) filtered by status
/threats?country=ES&type=ban, /security?tab=activity, /security?tab=scenarios&q=http, /appsec?range=6h, /notifications?tab=history&range=7d, /hosts?q=example.org each lands on the tab / filter named in the URL
Logs: type vault, click 6h URL becomes /logs?range=6h&q=vault; back returns to /logs?q=vault
header search 203.0.113.9 panel: decisions live 0, Logs last 24 h 1,853 with five rows, whitelist 0, WAF 0; links filtered
header search crowdsecurity/http-probing decisions and scenarios sections
Settings countries request 1,704 bytes (8 countries)

Note on ip in Logs: the server's remote_ip filter is a substring match, so 203.0.113.9 also matches 203.0.113.9x; exact-or-CIDR is a v1.3.42.2 backend note.

Deploy

Inside the drift window on purpose (operator, 2026-09-26): the panel restart exercises the rollup recovery from MAX(hour) and the drift check keeps running; recorded in the planning doc when it happens. make deploy-prod, rollback to 1.3.42.0 if not healthy in 60 s. After-smokes: read-pool.sh gates 0-2, dashboard-latency.sh strict, panel-boot.sh, boot log (rollup: fill done for the hours missed during the restart), and the operator's manual checklist from the planning doc (deep link from the Dashboard, reload and back on Logs, Threats URL in a new tab, ?tab= on Security, header search with an IP / domain / scenario, countries response under 20 KB).

Results (deployed 2026-09-26 17:54 UTC)

make deploy-prod 93 s, panel healthy in 10 s, read pool enabled. Rollup recovery after the restart, as intended: the boot purge at +2 min (3,333 rows) was followed by rollup: fill done reason=boot backfill hours=1 groups=26 paths=234 total=117ms re-filling the newest hour (16:00 UTC; 17:00 was still open at 17:56 and is the HH:02 job's), last_run_at 2026-09-26T17:56:44Z; the drift window keeps running.

smoke result
read-pool.sh gates 0-2 PASS: idle p99 4.8 ms (n=1,103), strip (2,816 rows) p99 1.7 ms
read-pool.sh gate 3 (information, not this release's gate) PASS this run: 3 exports of 63,520 rows, p99 8.6 ms, max 9.9 ms
dashboard-latency.sh strict PASS: health 1.3 ms cache hit, overview 3.6 ms
panel-boot.sh PASS: boot-to-listen 241 ms, first purge 122 s after listen
GET /api/security/countries 1,593 bytes (was about 770 KB)

The operator's manual checklist on prod (deep link from the Dashboard, reload and back on Logs, Threats URL in a new tab, ?tab= on Security, header search with an IP / domain / scenario, countries response size, no new polling) passed on 2026-09-26.

Known issues carried

v1.3.41.1 export gate tail (until v1.3.42.2); Until shown as "expired" on imported decisions; blocked_requests_24h mixing; dashboard/cache_test timing flake; the 48 h DB-size reading. Items 10 (one decisions table) and 11 (navigation by intent) follow with their own PHASE 0.