Status: Final audited architecture
Target release: Lorepack v0.1
Working codename: Lorepack
Primary CLI: lore
Date: 30 July 2026
Product statement: Lorepack is a versioned context build system for AI. It compiles a directory of documents, spreadsheets, data, and project artifacts into an immutable build that can be inspected, diffed, deployed, activated, and rolled back, then accessed by chat models and agents through MCP, HTTP, or a bounded export.
Build Lorepack as a local-first, Apache-2.0 developer tool with this primary mental model:
Git and Terraform for the context that AI systems depend on.
The product is not differentiated by indexing documents or exposing search through MCP. Several active open-source tools already provide local document parsing, file watching, BM25 or FTS5 retrieval, embeddings, reranking, and MCP integration.[12][13][14]
Lorepack's wedge is the complete lifecycle around context:
source artifacts
-> plan
-> deterministic build
-> immutable version
-> validate
-> project to a runtime
-> activate atomically
-> diff or roll back
Search and retrieval are required capabilities, but they are table stakes. The product identity is the build system.
The central invariant is:
A Lore build is the source of truth. Every local or remote runtime is a projection of that immutable build.
This means:
- source files are never the live serving database;
- a mutable vector index is never the canonical state;
- local and Cloudflare deployments receive the same logical build;
- activation is a pointer change after verification;
- a failed build or deployment cannot corrupt the previously active version;
- rollback does not require recompilation.
| Area | Final MVP decision |
|---|---|
| First-run experience | No account, API key, Docker daemon, model download, Python runtime, C/C++ compiler, or native npm add-on. |
| Default retrieval | Structure-aware lexical retrieval plus metadata, hierarchy, explicit source authority, provenance, and typed table access. |
| Semantic retrieval | Explicit post-v0.1 enhancement unless lifecycle validation shows it is required earlier; never part of the default install or first-run critical path. |
| Local data | SQLite through Node's bundled node:sqlite, isolated behind an adapter, with an FTS5 capability check. |
| AI interfaces | MCP stdio, MCP Streamable HTTP, REST, and bounded Markdown/JSON exports. |
| Client setup | lore connect detects supported clients, shows a plan, maps the current workspace to each client's safest documented scope, and verifies both the Lore server and the client registration. |
| Build command | lore build hides compile, validate, index, and package stages behind one user-facing operation. |
| Deployment | Backend projections are build-scoped; candidate verification precedes one atomic active-build switch. |
| First remote target | Cloudflare Worker + D1 + R2. Vectorize is a post-v0.1 extension gated by exact embedding compatibility and query-visibility verification. |
| Platform support | macOS, Windows, and Linux are explicit v0.1 targets with cross-platform CI. |
| Feedback | Audit result | Design response |
|---|---|---|
| Local MCP document search is crowded | Confirmed by current open-source implementations.[12][13][14] | Versioning, plans, deployment, activation, and rollback now lead the specification and product narrative. |
| Screenshots were promised but OCR was excluded | Valid mismatch | Screenshots and scanned documents are removed from the v0.1 promise and listed as a future parser class. |
| Native SQLite and ONNX dependencies threaten DX | Confirmed risk; prebuilt gaps can force local compilation.[19] | better-sqlite3 and ONNX are removed from the default installation. The core uses bundled node:sqlite; semantic support is optional. |
| First run must survive offline use | Valid | The default build is entirely deterministic and offline after npm installation. No model download occurs; any future semantic enhancement has explicit progress, resumable cache, checksum verification, offline-only mode, and lexical fallback. |
| Agent configuration should be automatic | Confirmed as practical because major clients expose CLI or workspace configuration surfaces.[3][4][5] | Add lore connect, --dry-run, a non-global workspace default mapped per client, safe merge, backup, disconnect, protocol verification, and client status verification. |
| Conflict handling lacked a producer | Valid | Automatic conflict detection is removed. Explicit authority, status, and supersedes rules are added. |
| Linear vector scan had no bound | Valid | Semantic search is not a v0.1 gate; a future exact-scan adapter is capped at 25,000 vectors x 384 dimensions, a 50 MiB resident matrix, and a release gate of p95 top-20 scan at 250 ms or less on the reference machine. |
| Windows support was unspecified | Valid | Windows 11 x64 is part of the support matrix and CI, with explicit path and watcher rules. |
| Context export needed a useful default budget | Valid | chat exports default to an estimated 24,000 tokens with a complete omission report. |
| Finding | Why it matters | Final design response |
|---|---|---|
| A long-lived MCP or HTTP process could keep an old SQLite handle after activation | Updating the active pointer is insufficient if connected agents need a restart before seeing the new build. | Add request-scoped build handles. In-flight requests finish on their captured immutable build; the next request opens the new active build without reconnecting the client. |
| A semantic build cannot assume that a remote target can embed queries into the same vector space | Matching dimensions alone does not make vectors compatible. | Cloudflare v0.1 is lexical-only. A future semantic target must match the build's exact embedding profile and pass compatibility fixtures; capability loss is never silent. |
| Vectorize acknowledges durable writes before they become query-visible | Activating immediately after upload can expose an incomplete semantic candidate. | Future Vectorize projection uses build-scoped namespaces, batched writes, visibility polling through the runtime query path, and a timeout that leaves the candidate inactive.[27] |
| Byte-identical SQLite files are not required to prove a logically identical build | Treating physical database bytes as canonical would make the portability promise depend on SQLite file-layout details. | Build identity uses canonical logical hashes. Package-member checksums detect corruption, while the SQLite file remains an immutable runtime projection rather than the source of identity. |
A project or research topic accumulates durable context in human-oriented formats:
- Markdown and text documents;
- PDFs and DOCX files;
- CSV exports and XLSX workbooks;
- source code and configuration;
- research notes, requirements, decisions, and historical versions.
Today's AI workflows repeatedly pay the same tax:
- users upload the same artifacts to separate web chats;
- coding agents scan the same directory again in each session;
- large attachments consume a limited model context window;
- conversation compaction loses exact numbers, exceptions, and decision rationale;
- spreadsheets are flattened into prose instead of queried as typed data;
- different clients use inconsistent or stale snapshots;
- a changed requirement does not automatically invalidate context already indexed elsewhere.
Given:
project-context/
strategy.md
requirements.docx
customer-research.pdf
analytics.csv
pricing.xlsx
architecture/
decisions/
archive/
The zero-config path is:
lore dev ./project-contextLorepack should:
- create a minimal project configuration when none exists;
- discover and parse supported artifacts;
- build an immutable local version;
- start a file watcher and local Studio;
- expose MCP and HTTP interfaces;
- print the exact command to connect a supported AI client;
- rebuild only affected artifacts when sources change.
The explicit path remains available:
lore init ./project-context
lore build
lore connect claude-codeWhen a remote runtime is needed:
lore deploy cloudflareLorepack plans the change, creates or reuses a build, projects it to Cloudflare, verifies the candidate, and activates it atomically.
The user receives:
- a reproducible build ID;
- a local context runtime independent of any chat session;
- workspace-scoped client integration;
- exact source provenance in every result;
- typed access to spreadsheet data;
- bounded task context rather than whole-directory dumping;
- source and build diffs;
- local and remote rollback.
Lorepack is a:
- context build system;
- deterministic compiler and indexer;
- portable context package format;
- read-only context runtime;
- deployment and lifecycle tool;
- set of AI-native protocol adapters.
Lorepack is not initially a:
- chatbot;
- autonomous agent framework;
- conversation-memory product;
- vector database;
- enterprise search suite;
- document editor;
- source-of-truth knowledge-management application.
"Lore" describes accumulated knowledge around a project or subject. "Pack" communicates a portable, versioned artifact. The name remains a working codename until package-name, repository, domain, and trademark clearance; none of those are assumed by this architecture.
Build, version, and deploy the context your AI depends on.
Git/Terraform for AI context.
This shorthand is useful because it conveys:
- declarative source configuration;
- a plan before mutation;
- immutable versions;
- deterministic builds;
- local and remote projections;
- atomic activation;
- rollback.
Lorepack is a local-first, open-source context build system that compiles documents, spreadsheets, data, and project artifacts into an immutable package exposed through MCP, HTTP, and bounded exports.
| Term | Meaning |
|---|---|
| Lore project | A configured set of artifact sources and deterministic rules. |
| Artifact | One discovered source file or logical input. |
| Node | A structured unit extracted from an artifact, such as a section, sheet, table, or code region. |
| Chunk | A retrieval projection derived from one or more nodes. |
| Lore build | An immutable compiled snapshot with a content-derived ID. |
| Context bundle | A bounded task-specific selection returned to an AI client. |
| Projection | Runtime data derived from a Lore build for a backend. |
| Candidate build | A compiled or deployed build not yet active. |
| Active build | The verified version currently served by a runtime. |
Every major workflow must reinforce:
plan -> build -> validate -> activate -> diff -> rollback
Retrieval quality matters, but Lorepack should never present itself as another local RAG or MCP search server.
The open-source local version must support the complete core workflow without a hosted account:
- initialize;
- discover and parse;
- build and validate;
- inspect and search;
- assemble task context;
- query structured tables;
- expose MCP and HTTP;
- connect supported clients;
- export bounded context;
- retain build history;
- diff and roll back.
A future hosted platform sells operational convenience, collaboration, and synchronization, not access to a deliberately crippled core.
The default installation must not require:
- Python;
- Docker;
- a local compiler toolchain;
- a database server;
- an API key;
- an embedding-model download;
- cloud credentials;
- a background daemon.
No command may appear to hang silently. Long stages emit progress, artifact counts, elapsed time, and recovery instructions.
The compiler first preserves:
- artifact identity and checksum;
- document hierarchy;
- headings and locators;
- sheets, columns, rows, and cell ranges;
- code boundaries;
- explicit status, authority, and supersession;
- provenance.
Models and embeddings are optional indexes over this structure, not the canonical representation.
Lorepack does not automatically decide which conflicting document is correct in v0.1.
Users may declare deterministic rules:
status: active | draft | archived;authority: 0..100as a ranking preference;supersedesrelationships.
Without those declarations, Lorepack may return multiple relevant sources, but it must not label them as a detected conflict or silently choose one as truth.
CSV and XLSX inputs become:
- typed tables;
- column metadata;
- row counts and statistics;
- compact retrieval descriptions;
- a constrained read-only SQL surface;
- exact file, sheet, and cell provenance.
Flattening a workbook into a long block of prose is an invalid implementation.
MCP is the primary AI-native interface, but it is not the product. The same runtime capabilities are exposed through:
- MCP stdio;
- MCP Streamable HTTP;
- REST;
- CLI and Markdown/JSON export.
The current MCP specification and stable TypeScript SDK support stdio and Streamable HTTP, including the July 2026 protocol revision.[1][2]
The codebase uses ports and adapters from day one, but v0.1 does not introduce dynamic plugin discovery, a plugin manifest format, or a marketplace. Built-in adapters are registered explicitly and tested as one coherent product.
Lorepack should hide operational complexity while preserving inspectability:
- defaults work without configuration;
lore config show --effectivereveals every resolved default;lore planshows intended mutations;--verboseexposes stage details;- build manifests record versions and capabilities;
- Studio explains why context was selected or omitted.
The client configuration generated by Lorepack runs:
lore mcp --project /absolute/path/to/project --ensure-currentBefore emitting protocol messages, the server performs an authoritative source reconciliation: it discovers the configured files and streams their contents into the project fingerprint. Existing per-artifact hashes still make parsing, normalization, table import, and indexing incremental; reading bytes to verify freshness does not consume model context. Any check lasting more than 250 ms prints file and byte progress to stderr, while MCP stdout remains untouched.
A dirty project triggers an incremental build, validation, and atomic local activation. If that candidate fails, Lorepack exits without serving stale context and leaves the previous build untouched. Serving a known-stale build requires the explicit --allow-stale escape hatch.
Every search, source, table, and context result includes the active build ID and source-state metadata. Freshness is therefore visible to both the user and the consuming agent.
- Local directories and explicit file inputs.
- Markdown, plain text, HTML, text-based PDF, DOCX, CSV, and XLSX.
- Optional source-code text ingestion for common UTF-8 code and configuration files.
- Recursive discovery with
.loreignore. - Content hashing and incremental reuse.
- Canonical structured intermediate representation.
- Hierarchy-aware deterministic chunking.
- SQLite catalog and typed table storage.
- SQLite FTS5 lexical retrieval.[8]
- Metadata, path, heading, status, and authority ranking.
- Bounded task-aware context assembly.
- Exact provenance in every response.
- Read-only table description and SQL query tools.
- MCP stdio and Streamable HTTP.
- REST API and TypeScript SDK.
- Markdown and JSON context exports.
- Local React/Vite Studio.
- Immutable build history, plan, diff, activation, and rollback.
- Cloudflare reference deployment.
- Apache-2.0 licensing.
- OCR and scanned-document extraction.
- Screenshot, image, audio, or video understanding.
- PPTX parsing.
- Google Drive, Notion, Slack, SharePoint, GitHub, or other SaaS synchronization.
- Multi-user tenancy and source-permission synchronization.
- Automatic contradiction or truth detection.
- LLM-generated summaries as canonical build content.
- Semantic embeddings in the default installation or release gate.
- Knowledge-graph extraction.
- Conversation and personal memory.
- Agent workflows or autonomous actions.
- Server-side compilation on Cloudflare.
- A proprietary opaque binary format.
- Dynamic third-party plugin loading.
The v0.1 compatibility contract is:
| Platform | Support target |
|---|---|
| macOS | macOS 14+ on Apple Silicon and Intel where CI capacity is available. |
| Windows | Windows 11 x64 using PowerShell, Command Prompt, or a compatible terminal. |
| Linux | Ubuntu 22.04+ x64; other modern glibc distributions are best effort. |
| Node.js | >=24.15 <25 (Node 24 LTS), pinned in engines and CI.[6][7] |
Unsupported Node versions fail immediately with the detected version and an exact upgrade instruction. Lorepack does not fall through into native compilation.
The first release is designed and tested for one developer or team project, not enterprise-scale search.
| Dimension | Supported v0.1 envelope | Behavior beyond envelope |
|---|---|---|
| Source files | Up to 2,500 | Warn during plan; continue only with --allow-large-project. |
| Source bytes | Up to 1 GB total | Warn and show the largest artifacts. |
| Normalized chunks | Up to 50,000 | Supported lexical benchmark envelope. |
| Imported table rows | Up to 500,000 total | Warn; recommend splitting data or a future backend. |
| Columns per table | Up to 100 | Fail that table with an actionable parser message; this also matches D1's current per-table column limit.[25] |
| Single text PDF | Up to 500 pages | Warn before processing larger files. |
| Export budget | 4,000 to 40,000 estimated tokens | Require an explicit override outside the range. |
These are product limits and release gates, not claims that underlying SQLite cannot exceed them.
On a documented reference machine with 8 modern CPU cores, 16 GB RAM, and local NVMe storage:
- authoritative source fingerprint over the full 1 GB / 2,500-file envelope: p95 below 4 s;
- warm lexical search over 50,000 chunks: p95 below 250 ms;
lore_context_for_taskwithout semantic retrieval: p95 below 1.5 s;- an incremental rebuild of one changed ten-page text document: below 2 s after the file is stable;
- the CLI emits visible progress at least once per second during long operations;
- cancellation leaves the previously active build intact.
These are benchmark gates to measure before release. They must not be advertised until achieved.
A later optional local semantic package may use a small ONNX embedding model. ONNX Runtime distributes prebuilt Node bindings for major Windows, Linux, and macOS targets, but it remains a native runtime dependency and is therefore excluded from the core installation.[18]
Enabling it is explicit:
lore enhance semanticThe enhancement flow must:
- show the exact package, model, revision, dimensions, download size, and cache path before mutation;
- report downloaded bytes and extraction/indexing progress;
- download into a partial file and resume when the provider supports byte-range requests;
- verify expected size and checksum before activation;
- support
--offline, which uses only a verified local cache; - remove or quarantine a corrupt partial download;
- leave the current lexical build fully usable when installation or loading fails.
The first exact cosine implementation must:
- be installed explicitly;
- default to a maximum of 25,000 vectors at 384 dimensions;
- keep the raw resident vector matrix at or below 50 MiB;
- achieve p95 of 250 ms or less for a top-20 exact scan on the documented reference machine, excluding query embedding time;
- refuse an unbounded scan and explain the scalable-backend alternatives;
- fall back to the always-available lexical path when unavailable.
Primary installation:
npm install -g @lorepack/cliTrial path:
npx @lorepack/cli dev ./project-contextThe published core package must have no install script that compiles native code. The clean-install test runs on fresh macOS, Windows, and Linux environments without Python, Xcode command-line tools, Visual Studio Build Tools, or make.
lore dev ./project-contextWhen no lore.yaml exists, Lorepack:
- validates the runtime and SQLite/FTS5 capabilities;
- inspects the directory without modifying it;
- writes a minimal
lore.yaml,.loreignore, and.gitignoreentry atomically; - prints the files it created;
- plans and creates the first build;
- starts watch mode, Studio, HTTP, and local Streamable HTTP MCP;
- prints client connection commands.
No interactive question is required for the default path. Prompts appear only when a decision is genuinely ambiguous or destructive.
lore init ./project-context
lore plan
lore build
lore devlore init is idempotent. Re-running it shows the proposed changes and never overwrites user configuration without confirmation or --force.
Lorepack 0.1.0
Project: sarjbot
Discovering 184 files done
Parsing 173 documents, 11 tables done
Indexing 12,418 chunks with FTS5 done
Validating provenance, rules, table schema done
Activating lore_b7f2a9c1d4e8 done
Build lore_b7f2a9c1d4e8
Reused 0 artifacts (first build)
Warnings 2 unsupported files; run `lore inspect warnings`
Studio http://127.0.0.1:43110
HTTP http://127.0.0.1:43110/v1
MCP HTTP http://127.0.0.1:43110/mcp
MCP stdio lore mcp --project "/path/to/project"
Connect now:
lore connect claude-code
lore connect codex
lore connect vscode
If a stage exceeds one second, the CLI shows an updating count or progress bar. A spinner without measurable progress is insufficient for parsing or indexing.
The normal first-time workflow is deliberately two commands:
lore dev [path]
lore connect [client|all]The explicit build lifecycle uses four verbs:
lore plan
lore build
lore deploy [target]
lore rollback [build-id]lore init [path] remains available for users who want to configure before starting the runtime. lore build deliberately hides the internal compile, index, validate, and package phases. By default it validates and atomically activates the new local build; --no-activate leaves a verified candidate for CI, inspection, or packing.
Supporting commands:
| Command | Purpose |
|---|---|
lore plan |
Read-only preview of source, build, rule, and deployment changes. |
lore connect [client] |
Safely configure and verify one AI client; pass all to configure every detected supported client. |
lore disconnect [client] |
Remove only Lorepack-owned configuration; pass all to remove it from every detected supported client. |
lore mcp |
Run the workspace-scoped stdio MCP server; generated client configs add --ensure-current. |
lore serve |
Serve an active build without watching or rebuilding. |
lore status |
Show source dirtiness, active build, warnings, and target state. |
lore diff [a] [b] |
Compare artifacts, nodes, rules, tables, and capabilities. |
lore inspect [item] |
Inspect parsed structure, provenance, warnings, or a build. |
lore search "query" |
Exercise lexical retrieval from the terminal. |
lore export --task "..." |
Produce a bounded Markdown or JSON context bundle. |
lore pack [build-id] |
Export a portable .lorepack archive; not required for normal deploys. |
lore activate [build-id] |
Activate a verified local build. |
lore rollback [build-id] |
Restore the prior or specified verified build. |
lore doctor |
Validate Node, SQLite/FTS5, paths, parsers, watcher, and client setup. |
lore config show --effective |
Show the complete resolved configuration and its source. |
lore connect claude-codeLorepack uses a conceptual workspace scope: the server is available only for the current project and is never made global without an explicit flag. That scope maps to each client's documented model:
| Client | Default mapping | Shared/team option |
|---|---|---|
| Claude Code | Official local scope for the current project, stored privately by Claude Code. |
--shared uses project .mcp.json, which the client asks users to trust.[3] |
| Codex | Project .codex/config.toml in a trusted project. |
The same project file may be committed deliberately.[4] |
| VS Code | Workspace .vscode/mcp.json, with an explicit notice that it is shareable source-controlled configuration. |
Same file; Lorepack never chooses the user profile silently.[5] |
The command must:
- detect whether the client and a supported configuration surface are available;
- detect existing Lorepack configuration and ownership receipts;
- default to the non-global workspace mapping above;
- show the exact command or file mutation plan;
- prefer the client's official CLI when it can express the selected scope safely;
- otherwise parse and merge the documented workspace configuration format;
- represent commands as executable plus argument arrays, never shell-concatenated strings;
- write atomically, preserve unrelated configuration, and create a timestamped backup before direct file edits;
- spawn
lore mcp --ensure-currentand verify the current MCP protocol withserver/discoverplustools/list; use the SDK's backward-compatibility path for 2025-era clients that still initialize a connection; - invoke the client's own list/status command when one exists;
- print the one remaining approval or workspace-trust step, if the client requires it.
Safety flags:
lore connect claude-code --dry-run
lore connect codex --scope workspace
lore connect vscode --shared
lore connect all --yes
lore disconnect vscode--scope user is explicit and never implied by all. Unsupported client versions degrade to a validated copy-paste snippet rather than a speculative configuration edit.
The generated lore.yaml is intentionally small:
version: 1
name: sarjbot
sources:
- ./project-contextUseful deterministic rules are opt-in:
version: 1
name: sarjbot
sources:
- ./project-context
rules:
- match: "archive/**"
status: archived
- match: "requirements/current/**"
status: active
authority: 100
- match: "requirements/v2.docx"
supersedes:
- "requirements/v1.docx"
context:
defaultProfile: chatEverything else has versioned defaults. lore config show --effective prints the expanded configuration, including include patterns, parser choices, limits, ports, and context budgets.
From lowest to highest priority:
- versioned product defaults;
lore.yaml;- target-specific local configuration under
.lore/targets/; - environment variables for secrets and CI-only overrides;
- command-line flags.
lore config explain <path> shows the final value and which layer supplied it.
| Failure | Required behavior |
|---|---|
| Unsupported file discovered | Exclude with a visible warning and exact path; do not silently index garbage. |
| Included supported file fails to parse | Fail the candidate build by default; previous build remains active. |
| Optional semantic adapter unavailable | Continue with lexical retrieval and show the capability difference. |
| Offline machine | Default build succeeds; no network call is attempted. |
| FTS5 capability missing | Fail fast in doctor/startup with the detected SQLite version and supported remediation. |
| Client launches against dirty sources | Generated --ensure-current performs an incremental build before MCP starts; failure exits without serving stale data or changing the previous active build. |
| Port occupied | Select the next available localhost port, print it, and persist it for the dev session. |
| Watch event storm | Debounce, wait for stable content, hash, and treat duplicate events as no-ops. |
| Ctrl-C during build | Remove the incomplete candidate and leave current activation unchanged. |
| Remote deploy partially fails | Candidate remains inactive; emit a resumable deployment receipt. |
After source edits:
lore status
lore plan
lore buildTypical output:
Plan for lore_b7f2a9c1d4e8 -> candidate
Artifacts
+ 2 added
~ 1 changed
- 0 removed
= 181 reused
Rules
~ requirements/v2.docx authority 80 -> 100
+ requirements/v2.docx supersedes requirements/v1.docx
Tables
~ pricing.xlsx / operator_prices
rows 1,982 -> 2,104
columns + membership_price
Expected work
parse 3 artifacts
reuse 181 artifacts
rebuild 27 chunks
lore build performs plan -> compile/index -> validate -> local activate by default. --no-activate keeps the verified candidate inactive. lore deploy cloudflare implicitly builds when sources are dirty, but prints the same plan before remote changes. --no-build requires a clean working set.
Artifact pool
-> deterministic compiler
-> immutable Lore build
-> local activation or backend projection
-> portable context runtime
-> MCP / HTTP / export
-> coding agents, chat models, and custom agents
The architecture has four explicit planes.
Runs locally in v0.1:
- discover;
- fingerprint;
- parse;
- normalize;
- import typed tables;
- apply deterministic rules;
- chunk;
- create lexical indexes;
- validate;
- write an immutable candidate.
Owns:
- plan;
- build history;
- candidate state;
- validation gates;
- active pointer;
- diff;
- deployment receipts;
- rollback and retention.
This plane is the differentiating product layer.
Loads one active build through storage interfaces and exposes:
- project/build description;
- lexical search;
- task context assembly;
- source reads;
- table description and safe queries;
- provenance.
Adapts the same runtime capabilities to:
- MCP stdio;
- MCP Streamable HTTP;
- REST;
- CLI;
- Studio;
- Markdown/JSON export.
Cloudflare, MCP, UI, and parser packages must never leak into the domain model.
| Area | Choice | Reason |
|---|---|---|
| Main language | TypeScript | One language across CLI, compiler, local runtime, Cloudflare Worker, SDK, and UI. |
| Runtime | Node.js >=24.15 <25 |
Bundled SQLite release-candidate API and current LTS support.[6][7] |
| Module format | ESM | Aligns with current Node and edge tooling. |
| Monorepo | pnpm workspaces | Native workspace support without an orchestration framework.[10] |
| Formatting/linting | Biome | One fast formatting and static-analysis path. |
| Tests | Vitest | Shared unit/integration runner for TypeScript and Vite code.[11] |
| Releases | Changesets | Package versioning and changelog discipline. |
Do not add Turborepo, Nx, Bazel, or a remote build cache until repository timings demonstrate the need.
Use:
commanderfor command definitions;@clack/promptsonly for genuine interactive decisions;zodfor config, manifest, and public input validation;chokidarfor cross-platform watch mode;picocolorsand a small progress renderer;execafor invoking supported client CLIs and Wrangler;proper-lockfileor an equivalent narrow lock for build/activation coordination.
Chokidar supports cross-platform watching and options for atomic or chunked writes, but Lorepack must still reconcile with content hashes and a post-ready scan rather than trusting a single event stream.[9]
CLI handlers orchestrate application services. No parser, storage, ranking, or deployment logic belongs in command files.
Use Node's bundled node:sqlite API with raw SQL migrations.
Reasons:
- no native npm add-on;
- no
node-gypfallback; - no post-install binary download;
- SQLite ships with the supported Node runtime;
- local schema can remain close to D1's SQLite semantics.
The API is release-candidate stability in the supported Node 24 range, so this is a conscious trade-off, not an assumption.[7]
Mitigations:
- isolate all use behind
CatalogStoreandTableStoreinterfaces; - pin and test a narrow Node LTS range;
- run a startup capability probe that creates and queries an FTS5 table;
- open completed build databases with
readOnly: true,defensive: true, extension loading disabled, and bounded SQLite runtime limits; - maintain adapter contract tests;
- avoid depending on experimental session/changeset features;
- retain the option to replace the adapter without changing the build format.
Do not use an ORM in v0.1. Versioned SQL migrations are easier to inspect and share with the D1 projection.
- Candidate build: writable SQLite file in a temporary build directory.
- Completed build: immutable file; runtime opens read-only.
- Dev metadata: a separate small writable database or JSON receipt, never writes into the completed build.
- FTS5: one content-indexed table for chunks with weighted title, path, heading, and body columns.[8]
- Structured tables: namespaced physical tables with a catalog mapping stable Lore table IDs to SQL names.
Use Hono for portable Web-Standards request/response routing across Node and Cloudflare.[15]
Route handlers depend on LoreRuntime capabilities, not on SQLite or Cloudflare bindings.
Use the official Model Context Protocol TypeScript SDK v2, pinned to a tested minor version. The v2 line implements the 2026-07-28 specification and supports stdio and Streamable HTTP.[1][2]
Keep MCP in one package so protocol changes do not affect the compiler or storage schema.
| Format | Library/approach | MVP behavior |
|---|---|---|
| Markdown | unified + remark |
Preserve heading hierarchy, lists, code blocks, links, and source offsets where available. |
| Plain text/code | Native decoding + extension registry | Paragraph or syntax-neutral region splitting; no AST requirement in v0.1. |
| HTML | unified/rehype |
Remove script/style/navigation noise; preserve headings, links, lists, code, and tables. |
pdfjs-dist |
Text-based PDFs only; preserve page locators and emit extraction warnings. | |
| DOCX | mammoth |
Convert semantic document structure to HTML, then normalize. |
| CSV | csv-parse |
Detect header, infer conservative types, and import as a table. |
| XLSX | exceljs |
Preserve workbook, sheet, cell range, formulas-as-text, and inferred table regions. |
No Python sidecar is part of the MVP. Advanced layout extraction, OCR, and complex workbooks can later use optional parser adapters.
Use:
- React;
- Vite;
- React Router;
- TanStack Query;
- a small accessible component set;
- no global state library initially.
Studio is an inspector, planner, and context debugger. It is not a chat application.
Keep semantic dependencies outside the core dependency graph:
@lorepack/semantic-local
-> @huggingface/transformers
-> onnxruntime-node
A future command may be:
lore enhance semanticThe download flow must expose byte progress, a resumable partial cache, pinned model revision, expected size/checksum, and local-files-only mode; Transformers.js exposes progress and offline lookup controls.[17] The feature is never imported by the base CLI until explicitly enabled.
Keep one repository with a small number of packages:
lorepack/
apps/
studio/ # React/Vite inspector
packages/
core/ # domain types, rules, plan, build IDs
compiler/ # deterministic pipeline and validation
parsers/ # built-in format adapters
backend-local/ # node:sqlite + filesystem implementation
runtime/ # portable context capabilities + Hono routes
mcp/ # MCP tools/resources and transports
cli/ # `lore` executable and DX orchestration
connect-clients/ # safe client detection/config adapters
deploy-cloudflare/ # Cloudflare plan/apply/verify/activate
sdk/ # small TypeScript HTTP client
schemas/ # public JSON Schemas
migrations/
local/
cloudflare/
fixtures/
documents/
spreadsheets/
paths/
expected/
benchmarks/
retrieval/
incremental-build/
examples/
product-research/
coding-project/
docs/
architecture/
package-format/
integrations/
compatibility/
pnpm-workspace.yaml
biome.json
vitest.workspace.ts
LICENSE
core <- compiler <- cli
core <- parsers <- compiler
core <- backend-local <- runtime
runtime <- mcp
runtime HTTP <- studio
core <- backend-local <- deploy-cloudflare <- cli
runtime <- mcp <- deploy-cloudflare
connect-clients <- cli
Rules:
coreimports no parser, database, MCP, UI, or Cloudflare code.compilersees parser and build-store interfaces, not client protocols.parsersimplement contracts declared bycoreorcompiler.backend-localimplements catalog, table, object, build-store, and active-build-provider ports.runtimeconsumes request-scoped read-only build handles.mcpmaps runtime capabilities into protocol schemas.deploy-cloudflareowns the Cloudflare Worker app plus plan/apply/verify/activate logic. It may consume the portable runtime and MCP layers and read sealed local builds throughbackend-local, but it never reaches into compiler internals.studiocommunicates only through HTTP APIs.
Do not create one package per parser or storage table. Split only where there is a real runtime, dependency, or licensing boundary. Semantic support is separate because it changes installation weight and native-runtime risk.
The canonical model is more important than any retrieval index.
interface Source {
id: string;
kind: "directory" | "file";
root: string;
include: string[];
exclude: string[];
followSymlinks: boolean;
}type ArtifactStatus = "active" | "draft" | "archived";
interface Artifact {
id: string; // normalized source ID + POSIX relative path
sourceId: string;
relativePath: string; // always POSIX-style internally
displayPath: string; // native path for user-facing output
mediaType: string;
byteSize: number;
contentHash: string;
parserId: string;
parserVersion: string;
title?: string;
status: ArtifactStatus;
authority: number; // 0..100 ranking hint, not a truth score
supersedes: string[]; // artifact IDs
metadata: Record<string, unknown>;
}type NodeKind =
| "document"
| "section"
| "paragraph"
| "list"
| "code"
| "table"
| "sheet"
| "row-group";
interface LoreNode {
id: string;
artifactId: string;
parentId?: string;
kind: NodeKind;
ordinal: number;
title?: string;
text?: string;
locator: SourceLocator;
metadata: Record<string, unknown>;
revisionHash: string;
}A chunk is a retrieval projection, not the primary representation.
interface Chunk {
id: string;
artifactId: string;
nodeIds: string[];
headingPath: string[];
text: string;
estimatedTokens: number;
locator: SourceLocator;
revisionHash: string;
}interface LoreTable {
id: string;
artifactId: string;
name: string;
sheet?: string;
sqlName: string;
columns: Array<{
name: string;
type: "text" | "integer" | "real" | "boolean" | "date" | "unknown";
nullable: boolean;
}>;
rowCount: number;
locator: SourceLocator;
}interface ResolvedArtifactRule {
artifactId: string;
status: ArtifactStatus;
authority: number;
supersedes: string[];
matchedRules: string[];
}Validation rejects:
- missing superseded targets;
- supersession cycles;
- authority outside
0..100; - case-only path collisions on case-insensitive filesystems;
- rules that match no artifact when
strictRulesis enabled.
type BuildId = `lore_${string}`; // full lowercase SHA-256 after the prefix
interface EmbeddingProfile {
modelId: string;
revision: string;
tokenizer: string;
pooling: "mean" | "cls";
normalized: boolean;
dimensions: number;
valueType: "float32";
}
interface LoreBuildManifest {
formatVersion: 1;
buildId: BuildId;
projectName: string;
compilerVersion: string;
schemaVersion: number;
configurationHash: string;
sourceFingerprint: string;
canonicalRoots: {
artifacts: string;
nodes: string;
chunks: string;
tables: string;
objects: string;
};
capabilities: Array<
| "lexical-search"
| "structured-context"
| "table-query"
| "semantic-search"
>;
embeddingProfile?: EmbeddingProfile;
counts: {
artifacts: number;
nodes: number;
chunks: number;
tables: number;
tableRows: number;
};
warnings: BuildWarning[];
}interface SourceLocator {
artifactId: string;
relativePath: string;
page?: number;
headingPath?: string[];
sheet?: string;
cellRange?: string;
lineStart?: number;
lineEnd?: number;
}A search result, table result, or context item without a locator is invalid and fails runtime contract tests.
lore.yaml # user configuration
lore.lock # parser/schema/optional model locks
.loreignore # exclusions
.lore/
cache/ # disposable content-addressed cache
builds/
lore_<full-sha256>/
manifest.json
context.sqlite
objects/
reports/
state.sqlite # mutable active pointer, deployment state, and operational build receipts
targets/
cloudflare.json # local non-secret target receipt
Commit:
lore.yaml;lore.lock;.loreignore.
Ignore .lore/ by default. CI may publish .lorepack archives as build artifacts.
lore_<full-sha256>/
manifest.json
context.sqlite
objects/
sha256/ab/cd/...
reports/
warnings.json
omissions-schema.json
benchmark-metadata.json
canonical-hashes.json
context.sqlite contains normalized metadata, nodes, chunks, FTS5 indexes, table catalog, typed tables, and rule results. Large normalized source bodies may be content-addressed objects referenced from SQLite.
Normalized source text required for remote source reads is included in the build. Original binary files are excluded by default and may be added only through an explicit package.includeOriginals: true setting.
lore pack lore_b7f2a9c1d4e8Produces:
sarjbot-lore_b7f2a9c1d4e8.lorepack
A .lorepack file is a standard ZIP envelope with:
- stable file ordering;
- normalized timestamps;
- no encrypted or proprietary payload;
- a top-level manifest;
- checksums for every member.
The build ID is derived from canonical logical content, not from incidental ZIP container bytes or the physical byte layout of context.sqlite. Member checksums detect package corruption; they are not the cross-platform identity of the build.
The canonical ID is lore_ followed by the full lowercase SHA-256 digest. Manifests, APIs, receipts, and on-disk build directories store the full ID. Human-facing output displays the shortest unambiguous prefix, with 12 hexadecimal characters as the default; the examples in this document use that display form.
The digest is derived from canonical logical hashes of:
- format and schema versions;
- compiler version where output semantics require it;
- effective configuration excluding secrets and local absolute paths;
- normalized source paths and content hashes;
- parser IDs and versions;
- rule resolution;
- exact optional embedding profile;
- canonical artifact, node, chunk, table, and object roots.
Operational timestamps, machine name, absolute workspace path, temporary directory, deployment target, ZIP metadata, and physical SQLite page layout are excluded.
lore.lock records the versions that can affect deterministic output:
formatVersion: 1
compiler: 0.1.0
schema: 1
parsers:
markdown: 0.1.0
pdf-text: 0.1.0
docx: 0.1.0
xlsx: 0.1.0
semantic: nulllore build --frozen fails if the lockfile would change.
planned -> building -> validating -> verified -> active
\-> failed
verified -> packed
verified -> projected -> remotely_verified -> remotely_active
Only verified builds may be activated or deployed.
Wall-clock and machine-specific information is kept outside the canonical build and outside .lorepack archives:
interface BuildReceipt {
buildId: BuildId;
startedAt: string;
completedAt: string;
durationMs: number;
cache: { reusedArtifacts: number; rebuiltArtifacts: number };
platform: string;
nodeVersion: string;
}This separation allows two machines to produce the same build ID, canonical manifest, and logical hash roots without pretending that operational history or physical SQLite bytes are identical.
Discover
-> Normalize paths
-> Fingerprint
-> Parse
-> Normalize structure
-> Import tables
-> Resolve explicit rules
-> Chunk
-> Build lexical index
-> Validate
-> Seal immutable build
Each stage consumes and emits typed records. No stage mutates a previously completed build.
Rules:
- use
lore.yamlsources plus.loreignore; - ignore
.git,node_modules,.lore, build outputs, and credential-shaped files by default; - do not follow symlinks unless explicitly enabled;
- reject paths escaping the configured root;
- detect case-insensitive collisions;
- sort normalized POSIX relative paths before processing.
Cache key:
artifact content hash
+ parser ID/version
+ relevant effective config
+ rule inputs that affect output
Explicit lore build and lore mcp --ensure-current runs discover and content-hash every configured file before declaring the project clean. File metadata is retained for diagnostics and watch-event coalescing, but it is not sufficient proof of freshness.
A running lore dev process hashes affected paths immediately and performs a full reconciliation after watcher startup, after watcher recovery, and periodically during long sessions. Watch events are an acceleration mechanism; content hashes are the source of truth.
Unchanged artifacts reuse parsed nodes, chunks, table data, and normalized objects. The new build still receives independent immutable catalog rows.
Parser output:
interface ParsedArtifact {
artifact: Artifact;
nodes: LoreNode[];
tables: ParsedTable[];
normalizedObjects: ObjectReference[];
warnings: ParserWarning[];
}A parser may emit warnings for recoverable loss, such as malformed PDF text order. A supported included file that cannot be parsed fails the candidate by default.
Normalization must be deterministic:
- Unicode normalization policy is versioned;
- line endings become
\ninternally; - repeated whitespace is normalized only where semantically safe;
- headings and list structure remain explicit;
- code blocks preserve exact text;
- absolute paths never enter canonical IDs;
- normalized source copies retain enough text for remote source reads.
For CSV/XLSX:
- identify sheet or region;
- detect or synthesize a stable header;
- infer conservative column types from a bounded sample;
- import values into a namespaced physical table;
- store formula text separately where present;
- calculate row count and lightweight null/distinct summaries;
- generate a compact retrieval node describing schema and provenance.
Type inference must prefer text when values are ambiguous. It must never silently coerce identifiers such as leading-zero postal codes into integers.
Apply config rules after discovery and before indexing.
Rules are deterministic and ordered. Later rules may override scalar fields, while supersedes lists merge and deduplicate unless replace: true is explicit.
Semantics:
archivedartifacts are searchable only when requested or when no active source satisfies the query;draftartifacts receive a ranking penalty and a visible label;authorityis a ranking multiplier, not evidence that content is true;- a superseded artifact remains readable and diffable but is excluded from default task bundles.
Chunking is hierarchy-aware and format-specific:
- preserve heading ancestry;
- prefer whole semantic nodes;
- split only beyond a configurable size;
- include a small parent-heading prefix for retrieval;
- never join unrelated artifacts;
- store exact node IDs and locators;
- estimate tokens conservatively.
Initial defaults:
- target 700 estimated tokens;
- hard maximum 1,200;
- overlap only when a split occurs, maximum 100 estimated tokens.
FTS5 columns:
chunk_id UNINDEXED
artifact_id UNINDEXED
status UNINDEXED
authority UNINDEXED
path
title
heading
body
Ranking combines FTS5 BM25 with deterministic boosts in the runtime. Do not bake mutable ranking weights into the primary text data.
A candidate cannot be sealed unless:
- every artifact has a stable ID and content hash;
- every node belongs to an artifact;
- every chunk points to existing nodes and provenance;
- every table has a valid catalog mapping;
- FTS row counts match chunk counts;
- rule references and supersession graph are valid;
- object checksums match;
- no secret value from environment/config is present in the manifest;
- a smoke search and source read succeed;
- the database passes
PRAGMA integrity_checkor the supported equivalent.
Watch mode uses Chokidar for event collection but content hashing for truth.
Algorithm:
- perform initial scan;
- start watcher;
- after watcher reports ready, run a reconciliation scan to close the scan/watch race;
- coalesce path events for a short debounce interval;
- wait until size and modification time are stable;
- fingerprint content;
- ignore duplicate hashes;
- create a new candidate build;
- activate only after validation.
On Windows, internal IDs use POSIX separators while filesystem calls use native paths. Rename/save patterns are tested with common editors.
interface LoreRuntime {
describeBuild(): Promise<BuildDescription>;
search(request: SearchRequest): Promise<SearchResult>;
contextForTask(request: TaskContextRequest): Promise<ContextBundle>;
readSource(request: SourceReadRequest): Promise<SourceReadResult>;
listTables(): Promise<LoreTable[]>;
describeTable(id: string): Promise<TableDescription>;
queryTable(request: TableQueryRequest): Promise<TableQueryResult>;
}MCP, REST, CLI, and Studio all call this interface.
The v0.1 retrieval path is deterministic:
- FTS5 candidate search;
- exact path/title/heading match boosts;
- active/draft/archived status adjustment;
- user-declared authority boost;
- superseded-source suppression;
- optional file-type and path filters;
- parent and adjacent-node expansion;
- duplicate and near-duplicate removal;
- artifact diversity;
- budget-aware packing.
Search results expose score components in debug mode. Lorepack should never imply that a lexical score is a confidence or truth score.
interface TaskContextRequest {
task: string;
profile?: "agent" | "coding" | "chat" | "deep";
budget?: number;
includeArchived?: boolean;
filters?: ContextFilter[];
}The assembler returns:
interface ContextBundle {
buildId: BuildId;
task: string;
profile: string;
estimatedTokens: number;
overview: ContextItem[];
selected: ContextItem[];
tables: TableReference[];
alternatives: ContextItem[];
omitted: OmittedItem[];
citations: Citation[];
}Selection policy:
- reserve a small budget for build/project orientation;
- prioritize active, authoritative, directly matched sources;
- include parent headings and enough adjacent context to preserve meaning;
- include alternative sources when no explicit precedence exists;
- avoid overfilling from one artifact unless the task clearly targets it;
- list every omission category and cut-off reason;
- never generate a synthetic answer inside the core runtime.
Lorepack may return:
Alternative relevant sources
- requirements/v1.docx [superseded]
- notes/launch-draft.md [draft]
It may not return:
Detected conflict: source A contradicts source B
unless a future explicit analysis capability actually produced and stored that conclusion.
| Profile | Default estimated token budget | Intended use |
|---|---|---|
agent |
12,000 | Repeated tool calls where the agent can fetch more. |
coding |
16,000 | Coding harness tasks with source code already in the agent workspace. |
chat |
24,000 | One bounded file or paste for a web chat. |
deep |
40,000 | Deliberate broad review in a large-window client. |
lore export defaults to chat. lore_context_for_task defaults to agent unless the client passes a profile.
The core uses a deterministic conservative estimate and labels it as an estimate. The report includes:
- budget requested;
- estimated tokens selected;
- reserved overhead;
- items omitted by budget;
- largest selected items;
- truncation boundaries.
Model-specific tokenizers may be added as optional adapters, but the package format cannot depend on one model vendor.
The runtime accepts one constrained SQL statement against build-owned tables.
Rules:
- exactly one
SELECTorWITH ... SELECT; - no comments that hide extra statements;
- no
PRAGMA,ATTACH,DETACH, DDL, DML, extension loading, or filesystem functions; - allowlisted tables only;
- bound row, byte, and execution-time limits;
- default
LIMITinjection when absent; - read-only database connection;
- result includes table and source provenance.
A separate describeTable tool should be preferred before free-form SQL.
When the semantic capability is installed, candidate lists may be fused with Reciprocal Rank Fusion. The runtime contract remains the same and the build manifest records the complete EmbeddingProfile, not only model name or dimensions. A query embedder is compatible only when model ID, immutable revision, tokenizer, pooling, normalization, value type, and dimensions match. A build without semantic vectors remains fully valid.
Keep the surface small to reduce schema/context overhead:
| Tool | Purpose |
|---|---|
lore_build_info |
Describe active build, capabilities, counts, warnings, and freshness. |
lore_search |
Find relevant passages with filters and provenance. |
lore_context_for_task |
Assemble a bounded, task-aware context bundle. |
lore_read_source |
Read a precise normalized source range. |
lore_list_tables |
Discover available structured datasets. |
lore_describe_table |
Read schema, row count, examples, and provenance. |
lore_query_table |
Execute constrained read-only SQL. |
Do not expose one MCP tool per document or internal compiler stage.
Useful resources:
lore://project/build
lore://project/sources
lore://project/tables
lore://source/{artifactId}
lore://build/{buildId}/diff/{otherBuildId}
Resources are supplemental. Tools remain the most predictable path for task-aware retrieval across clients.
Generated client configurations launch:
lore mcp --project /absolute/path/to/project --ensure-currentStartup sequence:
- acquire the project build lock;
- fingerprint configured sources and effective build inputs;
- reuse the active build when clean;
- when dirty, perform an incremental build, validation, and atomic activation before protocol output begins;
- open the active build read-only;
- expose protocol messages only on stdout and diagnostics only on stderr.
If no verified build exists, or a required rebuild fails, the process exits with an actionable error and leaves the previous active pointer untouched. --allow-stale is an explicit recovery option; when used, every tool result carries sourceState: "dirty" and a warning. --active-only skips source checks for pinned CI or forensic use.
The current protocol verification path uses server/discover and tools/list. The MCP adapter retains backward compatibility with clients implementing the preceding connection-oriented revision.[1][2][26] List responses use deterministic ordering and the current cache fields; every content result carries its build ID, so content freshness does not depend on a cached capability list.
lore dev and lore serve expose:
POST /mcp
Use the current stateless Streamable HTTP model where possible. Local HTTP binds only to 127.0.0.1 by default and validates request origins. Remote deployment requires authentication.[1][20]
GET /v1/build
POST /v1/search
POST /v1/context
GET /v1/sources/:artifactId
GET /v1/tables
GET /v1/tables/:tableId
POST /v1/tables/:tableId/query
GET /health
MCP and REST share Zod contracts generated into JSON Schema and SDK types.
lore export \
--task "Review the pricing strategy and identify unsupported assumptions" \
--profile chat \
--format markdown \
--output pricing-review-context.mdDefault output budget: 24,000 estimated tokens.
The file includes:
- project and build ID;
- task and profile;
- selected context grouped by source;
- exact citations;
- relevant table schemas or bounded row samples;
- estimated token usage;
- omitted sources and reasons;
- command to retrieve more.
This is the universal compatibility bridge for chat products that cannot connect to MCP.
| Client type | Local path | Remote path | Lorepack experience |
|---|---|---|---|
| Claude Code | stdio MCP | Streamable HTTP | lore connect claude-code using official CLI/project config.[3] |
| Codex CLI/IDE/ChatGPT desktop configuration | stdio MCP | Streamable HTTP | lore connect codex; project .codex/config.toml by default.[4] |
| VS Code agent mode | stdio MCP | Streamable HTTP | lore connect vscode; workspace .vscode/mcp.json by default.[5] |
| Cursor and other MCP clients | client-dependent | client-dependent | Detect known format only when verified; otherwise print a validated copy-paste snippet. |
| Web chat without MCP | not available | not available | lore export --profile chat. |
| Custom agent | stdio/HTTP | HTTP | MCP or REST SDK. |
The product must never claim that every web chat can connect directly to a localhost MCP server.
interface ClientConnector {
id: string;
detect(): Promise<ClientDetection>;
plan(input: ConnectInput): Promise<ConnectPlan>;
apply(plan: ConnectPlan): Promise<ConnectReceipt>;
verify(receipt: ConnectReceipt): Promise<ConnectionCheck>;
remove(receipt: ConnectReceipt): Promise<void>;
}Adapters are versioned and fixture-tested against documented client config shapes. Unsupported versions degrade to a printed configuration snippet rather than risky file mutation.
lore dev runs one foreground supervisor containing:
- file watcher;
- incremental build coordinator;
- local Hono server;
- Streamable HTTP MCP route;
- Studio static assets;
- active-build generation monitor.
lore mcp remains a separate client-managed stdio process. Both resolve the same transactional active-build pointer and open immutable build databases read-only.
No background system service is installed in v0.1.
interface ActiveBuildProvider {
current(): Promise<{ buildId: BuildId; generation: number }>;
acquire(): Promise<BuildHandle>; // read-only and reference-counted
}At the start of every MCP tool call or HTTP request, the runtime checks the monotonic active-build generation and acquires one immutable build handle. The request uses that handle for its entire lifetime and includes its buildId in the result.
Activation semantics:
- a request already in flight finishes against its captured build;
- the first request after the pointer transaction observes the new generation and opens the new build;
- no single response may mix rows from two builds;
- an old database handle closes only after its final in-flight request releases it;
- a missed filesystem notification is harmless because the request boundary rechecks the generation in
state.sqlite.
Connected coding agents therefore see a successful lore build, lore dev rebuild, or rollback on the next tool call without restarting or reconfiguring the client.
127.0.0.1:43110 preferred dev port
.lore/dev.json current dev-session receipt
.lore/state.sqlite transactional active-build pointer and receipts
If the preferred port is occupied, select the next available port and print it. Never bind to all interfaces without an explicit --host flag and warning.
interface BuildStore {
createCandidate(...): Promise<CandidateBuild>;
seal(...): Promise<VerifiedBuild>;
listBuilds(): Promise<BuildSummary[]>;
activate(buildId: BuildId): Promise<void>;
current(): Promise<BuildSummary | null>;
}
interface CatalogStore {
describeBuild(): Promise<BuildDescription>;
searchLexical(...): Promise<RankedChunk[]>;
readChunks(...): Promise<Chunk[]>;
readSource(...): Promise<SourceReadResult>;
}
interface TableStore {
listTables(): Promise<LoreTable[]>;
describeTable(id: string): Promise<TableDescription>;
query(request: TableQueryRequest): Promise<TableQueryResult>;
}
interface ObjectStore {
get(hash: string): Promise<Uint8Array | null>;
}Local implementations:
LocalBuildStore;NodeSqliteCatalogStore;NodeSqliteTableStore;FileObjectStore.
Milestone 1 ships five routes only:
- Overview - active build, source counts, warnings, capabilities, dirty state, and the next plan summary.
- Sources - artifact tree, normalized structure, status, authority, supersession, and provenance.
- Context Playground - task, profile, budget, lexical ranking, selected items, and omissions.
- Versions - build history, diff, activate, pack, and rollback.
- Diagnostics - parser, watcher, SQLite/FTS5, path, and environment checks.
Milestone 2 adds Tables when structured data exists and an Integrations view for client status. Search remains a tab within Context Playground; Plan remains a panel rather than a separate application area. This keeps the first frontend an inspector, not a second product surface.
- no chat interface;
- no source editing;
- no model-generated answer as the central experience;
- no deployment credential display;
- all build-changing actions show a plan and confirmation;
- keyboard-accessible and readable on a laptop-sized viewport.
Define narrow interfaces for:
ArtifactParser;BuildStore;ActiveBuildProvider;CatalogStore;TableStore;ObjectStore;SemanticIndex;DeploymentTarget;ClientConnector;LoreRuntime.
Built-in adapters are imported explicitly. A dynamic plugin system would add:
- arbitrary-code trust concerns;
- compatibility negotiation;
- package-resolution differences across operating systems;
- complex support and debugging;
- premature public API commitments.
Add external plugins only after two or more real third-party adapter needs reveal a stable contract.
interface DeploymentTarget {
id: string;
detect(): Promise<TargetDetection>;
capabilities(): Promise<TargetCapabilities>;
plan(input: DeployInput): Promise<DeployPlan>;
apply(plan: DeployPlan): Promise<DeployReceipt>;
verify(receipt: DeployReceipt): Promise<VerificationResult>;
activate(receipt: DeployReceipt): Promise<ActivationReceipt>;
rollback(buildId: BuildId): Promise<ActivationReceipt>;
}Target rules:
planis read-only and reports build capabilities, target capabilities, and any loss;- capability loss fails by default and requires a named
--allow-capability-loss <capability>override; applywrites only build-scoped candidate data;verifymust query the candidate explicitly;activateperforms the smallest possible pointer mutation;- deployment receipts are resumable and serializable;
- targets cannot change canonical build contents.
Possible sibling packages:
- Docker + filesystem/SQLite;
- PostgreSQL + object storage;
- AWS Lambda/ECS + S3;
- Kubernetes;
- Vercel or another edge runtime.
These are not v0.1 deliverables.
The public package schema uses JSON Schema and explicit formatVersion. TypeScript types are generated from or checked against the schema, not treated as the only specification.
Cloudflare is the first remote projection, not a dependency of local use and not the source of truth.
Default lexical deployment:
| Service | Role |
|---|---|
| Worker | Hono REST runtime, Streamable HTTP MCP, and optional Studio assets. |
| D1 | Build metadata, chunks, FTS5 lexical index, typed tables, and active pointer. |
| R2 | .lorepack archive and content-addressed normalized objects. |
D1 supports SQLite semantics and the FTS5 extension, allowing the lexical path to remain consistent without requiring Vectorize; R2 stores the immutable archive and normalized objects.[16][21][24]
Post-v0.1 semantic extension:
| Service | Role |
|---|---|
| Vectorize | Candidate semantic vectors stored under a build-scoped namespace after embedding compatibility has been proven. |
The v0.1 Cloudflare target advertises lexical-search, structured-context, and table-query only. It rejects a semantic-capable build by default rather than silently dropping that capability. A future Vectorize adapter may be enabled only when the target can generate query embeddings matching the build's complete EmbeddingProfile. Matching dimensions is insufficient. The target must pass fixed-string compatibility fixtures within a documented cosine tolerance before projection is allowed. Current Vectorize limits are ample for Lorepack's bounded projects, but do not remove this compatibility requirement.[22]
Do not require:
- Durable Objects;
- Queues;
- Workflows;
- Workers AI;
- AI Gateway.
The July 2026 Streamable HTTP direction supports stateless remote MCP requests, so protocol session state does not justify a Durable Object in the initial target.[20]
These services may become useful for a hosted control plane or server-side source synchronization later.
Lore build
manifest + archive + objects -> R2
artifacts + chunks + FTS5 + tables -> D1
future compatible vectors -> Vectorize build namespace
active_build_id + generation -> D1 project record
Every row, object reference, and vector is namespaced by:
project_id + build_id
Do not upload the local SQLite file as the remote database.
The adapter reads the canonical build and writes backend-specific batches:
- D1 schema migrations are target-owned;
- chunk and metadata inserts are batched;
- FTS5 rows are generated from canonical chunks;
- table schemas and rows are created with validated names;
- R2 writes use content hashes and skip existing objects;
- future Vectorize writes use build-scoped namespaces and large batches; verification polls a deterministic candidate query/sample until all expected records are visible or a deadline expires.[27]
D1 export has limitations around virtual tables, which is another reason to treat D1 as a projection rather than the canonical archive.[23]
- Ensure target resources and schema.
- Create candidate build record.
- Upload archive and objects to R2.
- Insert D1 artifacts, chunks, FTS rows, and tables under the build ID.
- For a future compatible semantic projection, insert vectors into a build-scoped namespace and wait for query visibility; timeout leaves the candidate inactive.[27]
- Run candidate-scoped smoke searches, source reads, and table queries.
- Record verification result and the exact runtime capability set.
- Change
active_build_idand its monotonic generation in one D1 transaction. - Run a public-endpoint health query and confirm the returned build ID.
- Write a local deployment receipt.
Partially uploaded candidates are invisible because the Worker reads only the active build.
One-time setup:
lore target add cloudflareExpected behavior:
- use the pinned Wrangler dependency from the adapter;
- check or initiate Wrangler authentication;
- show resources that will be created;
- allow connection to existing resources;
- write non-secret resource identifiers under
.lore/targets/cloudflare.json; - store secrets through Wrangler/Cloudflare mechanisms, not in
lore.yaml; - perform a target capability check.
Deploy:
lore deploy cloudflareExample plan:
Target: cloudflare / personal
Build: lore_b7f2a9c1d4e8
Resources
= Worker lore-sarjbot
= D1 lore-sarjbot
= R2 lore-sarjbot
- Vectorize unavailable in v0.1 target (no capability loss for this lexical build)
Projection
+ 2 artifacts
~ 1 artifact
= 181 artifacts reused by content hash
+ 27 chunks
+ 122 table rows
Activation
current lore_61c30ef2a7b4
next lore_b7f2a9c1d4e8
Personal MVP modes:
- generated bearer token with stored hash;
- optional Cloudflare Access in front of the Worker.
The public runtime exposes only read-only context routes. Deployment and activation occur through the CLI using scoped Cloudflare credentials, never through model-facing MCP tools.
OAuth and team authorization belong to a future managed platform.
lore rollback --target cloudflare lore_61c30ef2a7b4Rollback validates that the build remains complete, changes the pointer, and performs a health query.
Default retention:
- keep the active build;
- keep the previous five verified builds;
- never delete content-addressed objects still referenced by a retained build;
- show a cleanup plan before deletion.
plan is side-effect free and compares:
- configured sources versus active build;
- content hashes;
- parser/lock changes;
- authority/status/supersession changes;
- table schemas and row counts;
- capabilities;
- target resources and active remote build.
It returns a machine-readable plan with --json for CI.
same normalized path
+ same content hash
+ same parser version
+ same relevant config/rules
-> reuse cached parsed output
otherwise
-> rebuild artifact projections
Deletion removes content only from the new build. Previous builds remain immutable.
Build lore_61c30ef2a7b4 -> lore_b7f2a9c1d4e8
Artifacts
+ research/customer-interviews-july.md
~ requirements/v2.docx
- none
Rules
~ requirements/v2.docx authority 80 -> 100
+ requirements/v2.docx supersedes requirements/v1.docx
Context
+ 41 chunks
~ 14 chunks
- 9 chunks
Tables
~ pricing.xlsx / operator_prices
rows 1,982 -> 2,104
columns + membership_price
Capabilities
= lexical-search
= structured-context
= table-query
Local activation:
- build the candidate in a new directory;
- validate and fsync critical files;
- update
active_build_idand a monotonicactive_generationin.lore/state.sqlitein one transaction; - let each runtime switch at the next request boundary through
ActiveBuildProvider; - retain the previous build and any handle still serving an in-flight request.
An in-flight request is allowed to finish on the old immutable build; a later request must observe the new generation. No response may mix builds. Remote activation uses the target's smallest atomic pointer operation and returns the activated build ID from the public endpoint before the deployment is considered complete.
lore deploy target performs:
status -> plan -> build if dirty -> project candidate -> verify -> activate -> smoke check -> receipt
Flags:
lore deploy cloudflare --dry-run
lore deploy cloudflare --no-build
lore deploy cloudflare --yes
lore deploy cloudflare --resume <receipt-id>{
"target": "cloudflare",
"project": "sarjbot",
"buildId": "lore_b7f2a9c1d4e8",
"previousBuildId": "lore_61c30ef2a7b4",
"state": "active",
"deployedAt": "2026-07-30T20:00:00Z",
"endpoint": "https://context.example.com/mcp",
"verification": {
"search": "passed",
"sourceRead": "passed",
"tableQuery": "passed"
}
}Without arguments, roll back to the previous verified build:
lore rollbackExplicit:
lore rollback lore_61c30ef2a7b4
lore rollback --target cloudflare lore_61c30ef2a7b4Rollback never rebuilds. If the requested remote projection is incomplete, fail without changing activation.
steps:
- run: pnpm install --frozen-lockfile
- run: lore doctor --ci
- run: lore plan --json > lore-plan.json
- run: lore build --frozen
- run: lore test
- run: lore deploy cloudflare --yes --no-buildCI artifacts should include the plan, manifest, warnings, test results, and .lorepack archive.
- no account required;
- no telemetry by default;
- no source content leaves the machine;
- no model or network call in the core build path;
- remote adapters require explicit target setup;
- Studio and HTTP bind to localhost by default.
If telemetry is ever added, it must be opt-in, content-free, documented, and independently disableable.
Default exclusions:
.git/
node_modules/
.lore/
.env*
*.pem
*.key
id_rsa*
*.p12
*.pfx
.DS_Store
Thumbs.db
The init/plan flow warns about probable secret-shaped files before inclusion. This is a guardrail, not a claim to be a full secret scanner.
- resolve and verify every source path under its configured root;
- do not follow symlinks by default;
- do not parse archive containers in v0.1;
- cap individual artifact size;
- use temporary files and atomic rename for build outputs;
- normalize IDs independently of OS separators;
- never write into source directories except generated project config at the chosen root.
- every model-facing tool is read-only;
- no build, deploy, source edit, or shell execution tool;
- local HTTP validates Origin and binds to loopback;
- request size and response budget limits;
- remote HTTP requires authentication;
- logs avoid source bodies by default;
- protocol errors never print secrets.
- parse and validate exactly one
SELECTorWITH ... SELECTbefore preparation; - open
DatabaseSyncwithreadOnly: true,defensive: true,allowExtension: false, and boundedlimitsfor statement length, columns, expression depth, compound selects, VDBE operations, attached databases, variables, and pattern length; - install
setAuthorizer()to allow reads only from the catalog-approved tables and to deny writes, schema changes,ATTACH,PRAGMA, and extension operations at the SQLite engine boundary; these controls are available in the supported Node 24 line.[7] - execute user-authored table SQL in a dedicated worker-thread executor so a hard deadline can terminate and replace the worker without blocking MCP/HTTP traffic;
- inject a default row limit, and enforce row, serialized-byte, and wall-clock ceilings;
- return table, sheet/range, and build provenance with every result;
- require equivalent deny-by-default enforcement from every remote adapter. The D1 adapter uses the same SQL AST allowlist, exposes no deployment/admin binding to model-facing routes, and does not advertise
table-queryif it cannot meet the contract.
- least-privilege API token for provision/deploy;
- runtime bearer token separate from deployment credential;
- hashed runtime token storage;
- build/project namespace on every query;
- no administrative route in the public Worker;
- candidate data inaccessible until activation.
- lock dependencies;
- publish npm provenance where supported;
- generate SBOMs for releases;
- run dependency and license checks;
- avoid post-install scripts in core packages;
- document every optional native dependency separately.
Every release candidate installs and runs on:
- macOS 14+;
- Windows 11 x64;
- Ubuntu 22.04+ x64;
>=24.15 <25(Node 24 LTS).
The test image intentionally lacks Python and native compiler tools.
For every format, store:
- source fixture;
- expected artifact metadata;
- expected node tree;
- expected table schema/data sample;
- expected locators;
- expected warnings;
- canonical hash.
Include malformed and edge-case fixtures, not only happy paths.
Build the same project:
- twice on one machine;
- on Windows and POSIX;
- in different absolute workspace paths;
- with different file enumeration order.
The full build ID, canonical manifest, and logical hash roots must match. Package checksums must validate each produced archive, but physical context.sqlite bytes are not required to match across operating systems or SQLite patch revisions. Operational build receipts are expected to differ.
Test:
- drive letters and UNC-like rejection rules;
- backslash/native display versus POSIX canonical IDs;
- case-only filename collisions;
- long paths within supported OS settings;
- atomic editor saves;
- rename/delete/recreate sequences;
- PowerShell quoting in generated client commands.
- events during initial scan;
- duplicate events;
- chunked large-file writes;
- atomic rename saves;
- rapid add/edit/delete;
- watcher restart and reconciliation;
- no-op hash changes;
- Ctrl-C during rebuild.
Run the same suite against:
- local catalog/table/object/build stores;
ActiveBuildProvider, including an in-flight old-build request and a next-request new-build switch;- Cloudflare integration environment where credentials are available;
- future adapters.
A future semantic target additionally runs fixed-string embedding-profile compatibility tests and delayed-write visibility tests before it can advertise semantic-search.
Each fixture declares:
- task/query;
- required source IDs;
- forbidden superseded sources by default;
- acceptable alternatives;
- maximum estimated budget;
- provenance expectations;
- omission expectations.
Track lexical ranking regressions without claiming general answer quality.
For each supported client:
- detect installed/not installed;
- generate project-scoped config;
- merge without deleting unrelated entries;
- dry-run output;
- backup and restore;
- disconnect only Lorepack-owned entry;
server/discover/tools/listverification against a fixture server, plus a backward-compatibility fixture;- unsupported client version fallback to copyable snippet.
- path traversal;
- symlink escape;
- malformed PDFs and Office files;
- SQL injection and multi-statement attempts;
- oversized requests/responses;
- localhost Origin validation;
- auth bypass;
- secret exclusion from manifest/logs;
- malicious config values.
Version benchmark data and reference-machine details. Gate releases on the scale envelope in section 5, but do not optimize beyond measured bottlenecks.
A clean environment must pass:
npm install -g @lorepack/cli
lore dev ./fixtures/product-research
lore connect <fixture-client>
lore export --task "Summarize the launch decision"
# edit one source
lore plan
lore build
lore diff
lore rollbackA Cloudflare integration environment additionally passes deploy, remote MCP search, and remote rollback.
Deliver:
- Markdown/plain-text source;
- discovery and hashing;
- minimal canonical model;
- deterministic SQLite build;
- FTS5 search;
- immutable build ID;
- active pointer;
init,plan,build,search,diff, androllback.
Exit criterion: editing one file creates a new immutable version, shows a correct diff, and rolls back without re-indexing.
This milestone proves the differentiator before broad parser work.
Add:
lore dev ./folderauto-init path;- watch/reconciliation flow;
- MCP stdio with
--ensure-current; - REST and local Streamable HTTP;
lore_context_for_task;- bounded export with 24k chat default and complete omissions;
- minimal five-route Studio: overview, sources, context playground, versions, diagnostics;
lore connect claude-codeplus a safe generic snippet path;- plan/dry-run, non-global scope, server verification, and disconnect;
- live activation so connected clients use the new build on their next request without reconnecting;
lore doctor;- macOS/Windows/Linux clean-install CI.
Exit criterion: on a clean supported machine, a new user runs lore dev ./folder and lore connect claude-code, approves the client trust prompt, and receives grounded context without an account, model download, Python, Docker, native compilation, manual JSON, or stale-build ambiguity.
Add:
- HTML;
- text PDF;
- DOCX;
- CSV;
- XLSX;
- typed table catalog and safe SQL;
- authority/status/supersedes rules;
- parser warnings and inspection;
lore connect codexandlore connect vscode;- path/watcher/client fixtures across supported platforms;
- scale-envelope benchmarks.
Exit criterion: the user's real mixed project folder produces useful bounded context with reliable provenance and spreadsheet queries, and all three supported clients connect without hand-editing configuration.
Add:
- target setup;
- Worker/Hono runtime;
- D1 schema and FTS5 projection;
- R2 archive/objects;
- candidate verification;
- atomic activation;
- remote auth;
- deployment receipts and rollback.
Exit criterion: one command deploys the exact local build remotely, and rollback changes only the active pointer.
Add:
- package-format specification;
- contributor and architecture docs;
- examples;
- npm provenance/SBOM;
- release automation;
- security policy;
- compatibility matrix;
- performance report;
- stable v0.1 release.
- optional semantic-local package with the bounded download/scan contract in section 5.6;
- semantic deployment only after exact
EmbeddingProfilecompatibility and asynchronous query-visibility gates; - Docker/PostgreSQL backends;
- SaaS source connectors;
- hosted registry/control plane;
- team permissions and OAuth;
- OCR/visual artifact parsing.
Open source:
- CLI and DX flows;
- compiler and deterministic IR;
- package/build specification;
- built-in parsers;
- local backend and runtime;
- plan, diff, activation, and rollback;
- MCP, REST, export, and SDK;
- Studio;
- client connectors;
- Cloudflare deployment adapter;
- tests and benchmarks;
- optional semantic adapter when created.
Apache-2.0 is recommended for permissive adoption and an explicit patent grant.
A paid service can provide:
- managed build registry;
- hosted deployment and domain management;
- continuous source connectors;
- server-side compilation;
- team projects;
- source permission synchronization;
- OAuth/SSO;
- audit logs;
- build and retrieval analytics;
- policy and retention controls;
- private networking;
- support and SLAs.
The commercial value is operations, governance, and collaboration. Local users should not need the hosted product to retain access to their builds or protocol interfaces.
The open package format and local runtime prevent lock-in. A hosted platform may store and project builds, but users can always export a .lorepack and run it locally or through another adapter.
| Decision | Choice | Rationale |
|---|---|---|
| Product wedge | Versioned context lifecycle | Local MCP retrieval is crowded; build/plan/deploy/rollback is the defensible layer. |
| Working codename | Lorepack | Conveys accumulated knowledge packaged as a portable artifact. |
| Main language | TypeScript | One stack across CLI, compiler, MCP, edge runtime, SDK, and UI. |
| Node baseline | 24.15+ LTS | Current LTS and bundled node:sqlite release-candidate API.[6][7] |
| Local binding | node:sqlite |
Avoid native npm add-on installation failures; isolate RC API behind a port. |
| Local lexical search | SQLite FTS5 | Mature deterministic retrieval and supported by both local SQLite and D1.[8][16] |
| Semantic default | Disabled/not installed | Preserves zero-network, zero-native-dependency first run. |
| Table model | Typed SQLite tables | Keeps structured data queryable and provenance-aware. |
| Build command | One lore build |
Hide compile/index/package stages without hiding inspectability. |
| Canonical state | Immutable Lore build identified by logical hashes | Enables reproducibility without coupling identity to SQLite page layout. |
| Runtime switching | Request-scoped active-build handles | Connected clients see activation or rollback on the next request without mixed-build responses. |
| Archive | Inspectable .lorepack ZIP |
Portable, standard, and non-proprietary. |
| Primary AI protocol | MCP | Standard model-facing tools/resources; stdio and HTTP support.[1][2] |
| Universal fallback | Bounded Markdown/JSON export | Works with clients that cannot connect to MCP. |
| Client setup | Safe lore connect adapters |
Maps a conceptual workspace scope per client, removes manual config, and avoids silent global mutations. |
| Cloudflare stack | Worker + D1 + R2 for v0.1 | Minimal lexical remote projection; Vectorize is post-v0.1 and requires exact query-embedding compatibility plus visibility verification. |
| Plugin model | Typed ports, no dynamic loader | Extensible without premature security and compatibility complexity. |
| License | Apache-2.0 | Broad adoption and patent grant. |
Risk: Users compare Lorepack only on parser count or semantic retrieval quality.
Mitigation: lead the README, website, demo, and milestones with plan/build/diff/deploy/rollback. Retrieval is described as a runtime capability, not the category.
Risk: Default retrieval is less forgiving than embeddings.
Mitigation: strong path/title/heading weighting, task-oriented queries, hierarchy expansion, explicit filters, transparent omissions, and a later opt-in semantic adapter. Do not sacrifice first-run reliability before validating the lifecycle wedge.
Risk: API behavior or performance may change.
Mitigation: pin Node LTS, use a narrow API subset, isolate behind ports, contract-test, and retain a replacement path. This trade-off avoids the confirmed installation fragility of native add-ons.[7][19]
Risk: PDFs and spreadsheets can be irregular.
Mitigation: conservative v0.1 formats, visible warnings, source inspection, golden fixtures, and build failure for unsupported-loss cases. Do not claim OCR or visual-layout support.
Risk: duplicate, missed, or partial-write events create stale builds.
Mitigation: reconciliation scan, stable-write wait, content hashing, duplicate no-ops, periodic optional rescan, and cross-platform tests.
Risk: authority is treated as factual certainty.
Mitigation: label it as a user-declared ranking hint everywhere; never automatically claim conflict resolution.
Risk: A broad query floods the model.
Mitigation: strict profiles, budget reserve, diversity, omissions, alternative sources, and a default 24k chat export rather than dumping the corpus.
Risk: lore connect breaks or corrupts configuration.
Mitigation: prefer official CLIs, non-global workspace mapping, plan/dry run, schema fixtures, atomic merge, backups, version detection, and snippet fallback.
Risk: protocol revisions affect transports or schemas.
Mitigation: isolate MCP, pin official SDK, run compatibility tests, and keep REST/runtime contracts independent.[1][2]
Risk: D1, R2, or a future Vectorize namespace contains partial candidate data.
Mitigation: build namespace, resumable receipt, candidate verification, active pointer, and retention cleanup only after activation. Future vector candidates must also become query-visible before activation.[27]
Risk: activation changes a pointer but a long-lived runtime continues using its existing SQLite handle.
Mitigation: request-scoped BuildHandle acquisition keyed by a monotonic generation; old handles drain, and the next request observes the new build without reconnecting.
Risk: local corpus vectors and remote query vectors share dimensions but not an embedding space, producing plausible but invalid retrieval.
Mitigation: record the complete embedding profile, reject mismatches, run fixed compatibility fixtures, and make capability loss explicit. Cloudflare v0.1 remains lexical-only.
Risk: connectors, chat, memory, agents, and enterprise permissions delay the wedge.
Mitigation: every v0.1 feature must improve one of four promises: build, inspect, connect, or deploy durable context.
- pnpm workspace and package boundaries.
engines.nodeguard for>=24.15 <25.- JSON Schemas for config, lockfile, manifest, plan, receipt, and runtime requests.
node:sqlitecapability probe and migrations.- canonical POSIX path/ID utilities.
- content-addressed object store.
- atomic build-directory helpers, canonical logical hash roots, and transactional ID/generation activation.
lore init.- discovery and
.loreignore. - fingerprint/cache.
- Markdown/plain-text parser.
- deterministic nodes/chunks.
- FTS5 index.
- build validator, canonical roots, and full SHA-256 ID.
plan,build,status,diff,activate,rollback.
LoreRuntimeinterface.- lexical ranking and filters.
- context profiles and budget accounting.
- source read.
- build description.
- Hono routes.
- progress renderer.
- actionable error taxonomy.
doctorandconfig show --effective.- watch/reconciliation flow.
- local dev supervisor.
- clean cancellation.
- Windows command/path handling.
- MCP stdio with
--ensure-current,--active-only, and explicit stale recovery. - MCP Streamable HTTP.
- small MCP tool surface.
- REST SDK.
- Markdown/JSON export and omission report.
- overview with plan summary.
- sources.
- context playground with search/debug tab.
- versions.
- diagnostics.
- later milestone: tables and integrations views.
- HTML.
- PDF text.
- DOCX.
- CSV.
- XLSX.
- typed table catalog/import.
- constrained query validator.
- status/authority/supersedes resolution.
- cycle and missing-target validation.
- ranking and bundle behavior.
- rule inspection in CLI/Studio.
- connector port.
- Claude Code adapter.
- Codex adapter.
- VS Code adapter.
- generic snippet renderer.
- dry run, client-specific workspace mapping, backup, protocol/client verify, and disconnect.
- target detection/setup.
- Worker/Hono runtime.
- D1 migrations and FTS5 projection.
- R2 archive/object upload.
- candidate-scoped verification.
- active pointer/generation, request-scoped hot switching, and target capability planning.
- auth token setup.
- remote rollback and retention.
- cross-platform clean-install CI.
- parser/path/watcher fixtures.
- performance benchmarks.
- SBOM/provenance.
- package-format docs.
- examples and README demo.
Lorepack v0.1 succeeds when a technical user can:
- install it without Python, Docker, a compiler toolchain, or a model download;
- run
lore dev ./artifactsand receive a verified active build; - inspect exactly what was parsed and what was excluded;
- connect Claude Code, Codex, or VS Code through one safe command with no global mutation by default;
- let an agent launch against a source-checked active build and retrieve task-specific context without scanning every artifact;
- create a 24k-budget context export for a web chat;
- query CSV/XLSX-derived tables without flattening them into prose;
- trace every result to a document section, page, sheet, cell range, or line range;
- declare an active source, archive old material, and mark supersession deterministically;
- edit/add/delete artifacts and rebuild only affected outputs;
- see a human-readable plan and build diff;
- activate and roll back locally without recompilation;
- deploy the exact build to Cloudflare through one command;
- verify and activate the remote candidate atomically;
- use the full local workflow without an account or hosted service;
- obtain the same build ID on supported operating systems from the same canonical inputs.
The product has not succeeded merely because it can answer questions over PDFs. It succeeds when context behaves like reliable infrastructure.
The first public demo should make the wedge obvious in under three minutes.
lore dev ./project-context
lore connect claude-codeShow:
- no model/API setup;
- active build ID;
- Studio source inspection;
- client launch verifies freshness and the agent retrieves bounded context.
Edit a requirement and add one CSV row:
lore plan
lore build
lore diffShow:
- unchanged work reused;
- exact document/table changes;
- new immutable ID;
- active version switch.
lore rollbackShow immediate return to the previous build without parsing or indexing.
lore deploy cloudflareShow:
- resource/build plan;
- candidate verification;
- atomic activation;
- remote MCP endpoint using the same build ID.
Stop re-uploading your project to AI. Build it once, version every change, and let any agent fetch the right context on demand.
Secondary line:
Local-first and open source. MCP, HTTP, and chat-ready exports. Deploy the same immutable build locally or to Cloudflare.
Proceed with Lorepack, but build it as a versioned context build system, not as a local RAG product.
The simple user journey is:
lore dev ./artifacts
lore connect claude-codeThe durable engineering model is:
artifacts
-> deterministic compiler
-> immutable Lore build
-> plan / diff / validate
-> local activation or backend projection
-> MCP / HTTP / export
-> atomic rollback
The most important MVP discipline is what the design does not require:
- no default embeddings;
- no remote semantic assumption in v0.1;
- no native npm add-on;
- no Python sidecar;
- no Docker;
- no hosted account;
- no dynamic plugin framework;
- no chat UI;
- no connector catalog;
- no automatic truth claims.
The product should feel magical because the runtime starts in one command, client connection is a second safe command, updates are incremental, and deployment is atomic. It should remain trustworthy because every default is inspectable, every result has provenance, every mutation has a plan, and every active version can be rolled back.
- Model Context Protocol specification, transports (2026-07-28): https://modelcontextprotocol.io/specification/2026-07-28/basic/transports
- Official Model Context Protocol TypeScript SDK v2: https://github.com/modelcontextprotocol/typescript-sdk
- Claude Code MCP configuration and scopes: https://code.claude.com/docs/en/mcp
- OpenAI Codex and ChatGPT desktop MCP configuration: https://developers.openai.com/codex/mcp
- Visual Studio Code MCP server configuration: https://code.visualstudio.com/docs/agent-customization/mcp-servers
- Node.js release schedule and Node 24 LTS status: https://nodejs.org/en/about/previous-releases
- Node.js
node:sqliteAPI and release-candidate status: https://nodejs.org/docs/latest-v24.x/api/sqlite.html - SQLite FTS5 documentation: https://www.sqlite.org/fts5.html
- Chokidar cross-platform file watching: https://github.com/paulmillr/chokidar
- pnpm workspaces: https://pnpm.io/workspaces
- Vitest guide: https://vitest.dev/guide/
- Knowledge RAG, local hybrid MCP document server: https://github.com/lyonzin/knowledge-rag
- kb-mcp, local hybrid document MCP server with watch mode: https://github.com/alphabet-h/kb-mcp
- kb, local multi-format hybrid search and MCP tool: https://github.com/ariel-frischer/kb
- Hono documentation: https://hono.dev/docs/
- Cloudflare D1 supported SQL extensions including FTS5: https://developers.cloudflare.com/d1/sql-api/sql-statements/
- Transformers.js model download progress and local-files-only controls: https://huggingface.co/docs/transformers.js/api/utils/hub
- ONNX Runtime Node binding and prebuilt platform support: https://onnxruntime.ai/docs/get-started/with-javascript/node.html
- Example
better-sqlite3Node 24 prebuild gap: WiseLibs/better-sqlite3#1384 - Cloudflare MCP servers and July 2026 stateless Streamable HTTP support: https://developers.cloudflare.com/agents/model-context-protocol/cloudflare/servers-for-cloudflare/
- Cloudflare D1 overview: https://developers.cloudflare.com/d1/
- Cloudflare Vectorize limits: https://developers.cloudflare.com/vectorize/platform/limits/
- Cloudflare D1 import/export limitations for FTS5 virtual tables: https://developers.cloudflare.com/d1/best-practices/import-export-data/
- Cloudflare R2 overview: https://developers.cloudflare.com/r2/
- Cloudflare D1 platform limits: https://developers.cloudflare.com/d1/platform/limits/
- MCP 2026-07-28 key changes and backward compatibility: https://modelcontextprotocol.io/specification/2026-07-28/changelog
- Cloudflare Vectorize batching and asynchronous query visibility: https://developers.cloudflare.com/vectorize/best-practices/insert-vectors/