Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,15 @@ Use `--render mermaid` instead to get a diagram you can paste into any Markdown

Every write appends a new version rather than overwriting — so history is never lost. That's also what makes `--prev` work: it's *optimistic concurrency*. You tell a write which version you started from; if someone else has written in the meantime, yours is rejected and you're handed the current version to reconcile against, instead of silently clobbering their change. Deleting a document moves it aside to `:deleted/…` rather than erasing it, so a delete can be undone with an ordinary write. When you need the record, `docs history` lists a document's versions and `docs diff --from v1 --to v2` shows what changed.

Because the chain *is* the guarantee, `mrplex verify` is the way to confirm it holds. It's a read-only scrub — mrplex's `git fsck` — that re-derives the search, link, and hash indexes and checks the version chain, reporting any inconsistency as a structured finding without ever writing. Reach for it during maintenance, after a bulk import, or whenever you suspect something drifted:

```sh
$ mrplex verify # scan the whole store
clean — no findings
scanned 128 versions across 96 documents; 0 error, 0 warn
$ mrplex verify --check links --ci # one family; exit non-zero on any finding (CI gate)
```

## Connect an agent

The CLI, the MCP server, and the REST API are three doors into the same store. For a database only you touch, the quickest way to give an agent access is MCP over local stdio — for example, in a client's MCP configuration:
Expand Down Expand Up @@ -205,6 +214,7 @@ mrplex is built from a few concepts:
| **Query** | A CEL filter over frontmatter and `$path` / `$body` / `$updated_at`, combined with full-text and semantic search |
| **Link graph** | Links from Markdown syntax, wikilinks, and frontmatter paths, tracked by identity so renames don't break them |
| **Graph walk** | A breadth-first tour of that link graph — *how* documents connect, not just which ones match |
| **Verify** | A read-only integrity scrub that re-derives every index and checks the version chain, reporting drift as findings |
| **Surfaces** | The CLI, an MCP server, and a REST API, all over the same store |

Underneath, mrplex is two layers. The **kernel** is the store itself — documents, versions, queries, the graph — and it is full-trust: it has no notion of users, so whoever holds the database file holds everything. Around it is an optional **access-and-identity shell** that adds keys, OIDC, per-path permissions, and an audit log when you need them. The store runs on SQLite by default, or Postgres with pgvector when you want it; the same test suite runs against both, so behavior matches.
Expand Down
2 changes: 1 addition & 1 deletion docs/archive/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -982,7 +982,7 @@ Remaining `[OPEN]` markers throughout the doc are narrower questions (query cach
- **Per-repo frontmatter schema** `[OPEN]`. Declared shape stored per repo (types, required fields, enums, string patterns), validated at write time. Turns the "YAML soup" reality into typed records without giving up prose, and is load-bearing for three downstream features: MCP tools shaped like the domain (`notes.create_task(title, due, tags)` derived from the schema, not just generic `docs.put`), LSP completion (below), and aggregations (above) that can trust field types. Open: schema language (JSON Schema for reach, or a small mrplex-native dialect that maps directly to CEL types?); enforcement mode (strict / warn / advisory, per repo *and* per field?); evolution when a required field is added to a repo with existing docs (reject writes, allow with defaults, or trigger a bulk-update pass via the future bulk-update op?); scope (schema lives in repo config, or as a system-namespace doc so it versions like anything else?).
- **Computed frontmatter as `$`-intrinsics.** `$word_count`, `$reading_time`, `$outgoing_links` (once §11.2 lands), `$last_body_edit` (most recent version whose body hash actually differed — distinguishes real edits from frontmatter-only touches). All derivable from data mrplex already stores; queryable via the same CEL surface as `$path`/`$updated_at`. Read-only — writes rejected with `computed_field`. Kills the "stash derived value in frontmatter and forget to update it" antipattern that otherwise grows in every corpus.
- **Change feed — webhooks and SSE.** Every write (create/update/move/delete) emits `{ repo, path, document_id, version_id, prev_version_id, author, kind }`. Two subscribers: outbound webhooks (per-repo config, HMAC-signed, at-least-once with a small retry queue) and a `GET /repos/{repo}/events` SSE stream filtered by the caller's read scope claim (§8.2) — same scope filter as `query`, so no subscriber ever sees an event it couldn't have read. MCP notifications already exist; this is the plain-HTTP twin so a static-site builder, Meilisearch indexer, or an agent doesn't have to poll. Ordering guarantee is per-document, not global (matches the write model). Resume via `?from_version_id=…`.
- **`mrplex verify`.** Integrity scrub over the version chain: walk each document oldest-to-newest, recompute body/frontmatter hashes, confirm `frontmatter_raw` ↔ `frontmatter` round-trips byte-exact (§3.2), check `prev_id`/`next_id` symmetry, verify FTS/chunk/link derived tables against their source versions, report orphans. No writes. CLI + kernel op + optional CI mode that exits non-zero on any inconsistency. Cheap insurance for an append-only store where the chain *is* the guarantee.
- **`mrplex verify`. Shipped** (`docs/verify-plan.md`). Read-only integrity scrub: `kernel.verify` re-derives the FTS / links / hash indexes and checks the version chain, reporting inconsistencies as structured findings (never throwing on a finding). Six families — `chain` (prev/next symmetry, one-current, one-live-per-path, cycles, repo-id drift), `hash` (recompute `contentHash` vs. stored), `frontmatter` (raw↔parsed round-trip, `$`-leak), `fts` (SQLite `fts_docs` rowid↔version bijection — skipped-with-note on Postgres, whose `fts_tsv` is a generated column), `chunks` (embedding provenance: nonexistent-version orphans, mixed-dim), `links` (re-`extractEdges` vs. stored rows + resolution correctness). No writes — findings carry a `suggested_fix` pointing at the relevant backfill. Surfaces: CLI `mrplex verify` (`--check`/`--severity`/`--max-findings`/`--json`/`--ci`), MCP `verify` tool, REST `GET /verify` and `GET /repos/{repo}/verify`. O(total versions) — it walks history, unlike everything else on the read path. Where implementation refined the sketch: "orphan" means a *nonexistent* version (the embed worker deliberately keeps chunks on superseded versions), the `fts` and `chunks`-orphan checks are whole-store (not repo-partitioned, skipped-with-note under `--repo`), and `chunks.unembedded` runs only when an embedder is configured.
- **Retention: rollup of autosave storms.** Per-repo policy that collapses contiguous same-author versions within N seconds into a single displayed step in `docs.history` — underlying versions retained, a `rollup_of` link identifies the group. Complements the embedding damper (§5.3): history stays readable when a WebDAV/Obsidian client sprays 40 saves per minute during an edit session. This is a view-time policy over an untouched underlying chain, not a delete — `docs.get --version` still resolves every intermediate step and `docs.diff` still spans them.
- **`mrplex-lsp`.** LSP over stdio for Markdown+YAML: frontmatter completion and diagnostics from the per-repo schema (above), go-to-definition and hover on links once §11.2 lands, code-actions surfacing `mrplex links repair`. Editors get the mrplex surface (VS Code, Neovim, Helix, Zed) through their existing LSP clients, without a per-editor plugin. Runs against `--database` or `--server` the same way the CLI does.
- **`mrplex export`.** Materialize a repo's live current versions as a filesystem tree — `path/` structure, `frontmatter_raw` + body written verbatim. Flags for `:deleted/` inclusion, historical version fanout (`--as-of` once PIT reads land), and index files. Hands the corpus to Hugo/Zola/11ty/rsync in one command; the byte-exact round-trip is what makes it trustworthy where a naive dump wouldn't be.
Expand Down
Loading
Loading