Know what needs attention, why it matters, and what to do next.

krnali Ops runs read-only inside your Kubernetes cluster. It learns local workload behaviour, detects current failures, predicts selected resource risks, and creates evidence-backed findings without exporting telemetry or mutating customer workloads.

Private preview Built and dogfooded. Direct installation for founding teams.

Customer-hosted · Read-only RBAC · Deterministic predictions · Works without an LLM · No telemetry export

A real finding from a running cluster

This is one object, captured with kubectl get finding -o json from the cluster krnali runs against every day, and printed here field for field. Nothing is rewritten for the page. It is in the HTML, so it is here with JavaScript off.

krnali-portal/krnali-b21b7eb38360a758 captured 2026-08-03 · ended
FINDING         krnali-b21b7eb38360a758
NAMESPACE       krnali-portal
SUBJECT         krnali-portal/portal is trending toward its memory limit
SEVERITY        warning
KIND            prediction
FAILURE CLASS   OOMKill
LEAD TIME       485h28m (range 388h22m to 582h34m)
PROVENANCE      deterministic
CONFIDENCE      40 / medium

OBSERVED SIGNALS
  memory.limit       256.0 MiB    workload
  memory.workingSet  12.5 MiB     metrics.k8s.io
  growthRate         513.3 KiB/h  baseline
  sampleCount        256          baseline
  windowSpan         21m0s        baseline

DEVIATION
  12.5 MiB observed against 11.4 MiB baseline   memory.workingSet
  working set is 1.1 MiB above the learned baseline

EVIDENCE CHAIN
  1. working-set memory rising on container portal
     latest working set 12.5 MiB against a 256.0 MiB memory limit
  2. baseline EWMA mean 11.4 MiB over 256 samples
     trend observed over 21m0s
  3. deviation from learned-normal
     1.1 MiB above baseline (1.1σ); upward slope sustained beyond 15m0s (Mann-Kendall Z=11.9)
  4. coincident change: ReplicaSet krnali-portal-794dfcdbd6 (revision 5)
     rolled out at 2026-08-03T09:10:51Z (outside the correlation window); images: krnali-portal:main-2465dc8
  5. projected to reach the memory limit in ~485h28m0s
     linear extrapolation of the working-set trend (513.3 KiB/h, R²=0.27) crosses 256.0 MiB
  6. same symptom already recorded 132 time(s), first seen 2026-07-31T17:05:27Z

ADVISORY
  raise the container memory limit or reduce its footprint yourself; krnali does not edit workloads

  $ kubectl set resources deployment/krnali-portal -c portal --limits=memory=<above the projected peak>
    target deployment/krnali-portal   reversible yes   blast radius workload
    rollback: restore the previous memory limit with the same command using the prior value

  fix at source   
    find and fix the memory growth (leak, unbounded cache, or a recent change) rather than only raising the limit
    if the growth is expected load, size the container memory limit to the real working set

  verification    
    working-set memory levels off below the limit and the breach projection clears on the next baseline

FINGERPRINT     krnali-portal/krnali-portal/portal:memory-breach
RECURRENCE      132 occurrences, first seen 2026-07-31, last seen 2026-08-03

ACTIVE          False   TrendNoLongerRising
                the working-set series is judgeable and no longer shows the sustained rise this forecast was built on
OBSERVABLE      True   SeriesJudgeable
                the series behind this finding is present and sufficient for a verdict
Every number here was computed by the operator, not written for this page. The advisory line is the product's own wording, including the sentence about not editing workloads.
How this prediction was calculated

The lead time is a straight line, extended. krnali samples container working-set memory from metrics-server into a per-series store, fits an ordinary least-squares regression over the window, and extends that line until it crosses the container memory limit. In this record the fit gives 513.3 KiB/h against a 256.0 MiB limit, which is the 485h28m estimate. The range is a fixed band of plus or minus 20 percent around the estimate, documented as a band rather than a standard error because the fit does not expose one.

