AI News HubLIVE
In-site rewrite6 min read

Show HN: Mindlas – catch your coding agent drifting before the bad code lands

Mindlas is an open-source tool that uses deterministic gauges to monitor AI coding sessions for context deterioration, verification debt, change blast radius, and tool failure loops, providing concrete corrections before problems compound, all running locally without network calls.

SourceHacker News AIAuthor: MAESTRO1955

Uh oh!

There was an error while loading. Please reload this page.

Notifications You must be signed in to change notification settings

Fork 0

Star 10

BranchesTags

Open more actions menu

Folders and files

NameName

Last commit message

Last commit date

Latest commit

History

11 Commits

11 Commits

.claude-plugin

.claude-plugin

.github/workflows

.github/workflows

commands

commands

docs

docs

hooks

hooks

src/mindlas

src/mindlas

tests

tests

.gitignore

.gitignore

CONTRIBUTING.md

CONTRIBUTING.md

LICENSE

LICENSE

NOTICE

NOTICE

README.md

README.md

SECURITY.md

SECURITY.md

pyproject.toml

pyproject.toml

Repository files navigation

A coding agent rarely fails at turn one. It fails at turn forty.

The agent said done. The tests disagree. Mindlas (Mind-Atlas) reads the session live, catches the drift as it builds, and hands the agent a correction.

Open and local. Nothing leaves your machine.

Long sessions deteriorate silently. Context fills with tool-output noise. The original task scrolls away and stops steering the agent. Edits spread across files. The same tool fails in a loop. None of this throws an error; the agent keeps producing confident output while its working state rots.

Mindlas catches that moment live: deterministic gauges under your Claude Code prompt that read the session's own signals, alert before a failure compounds, and pair every alert with a concrete correction whose effect is measured before and after.

The whole product runs on one loop, end to end for every gauge:

measure → trigger → explain → correct → remeasure → report

Scores are pure functions of the session's event ledger. Same ledger in, same score out. There is no model and no network call anywhere in the scoring path, and that is permanent: a model grading another model's session is non-reproducible, expensive, and circular. Corrections are deterministic mechanisms, not prompt nudges: an earlier advisory design told the agent to fix itself and failed empirically, so the corrector changes state directly and records a before/after to prove it did something.

What Mindlas does not claim: it does not guarantee correctness, prevent hallucinations, know the model's mental state, or replace tests, reviews, or human judgment. Its claim is narrow and verifiable: detect known deterioration causes from deterministic local signals, apply non-native corrections, record before and after effects, and produce an exportable scorecard.

Sixty seconds to a catch

Requirements: Python >= 3.11, git, Claude Code.

git clone https://github.com/Evolutionairy-AI/MINDLAS.git cd MINDLAS python -m venv .venv source .venv/bin/activate # macOS / Linux

.venv\Scripts\activate # Windows

pip install -e .

mindlas status --demo context_rot_alert # a real ALERT, right now mindlas context repair --apply --demo context_rot_alert # watch the correction land: 100 -> 4

Already installed from PyPI? pip install mindlas skips the clone and the venv — run the two demo commands directly.

The demo runs the full loop offline against a bundled fixture. Every frame is labeled demo; live sessions earn their own numbers.

Wire it into your live sessions

Two pieces: the hooks, which record session events into the ledger the gauges read, and the status line, the always-on gauge readout under your prompt. The status line installs the same way in both options below. For the hooks there are two paths — pick one, never both: running both records every event twice and inflates the gauges.

Option A — plugin (recommended)

Loads the eight hooks and the five correction slash commands. Still standing in the MINDLAS clone from the quickstart, venv active? The plugin dir is simply .:

claude --plugin-dir . # hooks + slash commands, loaded as a plugin mindlas install-statusline # the status line (restart Claude Code after)

To use Mindlas on your own project, launch from that project's directory and point --plugin-dir at the clone instead:

cd ~/my-project claude --plugin-dir ~/path/to/MINDLAS

The plugin's hooks call mindlas by name, so launch claude from the shell where the venv is active; without that PATH they silently do nothing.

The five slash commands drive the corrections on the live session: /mindlas:mindlas-repair, /mindlas:mindlas-verify, /mindlas:mindlas-blast-split, /mindlas:mindlas-loop-stop, /mindlas:mindlas-loop-release. Each is a thin wrapper over its CLI equivalent (see the CLI reference). The gauges surface them in short form: /mindlas-repair is /mindlas:mindlas-repair.

Option B — CLI install (the PyPI path)

Use this when you installed Mindlas from PyPI — the plugin directory ships with the git clone, not the wheel — or when your setup can't load plugins. It wires the same eight hooks directly into Claude Code's settings.json:

pip install mindlas # from PyPI; skip if you already installed from the clone mindlas install-hooks # the same eight hooks (restart Claude Code after) mindlas install-statusline # the status line

install-hooks records the absolute path of your venv's mindlas, so these hooks work regardless of which shell launches claude. This path ships no slash commands; run the corrections through their CLI equivalents instead (mindlas context repair, mindlas verify gate, mindlas blast split, mindlas loop stop — see the CLI reference).

Undoing it

Each piece reverses independently:

Installed via Remove with

Plugin (Option A) launch claude without --plugin-dir

mindlas install-hooks (Option B) mindlas install-hooks --uninstall

mindlas install-statusline (both options) mindlas install-statusline --uninstall

The eight hooks

