Skip to content

Agent-Hellboy/ltm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ltm

Machine-history debugger for Linux. Records process, file, network, memory, and block I/O via eBPF, stores metadata in SQLite, and answers timeline / diff / plain-English / SQL questions about what happened on the box.

Quick start

go build -o bin/ltm ./cmd/ltm

sudo ./bin/ltm start                       # record (eBPF; root, Linux/x86_64)
./bin/ltm timeline --since 5m
./bin/ltm watch                            # live tail; Ctrl-C to stop
./bin/ltm diff --from 10m --to now
./bin/ltm query "who modified /etc/some.conf?"
sudo ./bin/ltm stop

Recording needs root (or CAP_BPF + CAP_PERFMON). Querying does not. Without a live host: ltm benchmark --count 1000 seeds synthetic events.

Global flags go before the subcommand (ltm --db /tmp/ltm.db status). Defaults: DB ~/.local/share/ltm/ltm.db, PID ~/.local/run/ltm.pid. Add --json to any read command for machine-readable output.

Commands

Command What it does
start / stop / status control the recorder
timeline filter by --pid --uid --comm --category --action --path --exe --since --until --limit (repeatable; --path/--exe are SQL LIKE)
watch live tail (--interval --since --category --comm --pid)
diff --from --to machine-state changes between two times
query "<question>" plain English (templates, or an agent → SQL)
query sql ["<SELECT>"] read-only SQL; no arg prints the schema (ltm sql works too)
prune --older-than 720h drop old rows and VACUUM
benchmark --count N write N synthetic events (no eBPF)
version build version, commit, platform

Storage and querying

One SQLite database, WAL writer held by the daemon. Every read path opens read-only (PRAGMA query_only=ON) — queries never contend with the writer or mutate the log. Metadata only; no file contents.

export LTM_AGENT=claude   # or codex, cursor, gemini, auto, or a custom command
ltm query "which process wrote to files the most today?"

Agent SQL is printed, then run on the read-only connection, and rejected unless it is a single SELECT. No agent (or agent failure) → built-in templates.

What gets recorded

~60 tracepoints: process (exec, exit, fork, clone, kill), file (open/close, read/write, rename, unlink, link, symlink, mkdir, rmdir, chmod, chown, stat, access, truncate, dup, pipe, …), memory (mmap, munmap, mprotect), network (socket, connect, bind, listen, accept, send/recv, shutdown), block (block_rq_issue).

BPF skips /proc, /sys, /dev and the daemon's own PID. Full list: internal/ebpf/tracepoints_linux.go. After editing collector.bpf.c, rebuild with make ebpf.

Limitations

  • x86_64 recording only — BPF is built -D__TARGET_ARCH_x86 (#2). Query works anywhere.
  • IPv4 addresses only — IPv6 connects/binds are stored without a decoded address.
  • Byte counts are the syscall's requested size (enter probe); short/failed I/O over-counts; readv/writev/sendmsg/recvmsg report 0.
  • fd→path covers fds ≤ 1024 and can misattribute after heavy PID reuse; higher fds are recorded without a path.

Development

go test ./...                # any OS
make integration             # real eBPF recording; Linux + root

Layout: cmd/ltm entrypoint; everything else under internal/ (cli, daemon, collector, ebpf, storage, agent, diff, query).

Docs: docs/ (CLI, querying, recording, architecture, security). Contributor rules: AGENTS.md.

About

ltm is a machine-history debugger for Linux. It records process, file, network, memory, and block-I/O metadata via eBPF, then lets you query the timeline.

Topics

Resources

License

Security policy

Stars

12 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors