← back to the fleet dashboard

How Keel works

Keel closes the AI-context gap: coding assistants see the files in their prompt, but real engineering decisions need to know what flows already exist, which rules govern them, and what broke last time. Keel builds that world model per repo — locally, code never leaves the machine — and wires it into the assistant's loop.

Architecture

Your repository routes · SQL migrations CLAUDE.md · rule packs agents · skills · manifests prompts · config · any code (git post-commit hook re-indexes on every commit) typed adapters Project graph (local) SQLite + local embeddings ~50 node types ~40 edge types every node cites file:line confidence per node/edge briefs rule gate AI assistant loop prompt → brief injected agent spawn → brief injected every edit → checked, violations blocked + cited session end → behavior rollup daily push Fleet collector counts only, never code judged blocks + brief feedback tune matchers, scoring, and the confidence floor Everything left of “daily push” runs on the laptop. The collector receives snapshot metadata and aggregate statistics, not repository content.

The brief pipeline — how context is chosen

Prompt or agent spawn Intent gate feature / refactor / question notifications suppressed Graph retrieval keyword + embedding match + neighbor expansion Confidence gate scored match quality vs. tunable floor Inject brief flows + rules + citations Rules only low match, governance kept Stay silent noise is worse than nothing

Fail direction is deliberate: below the confidence floor Keel degrades to governance-only (rules must always survive), and suppresses entirely only when there are no rules to show.

Languages & frameworks

AdapterLanguage / stackWhat it extracts
python-fastapi + py-astPythonAPIRouter/FastAPI endpoints, per-route dependencies, functions/classes
springJava / Kotlin@RestController, @*Mapping endpoints, @PreAuthorize role gates
nextjs + ts-permissionsTypeScript / JavaScriptApp Router pages & endpoints, capability matrices, RoleGate/usePermission, inline-role-check anti-patterns
go-routesGogorilla/mux, gin, chi, net/http route registrations
sql-migrationsSQL (Postgres)tables, columns, indexes, RLS policies, migrations, FK edges
prose-rulesMarkdownCLAUDE.md / DESIGN.md / RULES.md → rules & protected behaviors
project-contextMarkdown + YAML/JSON/TOML + Python/env templatesstable documentation sections, versioned prompt/config inputs, Python constants and environment gates with exact live relationships; prose remains distinct from runtime truth
ai-toolingrepository agent-tooling manifestsdeclared agents, skills, hooks, and MCP servers; declarations are inventory, not proof they ran or completed work
platform-manifestYAMLBackstage catalog-info.yaml / service manifests → services & ownership
generic-codeany languagefallback extractor — functions, types, modules — so every repo indexes non-empty

Annotation-driven rules (keel:rule pattern=…) work in any file of any language, so enforcement isn't limited to the adapter list.

What the graph captures — and why context comes out right

Node types (~50, grouped)

code: module · function · class · method · type surface: service · endpoint · UI page · UI component auth: role · capability · persona data: table · column · migration · entity · schema · RLS policy async: topic · queue · job · worker · webhook cross-cutting: cache · state machine · tenant scope · feature flag · env/config · constant · prompt template contracts: validator · rate limit · CSP/CORS rule · entitlement governance: rule · protected behavior · agent · skill · hook · MCP server

Edge types (~40, grouped)

structure: calls · implements · imports · depends-on · belongs-to auth: has-capability · gated-by · requires · extracts-tenant-id data: reads · writes · maps-to · reads-scoped-by routing: proxies-to · serves-endpoint · resolves-to events: produces · consumes governance: governs · tests · supersedes · regressed-by · owns bug-class: shadows (duplicate definitions) · binds-argument · exposes-schema · persists-to synthesized: similar-to · co-occurs-with

The correctness mechanisms