A slope alone is not a trend. Before a forecast is emitted the series has to clear a gate ladder: enough samples and history to be out of cold start, a usable fit over the whole window and over the trailing window, a Mann-Kendall rank test agreeing the rise is monotonic rather than the work of two outliers, a limit the line actually reaches, and a confidence above the emission floor. This record shows Mann-Kendall Z=11.9 in evidence step 3.

Confidence is a published formula, not a judgement. It is 60 · R² + 25 · min(span / 60min, 1) + 15 · min(recurrence / 3, 1), rounded and banded into low, medium or high. You can check this record by hand. R² is 0.27, the window span is 21m and the symptom had recurred 132 times, so 60 × 0.27 + 25 × 0.35 + 15 × 1 = 39.95, which rounds to the 40 the object carries. Same evidence, same number, every time.

That number is deliberately not high. A 21 minute window with an R² of 0.27 is a weak fit, and the formula says so rather than rounding it up. A tool that scored this 90 would be lying.

The forecast was withdrawn later, for a different reason. A weak fit lowers confidence; it does not close a record. The operator set Active=False with the reason TrendNoLongerRising because the sustained rise the forecast was built on had stopped. That is the condition printed at the foot of the record above.

Provenance on the lead time reads deterministic because a model was not involved in producing any figure on this object.

Kubernetes exposes state. krnali turns it into an operational conclusion.

The API server will tell you a pod restarted. It will not tell you whether that matters, what changed at the same time, or what you should do about it. That gap is the whole product.

Detect now

Crash loops, image and configuration failures, HPA saturation, node pressure, and rollout regressions. Findings deduplicate on a stable fingerprint and count recurrence.

Lifecycle is honest about how far it currently reaches. The two trend forecasts close themselves: when the rise a forecast was built on stops, the operator withdraws it and records why. Reactive findings have no closing path yet, so a crash loop that stops still reads as open until you close it. Extending the lifecycle to reactive findings is roadmap, not shipped.

Predict selected risks

Three forecasts today, all deterministic: a container trending toward its memory limit, a ResourceQuota running out of headroom, and a rollout that is regressing while it is still progressing. The first two are arithmetic over a learned baseline that survives operator restarts; the third carries a lead time only while the rollout is still in flight, and is filed as a reactive finding once it has completed.

Those three are the whole of it. None of them is a general prediction of anything else, and the page will say so when there are more.

Show the evidence

Every finding carries an ordered evidence chain, the signals it read and where each came from, the deviation from learned normal, the change that coincided with it, and an advisory whose steps state their blast radius, their rollback, and whether they are reversible. The advisory is assembled from computed facts by fixed templates. There is no model in the product today.

Three findings, as filed

Different shapes, same cluster, all captured on the same day. They are printed here including the parts that are unflattering, because a page of curated output would prove nothing.

Reactive: a crashloop in local-path-storage

captured 2026-08-03 · Live at capture

A cluster component, not a workload of ours, restarting on a fatal startup error. This is what a reactive finding contains: the restart count, the backoff state, the last termination reason, a bounded tail of the previous container's log, the change that coincided with it, and a two line advisory. No root cause, no stack analysis, no action steps. The product does not claim more than it observed.

local-path-storage/krnali-09ff37ddf61003dd captured 2026-08-03 · live
FINDING         krnali-09ff37ddf61003dd
NAMESPACE       local-path-storage
SUBJECT         local-path-provisioner-7b8c8ddbd6-9m4nq is crashlooping (4 restarts)
SEVERITY        info
KIND            reactive

OBSERVED SIGNALS
  restartCount                 4      pod/local-path-provisioner-7b8c8ddbd6-9m4nq
  lastState.terminated.reason  Error  pod/local-path-provisioner-7b8c8ddbd6-9m4nq