Either path registers the same eight hooks, the write side of the instrument, recording every session event into the ledger the gauges read. Every handler is best-effort and always exits 0: a hook failure can never block or break the session.

Hook What it does

SessionStart Logs the session, stamps the live-session pointer, reseeds a pending repair pack.

UserPromptSubmit Advances the turn counter, refreshes the live-session pointer.

PreToolUse Pre-edit baselines; the trust gate at commit/push boundaries (MINDLAS_GATE); the loop retry guard.

PostToolUse Records each tool result and its output volume; launches the debounced background test tier after edits.

PostToolUseFailure Records the failed call (the Tool Failure Loop gauge's telemetry source); alerts on a detected blind-retry loop.

Stop Captures the final assistant message (completion claims feed Verification Debt), snapshots the transcript, refreshes tests.

PreCompact Snapshots the transcript first, then recommends Context Repair. Never blocks native compact.

PostCompact Logs the compaction boundary.

Four causes, four gauges, four actions

Each known deterioration cause has exactly one gauge and one paired correction:

Deterioration cause Gauge Corrective action After-score type

Context deterioration Context Rot (ROT) Context Repair modeled, upgraded to measured

Unverified code change Verification Debt (VERIFY) Verify Gate evidence-based

Patch spread Change Blast Radius (BLAST) Patch Splitter planned

Repeated failed tools Tool Failure Loop (LOOP) Loop Stop controlled

Bands are action thresholds, not severity grades: WATCH surfaces the correction hint, WARNING formally recommends it, ALERT means correct before it compounds. Context Rot's score accumulates with normal session activity (turns and context mass alone earn points), so its bands sit higher (WATCH at 40, ALERT at 80) than the other three (25/70), which score 0 on a clean session. Each gauge triggers independently, with deliberately no cross-gauge rules.

Context Rot (ROT)

Deterioration of the working context, not window fullness; fullness is only one of six signals and is capped so a full window alone can never reach WARNING. The others are counts and ages read off the event ledger: turns, large tool outputs, task-contract age, unresolved user corrections, and turns since the last repair. That last signal resets only when Context Repair runs. Native /compact never resets it: compaction shortens the conversation but does not rebuild the agent's working state, so the gauge deliberately keeps counting. When elevated, the gauge suggests /mindlas-repair.

Verification Debt (VERIFY)

Code changed without fresh evidence it still works: changed files and lines, staleness of the last verifier result, production changed without tests, completion claimed without evidence, minus a coverage credit only when evidence is fresh. A truly clean tree scores 0. When elevated, the gauge suggests /mindlas-verify.

Change Blast Radius (BLAST)

How broadly a patch has spread across files, directories, and concerns: review and coordination risk, not proof the code is wrong. A small coherent patch earns a cohesion credit and never fires, even when Verification Debt is high; that is Verify Gate's job. When elevated, the gauge suggests /mindlas-blast-split.

Tool Failure Loop (LOOP)

The agent stuck retrying the same failing tool call without new evidence. Repetition is scored over the active evidence segment: a success or user prompt breaks the loop, and broken loops never trigger. An active stop boundary caps the score low, and the gauge reads controlled rather than healed. When elevated, the gauge suggests /mindlas-loop-stop.

The full signal weights and trigger math live in src/mindlas/features/; the signal builders in src/mindlas/runtime/.

The four corrections

Every correction is a pair: a dry-run preview that writes nothing, and an apply that records a before and an after.

Context Repair (modeled → measured). Rebuilds the task-critical working state from the event ledger into a compact nine-section pack: task contract, constraints, repo and diff state, next action, and an evidence index where every claim carries a turn reference and a sha256 of its source span. Eight validation gates must pass before a pack goes live; a failed validation writes an inert draft and resets nothing. The loop: repair writes the pack and a one-shot resume marker → you press /clear (the one step a hook cannot perform, by design) → the new session's SessionStart hook injects the pack automatically → the first status-line render records the measured post-repair score, upgrading the modeled one. It never calls native /compact, and there is no LLM anywhere in the pack builder.

Verify Gate (evidence-based). Plans deterministic checks for the files changed this session (AST syntax, ruff, targeted pytest, config-gated), runs them, and re-derives VERIFY from the evidence: a fail floors the score, a fresh pass is capped by what was actually covered. The gate refuses to certify what it didn't check: a skipped run preserves the debt rather than falsely clearing it.

Patch Splitter (planned). Partitions a sprawling diff into coherent, reviewable bundles under .mindlas/splits/ (source files untouched, by contract). The after-score is what BLAST would read if the plan were followed; a no-reduction preview prints the honest reason, never a fabricated improvement.

Loop Stop (controlled). Records a controlled stop boundary on a detected blind-retry loop: the gauge falls to controlled, a stop card is written, and while the boundary is active a retry of the exact stopped command signature is caught at PreToolUse (warn by default, deny with MINDLAS_LOOP_GUARD=block). mindlas loop release re-arms when the plan has genuinely changed. Detection is also live: the failure hook alerts your terminal and injects a stop directive in-session, de-duplicated per loop.

The scorecard: proof, not vibes

Every applied correction is recorded; every session ends with an exportable artifact. mindlas scorecard --json from the demo above:

{ "session_id": "demo", "features": { "context_rot": { "max": 100, "final": 4, "alerts": 1 }, "verification_debt": { "max": 0, "final": 0, "alerts": 0, "last_resul

[truncated for AI cost control]