Skip to content

siosig/mcp-hive-memory

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

106 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

hive

Ambient team memory for AI coding agents. Your team's hard-won knowledge — the failures, the LLM's wrong guesses, the research nobody wants to redo — shows up in your AI agent exactly when it's relevant, without anyone searching for it.

日本語版 / Japanese

Status: working vertical slice + knowledge graph. Spec-driven under specs/.


Contents


Why hive exists

Small teams lose the same hours over and over: someone already hit this bug, someone already learned this API's quirk, someone already found the answer — but that knowledge lives in a chat scrollback nobody will ever find again. Generic note tools don't help, because they require you to remember to search.

hive flips this around. You just work. Relevant knowledge from your teammates is injected into your agent's context automatically, and your own discoveries flow back to the team the same way.


Features

You get all of this without thinking about it:

  • One-shot setup. Register hive with Claude once — there's nothing to learn and no new habit to build.
  • So fast you won't even notice it's there. The auto-injection hook fires on every prompt and the pitfall guard fires before every tool call — both complete in the background before your turn begins. In practice, you won't see any delay or status message. hive is working; it just doesn't announce itself.
  • Give and receive, just by working. While you work normally, hive quietly collects a small team's knowledge across projects — especially failures, the LLM's misunderstandings, and research findings, the things most worth not repeating — and auto-injects the most relevant few back into your agent, matched by meaning (semantic + keyword) and ranked by relevance, no search required.
  • Discover by relationship, not just keywords. A self-hosted knowledge graph lets you traverse how knowledge connects — hive_trace (multi-hop) and hive_map (neighborhood) surface related lessons even when the wording is completely different.
  • Persists across sessions. Close the window, open a new conversation tomorrow — knowledge captured once shows up again whenever it's relevant. No context cliff, no re-explaining.
  • Spans every project. A lesson from one repository is available in any other codebase you open. One discovery, everywhere.
  • Shared across every person on your team. One teammate's hard-won discovery becomes available to everyone else — no wiki page to write, no Slack thread to find.

And privacy is handled before anything is published:

  • Privacy-sensitive content is stripped before it reaches the shared store. Personal data, customer names, credentials, and internal hostnames are caught by asynchronous redaction (Gemini-judged → block-by-default) and only the cleaned body is moved into the published tier. Raw content first lands in an internal staging tier that is never externally reachable (database-level row security via a dedicated hive_recall role); recall can only read the published tier.
  • Knowledge is shared as de-identified lessons. The recommended practice is to attach only a generic member label (never a real name), so what circulates is the lesson, not blame.

→ Full details: docs/privacy.md · docs/security.md


Install

hive is two halves: a client registered with your agent, and a server you self-host. The only external requirement is a Gemini API key.

Client (Claude Code)

hive ships as a Claude Code plugin (.claude-plugin/plugin.json + hooks/hooks.json): installing it wires the hive MCP server, the auto-injection hook (UserPromptSubmithive-inject, the primary zero-action experience), and the pitfall guard (PreToolUsehive-guard) in one step — no manual hook editing. The explicit hive_* MCP tools (ask / share / trace / map / mine / drafts / distribute / forget / status) are the manual surface.

Register the plugin with Claude Code using the install script. If you have not cloned the repo yet, the script clones and builds it automatically:

export HIVE_TOKEN=<your-token>

# Option A — fresh install (clones repo → builds → registers)
curl -fsSL https://raw.githubusercontent.com/siosig/mcp-hive-memory/main/install_claude_plugin.sh | bash

# Option B — from a cloned repo (uses the local build if already present)
./install_claude_plugin.sh

# → Restart Claude Code to activate the plugin

The script clones to ~/.local/share/hive (if needed), runs npm install && npm run build, registers a local marketplace entry, and writes a usage-rules file to ~/.claude/rules/mcp-hive-memory.md. The following env vars are overridable:

