# valis-cli - Doramagic AI Context Pack

> 定位：安装前体验与判断资产。它帮助宿主 AI 有一个好的开始，但不代表已经安装、执行或验证目标项目。

## 充分原则

- **充分原则，不是压缩原则**：AI Context Pack 应该充分到让宿主 AI 在开工前理解项目价值、能力边界、使用入口、风险和证据来源；它可以分层组织，但不以最短摘要为目标。
- **压缩策略**：只压缩噪声和重复内容，不压缩会影响判断和开工质量的上下文。

## 给宿主 AI 的使用方式

你正在读取 Doramagic 为 valis-cli 编译的 AI Context Pack。请把它当作开工前上下文：帮助用户理解适合谁、能做什么、如何开始、哪些必须安装后验证、风险在哪里。不要声称你已经安装、运行或执行了目标项目。

## Claim 消费规则

- **事实来源**：Repo Evidence + Claim/Evidence Graph；Human Wiki 只提供显著性、术语和叙事结构。
- **事实最低状态**：`supported`
- `supported`：可以作为项目事实使用，但回答中必须引用 claim_id 和证据路径。
- `weak`：只能作为低置信度线索，必须要求用户继续核实。
- `inferred`：只能用于风险提示或待确认问题，不能包装成项目事实。
- `unverified`：不得作为事实使用，应明确说证据不足。
- `contradicted`：必须展示冲突来源，不得替用户强行选择一个版本。

## 它最适合谁

- **正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**：README 或插件配置提到多个宿主 AI。 证据：`README.md` Claim：`clm_0002` supported 0.86

## 它能做什么

- **命令行启动或安装流程**（需要安装后验证）：项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 证据：`README.md` Claim：`clm_0001` supported 0.86

## 怎么开始

- `npm install -g valis-cli` 证据：`README.md` Claim：`clm_0003` supported 0.86
- `git clone https://github.com/Todmy/valis-cli && cd valis-cli/community` 证据：`README.md` Claim：`clm_0004` supported 0.86
- `npm i -g valis-cli && valis init      # choose Community; leave QDRANT_API_KEY empty` 证据：`README.md` Claim：`clm_0005` supported 0.86
- `npm install fastembed              # optional peer dependency` 证据：`README.md` Claim：`clm_0006` supported 0.86

## 继续前判断卡

- **当前建议**：需要管理员/安全审批
- **为什么**：继续前可能涉及密钥、账号、外部服务或敏感上下文，建议先经过管理员或安全审批。

### 30 秒判断

- **现在怎么做**：需要管理员/安全审批
- **最小安全下一步**：先跑 Prompt Preview；若涉及凭证或企业环境，先审批再试装
- **先别相信**：真实输出质量不能在安装前相信。
- **继续会触碰**：命令执行、本地环境或项目文件、环境变量 / API Key

### 现在可以相信

- **适合人群线索：正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**（supported）：有 supported claim 或项目证据支撑，但仍不等于真实安装效果。 证据：`README.md` Claim：`clm_0002` supported 0.86
- **能力存在：命令行启动或安装流程**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`README.md` Claim：`clm_0001` supported 0.86
- **存在 Quick Start / 安装命令线索**（supported）：可以相信项目文档出现过启动或安装入口；不要因此直接在主力环境运行。 证据：`README.md` Claim：`clm_0003` supported 0.86

### 现在还不能相信

- **真实输出质量不能在安装前相信。**（unverified）：Prompt Preview 只能展示引导方式，不能证明真实项目中的结果质量。
- **宿主 AI 版本兼容性不能在安装前相信。**（unverified）：Claude、Cursor、Codex、Gemini 等宿主加载规则和版本差异必须在真实环境验证。
- **不会污染现有宿主 AI 行为，不能直接相信。**（inferred）：Skill、plugin、AGENTS/CLAUDE/GEMINI 指令可能改变宿主 AI 的默认行为。
- **可安全回滚不能默认相信。**（unverified）：除非项目明确提供卸载和恢复说明，否则必须先在隔离环境验证。
- **真实安装后是否与用户当前宿主 AI 版本兼容？**（unverified）：兼容性只能通过实际宿主环境验证。
- **项目输出质量是否满足用户具体任务？**（unverified）：安装前预览只能展示流程和边界，不能替代真实评测。
- **安装命令是否需要网络、权限或全局写入？**（unverified）：这影响企业环境和个人环境的安装风险。 证据：`README.md`

### 继续会触碰什么

- **命令执行**：包管理器、网络下载、本地插件目录、项目配置或用户主目录。 原因：运行第一条命令就可能产生环境改动；必须先判断是否值得跑。 证据：`README.md`
- **本地环境或项目文件**：安装结果、插件缓存、项目配置或本地依赖目录。 原因：安装前无法证明写入范围和回滚方式，需要隔离验证。 证据：`README.md`
- **环境变量 / API Key**：项目入口文档明确出现 API key、token、secret 或账号凭证配置。 原因：如果真实安装需要凭证，应先使用测试凭证并经过权限/合规判断。 证据：`README.md`, `test/e2e/07-community-fresh-install.test.ts`
- **宿主 AI 上下文**：AI Context Pack、Prompt Preview、Skill 路由、风险规则和项目事实。 原因：导入上下文会影响宿主 AI 后续判断，必须避免把未验证项包装成事实。

### 最小安全下一步

- **先跑 Prompt Preview**：用安装前交互式试用判断工作方式是否匹配，不需要授权或改环境。（适用：任何项目都适用，尤其是输出质量未知时。）
- **只在隔离目录或测试账号试装**：避免安装命令污染主力宿主 AI、真实项目或用户主目录。（适用：存在命令执行、插件配置或本地写入线索时。）
- **不要使用真实生产凭证**：环境变量/API key 一旦进入宿主或工具链，可能产生账号和合规风险。（适用：出现 API、TOKEN、KEY、SECRET 等环境线索时。）
- **安装后只验证一个最小任务**：先验证加载、兼容、输出质量和回滚，再决定是否深用。（适用：准备从试用进入真实工作流时。）

### 退出方式

- **保留安装前状态**：记录原始宿主配置和项目状态，后续才能判断是否可恢复。
- **记录安装命令和写入路径**：没有明确卸载说明时，至少要知道哪些目录或配置需要手动清理。
- **准备撤销测试 API key 或 token**：测试凭证泄露或误用时，可以快速止损。
- **如果没有回滚路径，不进入主力环境**：不可回滚是继续前阻断项，不应靠信任或运气继续。

## 哪些只能预览

- 解释项目适合谁和能做什么
- 基于项目文档演示典型对话流程
- 帮助用户判断是否值得安装或继续研究

## 哪些必须安装后验证

- 真实安装 Skill、插件或 CLI
- 执行脚本、修改本地文件或访问外部服务
- 验证真实输出质量、性能和兼容性

## 边界与风险判断卡

