188 Commits

Author SHA256 Message Date
larssand
3e01ac977d Add dashboard-triggered replay jobs and detector deltas
Closes the last ROADMAP §1 item. The replay/replay-graylog CLI backend
already existed and was already safe (a temporary, auto-cleaned SQLite
baseline, never touching live state) — the gap was purely that a human had
to SSH in and run it by hand. Extracts the core logic from cli.py into
run_local_replay()/run_graylog_replay() in replay.py, reused by both the
CLI (now thin wrappers) and a new dashboard panel (Diagnostics -> Replay &
Detector Deltas). Runs as a background job via an in-memory job store,
since the dashboard already runs ThreadingHTTPServer and this session
directly observed live MCP polling take anywhere from 9 minutes to over an
hour — a synchronous request/response was never viable. Deliberately
serialized to one job at a time given this box's GPU/CPU constraints.

Also removed a redundant "Detector Precision" panel that duplicated (with
a weaker, current-poll-cycle-only computation) what the new Detector
Health panel already does correctly with real historical data.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 18:39:54 +02:00
larssand
bc4d2f465f Also veto timestamp-shaped fields from categorical/entity/relationship roles
Found live: a baseline-maintenance vacuum surfaced eventtime/timestamp
sitting in a stream's categorical_fields, hitting the max-values-per-field
cap at 2001 distinct values. Same failure mode as the original context
incident — a timestamp is near-unique on essentially every event, so
tracking it as a categorical or relationship field guarantees a "new"
finding every time. Extends _SHAPE_VETO (entity/categorical/relationship)
to also exclude "timestamp" shape, reusing the existing veto machinery and
its default 60-confidence threshold (timestamp classification isn't capped
low the way free_text is, so the stricter default applies correctly).
Existing profiles with this issue get flagged automatically via
detect_shape_mismatches, which already reuses the same veto check.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 18:27:45 +02:00
larssand
e61403d7f6 Surface baseline maintenance status in the dashboard
Retention and per-field value capping already ran automatically every poll
cycle, but the dashboard showed only a single "DB size" line — no
visibility into what got deleted, which fields are hitting the
max-values-per-field cap, or whether disk space is reclaimable, without
SSHing in. baseline.py's maintenance() now also reports the specific
(stream, entity, field) rows it trimmed for exceeding the cap, surfaced in
a new Baseline Maintenance dashboard panel alongside size/reclaimable bytes
and rows deleted last cycle. Deliberately no live-vacuum button: VACUUM
needs the service stopped first, so the dashboard only shows when it's
worth doing and points at the existing offline CLI command.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 16:35:09 +02:00
larssand
36516faf9a Add real detector health tooling: learning state and historical precision
Replaces the old Prometheus-only "detector precision" metric, which
recomputed from whatever field_deviations happened to be active in the
current poll cycle cross-referenced against live FeedbackStore rules — a
revoked or expired suppression rule made the signal vanish, and nothing was
tracked between polls. Adds DetectorPrecisionStore, a permanent append-only
log of review outcomes (kept deliberately separate from FeedbackStore's
mutable suppression rules) recorded the moment a human reviews a finding,
plus BaselineStore.detector_readiness() mirroring the existing per-field
profile_readiness() for per-detector learning state, and a plain-language
detector reference. Surfaced in a new Detector Health dashboard panel.
Observability only — nothing here changes scoring or suppression.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 16:22:02 +02:00
larssand
b0cc9dbdfe Let the dashboard LLM note read a bounded excerpt of real log content
The Ollama dashboard assessment was built entirely from pre-computed
statistical scores/reasons/counts — a deliberately tested compaction step
stripped all raw message content before it reached the model, presumably to
keep the prompt small for a local, GPU-constrained instance. That raw
content (sample_events/timeline, already truncated to short messages)
already flows through the pipeline; it was just filtered out at the last
step. Now the top-scoring field deviations and incidents each carry a
small, bounded number of real message excerpts, and the prompt explicitly
asks the model to flag suspicious content (injection attempts, unusual
command lines) that pure statistical scoring can't see — purely a
qualitative addition to the narrative note, never feeding back into scoring
or suppression.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 07:04:58 +02:00
larssand
caa37de98e Fix cardinality judged against sample size instead of real event volume
classify_field_shape() received a deduplicated set of observed values with
no real event-volume context, so cardinality was always measured against
itself — trivially 100%, making any field with more than ~16 distinct
values look "high cardinality" no matter how large the real traffic volume
was. This misclassified genuinely low-cardinality fields (e.g. username: 82
distinct values across 1,601 events) as free text, which the new shape-veto
work then surfaced as false-positive "remove this field" warnings in
production. Fixed by passing real event coverage as an explicit
total_events parameter; omitting it keeps prior behavior for other callers.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 22:02:44 +02:00
larssand
83ffef3570 Pool baseline state across streams sharing an entity concept
Completes the last deferred item from ROADMAP §0: entities recognized as
the same real-world concept across enabled streams (e.g. srcip in both a
firewall and an IIS stream) now share baseline knowledge of entity
presence/age and known relationship-target values, instead of each stream
learning it cold. Implemented additively (synthetic shared_entity:<group>
namespace in the existing baseline.py tables, no schema migration), scoped
to entity presence + relationship known-values only — per-stream
distribution baselines stay untouched. Also fixes a latent alias-map
collision bug found while building this (ALIAS_CANONICAL_BY_FIELD let
"context" silently steal "hostname"/"dns_query" from their own canonical
groups).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-23 18:50:14 +02:00
larssand
8c155ec9cf add new structure 2026-09-23 17:06:05 +02:00
larssand
7cbec64b0e ny roadmap och arch 2026-09-23 15:09:13 +02:00
larssand
5f8b1cd098 fix ollama 2026-09-23 13:40:51 +02:00
larssand
a3f545f1b0 fix anon 2026-09-23 13:32:09 +02:00
larssand
bf1109be81 add rule generalization, sized LLM defaults, ops docs, and UI polish
Feedback rules can now be suggested for merging when a human has already
reviewed the same pattern multiple times (never guesses about new values).
LLM defaults sized for constrained VRAM instead of llama3.3/llama3.1.
Adds systemd units, a state backup script, and reverse-proxy auth guidance
for production deployment. Findings view is collapsible and sorts
suggested-review rows to the top for a quicker overview.
2026-09-23 13:04:53 +02:00
larssand
c3e482f9ab fix more structure for UI and classification 2026-09-08 09:50:58 +02:00
larssand
59ac227dfd fix refresh so checkbox works 2026-09-08 09:32:00 +02:00
larssand
db87f65d97 add false-positive filter and bulk-clear for findings
Active Feedback Rules gets a status filter, and Field Baseline
Deviations gets multi-select with a bulk apply bar. Bulk scope is
restricted to exact-value/field only, so a batch action can never
create a broad rule that would suppress a genuinely new deviation.
2026-09-08 08:57:54 +02:00
larssand
67609e415f fix isssue classification and doc 2026-09-07 22:04:45 +02:00
larssand
e35445da4f add value-shape field classification and auto-apply
Field roles are now inferred from observed values instead of names,
with src/dst disambiguation, value-pattern detector hints, an Ollama
advisor scoped to ambiguous fields only, confidence-gated auto-apply
with manual-field protection, and drift flagging for review
2026-09-07 21:58:25 +02:00
larssand
7b94512abc add feedback scopes, revoke and precision metrics
Feedback rules now support value/field/entity/stream scope, require
expiry for broad suppressions, and can be revoked individually.
Adds an active-rules panel, detector precision metrics, and diagnostics.
2026-09-07 19:51:54 +02:00
larssand
e9e0ab8a46 fix delete och ollama 2026-07-06 23:10:42 +02:00
larssand
469b2f14b4 change size of delete 2026-07-06 23:02:07 +02:00
larssand
d027645af7 add delete profile 2026-07-06 22:54:19 +02:00
larssand
b9ca0e1760 fix clear 2026-07-06 17:45:39 +02:00
larssand
da540f81ae fix reset state 2026-07-06 17:05:27 +02:00
larssand
649c29a8c2 fix clear investi 2026-07-06 16:49:30 +02:00
larssand
49ac7e2958 llm fix 2026-07-06 16:37:05 +02:00
larssand
7f6a91f49c fix timeout 2026-07-06 16:29:38 +02:00
larssand
d314c94dee fix monitor error 2026-07-06 13:02:10 +02:00
larssand
35282bca7f fix ui readme 2026-07-06 12:58:16 +02:00
larssand
841f94dc9f fix retention 2026-07-06 12:41:34 +02:00
larssand
6a0df3bc74 fix ollama after profile change 2026-07-06 12:24:10 +02:00
larssand
9eb2448eb7 fix status issues ollama 2026-07-06 11:43:17 +02:00
larssand
b1a70351a6 fix label 2026-07-06 11:39:41 +02:00
larssand
2f208c91ca ändrar sattus ollama 2026-07-06 11:31:06 +02:00
larssand
b7f49214cb fix diagnostic view 2026-07-06 11:27:56 +02:00
larssand
5c3f43a596 advisor runs to update new and existing profiles if new field occur 2026-07-06 11:21:41 +02:00
larssand
897f593be9 add nested poll check mcp 2026-07-06 11:03:05 +02:00
larssand
fc4d83331a show more if fail refresh 2026-07-06 10:58:59 +02:00
larssand
6edbe0452e fix 2026-07-06 10:21:18 +02:00
larssand
830ca79dfa fix restore config 2026-07-06 09:46:22 +02:00
larssand
bddc84395c fix config 2026-07-06 09:36:00 +02:00
larssand
1238fd0e4d fix reload&refrehs 2026-07-06 09:25:40 +02:00
larssand
fde165d79b fix restart issue 2026-07-06 09:22:13 +02:00
larssand
1ced15e08f Fixed the incident ack/resolve behavior. 2026-07-02 21:20:13 +02:00
larssand
97d017e43c add timeout mcp poll 2026-07-02 21:17:50 +02:00
larssand
f45c275e20 change poll mcp again status 2026-07-02 21:14:43 +02:00
larssand
7d1bdd35c9 fix poll mcp 2026-07-02 21:03:37 +02:00
larssand
825bd0247a mcp status 2026-07-02 20:52:04 +02:00
larssand
75ebaaf307 contrinue cleanup UI 2026-07-02 20:45:32 +02:00
larssand
0a9a3d3dd2 Fixed both issues 2026-07-02 20:37:39 +02:00
larssand
5e14104f0a Entity labels now resolve like this for IP-based entities: 2026-07-02 20:30:33 +02:00