Variable Default Purpose
HIVE_TOKEN (required) Bearer token for the hive backend
HIVE_BACKEND_URL http://localhost:8765 Backend URL
HIVE_INSTALL_DIR ~/.local/share/hive Where the repo is cloned and built
HIVE_MARKETPLACE_NAME hive-local Local marketplace entry name

No GEMINI_API_KEY is needed on the client — AI inference runs server-side. Both hooks are fail-soft — a missing backend means no injection/warning, never a blocked turn. Prefer manual wiring? See deploy/claude/settings.json. Gemini CLI users use the hive-inject-gemini hook (BeforeAgent) — see deploy/gemini-cli/settings.json and specs/001-hive-ambient-kb/contracts/gemini-cli-hook.md.

Recording a lesson explicitly — the /hive-memory skill

Ambient capture is the primary path, but the plugin also ships a /hive-memory skill for deliberately recording a lesson — the manual counterpart, in the spirit of /chest-memory. Use it right after solving a non-obvious problem, making a design decision, or hitting a pitfall worth warning others about:

/hive-memory npm install corrupts the pnpm workspace here; use pnpm

With no argument it distills the key takeaway from the current conversation. The skill classifies the item (solution / pitfall / decision), adds topics and the project name, then records it through the hive_share tool — so secrets/PII are redacted on the server before storage. Recall stays automatic via injection (or on demand with hive_ask); remove a mistaken entry with hive_forget.

To see how much the team KB holds, run /hive-memory status — a read-only count per type for the active and archived stores (via the hive_status tool):

/hive-memory status
# hive knowledge
#   active:   solution 133 · pitfall 92 · decision 0 · other 0 — total 225
#   archived: solution 1   · pitfall 1  · decision 0 · other 0 — total 2

Server (Ansible-deployed Docker stack)

The server stack — the knowledge store (reference backend) + PostgreSQL/AGE graph — ships as a Docker stack. (The hive MCP server itself runs client-side over stdio, spawned on demand; it is gated behind the mcp compose profile, so a plain up brings up only the two long-running services.)

Ansible under deploy/ansible/ deploys it, split into two independently runnable roles:

Role / playbook Purpose Required?
docker.yml (role docker) Build + run the stack (reference backend + PostgreSQL/AGE) Required — Docker must be installed on the target
nginx.yml (role nginx) Reverse-proxy the store under /hive-memory Optional — only if you want HTTP(S) access via nginx

Requirements: Docker (+ compose plugin) on the docker target; nginx on the nginx target only if you deploy that role. GEMINI_API_KEY is set server-side (backend container only). HIVE_TOKEN and the Postgres password are generated and persisted automatically under deploy/ansible/.credentials/ (gitignored — never committed).

Both default to localhost. From deploy/ansible/:

export GEMINI_API_KEY=...           # server-side only; set before deploying

ansible-playbook docker.yml          # required: the stack
ansible-playbook nginx.yml           # optional: the /hive-memory reverse proxy
ansible-playbook site.yml            # both at once

# If host port 8765 (backend) or 5432 (postgres) is already taken:
ansible-playbook docker.yml -e hive_backend_host_port=8770 -e hive_pg_host_port=5433

By default nginx.yml writes a self-contained server block to /etc/nginx/conf.d/hive-memory.conf. To instead add /hive-memory as a location inside an existing vhost (matching its upstream port):

ansible-playbook nginx.yml \
  -e hive_nginx_mode=location \
  -e hive_nginx_dest=/etc/nginx/locations.d/<your-vhost>/hive-memory.conf \
  -e hive_nginx_upstream_port=8770

Targeting other hosts (set the docker and nginx hosts independently): the two roles have separate inventory groups, so they can run on different machines. Edit deploy/ansible/inventory.yml (or copy it to inventory, which is gitignored, and edit there) — replace localhost under hive_docker and/or hive_nginx with your host:

hive_docker:
  hosts:
    db-host.example.com: { ansible_user: ubuntu }
hive_nginx:
  hosts:
    edge-host.example.com: { ansible_user: ubuntu }

