From 7be06c9beeae039390146fec63b990278926b09c Mon Sep 17 00:00:00 2001 From: verify-sim Date: Sat, 5 Sep 2026 21:27:45 +0800 Subject: [PATCH] docs: align contributor guidance and architecture with current behavior --- .github/pull_request_template.md | 8 ++++---- CLAUDE.md | 4 ++-- CODEMAP.md | 14 ++++++------- CONTRIBUTING.md | 6 +++--- docs/ARCHITECTURE.md | 34 +++++++++++++++++--------------- 5 files changed, 34 insertions(+), 32 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 6049a1393..8bf348913 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -22,8 +22,8 @@ - [ ] `docs/ARCHITECTURE.md` updated if module structure or counts changed (incl. version header) - [ ] `docs/api/API_REFERENCE.md` updated if MCP / HTTP / CLI surface changed (incl. version header) - [ ] `README.md` updated if user-facing features / install / Smart Mode framing changed -- [ ] README locales (de / vi / th / pt / ja / ko / zh-CN / zh-TW / es / fr) re-synced if `README.md` changed -- [ ] Version files (`package.json` + `.claude-plugin/plugin.json` + `.claude-plugin/marketplace.json`) bumped consistently if any version-bumping +- [ ] README locales (`README.de.md` / `README.zh-TW.md`) re-synced if `README.md` changed +- [ ] Version anchors listed in `CONTRIBUTING.md` updated consistently if bumping a version - [ ] `dist/skills-manifest.json` regenerated via `npm run build` (required after ANY change to `.claude-plugin/`, `scripts/hooks/`, `skills/`, or version files) - [ ] `memesh doctor` reports `Overall: PASS` (or `PASS_WITH_CONCERNS` only when the WARN is `Update status` — that's expected for an unreleased local version) @@ -31,9 +31,9 @@ -- [ ] `npx tsc --noEmit` clean +- [ ] `npm run typecheck` clean - [ ] `npm run build` clean -- [ ] `npm test -- --run` passing (state count vs baseline if changed) +- [ ] `node scripts/run-tests-isolated.mjs` passing (report the actual exit code) - [ ] If hooks were touched: full hook protocol run (real Claude Code Stop / PreToolUse / etc. payload, `memesh doctor` hook-activity check post-install green) - [ ] If LLM flows were touched: `memesh telemetry` shows the new flow's rows after a manual run diff --git a/CLAUDE.md b/CLAUDE.md index 6f02171e4..0a68b3346 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -80,8 +80,8 @@ side of it. Do not report a test result, a CI status or a benchmark number you did not produce in this session. Paste the runner's actual output. `npm run verify:release` is the same gate the publish path runs, and -`scripts/check-doc-claims.mjs` — which it calls — checks every claim the public -documents make about the code. +`scripts/check-doc-claims.mjs` — which it calls — checks selected source-derived +documentation claims. Other descriptions still need source-backed review. **Read the exit code, not a grep of the output.** `cmd 2>&1 | grep …` returns *grep's* status and hides every line the pattern misses. Vitest prints diff --git a/CODEMAP.md b/CODEMAP.md index da210b565..ce2b9475e 100644 --- a/CODEMAP.md +++ b/CODEMAP.md @@ -57,7 +57,7 @@ docs/ # ARCHITECTURE.md, api/API_REFERENCE.md ### Recall / search (the LLM-free hot path) - Ranking / scoring weights → `src/core/scoring.ts` (`rankEntities`) - FTS5 + sqlite-vec query, access tracking → `src/knowledge-graph.ts` -- Recall operation (cross_project / namespace / include_archived) → `src/core/operations.ts` (`recallEnhanced`) +- Shared transport recall operation (cross_project / namespace / include_archived) → `src/core/operations.ts` (`recallWithConflicts`, backed by `recallEnhanced`) - Vector index / embedding dimension / migration → `src/db.ts`, `src/core/embedder.ts` ### Write flows (remember / forget / learn / pin) @@ -84,13 +84,13 @@ docs/ # ARCHITECTURE.md, api/API_REFERENCE.md ### Project identity + tags - `getProjectName()` (git-remote-slug → repo-root → cwd-basename, cached) → `src/core/paths.ts` - (mirrored in `scripts/hooks/_shared.js` — F5 boundary; kept in sync by `tests/core/project-identity.test.ts`) + (shared through build-generated `scripts/hooks/_generated/core-paths.js`, imported by `_shared.js`) - List / merge / rename `project:*` tags → `src/core/project-tags.ts` (backs `memesh kg rename-project`) - Heuristic relation backfill (orphan connector) → `src/core/kg-backfill.ts` ### Config / capabilities / self-update - Config read/write + capability detection + env auto-detect → `src/core/config.ts` -- Path resolution (HOME-first) → `src/core/paths.ts` +- Path resolution (explicit `MEMESH_DIR` / `MEMESH_DB_PATH` overrides, then HOME defaults) → `src/core/paths.ts` - `memesh doctor` health check + real probes → `src/core/doctor.ts` - npm version check / self-update → `src/core/version-check.ts`, `src/core/updater.ts`, `src/core/install-channel.ts`, `src/core/install-hooks.ts` @@ -114,7 +114,7 @@ docs/ # ARCHITECTURE.md, api/API_REFERENCE.md | `session-start.js` | SessionStart | inject top-N memories (additionalContext), banner, lesson warnings, auto-update | | `pre-edit-recall.js` | PreToolUse Edit/Write | inject file-relevant memories | | `guard-check.js` | PreToolUse Bash | enforce accepted lesson guards before risky repeats | -| `src/host-runtime/codex-session.ts` | SessionStart | register the exact configured Codex thread for metadata-only wakeups | +| `src/host-runtime/codex-session.ts` | SessionStart | register the exact configured Codex thread for bounded full-message native delivery | | `session-summary.js` | Stop | auto-capture, LLM failure analysis, dream auto-trigger | | `pre-compact.js` | PreCompact | end-of-context save | | `post-commit.js` | PostToolUse Bash | git commit tracking | @@ -130,7 +130,7 @@ is invoked by the session-start flow rather than registered directly in the mani ``` transport (cli/http/mcp) → validate (transports/schemas.ts, Zod) - → operations.recallEnhanced() + → operations.recallWithConflicts() → recallEnhanced() → knowledge-graph FTS5 + sqlite-vec → scoring.rankEntities() → conflict detection (storage/conflicts.ts) → result ``` @@ -141,7 +141,7 @@ The same `operations.ts` memory functions run identically from all three transpo ## Tests & docs -- Tests: `tests/` mirrors `src/`. Run `npm test -- --run` (pool: forks, not threads — native modules). +- Tests: `tests/` mirrors `src/`. Run `node scripts/run-tests-isolated.mjs` (throwaway HOME; forks pool, one worker). Cross-hook contract gate: `tests/hooks/hook-output-contract.test.ts` (validates every hook's stdout against the real Claude Code contract). - Owner-run live checks (never CI): `scripts/qa/live-journey.mjs` — `npm run qa:live-journey -- --host codex|claude` drives a real Codex thread or an interactive Claude channel session and requires model-visible proof. @@ -163,4 +163,4 @@ The same `operations.ts` memory functions run identically from all three transpo than merely available. After publishing, `npm run qa:post-release` (`scripts/qa/post-release.mjs`) checks registry acceptance, a fresh install from the registry, and whether this machine is on the release — read-only, printing fixes rather than running them. -- Version anchors that must agree on a bump: `package.json`, both root entries in `package-lock.json`, `.claude-plugin/plugin.json`, `.claude-plugin/marketplace.json`, `herdr-plugin.toml`, `CHANGELOG.md`, `CODEMAP.md`, `docs/ARCHITECTURE.md`, and `docs/api/API_REFERENCE.md`. Run `npm run build` after to regenerate `dist/skills-manifest.json`. +- Version anchors that must agree on a bump: `package.json`, both root entries in `package-lock.json`, `.claude-plugin/plugin.json`, `.codex-plugin/plugin.json`, `.claude-plugin/marketplace.json`, `herdr-plugin.toml`, `CHANGELOG.md`, `CODEMAP.md`, `docs/ARCHITECTURE.md`, and `docs/api/API_REFERENCE.md`. Run `npm run build` after to regenerate `dist/skills-manifest.json`. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e3d81a508..c86326123 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,7 @@ MeMesh is intentionally small. Changes should preserve that shape: a minimal MCP ## Prerequisites -- Node.js 22.5 or newer (`package.json` `engines.node`; Node 20 reached end of life on 2026-03-24) +- Node.js 22.13.0 or newer (see `package.json` `engines.node`) - npm ## Local Setup @@ -13,7 +13,7 @@ MeMesh is intentionally small. Changes should preserve that shape: a minimal MCP npm install npm run typecheck npm run build -npm test -- --run +node scripts/run-tests-isolated.mjs npm run test:packaged ``` @@ -27,7 +27,7 @@ Documentation is part of the change, not follow-up work. The CI's `Version coher - Update `docs/api/API_REFERENCE.md` when the MCP / HTTP / CLI surface changes (and bump its `**Version**: ` line on a release). - Update `docs/ARCHITECTURE.md` when module structure, storage behavior, or packaging flow changes (and bump its `**Version**: ` line on a release). - Read `DESIGN.md` before any dashboard change that touches colour, type, spacing or an interaction, and update it when a token or rule changes. It is derived from `dashboard/src/styles/global.css`; when the two disagree the CSS is what ships, so fix whichever is wrong rather than leaving them apart. -- Keep version metadata coherent: `package.json` + **`package-lock.json` (both the root `version` and `packages[""].version`)** + `.claude-plugin/plugin.json` + `.claude-plugin/marketplace.json` `plugins[].version` + `CHANGELOG.md` `## [X.Y.Z]` header + the two `**Version**:` lines above must all match. The `node scripts/check-version-coherence.mjs` check (run as a CI step) catches partial bumps. `package-lock.json` is called out because it is the one that drifted silently across four releases (4.2.6 through 4.2.10) while every other anchor stayed correct — `npm version` updates it, hand-editing `package.json` does not. +- Keep version metadata coherent: `package.json`, both the root `version` and `packages[""].version` in `package-lock.json`, `.claude-plugin/plugin.json`, `.codex-plugin/plugin.json`, `.claude-plugin/marketplace.json` `plugins[].version`, `herdr-plugin.toml`, the `CHANGELOG.md` release header, and the `**Version**:` lines in `CODEMAP.md`, `docs/ARCHITECTURE.md`, and `docs/api/API_REFERENCE.md`. Run `node scripts/check-version-coherence.mjs` to check these anchors. `npm version` updates the lockfile; hand-editing `package.json` does not. - After ANY change to `.claude-plugin/`, `scripts/hooks/`, `skills/`, or version files, run `npm run build` so `dist/skills-manifest.json` regenerates. Otherwise `memesh doctor` reports `Skills + hooks integrity FAIL` and users see "memesh setup is incomplete" in their dashboard. CI's `Doctor` step catches this before merge. `CLAUDE.md` carries the same rules in the form an AI coding assistant reads. It is a pointer file — this document is the source of truth for anything that applies to a human contributor. diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 20e2dc8f9..ffcea008d 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -14,7 +14,7 @@ The package is intentionally local-first and inspectable: - one SQLite database under the user's control - no cloud service required - Claude Code hook integration for session-start, pre-edit recall, user-prompt-intent detection, post-commit capture, session-summary learning, and pre-compact save -- optional smarter retrieval and extraction when an LLM is configured +- optional semantic retrieval when an embedding provider is configured, and extraction when an LLM is configured This repository is the standalone local package. Hosted workspace and enterprise operating-system products are intentionally out of scope for this package architecture. @@ -218,7 +218,7 @@ Thin adapter: imports shared Zod schemas from `transports/schemas.ts`, validates | Tool | Schema | Handler | |------|--------|---------| | `remember` | RememberSchema | Delegates to `operations.remember()` | -| `recall` | RecallSchema | Delegates to `operations.recallEnhanced()` | +| `recall` | RecallSchema | Delegates to `operations.recallWithConflicts()` | | `forget` | ForgetSchema | Delegates to `operations.forget()` | | `export` | ExportSchema | Delegates to `operations.exportMemories()` | | `import` | ImportSchema | Delegates to `operations.importMemories()` | @@ -231,7 +231,7 @@ Thin adapter: imports shared Zod schemas from `transports/schemas.ts`, validates ### transports/http/server.ts -- HTTP REST API Server -Express server exposed via `memesh serve` (default port 3737; the endpoint count is stated once, in the module list above, and checked against `server.ts` by `scripts/check-doc-claims.mjs`). Delegates all operations to `core/operations`. Includes `GET /v1/analytics` for computed health score, 30-day timeline, value metrics, and cleanup suggestions. See [HTTP REST API](#http-rest-api) in the API Reference. +Express server exposed via `memesh serve` (default port 3737; the endpoint count is stated once, in the module list above, and checked against `server.ts` by `scripts/check-doc-claims.mjs`). Delegates memory operations to `core/operations` and message actions to `transports/agent-messaging`. Includes `GET /v1/analytics` for computed health score, 30-day timeline, value metrics, and cleanup suggestions. See [HTTP REST API](api/API_REFERENCE.md#http-rest-api) in the API Reference. ### transports/cli/cli.ts -- CLI @@ -307,12 +307,12 @@ not a second durable registry, and the read creates no message or receipt facts. ``` Tool call: recall({query, tag, limit}) -> Zod validation (RecallSchema) - -> recallEnhanced() in core/operations + -> recallWithConflicts() in core/operations, backed by recallEnhanced() -> KnowledgeGraph.search() — FTS5 keyword match -> supplementWithVectors() — sqlite-vec embedding similarity merge -> rankEntities() applies multi-factor scoring (relevance, recency, frequency, confidence, impact) -> KnowledgeGraph.findConflicts() checks for contradicts relations among results - -> If conflicts: return {entities, conflicts}; else return Entity[] + -> Return {entities, retrieval, conflicts?}; omit conflicts when empty ``` ### Mine memory from transcripts (`dream run --from-transcripts`) @@ -332,17 +332,19 @@ memesh dream run --from-transcripts (current project only) -> accept creates the entity AND embeds it, so the next run recognises it ``` -### Delete knowledge (forget) +### Archive knowledge or remove an observation (forget) ``` -Tool call: forget({name}) +Tool call: forget({name, observation?}) -> Zod validation (ForgetSchema) - -> KnowledgeGraph.deleteEntity(name) - -> SELECT entity by name (return false if not found) - -> SELECT all observations for entity (needed for FTS5 delete) - -> Delete FTS5 entry (contentless delete requires original indexed values) - -> DELETE FROM entities (CASCADE handles observations, relations, tags) - -> Return {deleted: true/false} + -> operations.forget() + -> With observation: KnowledgeGraph.removeObservation() + -> Return {observation_removed, name, observation, + remaining_observations, entity_found} + -> Without observation: KnowledgeGraph.archiveEntity() + -> Remove entity from search indexes and set status = 'archived' + in one transaction; preserve observations, relations, and tags + -> Return {archived: true, name}, or {archived: false, message} ``` --- @@ -424,7 +426,7 @@ Hooks are defined in `hooks/hooks.json` and executed by Claude Code at specific - **Trigger**: `Stop` event (when Claude finishes responding) - **Matcher**: `*` (all sessions) -- **Behavior**: Extracts session knowledge (files edited, errors fixed, decisions made) and stores it as entities in the knowledge graph. When LLM is configured (Level 1), additionally runs failure analysis to create structured `lesson_learned` entities from session errors. Also reads `~/.memesh/last-session-injected.json` to track recall effectiveness — updates `recall_hits` (entity name found in transcript) or `recall_misses` (not found). Opt-out via `MEMESH_AUTO_CAPTURE=false` +- **Behavior**: Extracts session knowledge (files edited, errors fixed, decisions made) and stores it as entities in the knowledge graph. When LLM is configured (Level 1), additionally runs failure analysis to create structured `lesson_learned` entities from session errors. Also reads matching session-injection records under the database directory's `sessions/` folder: explicit `[mem:id]` citations for injected memories increment `recall_hits`, after excluding hook-output echoes; `recall_misses` remains unchanged. Opt-out via `MEMESH_AUTO_CAPTURE=false` ### Pre-Compact (`scripts/hooks/pre-compact.js`) @@ -470,7 +472,7 @@ MeMesh supports three integration tiers: | | Custom apps | Direct stdio MCP connection | | **HTTP API** | Custom apps/scripts | HTTP REST API (`memesh serve`, 37 endpoints) | -See [docs/platforms/](../platforms/) for platform-specific integration guides. +See [docs/platforms/](platforms/) for platform-specific integration guides. ### Anthropic API Feature Alignment @@ -593,7 +595,7 @@ Session with errors ``` type: "lesson_learned" -name: "lesson-{project}-{errorPattern}" (upsert-safe; explicit `learn` without errorPattern → "lesson-{project}-{error-slug}") +name: "lesson-{project}-{errorPattern}" (upsert-safe; explicit `learn` without errorPattern → "lesson-{project}-{readable-prefix}-{digest}") observations: - "Error: " - "Root cause: "