Context Guard 0.3.0
Feature release: Context Guard now watches Claude Code and Codex CLI sessions as well as Open WebUI chats, every score has an explanation page, and known-value drift was reworked against measured data. The 0.2.0 version was never tagged; these notes cover everything since 0.1.3. The Open WebUI filter file is updated (version 0.3.0): reinstall it to get the clickable status line.
Changes since 0.1.3
New sources
- Claude Code. A
Stop/PostToolUse/SessionEndhook ships the session transcript incrementally toPOST /api/v1/ingest/claude-code; one API call is one turn, the anomaly window is counted in prompts so a tool loop is one prompt. AstatusLinecommand shows the score in the status bar as a terminal hyperlink to the explanation page, refreshed on a timer so the just-scored turn appears without waiting for the next prompt. Verified against Claude Code 2.1.270. - Codex CLI. A hook ships session rollouts to
POST /api/v1/ingest/codex; one API response, closed by its usage record, is one turn. TheStophook prints the score under the reply as a Codex system message with a link. Verified against Codex CLI 0.154.0. - The hooks share one module (
agent-hooks/context_guard_shipper.py) for state, shipping and score fetching; everything stays standard-library Python.
Explanation page
GET /api/v1/conversations/{id}/explainis the document for a front end: the latest result, every reason with its title and explanation, every issue ever caught with whether it still counts, the score over turns, and the scoring parameters.GET /ui/conversations/{id}renders it as a self-contained page (no external assets).- The Open WebUI status line is now collapsible: expanding it shows a link to that page (new valve
explain_url, browser-reachable,{id}is the chat id). Claude Code and Codex lines link to it directly. GET /api/v1/signalslists the signal catalog with configured penalties.
Scoring
- Known-value drift learns facts in every recognised form but reads a reply as a claim only in explicit marker forms, and never from a sentence that hedges, conditions, suggests, negates or proposes a change, from a question, or from fenced code. Plain words anchor a value only when the conversation has named them (as an identifier or as the subject of a fact sentence). Many more fact shapes are recognised: sentence-final punctuation, quoted and colon markers (
"port": 8080,Version: 1.94.1), numerichost:port,listen,N/tcp, compose mappings, prose and flag settings, version pins. Loopback addresses, network prefixes, declaration lines,file.ext:LINEand quoted times are not facts. Measured with the new extraction-recall harness: registry recall 69% → 88%, drift-eligible recall 26% → 65%, false positives on benign replies (suggestions, defaults, hypotheticals) 5%. - Suspicious identifiers ignore a shortened form of a known name, a dotted attribute of one, and for plain names a hyphen/underscore swap; a suffix on a known name still counts.
- Context overflow errors from Claude Code and Codex are scored as overflows.
Tooling
scripts/extraction_recall/measures the extractor against planted facts: phrasing and tool-output templates, a model-paraphrased fixture with the planted tokens verified verbatim, a benign-reply tier, and a survey of real transcripts. It runs the pure functions throughexamples/extract.rsin seconds. CI runs its tests.- Database migration
0002_prompts.sqladds the prompt counters and is applied automatically at startup.
Install
See the README quick start. Verified against LiteLLM v1.94.1 and Open WebUI v0.11.3, Claude Code 2.1.270, and Codex CLI 0.154.0. With compose, create the bind-mount directory first and make it writable for uid 10001.
git clone https://github.com/dividehex/context-guard
cd context-guard
docker build -t context-guard . && docker run -d --name context-guard --restart unless-stopped -p 127.0.0.1:7432:7432 -v context-guard-data:/data context-guard🤖 Generated with Claude Code