EVIDENCE CHAIN
  1. container local-path-provisioner restarted 4 times
     in CrashLoopBackOff=false; last termination: Error
  2. coincident change: ReplicaSet local-path-provisioner-7b8c8ddbd6 (revision 1)
     rolled out at 2026-07-24T13:10:06Z (outside the correlation window); images: docker.io/kindest/local-path-provisioner:v20250214-acbabc1a
  3. previous log tail for container local-path-provisioner
     time="2026-07-29T19:51:37Z" level=fatal msg="Error starting daemon: invalid empty flag helper-pod-file and it also does not exist at ConfigMap local-path-storage/local-path-config with err: Get \"https://10.96.0.1:443/api/v1/namespaces/local-path-storage/configmaps/local-path-config\": dial tcp 10.96.0.1:443: i/o timeout"
  4. same symptom already recorded 599 time(s), first seen 2026-07-29T19:51:52Z

ADVISORY
  inspect the previous-container log tail and the coincident change; roll back the change if it is the cause

  verification    
    container local-path-provisioner stops restarting and stays Ready with no CrashLoopBackOff

FINGERPRINT     local-path-storage/local-path-provisioner:crashloop
RECURRENCE      600 occurrences, first seen 2026-07-29, last seen 2026-08-03

ACTIVE          True   SymptomObserved
                the symptom that raised this finding is currently observed
OBSERVABLE      True   SeriesJudgeable
                the series behind this finding is present and sufficient for a verdict

Rollout regression: revision 3 could not pull its image

captured 2026-08-03 · State unknown

An archived record. It was last reconciled on 2026-07-30, before the operator could record lifecycle conditions, so it carries none and its state today is unknown. It is here because the evidence is the point: a real registry error, an explicit contrast against the prior revision, a change inside the correlation window, and two action steps that are both reversible and both yours to run.

krnali-portal/krnali-4066cf03b05203ef captured 2026-08-03 · state unknown
FINDING         krnali-4066cf03b05203ef
NAMESPACE       krnali-portal
SUBJECT         krnali-portal: new revision 3 is regressing (ImagePullBackOff)
SEVERITY        critical
KIND            reactive

OBSERVED SIGNALS
  newRevision  3                 deployment/krnali-portal
  signature    ImagePullBackOff  pod/krnali-portal-6cf85594cb-lsmmj
  oldRevision  2                 deployment/krnali-portal

DEVIATION
  3 observed against 2 baseline   rollout.revision
  new ReplicaSet revision 3 shows ImagePullBackOff the prior revision did not

EVIDENCE CHAIN
  1. new revision 3 failing on container portal: ImagePullBackOff
     Back-off pulling image "krnali-portal:dogfood-757b657": ErrImagePull: failed to pull and unpack image "docker.io/library/krnali-portal:dogfood-757b657": failed to resolve reference "docker.io/library/krnali-portal:dogfood-757b657": pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
  2. prior revision 2 did not exhibit this signature
     the signature appeared with the new rollout, not before it, so it is a regression not a pre-existing fault
  3. coincident change: ReplicaSet krnali-portal-6cf85594cb (revision 3)
     rolled out at 2026-07-30T05:59:35Z (within the correlation window); images: krnali-portal:dogfood-757b657
  4. the new revision is already carrying full traffic
     the rollout has completed, so the regression is live on every replica
  5. same symptom already recorded 1 time(s), first seen 2026-07-30T05:59:37Z

ADVISORY
  roll back to the prior revision or fix the new image/config; krnali does not roll anything back itself

  $ kubectl rollout undo deployment/krnali-portal
    target deployment/krnali-portal   reversible yes   blast radius workload
    rollback: re-apply the new revision once its image/config is fixed (kubectl rollout undo to it, or re-apply the manifest)

  $ kubectl rollout pause deployment/krnali-portal
    target deployment/krnali-portal   reversible yes   blast radius workload
    rollback: kubectl rollout resume deployment/krnali-portal

  fix at source   
    fix the container image or config the new revision introduced, then re-roll forward
    if the change is unsafe to run at all, hold the rollout until the image is corrected

  verification    
    the new revision's error signature is absent from its pods
    kubectl rollout status completes cleanly with all replicas ready on the corrected revision

FINGERPRINT     krnali-portal/krnali-portal:rollout-regression
RECURRENCE      2 occurrences, first seen 2026-07-30, last seen 2026-07-30