- **把安装前预览误认为真实运行**：用户可能高估项目已经完成的配置、权限和兼容性验证。 处理方式：明确区分 prompt_preview_can_do 与 runtime_required。 Claim：`clm_0007` inferred 0.45
- **命令执行会修改本地环境**：安装命令可能写入用户主目录、宿主插件目录或项目配置。 处理方式：先在隔离环境或测试账号中运行。 证据：`README.md` Claim：`clm_0008` supported 0.86
- **待确认**：真实安装后是否与用户当前宿主 AI 版本兼容？。原因：兼容性只能通过实际宿主环境验证。
- **待确认**：项目输出质量是否满足用户具体任务？。原因：安装前预览只能展示流程和边界，不能替代真实评测。
- **待确认**：安装命令是否需要网络、权限或全局写入？。原因：这影响企业环境和个人环境的安装风险。

## 开工前工作上下文

### 加载顺序

- 先读取 how_to_use.host_ai_instruction，建立安装前判断资产的边界。
- 读取 claim_graph_summary，确认事实来自 Claim/Evidence Graph，而不是 Human Wiki 叙事。
- 再读取 intended_users、capabilities 和 quick_start_candidates，判断用户是否匹配。
- 需要执行具体任务时，优先查 role_skill_index，再查 evidence_index。
- 遇到真实安装、文件修改、网络访问、性能或兼容性问题时，转入 risk_card 和 boundaries.runtime_required。

### 任务路由

- **命令行启动或安装流程**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`README.md` Claim：`clm_0001` supported 0.86

### 上下文规模

- 文件总数：452
- 重要文件覆盖：40/452
- 证据索引条目：71
- 角色 / Skill 条目：4

### 证据不足时的处理

- **missing_evidence**：说明证据不足，要求用户提供目标文件、README 段落或安装后验证记录；不要补全事实。
- **out_of_scope_request**：说明该任务超出当前 AI Context Pack 证据范围，并建议用户先查看 Human Manual 或真实安装后验证。
- **runtime_request**：给出安装前检查清单和命令来源，但不要替用户执行命令或声称已执行。
- **source_conflict**：同时展示冲突来源，标记为待核实，不要强行选择一个版本。

## Prompt Recipes

### 适配判断

- 目标：判断这个项目是否适合用户当前任务。
- 预期输出：适配结论、关键理由、证据引用、安装前可预览内容、必须安装后验证内容、下一步建议。

```text
请基于 valis-cli 的 AI Context Pack，先问我 3 个必要问题，然后判断它是否适合我的任务。回答必须包含：适合谁、能做什么、不能做什么、是否值得安装、证据来自哪里。所有项目事实必须引用 evidence_refs、source_paths 或 claim_id。
```

### 安装前体验

- 目标：让用户在安装前感受核心工作流，同时避免把预览包装成真实能力或营销承诺。
- 预期输出：一段带边界标签的体验剧本、安装后验证清单和谨慎建议；不含真实运行承诺或强营销表述。

```text
请把 valis-cli 当作安装前体验资产，而不是已安装工具或真实运行环境。

请严格输出四段：
1. 先问我 3 个必要问题。
2. 给出一段“体验剧本”：用 [安装前可预览]、[必须安装后验证]、[证据不足] 三种标签展示它可能如何引导工作流。
3. 给出安装后验证清单：列出哪些能力只有真实安装、真实宿主加载、真实项目运行后才能确认。
4. 给出谨慎建议：只能说“值得继续研究/试装”“先补充信息后再判断”或“不建议继续”，不得替项目背书。

硬性边界：
- 不要声称已经安装、运行、执行测试、修改文件或产生真实结果。
- 不要写“自动适配”“确保通过”“完美适配”“强烈建议安装”等承诺性表达。
- 如果描述安装后的工作方式，必须使用“如果安装成功且宿主正确加载 Skill，它可能会……”这种条件句。
- 体验剧本只能写成“示例台词/假设流程”：使用“可能会询问/可能会建议/可能会展示”，不要写“已写入、已生成、已通过、正在运行、正在生成”。
- Prompt Preview 不负责给安装命令；如用户准备试装，只能提示先阅读 Quick Start 和 Risk Card，并在隔离环境验证。
- 所有项目事实必须来自 supported claim、evidence_refs 或 source_paths；inferred/unverified 只能作风险或待确认项。

```

### 角色 / Skill 选择

- 目标：从项目里的角色或 Skill 中挑选最匹配的资产。
- 预期输出：候选角色或 Skill 列表，每项包含适用场景、证据路径、风险边界和是否需要安装后验证。

```text
请读取 role_skill_index，根据我的目标任务推荐 3-5 个最相关的角色或 Skill。每个推荐都要说明适用场景、可能输出、风险边界和 evidence_refs。
```

### 风险预检

- 目标：安装或引入前识别环境、权限、规则冲突和质量风险。
- 预期输出：环境、权限、依赖、许可、宿主冲突、质量风险和未知项的检查清单。

```text
请基于 risk_card、boundaries 和 quick_start_candidates，给我一份安装前风险预检清单。不要替我执行命令，只说明我应该检查什么、为什么检查、失败会有什么影响。
```

### 宿主 AI 开工指令

- 目标：把项目上下文转成一次对话开始前的宿主 AI 指令。
- 预期输出：一段边界明确、证据引用明确、适合复制给宿主 AI 的开工前指令。

```text
请基于 valis-cli 的 AI Context Pack，生成一段我可以粘贴给宿主 AI 的开工前指令。这段指令必须遵守 not_runtime=true，不能声称项目已经安装、运行或产生真实结果。
```

## 角色 / Skill 索引

- 共索引 4 个角色 / Skill / 项目文档条目。

- **valis**（project_doc）：Team decision memory for AI coding agents. Your team's shared hippocampus -- every AI agent remembers what the team decided. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`README.md`
- **Valis Community Edition**（project_doc）：Self-hosted Valis backend with Docker Compose. Your data stays on your infrastructure. The valis CLI talks to this backend exactly as it talks to the hosted valis.krukit.co — via @supabase/supabase-js REST + auth and the Qdrant REST API. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`community/README.md`
- **Migrations — generated mirror do not hand-edit**（project_doc）：Migrations — generated mirror do not hand-edit 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`community/migrations/README.md`
- **Valis benchmark corpora — license registry**（project_doc）：Valis benchmark corpora — license registry 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`corpora/LICENSE-CORPUS.md`

## 证据索引

- 共索引 71 条证据。

