README.md

September 20, 2026 · View on GitHub

A stack of log lines with one highlighted and punched through

jev-logtriage
Jev decides whether a batch of logs is worth acting on.
Your code keeps the thresholds. Nothing is executed.

PyPI MIT Jev Python 3.10+

Independent. Not an official TypeSafe AI project.

logs  ->  collapse  ->  jev (6 questions, one call)  ->  code gates
                                                         |
                         suppress | watch | review | notify | page

Prometheus is good at conditions you already know how to write in PromQL. This is for the rest. Repeated benign warnings get suppress. A helm reconcile error and a failed ntfy push get notify. Low confidence never auto-acts. It goes to review.

Try it

Needs uv and a TypeSafe API key. Loki is not required.

No clone:

export TYPESAFE_API_KEY=apikey_...
uvx --from jev-logtriage logtriage --demo

From this repo:

export TYPESAFE_API_KEY=apikey_...
uv run logtriage --demo

uv run creates .venv, installs uv.lock, and runs the script. Python 3.10+ is enough.

Without uv:

pip install jev-logtriage
export TYPESAFE_API_KEY=apikey_...
logtriage --demo

--demo loads bundled fixtures (logtriage/fixtures/demo.json), a sanitized hour of homelab warn/error lines, and runs the same pipeline a Loki query would.

DECISION                  SEV  PRIO  CONF CATEGORY         SOURCE
-----------------------------------------------------------------
notify                    2.0  0.47  0.80 network          alertmanager
notify                    2.1  0.44  0.80 security         forgejo-runner
notify                    1.8  0.42  0.73 network          helm-controller
notify                    1.2  0.29  0.73 config           authentik
watch                     1.4  0.42  0.38 infra            coredns
watch                     0.6  0.19  0.54 expected_noise   news-linker
suppress                  0.6  0.17  0.54 expected_noise   kube-state-metrics

Numbers move a little from run to run. The gates do not.

What Jev decides

One System One call per source. Question ids are not sent to the model. The instructions are.

idtypequestion
is_routine_noisenoulwould an on-call engineer dismiss this?
severityscore0 routine to 3 critical
impact_scopescore0 one pod to 3 cluster-wide
needs_actionnoulshould a human do something?
auto_remediablenoulis there a safe, unambiguous automated fix?
categorychoiceapp_error, resource, infra, network, config, security, expected_noise

Patterns from the TypeSafe docs:

Gates, in order:

  1. is_routine_noise >= 0.80 and severity below the page line → suppress
  2. needs_action < 0.50watch
  3. min confidence below the floor → review
  4. severity >= 2.0 and priority >= 0.70page
  5. auto_remediable >= 0.85 and a safe category → auto_remediate_candidate
  6. otherwise → notify

Security is never an auto-remediation candidate. auto_remediate_candidate is a label. This repo does not restart pods, call webhooks, or page anyone.

Loki

If you already run Loki, point the same script at it.

# kubectl port-forward -n monitoring svc/loki 3100:3100
uv run logtriage --since 1h --errors-only --exclude-app loki

--port-forward will start that kubectl command if http://127.0.0.1:3100/ready fails.

A JSON report is written to reports/triage-<timestamp>.json unless you pass --no-report. Repeat batches skip Jev and use a local SQLite cache. --no-cache turns that off. See docs/cache.md.

Tests

uv run python -m unittest discover -s tests -t . -v

License

MIT. See LICENSE.