LIFECYCLE       no conditions recorded on this object

Prediction: a memory limit forecast that ended

captured 2026-08-03 · Ended

Rendered in full further up the page. It is a closed record: the operator withdrew its own forecast at 2026-08-03T09:54:13Z with the reason TrendNoLongerRising, because the rise it was built on had stopped. Read the full record.

How it works

  1. Install. One Helm release and a read-only ServiceAccount. Direct installation support during private preview. nali verify-rbac prints what the account can and cannot do.
  2. Observe. Workloads, events, resources, rollouts, node conditions, metrics-server, and bounded pod logs. All of it through get, list and watch.
  3. Learn. It samples working-set memory and quota usage into a baseline of your normal, and rebuilds that baseline across restarts instead of starting cold.
  4. File. krnali writes its own typed Finding and Baseline resources. It can optionally mirror a Finding to Jira. It does not mutate customer workloads.

Read-only is an enforceable boundary, not an operating preference.

The claim is checkable in three places. The ClusterRole in the chart, which you can read with helm template before you install anything. The guardrail suite in the repository, which fails the build when a verb outside get, list and watch appears on a resource krnali does not own. And nali verify-rbac, which you run on demand against your own cluster: step 4 of the install notes exists to make you run it.

Reads

  • Kubernetes API: pods, workloads, events, nodes, quotas, PVCs, HPAs, endpoint slices
  • metrics-server pod metrics
  • Bounded pod logs
  • Portal only: mounted markdown, public HTTPS git repositories, and Prometheus for workload panels when you configure it

Runs

  • Operator and portal, both inside your cluster
  • No krnali-operated service in the data path

Writes

  • Finding and Baseline resources in the krnali.io API group, and their status
  • The portal's own local index, views and audit state
  • Optional: a Jira issue, when you have configured a Jira destination

What it cannot do

krnali writes only its own Finding and Baseline resources. It cannot patch, delete, scale, restart, or execute inside customer workloads. pods/exec does not appear in any rule of the ClusterRole. nali verify-rbac prints the proof for your own audit, and it ships with a negative control that fails loudly if every answer comes back allowed.

Where data goes

Cluster telemetry remains inside the customer-controlled boundary by default. krnali sends data externally only through destinations the customer explicitly configures, such as Jira or a customer-owned model endpoint. There is no phone-home telemetry, and no krnali-held corpus is built from your cluster.

Default deny

The portal ships with a default-deny NetworkPolicy, a request body cap, an SSRF fence, and an auth gate that fails closed on any non-loopback listener. Its RBAC is get, list and watch, plus get on pod logs, and it makes no cluster write of any kind.

A vocabulary for not knowing

When krnali cannot reach a verdict on a series it marks the finding unobservable and names the gate it failed: the series is still cold, the source stopped delivering samples, there is no usable fit over the window, or the window is too sparse to support a sustained-trend verdict. Only a series that clears every one of those gates is allowed to resolve a finding, so silence is never read as recovery. Absence of evidence is never rendered as health.

The reasoning architecture

Ops and Axiom use the same evidence-bound reasoning architecture. It gathers attributable evidence, compares competing explanations, records uncertainty, and emits typed proposals. It cannot authorise or execute its own conclusions. A model may explain or investigate the evidence when configured. It never authors measurements, thresholds, confidence, or predicted lead time. Today the explanations are assembled by fixed templates from already-computed facts, and the seam a model would sit behind takes no network at all.

Keep your observability stack.

krnali is not a metrics store, a dashboard, or a pager. It sits on top of the systems you already run and answers a different question.

Your systems own

  • Collection
  • Storage and retention
  • Dashboards
  • Alert routing and paging

krnali owns

  • Qualification: whether a signal is worth your attention
  • Learned local behaviour rather than a global threshold
  • Typed findings with an ordered evidence chain
  • Provenance on every number
  • Selected deterministic predictions
  • Recurrence tracking and deduplication
  • Verification guidance for the fix you choose

For lean teams running serious Kubernetes.

