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.
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.
| Adapter | Language / stack | What it extracts |
|---|---|---|
python-fastapi + py-ast | Python | APIRouter/FastAPI endpoints, per-route dependencies, functions/classes |
spring | Java / Kotlin | @RestController, @*Mapping endpoints, @PreAuthorize role gates |
nextjs + ts-permissions | TypeScript / JavaScript | App Router pages & endpoints, capability matrices, RoleGate/usePermission, inline-role-check anti-patterns |
go-routes | Go | gorilla/mux, gin, chi, net/http route registrations |
sql-migrations | SQL (Postgres) | tables, columns, indexes, RLS policies, migrations, FK edges |
prose-rules | Markdown | CLAUDE.md / DESIGN.md / RULES.md → rules & protected behaviors |
project-context | Markdown + YAML/JSON/TOML + Python/env templates | stable documentation sections, versioned prompt/config inputs, Python constants and environment gates with exact live relationships; prose remains distinct from runtime truth |
ai-tooling | repository agent-tooling manifests | declared agents, skills, hooks, and MCP servers; declarations are inventory, not proof they ran or completed work |
platform-manifest | YAML | Backstage catalog-info.yaml / service manifests → services & ownership |
generic-code | any language | fallback 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.
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
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
| Mechanism | How it keeps context right |
|---|---|
| Citations everywhere | Every node carries file:line; every brief item and every block cites its source, so claims are checkable, not asserted |
| Freshness | Post-commit hook re-indexes; if the graph lags HEAD, briefs carry an explicit staleness warning and keel doctor flags it |
| Confidence scoring | Nodes, edges, and whole briefs are scored; low-confidence briefs degrade to rules-only or stay silent rather than inject noise |
| Local embeddings | Semantic match (BGE-small, on-device) finds related flows even when names differ — nothing sent to any API |
| Intent gating | Questions, bare acknowledgements, and machine-generated turns (notifications, command output) never trigger briefs |
| Feedback loop | Judged blocks (keel review --judge) and brief ratings (keel feedback) feed precision metrics that tune matchers and scoring — visible on this dashboard |
| Deterministic enforcement | On 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 |
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.
| Metric | Definition | Why 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.