# https://github.com/Todmy/valis-cli Project Manual

Generated at: 2026-06-20 05:30:02 UTC

## Table of Contents

- [Overview and System Architecture](#page-1)
- [CLI Commands, MCP Tools, and Agent Adapters](#page-2)
- [Data Management, Search, and AI Integration](#page-3)
- [Community Edition, Self-Hosting, and Operations](#page-4)

<a id='page-1'></a>

## Overview and System Architecture

### Related Pages

Related topics: [CLI Commands, MCP Tools, and Agent Adapters](#page-2), [Data Management, Search, and AI Integration](#page-3), [Community Edition, Self-Hosting, and Operations](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [src/commands/help-topics.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/help-topics.ts)
- [src/commands/index-cmd.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/index-cmd.ts)
- [src/commands/schema-cmd.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/schema-cmd.ts)
- [src/commands/admin-consolidate.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/admin-consolidate.ts)
- [src/cloud/qdrant/decisions.ts](https://github.com/Todmy/valis-cli/blob/main/src/cloud/qdrant/decisions.ts)
- [src/cloud/qdrant/admin.ts](https://github.com/Todmy/valis-cli/blob/main/src/cloud/qdrant/admin.ts)
- [src/cloud/supabase/members.ts](https://github.com/Todmy/valis-cli/blob/main/src/cloud/supabase/members.ts)
- [src/cloud/supabase/proposed-pending.ts](https://github.com/Todmy/valis-cli/blob/main/src/cloud/supabase/proposed-pending.ts)
- [src/mcp/tools/ground-truth-injector.ts](https://github.com/Todmy/valis-cli/blob/main/src/mcp/tools/ground-truth-injector.ts)
- [src/mcp/tools/link-extractor.ts](https://github.com/Todmy/valis-cli/blob/main/src/mcp/tools/link-extractor.ts)
- [src/mcp/tools/verdict-queue.ts](https://github.com/Todmy/valis-cli/blob/main/src/mcp/tools/verdict-queue.ts)
- [src/lib/type-inference.ts](https://github.com/Todmy/valis-cli/blob/main/src/lib/type-inference.ts)
</details>

# Overview and System Architecture

## Purpose and Scope

Valis (the CLI in this repository, `valis-cli`) is a **team knowledge capture and retrieval system** that bridges human workflows, AI agent harnesses, and a dual-backend persistence layer. It exposes both a CLI and an MCP (Model Context Protocol) tool surface so the same operations are reachable from interactive shells and from autonomous agents such as Cursor, Codex, Aider, Cline, and Goose. Per the help text in `src/commands/help-topics.ts`, *"the CLI is a thin facade — it loads config, resolves project from `.valis.json`, and forwards to the same MCP handlers that any agent harness can call directly."*

The product is opinionated about lifecycle: every write goes through a capture → triage → promote flow, with semantic deduplication at write time and bulk import for onboarding.

## Layered Architecture

The system is organized into four cooperating layers:

1. **CLI surface** — User-facing commands such as `valis index <folder>`, `valis admin consolidate`, and `valis schema`. `src/commands/index-cmd.ts` walks a directory and converts each `.md`/`.markdown` file into one decision draft; `src/commands/admin-consolidate.ts` performs knowledge compression via semantic grouping; `src/commands/schema-cmd.ts` emits a machine-readable catalog of every command for agent harnesses to ingest once per session.
2. **MCP tool layer** — The canonical mutation and read path. Tools include `valis_store`, `valis_search`, `valis_context`, `valis_check_duplicate`, `valis_check_diff`, `valis_lifecycle`, `valis_create_project`, `valis_list_projects`, and `valis_get_taxonomy_spec`. The CLI is a "thin facade" over these handlers; agents call them directly to avoid per-call shell-spawn overhead.
3. **Cloud storage** — Two coordinated backends: **Postgres (Supabase)** is the source-of-truth for decision rows, project metadata, and audit entries; **Qdrant Cloud** is the vector store used for semantic search. `src/cloud/qdrant/decisions.ts` describes this as a *dual-write* where each decision becomes one Postgres row plus one or more Qdrant points (chunked at 1500 chars + 200 overlap).
4. **AI services** — Two model paths sit on top: **Qdrant's server-side FastEmbed** (`e5-small` / `e5-large`) produces embeddings inside the vector store, and **Claude Haiku** is invoked for optional LLM enrichment (type inference, tag extraction, summary generation). Pricing constants in `src/commands/index-cmd.ts` document the cost model: `$1.00 / M input tokens`, `$5.00 / M output tokens`.

## End-to-End Data Flow

```mermaid
flowchart TD
  U[User / Shell] --> CLI[CLI command<br/>valis index, valis admin consolidate, ...]
  A[AI Agent Harness<br/>Cursor, Codex, Aider] --> MCP[MCP tools<br/>valis_store, valis_search, ...]
  CLI --> MCP
  MCP --> GTI[GroundTruthInjector<br/>0.97 dedup threshold]
  GTI --> LE[LinkExtractor<br/>depends_on enrichment]
  LE --> SD[Supabase Postgres<br/>source of truth]
  LE --> QD[Qdrant Cloud<br/>chunked vectors + FastEmbed]
  SD --> RG[Retrieval: pg + qdrant hybrid]
  QD --> RG
  RG --> U
  RG --> A
  MCP --> VQ[Verdict Queue<br/>Stage-A review]
  VQ --> SD
```

A typical write — for example, `valis index ./docs` per `src/commands/index-cmd.ts` — walks the folder, optionally pulls git blame, asks one confirmation prompt (run enrichment?), and then dispatches each file to the same path the MCP `valis_store` tool uses: `GroundTruthInjector` short-circuits near-duplicates, `LinkExtractor` auto-populates `depends_on`, and the row is dual-written to Postgres and Qdrant in a single transaction.

## Key Subsystems

**Pre-write semantic deduplication.** `src/mcp/tools/ground-truth-injector.ts` classifies the top search hit into three bands: `duplicate [0.97, 1.0]` short-circuits the write, `neighbour [0.70, 0.97)` proceeds and links via `depends_on`, and `none [0.00, 0.70)` writes unchanged. The threshold was raised from 0.92 to 0.97 in May 2026 after legitimate re-recordings were being blocked on mixed-domain workloads.

**Server-side `depends_on` enrichment.** `src/mcp/tools/link-extractor.ts` is a deep module that converts a decision body and a project-bound search function into a ranked list of UUIDs. The function is non-blocking (Constitution III) and never rejects; failures collapse to `status: 'failed'` so the decision always persists.

**Chunked vector storage.** `src/cloud/qdrant/decisions.ts` builds `contextual_text` and a HyDE-style `hypothetical_query` for each row, then chunk-points long bodies so the `e5-large` 514-token embedding window is respected. Payload fields include `org_id`, `project_id`, `type`, `status`, `affects`, `depends_on`, `replaces`, and `outcome` (defaulted to `'unknown'` at write time so the rerank multiplier can read it without a NULL guard).

**Draft queue and triage.** `src/cloud/supabase/proposed-pending.ts` exposes a server-side `COUNT(*)` of `status = 'proposed' OR type = 'pending'` rows with a per-type breakdown and a bounded 3-row preview. Per the lesson captured in the file header (id `104083be`), `.length` over a fetched `select()` result silently undercounts once the project exceeds PostgREST's `db-max-rows` ceiling, so all totals must use `count: 'exact', head: true`.

**Multi-stage review queue.** `src/mcp/tools/verdict-queue.ts` is the agent-facing surface over the web `/api/verdict-queue` endpoint, providing `verdict_list`, `verdict_resolve`, and `verdict_reverse` for the shared Stage-A review of contradictions and proposed-relevance items. Authentication requires a `tm_`/`tmm_` API key (exchanged for a JWT) or an OAuth bearer.

**Knowledge compression.** `src/commands/admin-consolidate.ts` runs semantic grouping against the active set, creates a new pattern decision summarizing the cluster, sets `depends_on` to all merged IDs, and deprecates the originals with an audit trail. Default cosine threshold is 0.7; `--auto-merge` fires when cluster similarity exceeds 0.9.

**Taxonomy inference.** `src/lib/type-inference.ts` regex-matches a `(summary, detail)` pair against four canonical types (`decision`, `constraint`, `pattern`, `lesson`) and falls back to `lesson` with `matched=false`. This drives both the interactive triage path and the `valis_get_taxonomy_spec` MCP tool.

## Configuration and Conventions

Projects are bound to a working directory via a `.valis.json` file written by `valis switch --project <name>`. Authentication uses either an OAuth bearer or a `tm_`/`tmm_` API key, which the CLI exchanges for a short-lived JWT. Backend URLs resolve through `src/cloud/supabase/members.ts` to either the hosted Supabase project or a self-hosted Vercel deployment. The `--enrich` flag in `valis index` is the single opt-in to LLM enrichment; everything else is deterministic and free.

## See Also

- `valis help workflows` and `valis help mcp` (in `src/commands/help-topics.ts`) — canonical workflow recipes and the CLI ↔ MCP tool mapping table.
- `valis schema` (in `src/commands/schema-cmd.ts`) — emits the full machine-readable command catalog for agent harnesses.

---

<a id='page-2'></a>

## CLI Commands, MCP Tools, and Agent Adapters

### Related Pages

Related topics: [Overview and System Architecture](#page-1), [Data Management, Search, and AI Integration](#page-3)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [src/commands/help-topics.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/help-topics.ts)
- [src/commands/index-cmd.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/index-cmd.ts)
- [src/commands/schema-cmd.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/schema-cmd.ts)
- [src/commands/admin-consolidate.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/admin-consolidate.ts)
- [src/commands/add-command.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/add-command.ts)
- [src/commands/init/helpers.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/init/helpers.ts)
- [src/mcp/tools/evolve.ts](https://github.com/Todmy/valis-cli/blob/main/src/mcp/tools/evolve.ts)
- [src/mcp/tools/verdict-queue.ts](https://github.com/Todmy/valis-cli/blob/main/src/mcp/tools/verdict-queue.ts)
- [src/mcp/tools/ground-truth-injector.ts](https://github.com/Todmy/valis-cli/blob/main/src/mcp/tools/ground-truth-injector.ts)
- [src/lib/type-inference.ts](https://github.com/Todmy/valis-cli/blob/main/src/lib/type-inference.ts)
- [src/cloud/qdrant/decisions.ts](https://github.com/Todmy/valis-cli/blob/main/src/cloud/qdrant/decisions.ts)
- [src/cloud/qdrant/admin.ts](https://github.com/Todmy/valis-cli/blob/main/src/cloud/qdrant/admin.ts)
</details>

# CLI Commands, MCP Tools, and Agent Adapters

## Overview

Valis exposes its decision-store backend through three cooperating surfaces: a Commander-driven CLI, a Model Context Protocol (MCP) server, and a set of IDE/agent adapters. The CLI is intentionally a thin facade — it loads configuration from `.valis.json`, resolves the active project, and forwards each invocation to the same handler that an MCP tool or agent harness would call directly. The CLI / MCP / agent split is described in the bundled help topic `valis help mcp`, which states that "every CLI command has a matching MCP tool" and recommends MCP for high-frequency agent calls, CLI for interactive user actions, and CLI for bulk filesystem walks ([src/commands/help-topics.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/help-topics.ts)). A separate topic, `valis help workflows`, ships canonical multi-step recipes (onboarding, capture loop, lifecycle curation) so LLMs and humans share one playbook ([src/commands/help-topics.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/help-topics.ts)).

## CLI Command Surface

The command tree is declared in `bin/valis.ts` and rendered as a JSON catalog by `valis schema`, which emits a machine-readable capability map for harnesses such as Cursor, Codex, Aider, Cline, Goose, OpenCode, and Gemini CLI ([src/commands/schema-cmd.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/schema-cmd.ts)). Each command carries two pieces of static metadata that Commander does not carry natively: a `phase` (onboarding, daily, meta) and a `mutating` flag agents use to gate destructive operations behind confirmation. YAML output is intentionally deferred until the upstream `clispec.dev` specification reaches v1.0; for now `--format=json` is the only supported shape ([src/commands/schema-cmd.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/schema-cmd.ts)).

Representative commands and their phase classification include:

| Command   | Phase       | Mutating | Notes                                                                          |
|-----------|-------------|----------|--------------------------------------------------------------------------------|
| `init`    | onboarding  | yes      | Seeds decisions from a template (`ts-saas`, `fintech`, `ai-agent`) or blank.   |
| `login`   | onboarding  | yes      | Authenticates against the hosted Supabase project.                             |
| `switch`  | onboarding  | yes      | Binds the current working directory to a project (writes `.valis.json`).        |
| `whoami`  | onboarding  | no       | Prints the resolved user and active project.                                   |
| `search`  | daily       | no       | Vector search with optional type, limit, and `--all-projects` filters.         |
| `index`   | daily       | yes      | Bulk-imports a folder of markdown files as decisions.                          |
| `serve`   | meta        | no       | Starts the local stdio MCP server for non-Claude-Code agents.                  |

Source: [src/commands/schema-cmd.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/schema-cmd.ts).

The `index` command illustrates the interactive flow: it walks a folder for `.md` / `.markdown` files, optionally pulls `git blame` for author and first-commit time, and asks a single follow-up — whether to run LLM enrichment — before persisting each draft. A token estimate and dollar cost are shown so the user can opt in with informed consent ([src/commands/index-cmd.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/index-cmd.ts)). Files prefixed with `decision-`, `pattern-`, `constraint-`, `lesson-`, or `postmortem-` are auto-classified; unprefixed files default to `decision` with `status: 'proposed'` so they sit in the drafts queue rather than polluting the active set ([src/commands/index-cmd.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/index-cmd.ts)). For operator-level maintenance, `valis admin consolidate` performs knowledge compression: it finds semantic groups above a cosine threshold, generates a merged pattern summary, and deprecates the source rows with full audit-trail entries ([src/commands/admin-consolidate.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/admin-consolidate.ts)).

## MCP Tool Bridge

Every CLI command has a 1:1 MCP counterpart, and several capabilities (`valis_store`, `valis_lifecycle`, `valis_create_project`, `valis_list_projects`, `valis_get_taxonomy_spec`, `valis_evolve`, and the verdict-queue tools) are MCP-only because they are most often driven by an agent harness ([src/commands/help-topics.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/help-topics.ts)). Tools fall into two trust tiers: read-only (`valis_search`, `valis_context`, `valis_check_duplicate`, `valis_check_diff`, `valis_list_projects`, `valis_get_taxonomy_spec`) and mutating (`valis_store`, `valis_lifecycle`, `valis_evolve`). The transport is HTTP with OAuth 2.1 in hosted mode (`https://valis.krukit.co/api/mcp`) and stdio locally via `valis serve` ([src/commands/help-topics.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/help-topics.ts)).

Two MCP-only handlers are worth highlighting. `valis_evolve` lets an agent declare a typed edge between two decisions — `supersedes`, `builds_on`, `synthesizes`, or `contradicts` — inserting a `decision_edges` row and an audit entry, and is treated as a primary write path with structured errors (no silent degradation) ([src/mcp/tools/evolve.ts](https://github.com/Todmy/valis-cli/blob/main/src/mcp/tools/evolve.ts)). The verdict-queue tools (`valis_verdict_list`, `valis_verdict_resolve`, `valis_verdict_reverse`) are thin HTTP clients over the web `/api/verdict-queue` endpoint and follow the escalate-first rule: the agent confirms with the human *before* calling a resolve/reverse tool — the tool call itself is the explicit confirm ([src/mcp/tools/verdict-queue.ts](https://github.com/Todmy/valis-cli/blob/main/src/mcp/tools/verdict-queue.ts)).

A pre-write semantic dedup layer, the `GroundTruthInjector`, runs inside `valis_store` and classifies the top vector-search hit into three similarity bands:

| Band       | Range          | Effect                                                                  |
|------------|----------------|-------------------------------------------------------------------------|
| duplicate  | [0.97, 1.0]    | Short-circuit the write and return the existing decision id.            |
| neighbour  | [0.70, 0.97)   | Write proceeds; auto-populate `depends_on` with the neighbour id.       |
| none       | [0.00, 0.70)   | Write proceeds unchanged.                                               |

The 0.97 boundary was raised from an original 0.92 after mixed-domain re-recordings of the same topic with new facts were being blocked ([src/mcp/tools/ground-truth-injector.ts](https://github.com/Todmy/valis-cli/blob/main/src/mcp/tools/ground-truth-injector.ts)). Complementing dedup, `lib/type-inference.ts` is a deterministic, regex-based classifier that assigns decision, constraint, pattern, or lesson without any LLM call, honoring the "No LLM Dependency for Core Ops" constitutional principle ([src/lib/type-inference.ts](https://github.com/Todmy/valis-cli/blob/main/src/lib/type-inference.ts)).

## Agent Adapter Integration

Adapters live in `src/adapters/` and are orchestrated by `init/helpers.ts`, which composes the per-harness steps during `valis init`. The setup flow installs Claude Code hooks, injects `AGENTS.md` / `CLAUDE.md` markers, writes a `.cursorrules` block, and calls `writeMcpServer` so the harness discovers the Valis MCP server automatically ([src/commands/init/helpers.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/init/helpers.ts)). Templates seed 18 starter decisions so a fresh project is queryable on day one ([src/commands/help-topics.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/help-topics.ts)).

`valis add-command` extends the harness with role-flavoured slash commands (`product-manager`, `researcher`, `security-advisor`, `architect`, `marketer`, and so on). Each command is a keyword-matched recipe that calls `valis_search` for prior context, performs the user-supplied analysis on `$ARGUMENTS`, and writes new findings via `valis_store` ([src/commands/add-command.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/add-command.ts)). Under the hood, all write paths converge on `cloud/qdrant/decisions.ts`, which performs the dual-write upsert to Postgres (source of truth) and Qdrant (chunked vector index with 1500-character windows and 200-character overlap, paragraph → sentence → hard-slice fallback) ([src/cloud/qdrant/decisions.ts](https://github.com/Todmy/valis-cli/blob/main/src/cloud/qdrant/decisions.ts)). Operator-grade utilities — dashboard counts, legacy-point detection, the `project_id` backfill migration, the reindex command, and the cosine similarity probe — are collected in `cloud/qdrant/admin.ts` and are typically driven by `valis admin *` commands ([src/cloud/qdrant/admin.ts](https://github.com/Todmy/valis-cli/blob/main/src/cloud/qdrant/admin.ts)).

The net effect is a single decision substrate reachable from a terminal, a Claude Code marketplace plugin, a Cursor / Codex / Aider adapter, or any stdio MCP client — with the CLI, the MCP tools, and the agent adapters sharing one set of handlers, one taxonomy, and one audit trail.

## See Also

- `valis help workflows` and `valis help mcp` — bundled playbook topics ([src/commands/help-topics.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/help-topics.ts))
- `valis schema --json` — full command catalog for harnesses ([src/commands/schema-cmd.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/schema-cmd.ts))
- Claude Code marketplace plugin: `github.com/Todmy/valis-plugin` ([src/commands/help-topics.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/help-topics.ts))

---

<a id='page-3'></a>

## Data Management, Search, and AI Integration

### Related Pages

Related topics: [Overview and System Architecture](#page-1), [CLI Commands, MCP Tools, and Agent Adapters](#page-2), [Community Edition, Self-Hosting, and Operations](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [src/commands/index-cmd.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/index-cmd.ts)
- [src/commands/help-topics.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/help-topics.ts)
- [src/commands/schema-cmd.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/schema-cmd.ts)
- [src/commands/admin-consolidate.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/admin-consolidate.ts)
- [src/commands/add-command.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/add-command.ts)
- [src/cloud/qdrant/decisions.ts](https://github.com/Todmy/valis-cli/blob/main/src/cloud/qdrant/decisions.ts)
- [src/cloud/qdrant/search.ts](https://github.com/Todmy/valis-cli/blob/main/src/cloud/qdrant/search.ts)
- [src/cloud/qdrant/scroll.ts](https://github.com/Todmy/valis-cli/blob/main/src/cloud/qdrant/scroll.ts)
- [src/cloud/qdrant/admin.ts](https://github.com/Todmy/valis-cli/blob/main/src/cloud/qdrant/admin.ts)
- [src/mcp/tools/ground-truth-injector.ts](https://github.com/Todmy/valis-cli/blob/main/src/mcp/tools/ground-truth-injector.ts)
- [src/mcp/tools/link-extractor.ts](https://github.com/Todmy/valis-cli/blob/main/src/mcp/tools/link-extractor.ts)
- [src/mcp/tools/verdict-queue.ts](https://github.com/Todmy/valis-cli/blob/main/src/mcp/tools/verdict-queue.ts)
</details>

# Data Management, Search, and AI Integration

## Overview

Valis stores team decisions in a two-tier backend: **Postgres (Supabase)** as the source of truth and **Qdrant** as the vector + hybrid search index. Every CLI command is a thin facade that resolves the active project (`.valis.json`) and forwards to MCP handlers that orchestrate writes through three cooperating AI-aware stages: a **GroundTruthInjector** that short-circuits duplicates, a **LinkExtractor** that auto-fills `depends_on` edges, and a chunked Qdrant upsert that carries contextual text and a HyPE hypothetical query for retrieval quality. The CLI ↔ MCP mapping, command lifecycle phases, and a stable JSON schema for agent harnesses are documented in [src/commands/help-topics.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/help-topics.ts) and emitted at runtime by [src/commands/schema-cmd.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/schema-cmd.ts). Source: [src/commands/help-topics.ts:39-58]() and [src/commands/schema-cmd.ts:14-30]().

The high-level flow from agent capture to retrievable decision is:

```mermaid
flowchart LR
  A[Agent / CLI capture] --> B[GroundTruthInjector]
  B -->|duplicate ≥0.97| Z[Return existing ID]
  B -->|neighbour 0.70-0.97| C[LinkExtractor]
  B -->|none <0.70| C
  C --> D[Postgres source-of-truth]
  D --> E[Qdrant upsert + chunking]
  E --> F[Hybrid search<br/>dense + BM25 + expansion]
  F --> G[Reranked results<br/>siblings / full-detail]
```

## Data Management

Decisions are dual-written. The Postgres row is authoritative; Qdrant stores one point per chunk (1500 chars + 200 overlap, paragraph→sentence→hard-slice) so retrieval hits sub-document chunks via `expand='siblings'`. Each payload includes `org_id`, `project_id` (when present), `type`, `summary`, `detail`, `contextual_text` (built by `buildContextualText`), `hypothetical_query` (HyPE), `author`, `affects`, `confidence`, `pinned`, `replaces`, `depends_on`, `status`, `source`, `outcome` (default `'unknown'`), and `created_at`. Source: [src/cloud/qdrant/decisions.ts:65-102]().

Backfill and project migration live in [src/cloud/qdrant/admin.ts](https://github.com/Todmy/valis-cli/blob/main/src/cloud/qdrant/admin.ts): `getDashboardStats` filters by `org_id` (+ optional `project_id`), and the `project_id` backfill iterates legacy points in batches of `MIGRATION_BATCH_SIZE` (100). Project-scoped filters are produced by `buildProjectFilter`, which emits a `should` clause that matches the target `project_id` *or* legacy points lacking the field — operators flip the switch by passing `legacyFallback: false` once migration is complete. Source: [src/cloud/qdrant/admin.ts:30-55]() and [src/cloud/qdrant/search.ts:30-60]().

Bulk ingestion (`valis index <folder>`) walks `.md` / `.markdown` files, optionally pulls author + first-commit-time from `git log`, and shows a preview. One optional prompt remains: run LLM enrichment? Token cost is estimated using Haiku pricing (`$1.00/M input`, `$5.00/M output`) with a 200-token system-prompt overhead and an 80-token output envelope per draft, so the user sees the dollar figure before opting in. Source: [src/commands/index-cmd.ts:25-55]() and [src/commands/index-cmd.ts:57-70]().

## Search

Hybrid search in [src/cloud/qdrant/search.ts](https://github.com/Todmy/valis-cli/blob/main/src/cloud/qdrant/search.ts) combines dense vectors with BM25 sparse vectors (`DENSE_VECTOR_NAME` + `BM25_VECTOR_NAME`) and query expansion. The synonym map groups terms such as `['db', 'database', 'sql', 'postgres', 'query']`; `_buildExpansionIndex` indexes every term against the rest of its group, and `expandQuery` appends matched synonyms to the expanded query for sparse matching while leaving the dense vector search driven by the original query. Source: [src/cloud/qdrant/search.ts:110-160]().

Chunk enrichment lets callers return either the matched chunk only, sibling chunks from the same decision (`expand='siblings'`), or the full concatenated detail (`expand='full'`). For predicate-only workloads the new `query_mode: "metadata_only"` path bypasses vector search entirely: it composes the project-scope predicate with the structured filter from `SearchFilterBuilder`, calls `qdrant.scroll` for a paginated payload-only scan, takes the first 1000 rows, and re-sorts by `created_at` descending so the result is deterministic across Qdrant versions. The scroll rows are mapped into the standard `RerankedResult` shape (with zeroed signal fields) so the same `SearchResponse` envelope works for both paths. Source: [src/cloud/qdrant/scroll.ts:14-30]() and [src/cloud/qdrant/scroll.ts:60-90]().

## AI Integration

AI integration is layered so that retrieval-time intelligence and write-time intelligence never block the user.

**Write-time dedup — GroundTruthInjector.** Runs *inside* `handleStore` before the database write, scoped to the authenticated project. It searches active decisions, classifies the top match into one of three bands — `duplicate` [0.97, 1.0] (short-circuit and return the existing ID), `neighbour` [0.70, 0.97) (write proceeds and `depends_on` is auto-populated), `none` [0.00, 0.70) (write proceeds unchanged) — and never rejects. The threshold was raised from 0.92 to 0.97 after the lower band kept blocking legitimate re-recordings on mixed-domain workloads; backlog item #181 tracks a richer "clone edge" replacement. Source: [src/mcp/tools/ground-truth-injector.ts:8-30]().

**Write-time linking — LinkExtractor.** A generic-over-`SearchFn` deep module that converts a decision body + a project-bound search function into an ordered list of UUIDs for `depends_on`. The contract is "never rejects": timeouts, search errors, and validation failures collapse to `status: 'failed'` so the write still completes and operators can read the structured failure reason from analytics. Defaults are `threshold=0.7`, `maxCandidates=3`, `timeoutMs=1500`, all clamped. Source: [src/mcp/tools/link-extractor.ts:6-30]().

**Lifecycle curation.** `valis admin consolidate` performs knowledge compression by finding semantic groups (cosine threshold 0.7 default), generating a merged summary, creating a new pattern decision with `depends_on` set to the merged IDs, deprecating the merged decisions, and writing audit entries for each action. `valis_check_diff` and the `verdict-queue` MCP tool support the human-in-the-loop proposals workflow that drains pending promotes and dismisses. Source: [src/commands/admin-consolidate.ts:12-30]() and [src/mcp/tools/verdict-queue.ts:18-40]().

**Agent personas.** `valis add-command` ships keyword-keyed personas (architect, security-advisor, researcher, product-manager, marketer, …) whose steps are explicit `valis_search` / `valis_store` calls. Each persona begins by checking what the team already knows, then stores a new decision, so the agent's loop mirrors the human capture loop documented in `valis help workflows`. Source: [src/commands/add-command.ts:8-30]().

## See Also

- `valis help workflows` and `valis help mcp` (printed by [src/commands/help-topics.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/help-topics.ts))
- `valis schema` — machine-readable CLI catalog for agent harnesses ([src/commands/schema-cmd.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/schema-cmd.ts))
- [README.md](https://github.com/Todmy/valis-cli/blob/main/README.md) — installation and hosted vs self-host overview

---

<a id='page-4'></a>

## Community Edition, Self-Hosting, and Operations

### Related Pages

Related topics: [Overview and System Architecture](#page-1), [Data Management, Search, and AI Integration](#page-3)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [community/README.md](https://github.com/Todmy/valis-cli/blob/main/community/README.md)
- [community/docker-compose.yml](https://github.com/Todmy/valis-cli/blob/main/community/docker-compose.yml)
- [community/.env.example](https://github.com/Todmy/valis-cli/blob/main/community/.env.example)
- [community/generate-keys.sh](https://github.com/Todmy/valis-cli/blob/main/community/generate-keys.sh)
- [community/kong.yml](https://github.com/Todmy/valis-cli/blob/main/community/kong.yml)
- [community/init-db/00_auth_compat.sql](https://github.com/Todmy/valis-cli/blob/main/community/init-db/00_auth_compat.sql)
- [README.md](https://github.com/Todmy/valis-cli/blob/main/README.md)
- [src/commands/init/helpers.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/init/helpers.ts)
- [src/commands/admin-consolidate.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/admin-consolidate.ts)
- [src/cloud/qdrant/admin.ts](https://github.com/Todmy/valis-cli/blob/main/src/cloud/qdrant/admin.ts)
- [src/commands/index-cmd.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/index-cmd.ts)
- [src/commands/help-topics.ts](https://github.com/Todmy/valis-cli/blob/main/src/commands/help-topics.ts)
</details>

# Community Edition, Self-Hosting, and Operations

## Overview

Valis ships in two distribution models. The Hosted tier runs on a managed cloud backend at `valis.krukit.co` and is the recommended path for most teams because LLM keys and infrastructure are pre-provisioned. The Community edition is the self-hostable counterpart: it bundles the full backend stack into a single `docker compose up` flow that operators run on their own hardware. The README explicitly frames the choice as "Hosted (recommended)" versus "Community / self-host (beta)" and notes that the self-host stack now boots from a clean `docker compose up` inside the [`community/`](https://github.com/Todmy/valis-cli/blob/main/community) directory. Source: [README.md]().

The two tiers share the same CLI surface. `valis init` and `valis serve` work against either backend; the CLI only switches where it points its Supabase and Qdrant clients. For the Community edition, the operator owns the credentials, the database, and the LLM keys. The CLI is a thin facade that loads the active config, resolves the project from `.valis.json`, and forwards calls to the same MCP handlers used by Hosted. Source: [src/commands/help-topics.ts]().

## Architecture of the Community Stack

The `community/` directory is the canonical self-host bundle. It contains the orchestration file ([`community/docker-compose.yml`](https://github.com/Todmy/valis-cli/blob/main/community/docker-compose.yml)), a template for environment variables ([`community/.env.example`](https://github.com/Todmy/valis-cli/blob/main/community/.env.example)), an API gateway routing layer ([`community/kong.yml`](https://github.com/Todmy/valis-cli/blob/main/community/kong.yml)), a database bootstrap script that handles auth compatibility ([`community/init-db/00_auth_compat.sql`](https://github.com/Todmy/valis-cli/blob/main/community/init-db/00_auth_compat.sql)), and a helper for generating signing keys ([`community/generate-keys.sh`](https://github.com/Todmy/valis-cli/blob/main/community/generate-keys.sh)). The README states that the backends are "Your own Supabase + Qdrant via Docker Compose" and that "You supply your own" LLM keys. Source: [README.md]().

```mermaid
flowchart LR
    A[Agent / CLI] -->|MCP / HTTP| B[Kong API Gateway]
    B --> C[Supabase<br/>Postgres + Auth]
    B --> D[Qdrant<br/>Vector store]
    C --> E[(init-db<br/>SQL bootstrap)]
    D --> F[.env secrets<br/>LLM keys]
    A -->|valis serve| G[Local MCP server]
    G --> B
```

The flow is intentionally simple: the CLI talks to a local MCP server (`valis serve`), which fans out to Kong-routed Supabase (Postgres source of truth, auth, project metadata) and Qdrant (vector search and chunked retrieval). Init-time SQL in `00_auth_compat.sql` reconciles the Supabase auth schema with what the rest of the stack expects, and `generate-keys.sh` produces the JWT signing material that Kong and the MCP server share. Source: [src/commands/help-topics.ts]().

## Day-One Setup

Operators start by copying `.env.example` to `.env`, running `generate-keys.sh` to produce JWT secrets, and then `docker compose up -d` to bring the stack online. After the services report healthy, the operator runs `valis init` on a workstation. The init flow is implemented in [`src/commands/init/helpers.ts`](https://github.com/Todmy/valis-cli/blob/main/src/commands/init/helpers.ts) and is composed of self-contained helper steps: prompts, third-party calls, and file writes. Helpers export the public verbs; the per-case handlers under `cases.ts` decide which to call for each setup path. The init command also wires the right adapter for the developer's editor — `injectClaudeMdMarkers`, `injectAgentsMdMarkers`, `injectCursules`, and `scaffoldBuiltInCommands` — so the same flow works for Claude Code, Codex, and Cursor. Source: [src/commands/init/helpers.ts]().

For teams that already have a `docs/` directory of architectural notes, the onboarding path is short. The `valis index` command walks a folder for `.md` and `.markdown` files and imports each one as a decision, optionally pulling author and created_at from `git log`. The interactive flow is deliberately minimal: a single optional question asks whether to run LLM enrichment after import, and a token estimate plus a USD cost preview is shown before the user opts in. Source: [src/commands/index-cmd.ts]().

## Day-Two Operations

Once the stack is live, operators interact with it through two channels: the `valis admin *` family of CLI commands and direct calls into the Qdrant admin module. The admin namespace owns dashboard counts, legacy-point detection, the `project_id` backfill migration, the reindex command, and the cosine similarity probe. The dashboard stats helper is project-scoped: when `projectId` is provided, counts are limited to that project via a filter built by `buildProjectFilter`; when omitted, counts span the whole `org_id`. Source: [src/cloud/qdrant/admin.ts]().

The most operationally interesting command is `valis admin consolidate`, which performs knowledge compression via semantic grouping. By default it runs as `--dry-run` and prints the groups it would act on without writing. With `--auto-merge` it creates a new pattern decision per group, sets `depends_on` to the merged IDs, deprecates the originals, and writes audit entries for every action. The threshold is configurable via `--threshold` and defaults to `0.7`; merges only fire for groups above `0.9`. Source: [src/commands/admin-consolidate.ts]().

The general workflow the project documents for the capture loop and the lifecycle curation loop is the same on Hosted and Community:

1. `valis search "<topic>"` — check what is already decided.
2. Capture via `/valis:store` (plugin / agent) or `valis index` (bulk).
3. `valis search "<topic>"` again to verify the new decision is queryable.
4. Triage drafts from the dashboard Proposals tab or by calling `valis_lifecycle`. Source: [src/commands/help-topics.ts]().

## Common Failure Modes

Three failure modes recur in operator reports. First, the `db-max-rows` ceiling on PostgREST silently truncates unfiltered `select()` results; the proposed-pending count helper defends against this by using `select('id', { count: 'exact', head: true })` for the total and per-type breakdown, and a bounded `.limit(3)` for the preview. Never compute counts from `.length` over a fetched page. Second, the legacy `pending` row type is normalized into the `decision` bucket of `by_type` so totals stay consistent with what the rest of the codebase reports. Third, the ground-truth injector raised its duplicate threshold from `0.92` to `0.97` to stop legitimate re-recordings from being short-circuited; the `0.92–0.97` band now routes into the neighbour tier and auto-populates `depends_on` instead. Source: [src/cloud/supabase/proposed-pending.ts](), [src/mcp/tools/ground-truth-injector.ts]().

## See Also

- Hosted tier overview and quick start — [README.md]()
- Capture loop and lifecycle workflows — [src/commands/help-topics.ts]()
- `valis index` bulk import semantics — [src/commands/index-cmd.ts]()
- Qdrant admin and migrations — [src/cloud/qdrant/admin.ts]()
- `valis admin consolidate` — [src/commands/admin-consolidate.ts]()

---

<!-- evidence_pipeline_checked: true -->

---

## Pitfall Log

Project: Todmy/valis-cli

Summary: Found 7 structured pitfall item(s), including 0 high/blocking item(s). Top priority: Configuration risk - Configuration risk requires verification.

## 1. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.host_targets | https://github.com/Todmy/valis-cli

## 2. Capability evidence risk - Capability evidence risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.assumptions | https://github.com/Todmy/valis-cli

## 3. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/Todmy/valis-cli

## 4. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: downstream_validation.risk_items | https://github.com/Todmy/valis-cli

## 5. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: risks.scoring_risks | https://github.com/Todmy/valis-cli

## 6. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: issue_or_pr_quality=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/Todmy/valis-cli

## 7. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: release_recency=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/Todmy/valis-cli

<!-- canonical_name: Todmy/valis-cli; human_manual_source: deepwiki_human_wiki -->