Good fit

  • Teams of 2 to 30 engineers
  • One to five clusters you manage yourselves
  • Shipping weekly or faster, often with a coding agent
  • The same engineers shipping the product are also responsible for running the cluster

Poor fit

  • Multi-hundred cluster fleets
  • Teams who already run a platform organisation
  • Anyone looking to replace their observability stack
  • Teams seeking autonomous production remediation today

The initial cohort is deliberately narrower than the long-term product.

Twenty founding teams

Founding teams get the full private-preview product free for twelve months, direct engineering support from the people building it, and influence over the roadmap. In exchange we ask for a 30-minute onboarding session and regular feedback during the first three months.

Apply by email

Applications arrive by email, at [email protected]. The button opens a message with the subject and a short template already filled in. If your mail client does not open, write to the same address directly.

Tell us four things:

  • How many clusters you run
  • Your Kubernetes distribution, whether that is EKS, GKE, AKS, k3s, kind or self-managed
  • The operational problem you have now: the thing that woke someone up, or the thing you know is coming
  • A LinkedIn or GitHub profile, if you want to include one. Optional.

What happens next: we read every application and reply, including when the answer is no. Teams we take on get an architecture call, an installation plan, and private chart access. This page is static, runs no analytics, sets no cookies, and stores nothing about you.

Where krnali goes next

krnali Axiom

Proposed

Engineering assurance for planned change. Axiom discovers the target environment, qualifies application requirements against customer standards, produces governed implementation plans, verifies the result, and maintains a living evidence-backed as-built.

Approved direction. No code. Ops is the product you can run.

Questions

Does krnali send my cluster data anywhere?

Cluster telemetry remains inside the customer-controlled boundary by default. krnali sends data externally only through destinations you explicitly configure, such as Jira or a customer-owned model endpoint. There is no krnali-operated service in the data path and no phone-home telemetry.

Does krnali modify my workloads?

No. krnali writes only its own Finding and Baseline resources. It cannot patch, delete, scale, restart, or execute inside customer workloads. Its own advisory says the same thing: the memory finding on this page reads "raise the container memory limit or reduce its footprint yourself; krnali does not edit workloads".

What access does it need?

A read-only ServiceAccount: get, list and watch on the resources it observes, and full verbs only on its own krnali.io group. pods/exec appears in no rule. The operator does not announce any of this at startup, and it should not have to be believed: run nali verify-rbac, which step 4 of the install notes tells you to run. It asks your cluster's own authorizer what the ServiceAccount may do, prints every answer, and exits non-zero if any of them is unexpected.

Do I need to supply a model?

No. Ops works without a model. Detection, baselining, predictions, evidence construction, recurrence tracking, and reports are deterministic. Optional customer-hosted inference will add explanation and cross-domain investigation. It is not built yet.

Does it work without an LLM?

Yes, and today that is the only way it works. There is no model in the shipped product. The narration seam exists and the one implementation behind it is a fixed set of templates that opens no socket and does no I/O.

Does it work without Prometheus?

Yes. Detection and the memory baseline need the Kubernetes API and metrics-server, and nothing else. Prometheus is optional, and today it adds workload panels in the portal rather than feeding the operator's own reasoning.

What happens when the evidence is missing?

The finding is marked unobservable and the specific gate is named: the series is still cold, the source stopped delivering samples, it has no usable fit, or the window is too sparse to judge. The finding's state is left as it was rather than resolved. A source going dark is never rendered as health.

Can I install it today?

Not publicly. The chart and container images are unpublished and the source repository is private, so there is no anonymous pull and no copyable command to give you. Founding teams get private chart access and direct installation support.

Which clouds does it work with?

The chart is cloud neutral. Any conformant Kubernetes cluster.

What is the difference between Ops and Axiom?

Ops watches what is running. Axiom governs what is about to change. Ops is in private preview. Axiom is a proposed direction with no code behind it.

Where does the name come from?

The Karnali, one of four rivers flowing from Mount Kailash. Pronounced kar nah lee. The CLI is nali.