MechanismHow it keeps context right
Citations everywhereEvery node carries file:line; every brief item and every block cites its source, so claims are checkable, not asserted
FreshnessPost-commit hook re-indexes; if the graph lags HEAD, briefs carry an explicit staleness warning and keel doctor flags it
Confidence scoringNodes, edges, and whole briefs are scored; low-confidence briefs degrade to rules-only or stay silent rather than inject noise
Local embeddingsSemantic match (BGE-small, on-device) finds related flows even when names differ — nothing sent to any API
Intent gatingQuestions, bare acknowledgements, and machine-generated turns (notifications, command output) never trigger briefs
Feedback loopJudged blocks (keel review --judge) and brief ratings (keel feedback) feed precision metrics that tune matchers and scoring — visible on this dashboard
Deterministic enforcementOn installed, supported edit-hook paths, the rule gate can block a covered write and cite the rule and reason. Fail-open errors, unsupported tools, and semantic correctness remain explicit assurance gaps

What leaves the machine

The Fleet transport contains the human repository and machine labels, a random working-copy id, aggregate counts, rule ids, adapter names, feedback tags, file basenames in block evidence, and cohort statistics. It does not include source code, diffs, prompts, skill bodies, or absolute local paths. Devices send a revocable bearer credential in the authorization header. For dashboard access, the server exchanges that credential for a random 12-hour read-only session in a host-bound HttpOnly, Secure, SameSite=Strict cookie. Only the cookie hash is stored by Fleet; JavaScript and browser storage never retain the reusable device credential. Refreshes reuse the session, while Lock revokes it and clears the cookie.

What the dashboard numbers mean

MetricDefinitionWhy it matters
Prompt events observed UserPromptSubmit hook events in each reporting working copy's bounded window Shows prompt activity covered by the reporter. It is not an all-time count and does not prove that context was delivered
Briefs served BriefServed records in the bounded report window, including prompt hooks and supported non-prompt surfaces such as CLI, MCP, review, or child-task context Shows Keel context generation activity without mislabeling every brief as a prompt delivery
Exact prompt deliveries distinct prompt-session/brief links emitted by the supported UserPromptSubmit delivery path in the bounded report window Counts proven deliveries without inflating the cohort with MCP, CLI, review, or child-task briefs. An incomplete evidence label means the activity reader reported a bound, parse, or read gap
Unclassified legacy delivery counter the historical prompts_enriched value from snapshots created before metric provenance was recorded Preserves old evidence without presenting it as total prompts or pretending its former counting rule is comparable to exact delivery links. Its definition can change between old reporter versions, and Fleet never adds it to the exact total
Graph nodes / edges latest indexed repository entities and typed relationships, with node type, edge relationship, and adapter breakdowns Shows whether Keel has merely indexed symbols or has the relational model needed for architectural context
Code durability % of commits ≥14 days old whose files were not touched again within 14 days The AI-era quality metric (churn is the documented failure mode of AI code)
Observed durability difference durability of timestamp-proximate commits − non-proximate commits, same repo A descriptive association. It is not randomized, does not isolate Keel as the only difference, and must not be read as causal uplift
Timestamp-proximate commit landed within 4h of a Keel brief/hook event on that machine A coarse proximity window; it is not exact session→commit attribution and can include unrelated activity
Block precision of blocks a human judged, % that were real violations A gate that false-blocks trains people to bypass it
Brief adherence % of brief-cited files the agent's edits actually touched Citation/edit overlap only. It does not prove the agent read, followed, or benefited from the brief
Agent/skill observation structured Task or Skill request records found in covered Claude Stop transcripts Positive name-level request evidence only; completion, effect, Codex coverage, and revision-bound verified use are not yet supported
Brief usefulness % of rated briefs tagged useful (via keel feedback) The developer's own verdict on the context quality
Audit battery synthetic probes: false-positive blocks and missed violations Product precision/recall measured without touching real code

Timing note Durability judges commits only after they're 14 days old, so new repos (and the timestamp-proximate cohort of a fresh install) show data ~2 weeks after Keel starts there.