Find a file
lakshit verma 9f4b6c2c5a
fix(audit,web,deploy): audit ids, web dry-run view, hardened chart, docs
Audit: correlation event_ids include stage and response code so the
multi-stage lines of one request no longer collapse under dedup; match
scans are bounded to a time window and a page instead of the object's full
history.

Web: dry-run results are read from dry_run_result (nested) so the verdict is
rendered correctly and conflicts/errors/skipped are shown; the plans view no
longer POSTs an unsolicited plan on page load; coverage and streams surface
API errors instead of showing a misleading empty state and follow cursor
pagination so they are not stuck on the oldest page; the diff path tokenizer
handles backslash-escaped dotted keys.

Deploy/CI: the chart no longer grants the query server a cluster-wide read
ClusterRole, runs as non-root with a read-only root filesystem, adds
liveness/readiness probes, wires the ConfigMap as env (STORE_PATH,
LISTEN_ADDR), defaults the journal to a PVC instead of an ephemeral
emptyDir, and adds imagePullSecrets; the replay ClusterRole drops the
unused update verb; a Dockerfile builds a static distroless image; GitHub
actions are pinned by commit SHA, jobs set least-privilege permissions, the
Vercel deploy skips fork PRs, CI passes the Makefile test timeouts, and
make lint runs a real web syntax check.

Docs: event-schema/consistency no longer describe an ingest_sequence field,
an observed-time-based event_id, or restart-from-checkpoint; the threat
model documents the unauthenticated HTTP API surface and the chart's RBAC
change; replay-safety matches the enforced dry-run gate.
2026-08-06 06:57:11 +05:30
.github/workflows fix(audit,web,deploy): audit ids, web dry-run view, hardened chart, docs 2026-08-06 06:57:11 +05:30
api fix(core): storage time ordering, watch state machine, replay safety, API pagination 2026-08-06 06:50:30 +05:30
cmd fix(audit,web,deploy): audit ids, web dry-run view, hardened chart, docs 2026-08-06 06:57:11 +05:30
deploy fix(audit,web,deploy): audit ids, web dry-run view, hardened chart, docs 2026-08-06 06:57:11 +05:30
docs fix(audit,web,deploy): audit ids, web dry-run view, hardened chart, docs 2026-08-06 06:57:11 +05:30
internal fix(audit,web,deploy): audit ids, web dry-run view, hardened chart, docs 2026-08-06 06:57:11 +05:30
test feat(server): seed demo journal from a bundled fixture 2026-08-06 06:00:54 +05:30
web fix(audit,web,deploy): audit ids, web dry-run view, hardened chart, docs 2026-08-06 06:57:11 +05:30
.gitignore fix(audit,web,deploy): audit ids, web dry-run view, hardened chart, docs 2026-08-06 06:57:11 +05:30
CONTRACT.md docs: add design and architecture documentation 2026-08-06 05:34:04 +05:30
Dockerfile fix(audit,web,deploy): audit ids, web dry-run view, hardened chart, docs 2026-08-06 06:57:11 +05:30
go.mod feat(core): add journal, collector, storage, and materializer 2026-08-06 05:30:51 +05:30
go.sum feat(core): add journal, collector, storage, and materializer 2026-08-06 05:30:51 +05:30
Makefile fix(audit,web,deploy): audit ids, web dry-run view, hardened chart, docs 2026-08-06 06:57:11 +05:30
README.md docs: add design and architecture documentation 2026-08-06 05:34:04 +05:30

krply

Gap-aware Kubernetes object history and replay planning.

krply records selected Kubernetes watch events in a local SQLite journal. It shows timelines, field changes, coverage, snapshots, and safe replay plans.

Features

  • List and watch selected resources.
  • Resume from durable resource versions.
  • Record bookmarks as progress checkpoints.
  • Mark 410 Gone responses as visible gaps.
  • Reconstruct object state at a time.
  • Compare state before and after a time.
  • Build sanitized server-side apply plans.
  • Review data through a CLI, HTTP API, or web UI.

Architecture

flowchart LR
    K["Kubernetes API"] --> C["Collector"]
    C --> J["SQLite journal"]
    J --> M["Materializer"]
    M --> Q["Query API"]
    Q --> CLI["CLI"]
    Q --> UI["Web UI"]
    M --> P["Replay planner"]
    P --> T["Test cluster"]

The collector writes the raw event before it advances the checkpoint. A reconnect can deliver an event again. The journal deduplicates that event.

Requirements

  • Go 1.26 or newer.
  • kubectl and access to a Kubernetes cluster for recording.
  • A kubeconfig with get, list, and watch access to selected resources.

Install

make build

Binaries are written to bin/krply and bin/krply-server.

Quick start

Record selected resources:

./bin/krply record \
  --kubeconfig ~/.kube/config \
  --context prod \
  --namespace shop \
  --resource deployments \
  --resource configmaps \
  --resource services \
  --store ./krply.db \
  --bookmarks

Inspect the journal:

./bin/krply status --store ./krply.db
./bin/krply coverage --store ./krply.db
./bin/krply timeline checkout-service --namespace shop --kind Deployment --store ./krply.db
./bin/krply diff --since 30m --until now --namespace shop --store ./krply.db
./bin/krply snapshot --store ./krply.db

Start the web UI and API:

./bin/krply-server --store ./krply.db --listen :8080

Open http://localhost:8080.

Live demo

The following output came from a live kind cluster. The recording had four streams and zero gaps.

$ krply coverage --store /tmp/krply-live.db
STREAM                                                       RESOURCE           NAMESPACE  AVAIL  LAST-RV  GAPS  COVERAGE
cluster-2b6b99a0-kind-krply-demo//v1/configmaps/shop/        configmaps         shop       true   2005     0     OK
cluster-2b6b99a0-kind-krply-demo//v1/services/shop/          services           shop       true   2023     0     OK
cluster-2b6b99a0-kind-krply-demo/apps/v1/deployments/shop/   apps/deployments   shop       true   1994     0     OK
cluster-2b6b99a0-kind-krply-demo/apps/v1/statefulsets/shop/  apps/statefulsets  shop       true   653      0     OK

The real diff from that recording:

$ krply diff --since 2026-08-05T23:41:40Z --until now --namespace shop --store /tmp/krply-live.db
CHANGED  3 objects
ConfigMap shop/app-config
    data.log_level  info -> debug
Deployment shop/checkout-service
    spec.replicas                                           2 -> 5
    spec.template.spec.containers[0].image                  nginx:1.25 -> nginx:1.27
Service shop/checkout-service
    metadata.labels.team  null -> payments

Web UI

Coverage

Timeline

Diff

Replay plan

Replay safety

replay plan is the normal entry point. It reconstructs state, checks coverage, removes server-owned fields, maps namespaces, sorts resources, and runs a server-side dry run.

It excludes Secrets, RBAC objects, Pods, Jobs, persistent storage, webhooks, and CRDs by default. It never forces server-side apply conflicts. Apply requires an explicit confirmation.

Consistency

  • Resource versions are comparable only within one cluster and API resource.
  • Ordering is guaranteed only within one watch stream.
  • observed_at is collector observation time, not object change time.
  • A snapshot is complete only when every contributing stream has a baseline and no gap.
  • Historical queries always return coverage information.

Documentation

Development

make build
make test
make test-integration
make test-e2e
make web

The repository contains unit tests, a fake Kubernetes API server, and an end-to-end recording pipeline. No real cluster is required for the tests.