https://github.com/parthalon025/senex
Local-LLM code audit tool: file-by-file repository audits using LM Studio with GitNexus graph awareness, integrated TUI, and Claude Code handoff
https://github.com/parthalon025/senex
Last synced: about 2 months ago
JSON representation
Local-LLM code audit tool: file-by-file repository audits using LM Studio with GitNexus graph awareness, integrated TUI, and Claude Code handoff
- Host: GitHub
- URL: https://github.com/parthalon025/senex
- Owner: parthalon025
- Created: 2026-04-27T03:38:24.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2026-04-27T04:58:18.000Z (about 2 months ago)
- Last Synced: 2026-04-27T05:26:27.796Z (about 2 months ago)
- Language: Python
- Size: 155 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# senex
Local-LLM repository audit tool. Audits a target repository file by file using a thinking-MoE
model running in LM Studio, with GitNexus as background graph awareness. Produces per-file
Markdown reports, a combined run report, a `findings.json` machine index, and a Claude Code
handoff artifact.
senex is a local-first tool: source code never leaves the machine, no telemetry, secret
redaction is applied to every persisted artifact. See "Security" below.
---
## Overview
senex pairs a small local thinking model (default: `google/gemma-4-26b-a4b` in LM Studio)
with a 6-tool framework (`gitnexus_query`, `gitnexus_context`, `gitnexus_impact`, `read_file`,
`grep`, `search_code`), context compaction safety, and a streaming Textual TUI. Each file
in the audited repo gets one model turn (with optional tool calls). Findings are aggregated
into a stable `findings.json` and a human-readable `combined.md`; a final `claude-handoff.md`
summarizes hot spots for downstream work in Claude Code.
## Prerequisites
- **Windows 10/11** (Linux/macOS supported but the scheduled-task scripts are Windows-only).
- **Python 3.11+** (3.13 supported and recommended).
- **LM Studio** — download from . Load `google/gemma-4-26b-a4b`
before running the audit (or set `[lmstudio.lifecycle].auto_load = true` for senex
to load it for you).
- **GitNexus** (optional but strongly recommended) — provides the graph context block
prepended to every per-file prompt. Install with `npx gitnexus init` in the audited
repo. Without it, senex still runs but with degraded context.
- **`gh`** (optional) — for the v1.0.0 release flow only.
## Install
### Windows (one-liner)
```powershell
git clone https://github.com/parthalon025/senex.git
cd senex
.\scripts\setup.ps1
```
`setup.ps1` creates `.venv`, runs `pip install -e .`, verifies `senex --version`, and
prints next steps.
### Manual (any platform)
```bash
git clone https://github.com/parthalon025/senex.git
cd senex
python -m venv .venv
.venv\Scripts\activate # PowerShell: . .\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -e .
senex --version
```
## Configure
Copy the example to the working file and edit:
```powershell
copy senex.config.toml.example senex.config.toml
notepad senex.config.toml
```
Minimum edits to ship:
1. **`[lmstudio].base_url`** — leave at `http://localhost:1234/v1` unless you bind LM
Studio elsewhere.
2. **`[lmstudio].model`** — the loaded model id (default: `google/gemma-4-26b-a4b`).
3. **`[[repos]]`** — at least one `name` + absolute `path` entry. `senex audit --nightly`
iterates every entry; ad-hoc runs target a single repo by argument.
## LM Studio setup
senex talks to LM Studio's local OpenAI-compat API. Two things must be done in the
LM Studio UI before every audit (they persist across restarts once configured):
### 1. Enable the local server
Open LM Studio → click the **server icon** in the left sidebar (or go to the
**Developer** tab) → click **Start Server**. The default address is
`http://localhost:1234`; leave it unless you also change `[lmstudio].base_url`.
> If the server is not running, `senex doctor` reports `lmstudio_reachable: fail`
> and the audit exits with code 3.
### 2. Load the model
In LM Studio, search for and load the model whose **identifier matches exactly**
what you have in `[lmstudio].model` (default: `google/gemma-4-26b-a4b`). The
identifier must match byte-for-byte; senex compares it against `/v1/models` at
preflight.
If you set `[lmstudio.lifecycle].auto_load = true`, senex will load/unload the
model automatically via the `lmstudio` Python SDK or the `lms` CLI — whichever
is available. The `lmstudio` SDK ships with the Python package; the `lms` CLI
requires a separate install from lmstudio.ai.
> Model not loaded + `auto_load = false` → `model_loaded: fail`, exit code 3.
### 3. Set context length before the first run (required)
LM Studio's default context window is **262 144 tokens**. At that size the
KV cache alone consumes ~24 GB of VRAM on gemma-4-26b and the model will fail
to load on most hardware. **Change it to 16384 or 32768** in the model's
load settings before starting the server.
To change it: in LM Studio, open the loaded model's settings panel →
**Context Length** → type `16384` → reload the model.
Also set this in `senex.config.toml` so the two values stay in sync:
```toml
[lmstudio]
context_window = 16384 # must match what you set in LM Studio
```
### 4. Recommended one-time settings
| LM Studio setting | Recommended value | Why |
|---|---|---|
| **Context Length** | 16384 or 32768 | Reduces KV-cache VRAM from ~24 GB to ~2–4 GB |
| **Parallel requests** | 1 | Each slot reserves KV cache headroom; use 4 only if VRAM allows |
| **Flash Attention v2** | On | KV cache compression; enable if your model supports it |
| **Speculative decoding** | On | 1.5–3× speedup; enable if available for your model |
| **GPU offload** | Max layers that fit | Any layer offloaded to CPU degrades throughput |
These settings persist per-model in LM Studio and do not need to be changed on
subsequent runs unless you switch models.
---
## Run
```powershell
senex audit # interactive launcher wizard
senex audit C:\path\to\your\repo # direct TUI launch
senex audit C:\path\to\your\repo --no-tui # headless (stdout progress)
senex audit --nightly # iterate every [[repos]]
senex audit C:\path\to\your\repo --resume # continue an interrupted run
senex audit --no-wizard # error: requires a positional path
```
Run `senex audit` with no path to launch the interactive wizard. The wizard
walks you through repo selection (from `[[repos]]`, on-disk discovery, or a
custom path), model selection (probed live from `GET /v1/models`), and a
handful of yes/no prompts before handing off to the TUI or headless flow.
Pass `--no-wizard` to disable it (a positional path is then required) — useful
for scripts and CI.
Inside the TUI Launcher screen, the **Scan disk for repos** button performs
the same on-disk discovery without leaving the UI — found repos are appended
to the configured-repos dropdown, deduplicated against any already-listed
paths. Tune the scan via `[ui].scan_root` (defaults to your home directory)
and `[ui].scan_max_depth` (default 6) in `senex.config.toml`.
Scheduled-task entrypoint for Windows Task Scheduler: `scripts\run_senex.bat`. It
activates the venv and runs `python -m senex audit --nightly`.
## View results
```powershell
senex view # latest audit (auto-detect)
senex view # specific run
senex view --speed 10.0 # 10x replay
```
The replay does not call LM Studio; it reads `events.jsonl` from the audit dir and
re-renders the Monitor screen offline.
## Diagnostics
```powershell
senex doctor # check every [[repos]] entry
senex doctor C:\path\to\your\repo # single repo
senex doctor --json # CI-friendly output
senex lifecycle status # loaded models + runlock holders
senex lifecycle clear-locks # prune stale-PID holders
senex config show C:\path\to\your\repo # resolved config (TOML)
senex aggregate # re-run Phase 5 after a crash
```
Run `senex doctor` once after install. Every check should return `pass` or `warn`;
`fail` exits non-zero and prints the failing check's diagnostic.
## Performance tuning
senex's per-file audit time is dominated by model thinking. With
`google/gemma-4-26b-a4b` at default settings, expect **~7-8 minutes per file**
on `effort=high`. Two axes to tune.
### LM Studio (GUI knobs — frees GPU VRAM)
| Knob | Default | Recommended start | Effect |
|------|---------|-------------------|--------|
| **Context length** | 262144 | **16384** or **32768** | Largest single VRAM win — KV cache scales with context; senex prompts are <16K tokens |
| **GPU offload** | All layers | All if you have headroom | Off-loaded layers run on CPU (slower but frees VRAM) |
| **Concurrent requests (`parallel`)** | 4 | **1** if VRAM-constrained, **4** if you want to enable senex's future parallel-files feature | Each parallel slot reserves KV cache headroom |
| **Speculative decoding** | varies | enable if available | 1.5-3× speedup with negligible quality loss |
| **Flash Attention v2** | varies | enable | KV cache compression |
### senex (config knobs — shapes what senex requests)
```toml
# senex.config.toml
[lmstudio]
# Should match (or be slightly under) LM Studio's context length.
context_window = 16384
# Set true ONLY for OpenAI/Together/Groq backends that honor strict json_schema
# reliably. False (default) routes through json_object + post-hoc Pydantic
# validation, which is what gemma-class models actually return correctly.
strict_json_schema = false
[lmstudio.sampling]
max_tokens = 4096 # output cap; lower = faster, less KV growth
[lmstudio.thinking]
# "high" -> deep reasoning, ~7-8 min/file
# "medium" -> balanced, ~3-4 min/file
# "low" -> shallow, ~1-2 min/file (fine for first-pass triage)
effort = "high"
max_thinking_tokens = 8192 # cap on reasoning phase
```
### Estimated audit time by configuration
| Config | Per-file | 50-file project | 500-file project |
|--------|---------:|----------------:|-----------------:|
| Default (`effort=high`, 8K thinking, 4K output) | ~7-8 min | 6.5 hr | 64 hr |
| `effort=low`, 2K thinking | ~1-2 min | 1 hr | 11 hr |
For nightly Windows scheduled-task usage on real repos, `effort=low` + small
thinking budget is usually the right tradeoff. For spot audits of critical
files, run with `effort=high` directly.
## Where reports go
```
E:\senex-audits\\-\
├── combined.md # human-readable run report
├── findings.json # stable machine index (schema-validated)
├── claude-handoff.md # downstream summary for Claude Code
├── events.jsonl # canonical event stream (replay source)
├── checkpoint.json # resume state machine
├── audit.log # human-readable log
├── config.snapshot.toml # resolved config (TOCTOU defense)
├── findings.partial.jsonl # streaming append (input to Phase 5)
└── .md # per-file report (one per audited file)
└── .thinking.md # per-file thinking trace (when enabled)
```
The output root is configurable via `[output].root` (default: `E:\senex-audits`).
## Security
- **Source stays local.** senex's only outbound network calls are to `localhost`
(LM Studio HTTP) and local subprocesses (`npx gitnexus`, `lms`). No telemetry,
no third-party APIs.
- **Loopback-only by default.** Non-loopback `[lmstudio].base_url` requires explicit
`[lmstudio].allow_non_loopback = true`.
- **Secret redaction is on by default.** Every persisted artifact (`.md`,
`combined.md`, `claude-handoff.md`, `events.jsonl`, `audit.log`, `config.snapshot.toml`)
passes through the SecretRedactor: PEM blocks, JWTs, AWS access keys, GitHub PATs,
`sk-...` style LLM keys, and generic `KEY=value` env-style secrets are masked.
Disable only for transient debugging via `[output].redact_secrets = false`.
- **Trust boundaries.** Audited source is wrapped in `...
` before LLM ingestion; the system prompt instructs the
model to disregard directives within. Tool-call inputs are path-validated and
regex-capped per spec section 5.11.4.
- **Checkpoint integrity.** `checkpoint.json` carries an HMAC over the resume hash
bundle (`config_hash`, `prompt_hash`, `model_fingerprint`, `tool_pack_hash`,
`lens_version`). Resume is refused on hash drift unless `--allow-mixed-resume`
is set.
## Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| `doctor` reports `lmstudio_reachable: fail` | LM Studio not running | Launch LM Studio and load the configured model. |
| `doctor` reports `model_loaded: fail` | Wrong model id | Update `[lmstudio].model` in `senex.config.toml`. |
| `doctor` reports `gitnexus_index: warn` | Repo not indexed | `cd && npx gitnexus analyze`. Audit still runs without it. |
| Audit aborts immediately | Bad config / repo path | Run `senex doctor` first; fix the failing checks. |
| Resume rejected: hash mismatch | Config or prompts changed since the original run | Use `--allow-mixed-resume` (advanced) or start a fresh run. |
| Stale runlock blocks startup | Prior crash left a holder | `senex lifecycle clear-locks` (use `--force` only for live PIDs). |
| `combined.md` missing after run | Aggregation phase crashed | `senex aggregate ` to retry. |
## License & contribution
License: TBD (see `LICENSE` at repo root once added). Contributions: please open
an issue or PR; conventions live in `docs/superpowers/conventions.md`.