- **valis**（documentation）：Team decision memory for AI coding agents. Your team's shared hippocampus -- every AI agent remembers what the team decided. 证据：`README.md`
- **Valis Community Edition**（documentation）：Self-hosted Valis backend with Docker Compose. Your data stays on your infrastructure. The valis CLI talks to this backend exactly as it talks to the hosted valis.krukit.co — via @supabase/supabase-js REST + auth and the Qdrant REST API. 证据：`community/README.md`
- **Migrations — generated mirror do not hand-edit**（documentation）：Migrations — generated mirror do not hand-edit 证据：`community/migrations/README.md`
- **Package**（package_manifest）：{ "name": "valis-cli", "version": "0.5.11", "description": "Shared decision intelligence for AI-augmented engineering teams", "type": "module", "main": "./dist/src/index.js", "bin": { "valis": "./dist/bin/valis.js", "valis-bench": "./dist/bin/valis-bench.js", "valis-ape": "./dist/bin/valis-ape.js" }, "scripts": { "gen:schema-version": "node scripts/gen-schema-version.mjs", "prebuild": "pnpm run gen:schema-version", "build": "tsc", "dev": "tsc --watch", "pretest": "pnpm run gen:schema-version", "test": "vitest run", "test:watch": "vitest", "prelint": "pnpm run gen:schema-version", "lint": "tsc --noEmit", "bench": "node dist/bin/valis-bench.js", "ape": "node dist/bin/valis-ape.js", "corpus:fe… 证据：`package.json`
- **License**（source_file）：Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ 证据：`LICENSE`
- **Claude Code**（source_file）：import { promises as fs } from 'node:fs'; import { homedir } from 'node:os'; import { join } from 'node:path'; import type { ConfigScope, HookEntry, HookFormat, McpFormat, McpServerEntry, ProjectMarker, } from './types.js'; import { projectMarkerDir, projectMarkerFile } from './types.js'; import type { HarnessAdapter } from './index.js'; import type { HarnessName } from './hook-events.js'; ⋮---- async function pathExists p: string : Promise async function parseJson path: string : Promise ⋮---- baseDir : string async detect : Promise skillDirs : string mcpConfigPath : string hookConfigPath : string pluginDirs : string hookFormat : HookFormat mcpFormat : McpFormat needsPathInjection : boolean… 证据：`src/adapters/claude-code.ts`
- **Claude Code**（source_file）：import type { AgentAdapter, ParsedSession, PatchDescriptor } from '../types.js'; ⋮---- function attachmentContentToString content: unknown : string / True iff a type:"attachment" event is a UserPromptSubmit hook carrying an injection block. / function attachmentInjected obj: Record : boolean function assistantConsulted message: unknown : boolean export class ClaudeCodeAdapter implements AgentAdapter ⋮---- parseLog jsonl: string : ParsedSession detectToolCall workerResponse: unknown : deployTarget surface: PatchDescriptor 'surface' : PatchDescriptor 证据：`src/ape/agents/claude-code.ts`
- **Admin**（source_file）：import { QdrantClient } from '@qdrant/js-client-rest'; import { detectEmbeddingStrategy, truncateForEmbedding, parseQuotaError, ClientEmbeddingStrategy, EmbeddingQuotaError, REINDEX BATCH SIZE, REINDEX ABORT THRESHOLD, } from '../embedding.js'; import { COLLECTION NAME } from './client.js'; import { buildProjectFilter } from './search.js'; ⋮---- export async function getDashboardStats qdrant: QdrantClient, orgId: string, projectId?: string, : Promise export function isLegacyPoint payload: Record null undefined, : boolean export async function backfillPointProjectId qdrant: QdrantClient, pointId: string, projectId: string, : Promise export interface QdrantMigrationReport { updated: number; s… 证据：`src/cloud/qdrant/admin.ts`
- **Decisions**（source_file）：import { QdrantClient } from '@qdrant/js-client-rest'; import type { RawDecision } from '../../types.js'; import { detectEmbeddingStrategy, truncateForEmbedding, parseQuotaError, ClientEmbeddingStrategy, } from '../embedding.js'; import { chunkText, type Chunk } from '../chunking.js'; import { chunkPointId, buildContextualText, generateHypotheticalQuery, } from '../decision-text.js'; import { COLLECTION NAME } from './client.js'; ⋮---- export interface UpsertExtras { pinned?: boolean; status?: string; depends on?: string ; replaces?: string null; project id?: string; source?: string; } export async function upsertDecision qdrant: QdrantClient, orgId: string, decisionId: string, raw: RawDeci… 证据：`src/cloud/qdrant/decisions.ts`
- **Search**（source_file）：import { QdrantClient } from '@qdrant/js-client-rest'; import type { SearchResult, DecisionType, DecisionStatus, DecisionSource, SearchExpand, } from '../../types.js'; import { detectEmbeddingStrategy, truncateForEmbedding, parseQuotaError, ClientEmbeddingStrategy, DENSE VECTOR NAME, BM25 VECTOR NAME, } from '../embedding.js'; import { COLLECTION NAME } from './client.js'; export function buildProjectFilter orgId: string, projectId?: string, options?: { type?: string; legacyFallback?: boolean }, : Record export function buildAllProjectsFilter orgId: string, projectIds: string , options?: { type?: string }, : Record ⋮---- function buildExpansionIndex : void export function expandQuery query:… 证据：`src/cloud/qdrant/search.ts`
- **Decisions**（source_file）：import type { SupabaseClient } from '@supabase/supabase-js'; import { randomUUID } from 'node:crypto'; import type { Contradiction, Decision, DecisionStatus, RawDecision, DecisionSource, } from '../../types.js'; import { contentHash } from '../../capture/dedup.js'; import { setOrgContext } from './client.js'; import type { AuditTrailRow } from './audit.js'; export interface StoreExtras { status?: 'active' 'proposed'; replaces?: string; depends on?: string ; } export async function getDecisionById supabase: SupabaseClient, orgId: string, decisionId: string, projectId?: string null, : Promise export async function getDecisionsByIds supabase: SupabaseClient, orgId: string, decisionIds: string… 证据：`src/cloud/supabase/decisions.ts`
- **Members**（source_file）：import type { SupabaseClient } from '@supabase/supabase-js'; import { HOSTED SUPABASE URL } from '../../types.js'; import { resolveApiUrl, resolveApiPath } from '../api-url.js'; import { getSupabaseClient } from './client.js'; export async function getOrgInfo supabase: SupabaseClient, orgId: string, : Promise export async function getProjectName supabase: SupabaseClient, projectId: string, : Promise export interface CreateProjectResponse { project id: string; project name: string; invite code: string; role?: string; org id?: string; template source?: string null; decisions seeded?: number; } export async function createProject supabaseUrl: string, apiKey: string, orgId: string, projectName:… 证据：`src/cloud/supabase/members.ts`
- **Proposed Pending**（source_file）：import type { SupabaseClient } from '@supabase/supabase-js'; import type { ProposedPending } from '../../types.js'; ⋮---- type TypeBucket = typeof TYPE BUCKETS number ; export interface CountProposedScope { orgId: string; projectId: string; } export interface CountProposedOpts { ranking?: 'created asc' 'created desc'; origin?: string null; similarityById?: Map ; } export function buildTriageUrl origin: string null undefined, projectId: string : string null / Run a single truncation-proof exact COUNT for the draft predicate, optionally narrowed to one type . Returns the count or throws callers wrap in try/catch . / async function exactCount client: SupabaseClient, scope: CountProposedScope,… 证据：`src/cloud/supabase/proposed-pending.ts`
- **Add Command**（source_file）：import { writeFile, mkdir } from 'node:fs/promises'; import { join } from 'node:path'; import { homedir } from 'node:os'; import { existsSync } from 'node:fs'; import select from '@inquirer/select'; import input from '@inquirer/input'; import pc from 'picocolors'; import { loadCredentials, isLoggedIn } from '../config/credentials.js'; import { HOSTED API URL } from '../types.js'; ⋮---- interface ProjectInfo { id: string; name: string; role: string; } async function listProjects memberApiKey: string : Promise async function analyzeProjectAreas memberApiKey: string, projectId: string, : Promise function suggestSkills areas: string : typeof SKILL ARCHETYPES export async function addCommandComm… 证据：`src/commands/add-command.ts`
- **Admin Consolidate**（source_file）：import pc from 'picocolors'; import { loadConfig } from '../config/store.js'; import { getSupabaseClient } from '../cloud/supabase.js'; import { getQdrantClient } from '../cloud/qdrant.js'; import { findSemanticGroups, type SemanticGroup, } from '../cleanup/semantic-groups.js'; import { generateGroupSummary } from '../synthesis/summarize.js'; import { storeDecision, changeDecisionStatus } from '../cloud/supabase.js'; import { buildAuditPayload, createAuditEntry } from '../auth/audit.js'; export interface AdminConsolidateOptions { dryRun?: boolean; autoMerge?: boolean; threshold?: string; org?: string; } export interface ConsolidationReport { mode: 'dry run' 'applied'; groups found: number;… 证据：`src/commands/admin-consolidate.ts`
- **Help Topics**（source_file）：export async function helpTopicCommand topic: string : Promise 证据：`src/commands/help-topics.ts`
- **Index Cmd**（source_file）：import { readdir, readFile, stat } from 'node:fs/promises'; import { join, extname, relative, basename, resolve } from 'node:path'; import { execFileSync } from 'node:child process'; import { createInterface } from 'node:readline/promises'; import select from '@inquirer/select'; import pc from 'picocolors'; import { loadConfig } from '../config/store.js'; import { resolveConfig } from '../config/project.js'; import { getSupabaseClient, storeDecision } from '../cloud/supabase.js'; import { getQdrantClient, upsertDecision } from '../cloud/qdrant.js'; import { isHostedMode, resolveApiUrl, resolveApiPath } from '../cloud/api-url.js'; import { getToken } from '../auth/jwt.js'; import { HOSTED SU… 证据：`src/commands/index-cmd.ts`
- **Helpers**（source_file）：import { basename, join } from 'node:path'; import { readdir, readFile } from 'node:fs/promises'; import { homedir } from 'node:os'; import select from '@inquirer/select'; import input from '@inquirer/input'; import pc from 'picocolors'; import { installClaudeHooks, injectClaudeMdMarkers, scaffoldBuiltInCommands } from '../../ide/claude-code.js'; import { injectAgentsMdMarkers } from '../../ide/codex.js'; import { injectCursorrules } from '../../ide/cursor.js'; import { ALL ADAPTERS } from '../../adapters/index.js'; import { writeMcpServer } from '../../adapters/deploy.js'; import { GLOBAL SCOPE } from '../../adapters/types.js'; import type { McpServerEntry } from '../../adapters/types.js';… 证据：`src/commands/init/helpers.ts`
- **Schema Cmd**（source_file）：import type { Command, Option } from 'commander'; interface CliArgSpec { name: string; required: boolean; description?: string; variadic: boolean; } interface CliOptionSpec { flag: string; short?: string; long?: string; description?: string; required: boolean; hasArg: boolean; default?: unknown; } interface CliCommandSpec { name: string; description?: string; mutating: boolean; phase: 'onboarding' 'daily' 'lifecycle' 'infrastructure' 'plan' 'configuration' 'operator' 'meta'; args: CliArgSpec ; options: CliOptionSpec ; examples: string ; exit codes?: Record ; } interface CliCatalog { name: string; version: string; description: string; homepage?: string; agent mode flag: '--agent-mode' '--jso… 证据：`src/commands/schema-cmd.ts`
- **Store**（source_file）：import { readFile, writeFile, mkdir } from 'node:fs/promises'; import { join } from 'node:path'; import { homedir } from 'node:os'; import type { ValisConfig, ResolvedConfig } from '../types.js'; import { resolveConfig as resolveProjectConfig } from './project.js'; ⋮---- export async function loadConfig : Promise export async function saveConfig config: ValisConfig : Promise export async function updateConfig updates: Partial : Promise export async function resolveFullConfig startDir?: string : Promise export function getConfigDir : string export function getConfigPath : string 证据：`src/config/store.ts`
- **Claude Code**（source_file）：import { readFile, writeFile, mkdir } from 'node:fs/promises'; import { join, dirname } from 'node:path'; import { homedir } from 'node:os'; import { existsSync } from 'node:fs'; import { trackFile } from '../config/manifest.js'; import { COMMAND TEMPLATES } from './command-templates.js'; import { policyMarkerLine } from '../hooks/self-heal-templates.js'; ⋮---- export async function installClaudeHooks : Promise export async function injectClaudeMdMarkers projectDir: string : Promise interface HookEntry { matcher: string; hooks: Array ; } function installSessionHook settings: Record : void function upsertHook hooks: Record , event: string, command: string, timeoutSeconds: number, : void expo… 证据：`src/ide/claude-code.ts`
- **Type Inference**（source_file）：export type InferredDecisionType = 'decision' 'constraint' 'pattern' 'lesson'; export interface InferenceResult { type: InferredDecisionType; matched: boolean; } ⋮---- function anyMatch haystack: string, patterns: readonly RegExp : boolean export function inferType summary: string, detail: string : InferenceResult export function deriveSummary detail: string : string / Apply FR-004 / FR-005 / FR-006 / FR-007 defaults to a valis store args shape. Used by handleStore before constructing the RawDecision to commit. The function never mutates its input; it returns the normalised trio plus boolean flags that the response layer surfaces so callers can detect and override silent inference. @param i… 证据：`src/lib/type-inference.ts`
- **Evolve**（source_file）：import { loadConfig } from '../../config/store.js'; import { getSupabaseClient, getSupabaseJwtClient, getDecisionById, } from '../../cloud/supabase.js'; import { buildAuditPayload, createAuditEntry } from '../../auth/audit.js'; import { canWriteToProject, getServiceRoleSupabase } from '../../lib/project-access.js'; import type { ServerConfig } from '../../types.js'; import type { EdgeType } from '../../cloud/edge-walker.js'; ⋮---- function isCanonicalEdgeType t: string : t is EdgeType export interface EvolveArgs { from id: string; to id: string; type: string; reason?: string; project id?: string; } export interface EvolveResponse { edge id: string; from id: string; to id: string; type: Edge… 证据：`src/mcp/tools/evolve.ts`
- **Ground Truth Injector**（source_file）：export type SearchFn = text: string = Promise ; export type MatchTier = 'duplicate' 'neighbour' 'none' 'failed'; export type GroundTruthStatus = 'duplicate detected' 'neighbours linked' 'neighbours informational' 'no matches' 'injector failed'; export interface GroundTruthCandidate { id: string; similarity: number; } export interface GroundTruthContext { status: GroundTruthStatus; band: MatchTier; existing id?: string; candidates: GroundTruthCandidate ; top similarity: number; latency ms: number; reason?: string; } export interface InjectGroundTruthOptions { duplicateThreshold?: number; neighbourThreshold?: number; maxCandidates?: number; timeoutMs?: number; callerSuppliedDependsOn?: boolea… 证据：`src/mcp/tools/ground-truth-injector.ts`
- **Link Extractor**（source_file）：export type SearchFn = text: string = Promise ; export interface LinkExtractionOptions { threshold?: number; maxCandidates?: number; timeoutMs?: number; } export interface LinkExtractionResult { chosen: string ; candidates: Array ; threshold: number; latency ms: number; status: 'ok' 'skipped' 'failed'; reason?: string; } ⋮---- function clampThreshold input: number undefined : number function clampMaxCandidates input: number undefined : number function clampTimeout input: number undefined : number function sanitiseReason err: unknown : string export async function extractLinks text: string, search: SearchFn, opts?: LinkExtractionOptions, : Promise 证据：`src/mcp/tools/link-extractor.ts`
- **Search**（source_file）：import { loadConfig } from '../../config/store.js'; import { resolveConfig } from '../../config/project.js'; import { rerank } from '../../search/reranker.js'; import { suppressResults } from '../../search/suppression.js'; import { incrementUsage } from '../../billing/usage.js'; import { isHostedMode } from '../../cloud/api-url.js'; import { chooseSearchTransport, type SearchTransport } from './search-transport.js'; import { buildSearchFilter, usedFilterDimensions, type DroppedArg, type ClampedArg, type SearchFilterArgs, } from '../../search/filter-builder.js'; import { metadataOnlyScroll } from '../../cloud/qdrant/scroll.js'; import { getQdrantClient, mmrRerank } from '../../cloud/qdrant.j… 证据：`src/mcp/tools/search.ts`
- **Store**（source_file）：import { loadConfig } from '../../config/store.js'; import { resolveConfig } from '../../config/project.js'; import { detectSecrets } from '../../security/secrets.js'; import { isDuplicate, markAsSeen } from '../../capture/dedup.js'; import { checkUsageOrProceed } from '../../billing/usage.js'; import { getSupabaseClient, getSupabaseJwtClient, storeDecision, getDecisionById, getDecisionsByIds, } from '../../cloud/supabase.js'; import type { StoreExtras } from '../../cloud/supabase.js'; import { getQdrantClient, buildProjectFilter, COLLECTION NAME } from '../../cloud/qdrant.js'; import { detectEmbeddingStrategy, truncateForEmbedding, ClientEmbeddingStrategy, DENSE VECTOR NAME, } from '../../… 证据：`src/mcp/tools/store.ts`
- **Verdict Queue**（source_file）：import { loadConfig } from '../../config/store.js'; import { getToken } from '../../auth/jwt.js'; import { resolveApiUrl, resolveApiPath } from '../../cloud/api-url.js'; import { HOSTED SUPABASE URL, type ServerConfig } from '../../types.js'; export interface VerdictListArgs { project id: string; kind?: 'contradiction' 'proposed relevance' 'all'; } export interface VerdictResolveArgs { project id: string; kind: 'contradiction' 'proposed relevance'; item id: string; action: string; reason?: string; } export interface VerdictReverseArgs { project id: string; kind: 'contradiction' 'proposed relevance'; item id: string; } type ConfigLike = { supabase url: string; member api key?: string null };… 证据：`src/mcp/tools/verdict-queue.ts`
- **Graph Search**（source_file）：import type { QdrantClient } from '@qdrant/js-client-rest'; import type { SearchResult, DecisionType, DecisionStatus } from '../types.js'; import { COLLECTION NAME } from '../cloud/qdrant.js'; export function collectNeighborIds results: SearchResult : string function mapNeighborPoint point: { id: string number; payload?: Record null }, : SearchResult export async function expandWithNeighbors qdrant: QdrantClient, results: SearchResult , orgId: string, : Promise export function buildSupersessionChains results: SearchResult , : Map export function attachSupersessionChains results: SearchResult : SearchResult export async function graphAugmentedSearch qdrant: QdrantClient, initialResults: Sear… 证据：`src/search/graph-search.ts`
- **Store**（source_file）：import type { SupabaseClient } from '@supabase/supabase-js'; import type { ClusterDecision } from './patterns.js'; import type { AuditEntry, AuditAction } from '../types.js'; import { storeDecision, changeDecisionStatus } from '../cloud/supabase.js'; import { buildAuditPayload, createAuditEntry } from '../auth/audit.js'; export type AuditPayload = Omit ; export interface SynthesisPatternRow { id: string; depends on: string ; affects: string ; } export interface DecisionStatusRow { id: string; status: string; } export interface CreatedPattern { id: string; } export interface SynthesisStore { fetchActiveDecisions orgId: string, windowDays: number : Promise ; findActiveSynthesisPatterns orgId:… 证据：`src/synthesis/store.ts`
- **Helpers**（source_file）：import { randomUUID } from 'node:crypto'; import { mkdtemp, rm, readFile, writeFile, mkdir } from 'node:fs/promises'; import { join } from 'node:path'; import { tmpdir, homedir } from 'node:os'; import type { ValisConfig, ProjectConfig, RegistrationResponse } from '../../src/types.js'; ⋮---- / Returns true when E2E env vars are configured. / export function canRunE2E : boolean / Unique suffix for this test run — prevents collisions across parallel runs. / ⋮---- // --------------------------------------------------------------------------- // Registration helper — calls /api/register directly // --------------------------------------------------------------------------- export interface E2ER… 证据：`test/e2e/helpers.ts`
- **Valis benchmark corpora — license registry**（documentation）：Valis benchmark corpora — license registry 证据：`corpora/LICENSE-CORPUS.md`
- **Tsconfig.Docker**（structured_config）：{ "compilerOptions": { "target": "ES2022", "module": "NodeNext", "moduleResolution": "NodeNext", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "declaration": true, "declarationMap": true, "sourceMap": true, "outDir": "dist", "rootDir": "." }, "include": "bin/ / .ts", "src/ / .ts" , "exclude": "node modules", "dist", "test" } 证据：`tsconfig.docker.json`
- **Tsconfig**（structured_config）：{ "extends": "../../tsconfig.base.json", "compilerOptions": { "outDir": "dist", "rootDir": "." }, "include": "bin/ / .ts", "src/ / .ts" , "exclude": "node modules", "dist", "test" } 证据：`tsconfig.json`
- **Ai Agent**（structured_config）：{ "id": "ai-agent", "version": "0.1", "name": "AI Agent / LLM App", "tagline": "Prompts, evals, fallbacks — agentic apps in production", "description": "Conventions for teams building agentic applications and LLM-powered products. Covers prompt versioning, eval suites, fallbacks, cost limits, and observability — the discipline that distinguishes a demo from a deployable agent. Founder-curated — review before merging.", "min plan": "free", "decision count": 15, "decisions": { "summary": "All prompts are version-pinned in source code — never edited at runtime via env vars or DB", "type": "constraint", "rationale": "A prompt is the agent's behavior contract. Editing at runtime decouples behavi… 证据：`src/templates/ai-agent.json`
- **Fintech**（structured_config）：{ "id": "fintech", "version": "0.1", "name": "FinTech / Regulated", "tagline": "Audit, encryption, retention — compliance-ready", "description": "Conventions for compliance-aware teams building financial-services or other regulated software. Covers audit, encryption, retention, PII handling, and operational discipline expected by SOC 2 / ISO 27001 / GDPR auditors. Founder-curated — review before merging.", "min plan": "pro", "decision count": 22, "decisions": { "summary": "Every state-changing operation writes an audit row with actor + before-state + after-state + reason", "type": "constraint", "rationale": "SOC 2 CC6.1 + 7.2 + 8.1 require attributable evidence of every change. The audit tr… 证据：`src/templates/fintech.json`
- **Ts Saas**（structured_config）：{ "id": "ts-saas", "version": "0.1", "name": "TypeScript SaaS", "tagline": "Next.js + Postgres + REST", "description": "Conventions for a typical TypeScript SaaS team building API-driven products on Next.js + Postgres. Covers API shape, error handling, logging, auth, deployment, and test discipline. Founder-curated — review before merging into your project's decision base.", "min plan": "free", "decision count": 18, "decisions": { "summary": "All API responses return JSON with a top-level data or error key — never bare values", "type": "decision", "rationale": "Frontend and SDK code branches on response shape. A consistent envelope means error handling is uniform across services and we neve… 证据：`src/templates/ts-saas.json`
- **Sc 002 Citations**（structured_config）：{ "version": 1, "description": "SC-002 multi-domain citation corpus. 30 questions across engineering / brand / communication / personal workflow domains. Each question has an expected Valis decision id; the harness asks each question against a freshly-installed Phase A configuration and counts answers where the agent cites the expected decision in its first turn.", "decision id note": "expected decision id values are placeholders. Replace with real IDs from your project's decisions table before running the harness.", "questions": { "id": "eng-01", "domain": "engineering", "question": "How do we cache decisions in the SessionStart hook?", "expected decision id": "REPLACE-eng-cache-ttl" }, {… 证据：`test/measurement/corpora/sc-002-citations.json`
- **Sc 008 Conflicts**（structured_config）：{ "version": 1, "description": "SC-008 conflict corpus. 20 scenarios where MEMORY.md and Valis disagree on a work topic. The agent should pick the Valis-side answer because the labeled block carries precedence outranking MEMORY.md. Replace expected valis decision id placeholders with real IDs before running.", "conflicts": { "id": "conf-01", "topic": "team context loading mechanism", "memory md position": "SessionStart hook preloads ranked team decisions by fetching /api/session-context with the user's API key.", "valis position": "Post- 172 SessionStart only self-heals locally and emits empty stdout. Agent loads team context on demand via the valis context MCP tool — Claude Code's OAuth-aw… 证据：`test/measurement/corpora/sc-008-conflicts.json`
- **.dockerignore**（source_file）：node modules dist test .git .gitignore .log npm-debug.log coverage .DS Store docs/krukit .md 证据：`.dockerignore`
- **.Env**（source_file）：SUPABASE URL=https://your-project.supabase.co SUPABASE SERVICE ROLE KEY=eyJ... QDRANT URL=https://your-cluster.qdrant.io QDRANT API KEY=your-qdrant-api-key 证据：`.env.example`
- **Generated by scripts/gen-schema-version.mjs prebuild step — never commit.**（source_file）：node modules/ dist/ coverage/ Generated by scripts/gen-schema-version.mjs prebuild step — never commit. src/generated/ .tsbuildinfo .log .DS Store .env .env.local .env. .local 证据：`.gitignore`
- **valis-cli — self-host image.**（source_file）：valis-cli — self-host image. Multi-stage: a full-deps builder compiles TypeScript with tsc, then a slim runtime carries only production deps + the compiled dist/. Build context is this directory packages/cli — the package is self-contained no workspace: protocol deps , and tsconfig.docker.json inlines the monorepo base config so no parent files are required. docker build -t valis-cli . docker run --rm valis-cli --version fastembed local embeddings for self-host is an optional peer dependency and is NOT bundled — install it in a derived image or mount it if you run in client embedding mode QDRANT EMBEDDING STRATEGY=client . 证据：`Dockerfile`
- **Valis Ape**（source_file）：import { Command } from 'commander'; import { runApe, DEFAULT BUDGET USD } from '../src/ape/index.js'; import type { ApeRunOpts, ApeMode } from '../src/ape/index.js'; ⋮---- export interface CliDeps { runApe: opts: ApeRunOpts = Promise ; } export async function runCli argv: string , deps: CliDeps = { runApe }, : Promise 证据：`bin/valis-ape.ts`
- **Valis Bench**（source_file）：import { Command } from 'commander'; import { runBenchmark } from '../src/benchmarks/index.js'; 证据：`bin/valis-bench.ts`
- **Valis**（source_file）：import { Command } from 'commander'; import { VERSION } from '../src/index.js'; import { initCommand } from '../src/commands/init.js'; import { serveCommand } from '../src/commands/serve.js'; import { statusCommand } from '../src/commands/status.js'; import { dashboardCommand } from '../src/commands/dashboard.js'; import { searchCommand } from '../src/commands/search-cmd.js'; import { configGetCommand, configSetCommand, configWizardCommand } from '../src/commands/config-cmd.js'; import { uninstallCommand } from '../src/commands/uninstall.js'; import { adminMetricsCommand } from '../src/commands/admin-metrics.js'; import { migrateAuthCommand } from '../src/commands/migrate-auth.js'; import {… 证据：`bin/valis.ts`
- **Valis Community Edition — environment**（source_file）：Valis Community Edition — environment Copy to .env, then run ./generate-keys.sh to fill the secret/JWT values. NEVER commit your real .env. 证据：`community/.env.example`
- **Self-hoster secrets — generated by generate-keys.sh, never commit.**（source_file）：Self-hoster secrets — generated by generate-keys.sh, never commit. .env 证据：`community/.gitignore`
- **Docker Compose**（source_file）：name: valis-community services: db: image: supabase/postgres:15.8.1.060 restart: unless-stopped ports: - "${POSTGRES PORT:-5432}:5432" environment: POSTGRES DB: ${POSTGRES DB:-postgres} POSTGRES PASSWORD: ${POSTGRES PASSWORD} JWT SECRET: ${JWT SECRET} JWT EXP: ${JWT EXPIRY:-3600} volumes: - db data:/var/lib/postgresql/data healthcheck: test: "CMD", "pg isready", "-U", "postgres", "-h", "localhost" interval: 5s timeout: 5s retries: 15 migrate: image: supabase/postgres:15.8.1.060 restart: "no" depends on: db: condition: service healthy environment: PGHOST: db PGPORT: 5432 PGUSER: postgres PGPASSWORD: ${POSTGRES PASSWORD} PGDATABASE: ${POSTGRES DB:-postgres} volumes: - ./init-db/apply.sh:/appl… 证据：`community/docker-compose.yml`
- **--- ensure a strong JWT SECRET =32 chars -------------------------------**（source_file）：set -euo pipefail cd "$ dirname "$0" " if ! -f .env ; then echo "No .env found. Run: cp .env.example .env first." &2 exit 1 fi if ! command -v node /dev/null 2 &1; then echo "node is required it ships with the valis-cli install ." &2 exit 1 fi --- ensure a strong JWT SECRET =32 chars ------------------------------- JWT SECRET="$ grep -E '^JWT SECRET=' .env head -1 cut -d= -f2- " if -z "$JWT SECRET" "${ JWT SECRET}" -lt 32 "$JWT SECRET" = "change-me-to-a-32-char-min-random-secret" ; then JWT SECRET="$ openssl rand -hex 32 " echo "Generated a fresh JWT SECRET." fi PG PW="$ grep -E '^POSTGRES PASSWORD=' .env head -1 cut -d= -f2- " if -z "$PG PW" "$PG PW" = "change-me-to-a-long-random-password"… 证据：`community/generate-keys.sh`
- **Kong**（source_file）：format version: '2.1' transform: true consumers: - username: anon keyauth credentials: - key: $SUPABASE ANON KEY - username: service role keyauth credentials: - key: $SUPABASE SERVICE KEY acls: - consumer: anon group: anon - consumer: service role group: admin services: - name: auth-v1-open url: http://auth:9999/verify routes: - name: auth-v1-open strip path: true paths: - /auth/v1/verify plugins: - name: cors - name: auth-v1-open-callback url: http://auth:9999/callback routes: - name: auth-v1-open-callback strip path: true paths: - /auth/v1/callback plugins: - name: cors - name: auth-v1-open-authorize url: http://auth:9999/authorize routes: - name: auth-v1-open-authorize strip path: true p… 证据：`community/kong.yml`
- **Ape Consult Claude Code**（source_file）：{"id":"ape-s1","turns": "Дивись, ми не можемо прив'язуватися до Qdrant Find. Тому що Qdrant — це суто моя локальна імплементація. У користувача вона може бути, а може й не бути. Ми не можемо прив'язуватися до цього інструмента, розумієш?Нам треба просто механізм, який точно буде викликатися і зберігати в Valis. Але, можливо, дивись, умовно ми кажемо: кожних 5 викликів read hook ми робимо запис в Valis. Але навіть через 5 викликів, можливо, нічого не треба писати в Valis. Тобто треба якийсь механізм, який точно буде запускатися, дивитися, чи є щось на запис, і записувати його. Тільки так." ,"should consult":true,"should inject":true,"stratum":"normal","label source":"llm proposed","needs hum… 证据：`corpora/ape-consult-claude-code.jsonl`
- **Longmemeval Sample**（source_file）：{"document":{"id":"lme-answer 530960c1","text":" user I've been using Zillow and HotPads, but I haven't tried the others. I'll definitely check them out. By the way, speaking of waiting, it's crazy how long it took for my asylum application to get approved. Over a year of uncertainty was really tough. But at least it's behind me now, and I can focus on building my new life here.\n\n user I'm trying to find a permanent place to live. Can you help me with that? I'm on a limited budget and not sure where to start looking.\n\n assistant I'd be happy to help you find a permanent place to live on a limited budget. Let's break down the process into manageable steps.\n\n Step 1: Assess Your Budget… 证据：`corpora/longmemeval-sample.jsonl`
- **Valis multilingual benchmark seed — DE slice translated from EN via Claude .**（source_file）：Valis multilingual benchmark seed — DE slice translated from EN via Claude . Apache-2.0 Valis-authored content reflecting team-decision profile . Sprint 2026-05-19 / Track 7 / Phase 9 multilingual extension DE+JA . {"document":{"id":"vme-doc-auth-jwt","text":"Entscheidung: kurzlebige JWTs 15-Minuten Access-Tokens gekoppelt mit rotierten Refresh-Tokens in httpOnly-Cookies verwenden. Geprüft: langlebige API-Keys abgelehnt — Revocation erfordert DB-Lookup bei jeder Anfrage , Session-Cookies abgelehnt — funktioniert nicht für den CLI-Client . Der JWT-Weg hält jede authentifizierte Anfrage serverseitig zustandslos und erlaubt uns dennoch, Refresh-Tokens serverseitig zu invalidieren, wenn ein Tok… 证据：`corpora/valis-multilingual-de.jsonl`
- **Valis multilingual benchmark seed — EN slice.**（source_file）：Valis multilingual benchmark seed — EN slice. Apache-2.0 Valis-authored content reflecting team-decision profile . Sprint 2026-05-14 / Track 7 / expanded corpus. 51 documents team-decision snippets + 50 queries with ground truth. Topics: auth, deployment, error handling, observability, contracts, data/storage, testing, performance, API design, dev workflow, frontend, search/retrieval, RBAC/billing. {"document":{"id":"vme-doc-auth-jwt","text":"Decision: use short-lived JWTs 15-minute access tokens paired with rotated refresh tokens stored in httpOnly cookies. Considered: long-lived API keys rejected — revocation requires DB lookup on every request , session cookies rejected — does not work f… 证据：`corpora/valis-multilingual-en.jsonl`
- **Valis multilingual benchmark seed — JA slice translated from EN via Claude .**（source_file）：Valis multilingual benchmark seed — JA slice translated from EN via Claude . Apache-2.0 Valis-authored content reflecting team-decision profile . Sprint 2026-05-19 / Track 7 / Phase 9 multilingual extension DE+JA . {"document":{"id":"vme-doc-auth-jwt","text":"決定: 短命JWT（15分のアクセストークン）と、httpOnlyクッキーに保存されるローテーション式リフレッシュトークンを組み合わせて使用する。検討対象: 長命APIキー（却下 — リクエストごとにDBルックアップが必要）、セッションクッキー（却下 — CLIクライアントで動作しない）。JWTパスは、認証された各リクエストをサーバー側でステートレスに保ちつつ、トークンが侵害された場合にリフレッシュトークンをサーバー側で無効化できる。","language":"ja","metadata":{"topic":"auth","decision type":"choice","translation":{"source id":"vme-doc-auth-jwt","source lang":"en","target lang":"ja","provider":"claude-opus-4-7"}}}} {"document":{"id":"vme-doc-refres… 证据：`corpora/valis-multilingual-ja.jsonl`
- **Valis multilingual benchmark seed — PL slice translated from EN via Claude .**（source_file）：Valis multilingual benchmark seed — PL slice translated from EN via Claude . Apache-2.0 Valis-authored content reflecting team-decision profile . Sprint 2026-05-14 / Track 7 / Phase 9 multilingual publish 2026-05-16. Provider: claude-opus-4-7 DeepL signup deferred — see LICENSE-CORPUS.md . Mirror of valis-multilingual-en.jsonl: 51 documents + 50 queries with same ground truth. {"document":{"id":"vme-doc-auth-jwt","text":"Decyzja: używamy krótkożyciowych JWT 15-minutowe access tokeny sparowanych z rotowanymi refresh tokenami przechowywanymi w httpOnly cookies. Rozważone: długożyciowe API keys odrzucone — revoke wymaga DB lookup przy każdym żądaniu , session cookies odrzucone — nie działa z k… 证据：`corpora/valis-multilingual-pl.jsonl`
- **Valis multilingual benchmark seed — UK slice translated from EN via Claude .**（source_file）：Valis multilingual benchmark seed — UK slice translated from EN via Claude . Apache-2.0 Valis-authored content reflecting team-decision profile . Sprint 2026-05-14 / Track 7 / Phase 9 multilingual publish 2026-05-16. Provider: claude-opus-4-7 DeepL signup deferred — see LICENSE-CORPUS.md . Mirror of valis-multilingual-en.jsonl: 51 documents + 50 queries with same ground truth. {"document":{"id":"vme-doc-auth-jwt","text":"Рішення: використовуємо короткоживучі JWT 15-хвилинні access-токени у парі з ротованими refresh-токенами, що зберігаються в httpOnly cookies. Розглянуто: довгоживучі API keys відхилено — revoke вимагає DB-lookup на кожен запит , session cookies відхилено — не працює з CLI-к… 证据：`corpora/valis-multilingual-uk.jsonl`
- **Backfill Qdrant**（source_file）：import { createClient } from '@supabase/supabase-js'; import { QdrantClient } from '@qdrant/js-client-rest'; ⋮---- interface Decision { id: string; org id: string; project id: string null; type: string; summary: string null; text: string; author: string; affects: string ; confidence: number null; status: string; replaces: string null; depends on: string null; created at: string; } async function main 证据：`scripts/backfill-qdrant.ts`
- **Delete Personal Project Data**（source_file）：import { createClient } from '@supabase/supabase-js'; import { QdrantClient } from '@qdrant/js-client-rest'; ⋮---- async function countQdrant : Promise async function countTable table: string : Promise async function countContradictions : Promise async function clearReplacesSelfRef : Promise async function main 证据：`scripts/delete-personal-project-data.ts`
- 其余 11 条证据见 `AI_CONTEXT_PACK.json` 或 `EVIDENCE_INDEX.json`。

## 宿主 AI 必须遵守的规则

- **把本资产当作开工前上下文，而不是运行环境。**：AI Context Pack 只包含证据化项目理解，不包含目标项目的可执行状态。 证据：`README.md`, `community/README.md`, `community/migrations/README.md`
- **回答用户时区分可预览内容与必须安装后才能验证的内容。**：安装前体验的消费者价值来自降低误装和误判，而不是伪装成真实运行。 证据：`README.md`, `community/README.md`, `community/migrations/README.md`

## 用户开工前应该回答的问题

- 你准备在哪个宿主 AI 或本地环境中使用它？
- 你只是想先体验工作流，还是准备真实安装？
- 你最在意的是安装成本、输出质量、还是和现有规则的冲突？

## 验收标准

- 所有能力声明都能回指到 evidence_refs 中的文件路径。
- AI_CONTEXT_PACK.md 没有把预览包装成真实运行。
- 用户能在 3 分钟内看懂适合谁、能做什么、如何开始和风险边界。

---

## Doramagic Context Augmentation

下面内容用于强化 Repomix/AI Context Pack 主体。Human Manual 只提供阅读骨架；踩坑日志会被转成宿主 AI 必须遵守的工作约束。

## Human Manual 骨架

使用规则：这里只是项目阅读路线和显著性信号，不是事实权威。具体事实仍必须回到 repo evidence / Claim Graph。

宿主 AI 硬性规则：
- 不得把页标题、章节顺序、摘要或 importance 当作项目事实证据。
- 解释 Human Manual 骨架时，必须明确说它只是阅读路线/显著性信号。
- 能力、安装、兼容性、运行状态和风险判断必须引用 repo evidence、source path 或 Claim Graph。

- **Project Overview and System Architecture**：importance `high`
  - source_paths: README.md, package.json, src/index.ts, bin/valis.ts, src/commands/schema-cmd.ts
- **Decision Capture, Storage, and Hybrid Search**：importance `high`
  - source_paths: src/cloud/supabase.ts, src/cloud/qdrant.ts, src/cloud/qdrant/search.ts, src/cloud/qdrant/decisions.ts, src/cloud/chunking.ts
- **MCP Tools, AI Agent Adapters, and APE Subsystem**：importance `high`
  - source_paths: src/mcp/server.ts, src/mcp/tools/store.ts, src/mcp/tools/search.ts, src/mcp/tools/context.ts, src/mcp/tools/lifecycle.ts
- **Self-Hosting, Admin Operations, and Configuration**：importance `high`
  - source_paths: community/README.md, community/docker-compose.yml, community/generate-keys.sh, community/migrations/README.md, src/commands/admin-cleanup.ts

## Repo Inspection Evidence / 源码检查证据

- repo_clone_verified: true
- repo_inspection_verified: true
- repo_commit: `06b96a41e7860a3259f042d50db61483617019a7`
- inspected_files: `Dockerfile`, `README.md`, `package.json`, `src/adapters/_util.ts`, `src/adapters/antigravity.ts`, `src/adapters/claude-code.ts`, `src/adapters/codex.ts`, `src/adapters/copilot.ts`, `src/adapters/cursor.ts`, `src/adapters/deploy.ts`, `src/adapters/gemini.ts`, `src/adapters/hook-events.ts`, `src/adapters/index.ts`, `src/adapters/opencode.ts`, `src/adapters/types.ts`, `src/adapters/windsurf.ts`, `src/ape/agents/adapter.ts`, `src/ape/agents/claude-code.ts`, `src/ape/corpus/label.ts`, `src/ape/corpus/mine.ts`

宿主 AI 硬性规则：
- 没有 repo_clone_verified=true 时，不得声称已经读过源码。
- 没有 repo_inspection_verified=true 时，不得把 README/docs/package 文件判断写成事实。
- 没有 quick_start_verified=true 时，不得声称 Quick Start 已跑通。

## Doramagic Pitfall Constraints / 踩坑约束

这些规则来自 Doramagic 发现、验证或编译过程中的项目专属坑点。宿主 AI 必须把它们当作工作约束，而不是普通说明文字。

### Constraint 1: 可能修改宿主 AI 配置

- Trigger: 项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。
- Host AI rule: 列出会写入的配置文件、目录和卸载/回滚步骤。
- Why it matters: 安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。
- Evidence: capability.host_targets | https://github.com/Todmy/valis-cli | host_targets=mcp_host, claude_code, claude, cursor
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 2: 能力判断依赖假设

- Trigger: README/documentation is current enough for a first validation pass.
- Host AI rule: 将假设转成下游验证清单。
- Why it matters: 假设不成立时，用户拿不到承诺的能力。
- Evidence: capability.assumptions | https://github.com/Todmy/valis-cli | README/documentation is current enough for a first validation pass.
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 3: 维护活跃度未知

- Trigger: 未记录 last_activity_observed。
- Host AI rule: 补 GitHub 最近 commit、release、issue/PR 响应信号。
- Why it matters: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- Evidence: evidence.maintainer_signals | https://github.com/Todmy/valis-cli | last_activity_observed missing
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

- Trigger: no_demo
- Evidence: downstream_validation.risk_items | https://github.com/Todmy/valis-cli | no_demo; severity=medium
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 5: 存在评分风险

- Trigger: no_demo
- Why it matters: 风险会影响是否适合普通用户安装。
- Evidence: risks.scoring_risks | https://github.com/Todmy/valis-cli | no_demo; severity=medium
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 6: issue/PR 响应质量未知

- Trigger: issue_or_pr_quality=unknown。
- Host AI rule: 抽样最近 issue/PR，判断是否长期无人处理。
- Why it matters: 用户无法判断遇到问题后是否有人维护。
- Evidence: evidence.maintainer_signals | https://github.com/Todmy/valis-cli | issue_or_pr_quality=unknown
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 7: 发布节奏不明确

- Trigger: release_recency=unknown。
- Host AI rule: 确认最近 release/tag 和 README 安装命令是否一致。
- Why it matters: 安装命令和文档可能落后于代码，用户踩坑概率升高。
- Evidence: evidence.maintainer_signals | https://github.com/Todmy/valis-cli | release_recency=unknown
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。