For the nginx server name in server mode, pass -e hive_nginx_server_name=your-host.example.com. On a fresh remote host, enable engine/package install with -e hive_docker_install_engine=true / -e hive_nginx_install=true.

To run the stack locally without Ansible instead:

cp .env.example .env   # set GEMINI_API_KEY (server), HIVE_TOKEN, HIVE_PG_PASSWORD
docker compose -f docker/docker-compose.yml up -d        # backend + postgres
# The MCP server is spawned per session over stdio (not a daemon):
docker compose -f docker/docker-compose.yml run --rm hive

Operating it (all deployment-agnostic, optional)

  • Auth — default is a shared bearer token (HIVE_TOKEN). For per-user SSO, set HIVE_AUTH=trusted-header behind any identity-aware proxy; see deploy/examples/trusted-header-proxy.md. Per-user identity is used for access/audit only and is never attached to stored knowledge.
  • Automation growth loop — mining runs by default (HIVE_MINE_INTERVAL_MS, 6h) to turn recurring solved patterns into Skill/playbook drafts. High-confidence drafts (cluster ≥ HIVE_AUTO_PROMOTE_MIN_OCCURRENCES) are auto-promoted when HIVE_AUTO_PROMOTE_DRAFTS is on (default); lower-confidence drafts still wait for a human hive_distribute.
  • Knowledge capture & recall — recall defaults surface more (HIVE_INJECT_MAX=8, HIVE_RELEVANCE_MIN=0.45, both overridable). Recorded items are auto-attributed to the current repo (basename only — never a URL/host). Session-end auto-capture always runs (fool-proof — no enable flag; the Stop hook distills marked lessons through the redaction/dedup intake, fail-soft). A same-project ranking boost is on by default (HIVE_BOOST_SAME_PROJECT, never a hard filter). Optional, OFF by default: a one-way HMAC project key (HIVE_PROJECT_KEY
    • HIVE_TEAM_SALT, computed client-side) and a project-scoped TTL (HIVE_PROJECT_TTL_DAYS).
  • Scoped rules & knowledge — every item carries a type (rule | knowledge) and a scope (personal | project | global). Rules are injected unconditionally within their scope (relevance bypassed, hard-excluded elsewhere) into a reserved sub-budget of HIVE_INJECT_MAX (HIVE_RULE_RESERVE=3, per-scope caps HIVE_RULE_CAP_PERSONAL/PROJECT/GLOBAL), so a must-always rule never silently fails to surface; rules are also exempt from reuse-based archival. Knowledge keeps relevance ranking with a soft same-scope boost and is never hard-excluded (cross-scope serendipity preserved). scope is injection applicability, not access control — scoped items stay retrievable by anyone via the explicit query tools. At record time the scope is auto-classified from content when not given (first-person environment / working-style → personal, explicit cross-project markers → global, else project); the recording project is auto-resolved (no more unknown) and the member comes from HIVE_MEMBER (configured by install_claude_plugin.sh from git config user.email / $USER), so a personal lesson follows you everywhere with zero extra input. A load-time migration re-classifies pre-existing items.
  • Performance self-optimization (perfup) — a hive perfup CLI measures the true usefulness of recall (was an injected item actually used in the next turn?) from local transcripts, distinct from selection-only reuse count, and posts it back via POST /feedback (updates a separate usefulness score, never the reuse count). Subcommands: collect (KB health), harvest/judge/feedback (measure), diagnose (classify dead knowledge: noise vs not-surfaced), evaluate/sweep (offline replay on a read-only snapshot — the live store is never mutated), experiment (retrieval changes, before/after, adopt only on improvement), and run (orchestrate). Config changes are recommend-only by default; auto-apply (HIVE_PERFUP_AUTOAPPLY, OFF) is gated by the offline regression check, auto-rolls-back on live-reward degradation, and is halted by a report/perfup/STOP kill switch. A record-time reusability gate (HIVE_REUSABILITY_GATE = block/downrank/off) keeps one-off knowledge out via an independent judge (HIVE_JUDGE_MODEL, distinct from the relevance scorer). (Feature 023 folded recall's semantic candidates into pgvector and added the recall importance floor HIVE_IMPORTANCE_MIN; the earlier in-process HIVE_SEMANTIC index and the hive perfup experiment arm were removed.) Scheduled measurement (feature 019) — a perfup Docker sidecar (same image as the backend) runs the full measurement loop every 30 minutes (HIVE_PERFUP_INTERVAL_SECONDS, default 1800) without a host scheduler. Results are written to a shared perfup-reports volume; the backend reads them and exposes them as hive_perfup_* Prometheus gauges on its existing /metrics endpoint, so Alloy forwards them to Prometheus with no new scrape path. The Grafana dashboard (exposed at /hive-metrics) shows precision@k, usefulness@turn, calibration, supply, latency p95, KB health trend, and last-run status. Quality gauges are absent (not 0) when sampleSize = 0 — Grafana shows "Not yet measured". The judge sample cap (HIVE_PERFUP_SAMPLE, default 40) bounds Gemini cost. A kill switch (report/perfup/STOP) stops the sidecar; the lock file prevents overlapping runs (a stale lock from a killed run is cleared on sidecar startup). Host transcript directory is bind-mounted read-only into the sidecar via HIVE_TRANSCRIPTS_DIR (set in docker/.env, never committed). Claude Code writes transcripts mode 0600, so the sidecar must run as the owning host user: set HIVE_PERFUP_UID/HIVE_PERFUP_GID in docker/.env to id -u/id -g (otherwise it harvests 0 episodes and the quality gauges stay unmeasured). The /perfup-review skill reads these Prometheus metrics and produces a recommend-only improvement plan — it no longer runs the measurement.
  • Defense-in-depth — set HIVE_RESCAN_INTERVAL_MS to periodically re-scan the stored KB for anything that slipped past write-time redaction (high-confidence secrets are auto-removed with a recoverable audit record; ambiguous items are flagged). Credentials can be supplied via a pluggable secret provider (env by default); logs are structured JSON.
  • Backup/restorescripts/backup.sh <conn> <out> / scripts/restore.sh <conn> <in> (pg_dump/pg_restore; covers the AGE graph, embeddings, drafts, and audit findings). Enrichment can run behind an external ingestion queue (HIVE_QUEUE) for burst absorption.

→ Full lifecycle, forget, UPSERT override, and automation details: docs/lifecycle.md


Architecture

Components

flowchart LR
  subgraph Client["Your AI agent"]
    Hook["auto-injection hook<br/>(primary, zero-action)"]
    Tools["hive_* MCP tools<br/>(ask / share / trace / map / mine ...)"]
  end

  subgraph Server["hive server (Docker)"]
    MCP["hive MCP server / backend"]
    Judge["async judgment (15-min batch)<br/>redaction + translation + scope/type"]
    Ingest["ingest job (5-min)<br/>publish judged items"]
  end

  subgraph Stores["self-hosted PostgreSQL (Docker)"]
    Staging[("staging tier<br/>raw, RLS-isolated")]
    KB[("published tier<br/>bilingual + pgvector + pg_trgm")]
    PG[("Apache AGE graph")]
  end

  subgraph Local["local sidecars (Docker)"]
    TEI["TEI embed + rerank<br/>(multilingual)"]
  end

  Gemini["Gemini API<br/>(async judgment only)"]

  Hook -- prompt --> MCP
  Tools --> MCP
  MCP -- record (zero processing) --> Staging
  Judge -- read --> Staging
  Judge -. offload .-> Gemini
  Judge -- embed --> TEI
  Judge -- judged --> Ingest --> KB
  Ingest -- enrich --> PG
  MCP -- trace / map --> PG
  MCP -- "hybrid recall<br/>pg_trgm ∪ pgvector → RRF" --> KB
  MCP -- "query embed + rerank" --> TEI
  MCP -- rank + inject --> Hook
Loading

Algorithm

Auto-injection (the ambient path) — fully local, zero external LLM calls:

flowchart TD
  F["A teammate starts related work"] --> G["Auto-injection hook fires"]
  G --> H["Hybrid gather:<br/>pg_trgm lexical ∪ pgvector semantic<br/>(query embedded once on local TEI)"]
  H --> K["Reciprocal Rank Fusion (RRF)<br/>+ importance / usefulness / recency prior"]
  K --> L["Optional local cross-encoder rerank"]
  L --> I["Inject the few most relevant<br/>lessons & pitfalls — no search needed"]
Loading

Capture & judgment (how a lesson is stored and connected):

flowchart TD
  A["You work as usual"] --> B{"Worth keeping?"}
  B -- yes --> C["Record raw, zero processing<br/>→ internal staging tier (RLS)"]
  C --> D["Async judgment (15-min batch, Gemini):<br/>redact + translate + scope/importance/type"]
  D --> E["Compute bilingual body + semantic vector (local TEI)"]
  E --> F2["Ingest job (5-min) physically moves<br/>only fully-judged items to the published tier"]
  F2 --> J["hive_trace / hive_map<br/>traverse relations on demand"]
Loading
  • Recording does zero processing. Raw content is stored immediately in an internal staging tier that is externally unreachable (row-level security via a dedicated hive_recall role). Masking, judgment, and translation all happen later, asynchronously. If the staging tier is full, recording applies backpressure (HTTP 429).
  • All judgment is asynchronous (a 15-minute batch). One aggregated Gemini call per item produces the source-language redacted body, an English translation, and the scope / importance / type / kind / redaction verdict; the bilingual body and semantic vector are computed off the hot path on a local embedding model. A 5-minute ingest job physically moves only fully-judged items into the published tier — un-judged raw content never becomes recall-visible.
  • Auto-injection (and the manual hive_ask) make zero external LLM calls. A local hybrid search unions pg_trgm lexical matches with pgvector semantic nearest-neighbors (the query is embedded once on a local TEI sidecar), fuses them with Reciprocal Rank Fusion, applies an importance / usefulness / recency prior, and optionally reranks with a local cross-encoder. The returned text is the source language for Japanese queries and the English translation otherwise (query language is auto-detected; there is no recall-time translation). Each stage is fail-soft — if the dense or rerank path is down, recall degrades gracefully and never blocks the turn. This retrieval path does not traverse the graph; relationship discovery is the explicit hive_trace / hive_map surface.

FAQ

Why hive, and not some other OSS knowledge base?

Because hive is ambient and relationship-aware, not a search box. Other tools make you remember to look things up and match on keywords. hive auto-injects relevant knowledge with zero action (ranked by relevance), and adds a knowledge graph for explicit multi-hop discovery so textually-dissimilar-but- related lessons can surface. It treats privacy as a first-class concern (redaction is mandatory on the publish path), is self-hostable with just a Gemini key, and offloads the heavy lifting so your agent stays fast and cheap.

Why PostgreSQL + Apache AGE, and not Supabase?

Because the graph is the point, and managed Supabase does not offer Apache AGE (AGE is a self-hosted PostgreSQL extension). hive needs real multi-hop graph traversal and a place for vector embeddings — AGE (graph) and pgvector live in one self-hosted PostgreSQL, so a single container gives you both with no extra service. On Supabase the graph layer would have to move to a separate database, which defeats the "one store, self-hostable" design.

Why Node.js, and not Python?

Because hive lives in the MCP / AI-agent ecosystem, which is Node/TypeScript- native: the client-side hooks (Claude Code, Gemini CLI) and the MCP server share one language and one type system. The heavy ML work is split between asynchronous Gemini judgment (off the hot path) and local inference sidecars (embedding / rerank), so there's no need for Python's ML stack on the hive side — TypeScript keeps it small, typed, and easy to self-host.


Japanese team support

hive is bilingual by construction, so Japanese-speaking teams get strong recall without a query-translation layer:

  • Every published item is stored bilingually. Async judgment produces both the source-language redacted body and an English translation, so a lesson is retrievable in either language directly.
  • Cross-lingual recall needs no translation at query time. The query language is auto-detected: Japanese queries return the source-language body, other languages return the English translation. The dense path embeds the query once on a local multilingual model (intfloat/multilingual-e5-base via TEI), so a Japanese query surfaces English knowledge (and vice versa) directly.
  • Lexical recall is Japanese-aware. A PostgreSQL pg_trgm GIN index on the published content backs the lexical side of hybrid search (floor HIVE_TRGM_MIN, default 0.1).

The earlier JA→EN query-translation layer (HIVE_LANG_LAYER) has been removed: bilingual storage plus a multilingual embedder make a recall-time translation step unnecessary.

Observability

hive ships a zero-cost MetricsSink seamHIVE_METRICS=off (default, zero overhead) or HIVE_METRICS=prometheus (exposes GET /metrics).

GET /version (no auth) returns { name, version } from the running build's package.json — a deployment/health probe to confirm which build is live. The patch version is auto-bumped on every commit (pre-commit hook).

The Docker observability stack (docker/observability/) brings up Alloy + Prometheus + Loki + Grafana in one command. Alloy scrapes /metrics every 15 s and pushes to Prometheus; the pre-built Hive — KPI dashboard covers supply ratio, high-relevance ratio, P95 latency, fail-soft trips, and knowledge health. A Recall Displacement row visualizes the perfup instrumentation — displaced dead candidates (eligible knowledge that lost a slot to the injectMax cap: hive_inject_displaced_dead_total), injection saturation (hive_inject_saturated_total), and gather candidates by source (hive_gather_candidates_total{source}) — so recall tuning is decided from real traffic rather than guessed.

docker compose -f docker/docker-compose.yml up -d          # start hive first
docker compose -f docker/observability/docker-compose.yml up -d

For apt-based installs (Grafana / Alloy / Prometheus / Loki on the host), the Ansible roles under ansible/ configure each service additively.

→ Full details, metrics catalog, and Ansible variables: docs/grafana.md

Async judgment + local hybrid recall (the single method)

hive runs one knowledge pipeline: a two-tier Postgres store with asynchronous Gemini judgment and fully local recall. PostgreSQL is the sole store — the backend refuses to start without HIVE_KNOWLEDGE_URL. There is no in-memory/JSON production fallback and no behavior toggles.

Recording does zero processing. POST /knowledge stores raw content immediately in an internal staging tier (pre_judgment) and returns at once. Masking, judgment, and translation all happen later, asynchronously. The staging tier is never externally reachable: recall reads through a DB role (hive_recall) granted SELECT on the published tier only, so a staging read raises a permission error and an application bug cannot leak un-judged content. A saturated staging tier applies backpressure (POST /knowledge429).

All judgment is asynchronous (a 15-minute batch, routed through the Gemini Batch API~50% cheaper). One aggregated call per item produces the source-language redacted body, an English translation, and the scope / importance / type / kind / redaction verdict; the item's bilingual body and semantic vector are computed off the hot path on a local embedding model. The judgment DAG is idempotent (re-running only unfinished tasks). A 5-minute ingest job physically moves only fully-judged items into the published tier; retry-exhausted or stuck items are dead-lettered (failed), never published. Sensitive content the model cannot clean becomes withdrawn and is quarantined.

Recall makes zero external LLM calls. A local hybrid search unions pg_trgm lexical matches with pgvector semantic nearest-neighbors (the query is embedded once on a local Text Embeddings Inference sidecar), fuses them with Reciprocal Rank Fusion, applies an importance / usefulness / recency prior, and optionally reranks with a local cross-encoder. The returned text is the source language for Japanese queries and the English translation otherwise (query language is auto-detected; there is no recall-time translation). If the dense or rerank path is slow/unavailable, a circuit breaker degrades to lexical + importance order, so recall never blocks.

PublishStatus is pre_judgmentjudgingready_for_publishpublished, with withdrawn / failed terminal states. An item is recall-visible only when published and the viewer's scope matches.

Privacy note (ADR-0002 tradeoff). Recording stores raw content with no record-time masking, so raw PII may transiently live in the internal staging tier. This is bounded by three guarantees: the staging tier is never externally reachable (row-level security via the hive_recall role), it is cleaned before anything is published, and it is TTL-bounded (HIVE_STAGING_TTL_HOURS). Only the redacted, published tier is ever recall-visible.

Team propagation of a new lesson may therefore arrive minutes (or, when the Gemini Batch turnaround is long, up to a day) later — judgment is asynchronous.

All Gemini calls emit a structured gemini_call log line (time, model, thinking level, context size in chars + real tokens, call site, purpose) and update Prometheus counters labelled by model / thinking level / mode, plus hive_batch_jobs_total and hive_batch_pending.

Env Default Meaning
HIVE_KNOWLEDGE_URL (required) Postgres URL. The backend refuses to start without it (Postgres is the sole store).
HIVE_TEI_EMBED_URL / HIVE_TEI_RERANK_URL http://tei-embed:80 / http://tei-rerank:80 Local TEI embedding / reranker endpoints.
HIVE_TEI_EMBED_MODEL / HIVE_TEI_RERANK_MODEL intfloat/multilingual-e5-base / BAAI/bge-reranker-base TEI model ids (Apache-2.0).
HIVE_RERANK on Local cross-encoder rerank stage (off → fusion order only).
HIVE_RERANK_TIMEOUT_MS 800 Reranker call budget; on breach the breaker opens and recall degrades.
HIVE_RECALL_W_RRF 0.6 Hybrid prior weight: Reciprocal Rank Fusion score.
HIVE_RECALL_W_IMP 0.2 Hybrid prior weight: importance.
HIVE_RECALL_W_USE 0.15 Hybrid prior weight: usefulness.
HIVE_RECALL_W_AGE 0.05 Hybrid prior weight: recency.
HIVE_RRF_K 60 Reciprocal Rank Fusion k constant.
HIVE_TRGM_MIN 0.1 pg_trgm similarity floor for the lexical side.
HIVE_IMPORTANCE_MIN 0.3 Recall importance floor: items below this importance are filtered out of recall (hive_ask can override per request via importanceMin).
HIVE_JUDGE_INTERVAL_MS 900000 Judgment DAG interval (15 min).
HIVE_INGEST_INTERVAL_MS 300000 Ingest job interval (5 min).
HIVE_MAX_STAGING 10000 Backpressure ceiling (429 once staging holds this many).
HIVE_STAGING_TTL_HOURS 168 Staging cleanup TTL (raw/failed/withdrawn residue retention bound).
HIVE_JUDGE_RETRY_MAX 3 Per-item judgment retry budget before dead-letter.
HIVE_JUDGE_STUCK_HOURS 24 Hours an item may stay judging before dead-letter.

Debugging

Set HIVE_LOG_LEVEL=debug to see why a contribution was not registered, was blocked, or a search returned nothing — one structured record per pipeline stage, tied together by a correlation id. Quiet by default (info); the log level is the single control, and no raw content or secrets are ever emitted.

HIVE_LOG_LEVEL=debug docker compose -f docker/docker-compose.yml up
# {"level":"debug","event":"diag_stage_outcome","corr":"a1b2c3d4","stage":"redaction","outcome":"blocked","reason":"redaction_blocked"}

→ Stages, reasons, and how to read the output: docs/debugging.md

Develop

npm run check              # format + lint + build + tests (offline)
./scripts/scrub-check.sh   # verify no internal/private details before committing

Live integration tests need a running backend + Gemini key: HIVE_LIVE=1 for the capture/inject slice, HIVE_GRAPH_LIVE=1 for the graph (Postgres+AGE) slice.

License

MIT — see LICENSE.

About

Ambient team memory for AI coding agents — your team's failures, fixes, and research auto-injected into your agent exactly when relevant. Self-hosted, with a knowledge graph and privacy redaction.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors