Release notes for Lore CLI and public documentation.
lore ingest gains --replaces <id> --reason "<why>" — the by-id correction primitive, previously reachable only over MCP. Closes a write-surface CLI/MCP parity gap (sibling to the May 16 read-surface sweep): an agent correcting a source while its MCP connection was down had to drive lore mcp over raw stdio JSON-RPC because no CLI command could.
lore ingest --replaces <id> --reason "…" supersedes a source with new content, creating a v2 in its version chain while v1 stays immutable — auditable, with citations resolving through the chain root. <id> is a full source id or an unambiguous 8+ char prefix. Content comes from the positional arg, --file, or stdin.--tags / --project / --workstream with --replaces is a clear error rather than a silent no-op. --title / --type / --url / --name remain optional overrides.ingest tool uses for replaces + reason, so behavior is identical: identical content short-circuits as a no-op; a stale parent prints the current chain head and a ready-to-run retry. In-place action: update stays MCP-only — versioned replace is the correction primitive on the CLI.Cut 2 from the post-smoke-test fix plan. Four CLI/MCP parity gaps closed; each was a place where the same data surfaced differently — or not at all — depending on which API consumed it.
Workstream: — lore docs create (no --project) was dropping the auto-router's workstream proposal from its banner even though the LLM's reasoning mentioned it. The CLI now prints a Workstream: <slug> (<confidence>) row when the proposal includes one, matching what MCP ingest has always returned in routing_decision.workstream.ingest response: top-level visibility + workstream — visibility was only emitted in the response when it resolved to 'personal'; agents auditing whether a write went team-public had no positive signal. Now always present ('workspace' or 'personal'). When a workstream resolved (explicit --workstream arg or high-confidence auto-route), the response also carries the resolved workstream slug at top level — no need to scrape routing_decision.get_source returns routing_metadata + workstream slug — the DB had both; the response shape omitted them. Agents calling get_source couldn't see what the auto-router decided at ingest, or what scope the source actually sits in. Both fields are now part of the response when present.get_entity accepts name — pre-cut, only entity_id (UUID) worked; passing name surfaced as "Entity not found: undefined" (a missing-row error masking a schema mismatch). The schema now accepts entity_id OR name (workspace-scoped, case-insensitive); entity_id wins when both are passed; non-UUID entity_id returns a clear validation error pointing at name; clean miss when the name resolves to nothing.audience='shared' with high confidence. The classifier prompt now treats ambiguous as a first-class verdict for mixed-intent content (explicit "half X, half Y" markers, sources that braid private observation with team-substrate analysis), not as a verdict-failure last resort. As a safety net, the personal-review queue gains a third class — low-confidence-shared — surfacing workspace-visibility sources stamped audience='shared' with project-confidence 'low'. New CLI verb: c = confirm shared (accept verdict, stay workspace-visible). Flipping to personal is intentionally not a queue verb (un-publishing a workspace source the team may have already read is too consequential for a one-keystroke action); use lore docs reclassify if a flip is genuinely warranted.Cut 1A from the post-smoke-test fix plan: restricted agents (home workstream + grants) couldn't trigger project-brief auto-updates as a side-effect of their authorized source writes. The workstream brief moved v_n→v_n+1 cleanly; the project brief regen was RLS-refused and silently swallowed. Only a future "stale" chip surfaced the drift.
20261101_cascade_brief_regen.sql adds _lore_cascade_project_brief_regen (project-scope INSERT) and _lore_mark_brief_upstream_stale (cascade stale-mark UPDATE). Both re-validate the caller's source-write authority on the workstream that triggered the cascade, then bypass RLS for the higher-scope write. A new agent with no workstream authority anywhere in the project still cannot trigger a cascade — the authority chain is enforced inside the RPC body.lore brief generate stays RLS-gated — explicit user intent still flows through the direct INSERT, so step-8 authority isolation holds for callers who explicitly opt into a project-scope write.lore doctor check cascade_stale_rls_refused — surfaces project briefs whose source count has fallen behind their project by ≥3, catching pre-fix residue and any future regression in the cascade path.VISION.md principle 4 ("higher-scope briefs synthesize lower briefs, not raw sources") no longer silently degrades when agents are the primary ingest source.
Closes the context-capture maturity track. The ambient corpus (terminal/observed-session scroll — corpus_class='ambient') now has a full management surface alongside the read-only show/hide toggle.
lore ambient stats — workspace-scoped volume report. Grouped counts by app_bundle_id, by capture_method, by month; total + total size + date range; pre-2026-05-15 unattributed slice surfaced separately so you know what the bucket totals exclude. --json for machines.lore docs reclassify <id> --to signal|ambient — flip one source's capability profile between browsable (feeds briefs) and chunks-only (hidden from default browse). Human-only — agents are refused at the §4 write gate. Each reclassification writes an org_ops_log row (op_kind='source-reclassified') so the audit trail explains why a source quietly stopped surfacing.lore docs gc-ambient --older-than <duration> — retention sweep. Mirrors lore docs gc's dry-run preview pattern. --app <bundle_id> / --capture-method <kind> for targeted cleanup. The safety check refuses any source whose chunks are cited in a current workspace brief, regardless of age. Soft-delete only — on-disk content stays put; lore docs restore recovers.list_sources gains a corpus_class filter so agents can audit ambient hygiene without shelling out. Reclassify and gc-ambient stay CLI-only — binding write paths under the human gate.[ambient] chip when the source has corpus_class='ambient' (dim gray, mirrors the private badge pattern). Landing view gains an optional 4th header line — Ambient: N sources · X MB · Ctrl-A toggle · \lore ambient stats`` — rendered only when the ambient corpus is non-empty, so the headline volume is visible at workspace-glance.Migration 20261027_source_reclassified_op_kind.sql widens the org_ops_log.op_kind CHECK with 'source-reclassified' — additive + idempotent.
Producer-stamped capture origin is now a first-class queryable axis on every source row. The lore-context-capture daemon already emitted capture_method / app_bundle_id / app_name in frontmatter; Lore parsed them as auto-router classification hints and then discarded them. They now persist on sources as an attribute-plane axis — distinct from scope (where a source lives) and tags (cross-cutting topics).
lore docs list --app com.tinyspeck.slackmacgap shows every Slack-captured source. lore docs list --capture-method browser_gmail filters by the producer rule. The same filters compose into MCP list_sources and search for agents (app_bundle_id / capture_method args).app_name was stamped) gray chip alongside the actor, entity, and procedure chips.get_source returns the trio — capture_method, app_bundle_id, app_name are now part of the response shape.ingest accepts the trio — sync stamps them automatically from frontmatter; agents ingesting via MCP can stamp them when they know the value (most agent ingests will leave them null — they aren't observation-time captures).Unblocks ambient-source management (filter within ambient by capture origin), context-routing follow-ups (use bundle id as a routing prior), and personal-layer enrichment ("where do my captures come from").
Lore now has a first-class procedural memory primitive — procedures — for the "how this team acts" layer (release cadences, onboarding playbooks, review checklists). Distinct from briefs, which describe what's true; procedures prescribe action.
get_brief_stack's composed prompt, so agents read procedures as constraints alongside the descriptive brief content at every scope.proposed → confirmed → superseded / archived. Authorship is mixed: humans author directly via lore procedures create; agents (and humans) propose via lore procedures propose / MCP propose_procedure. The §4 write gate makes confirm_procedure / supersede_procedure / archive_procedure human-only by design — agents propose, humans ratchet.lore procedures CLI — list, show, history, create, propose, confirm, supersede, dismiss, archive with --scope workspace|project:<slug>|workstream:<project>/<workstream>.list_procedures, get_procedure, propose_procedure, confirm_procedure, supersede_procedure, dismiss_procedure). get_brief_stack folds confirmed procedures into the composed prompt at each scope.r filter that surfaces only proposed rows for human review. Procedure chips render on source detail when a procedure cites a source.Alongside the primitive, the three-deposit-kind convention is now named explicitly across .claude/rules/lore.md and every plugin manifest: narration via log, artifact via ingest, how-to-proposal via propose_procedure. The whoami tool surfaces last_deposit_at — a per-actor timestamp of the most recent deposit across all three kinds — as a soft "have I deposited yet this session?" signal.
Lore now resolves the people, companies, products, and deals named in your content. A new thin registry (the bridge layer between sources and the structured world) gets stamped automatically at ingest with a conservative under-merge bias.
claude-haiku-4-5, ~$0.0014/source) and matched against the workspace registry. High-confidence matches attach existing entities; ambiguous matches surface candidates instead of guessing; unknown names create new entries.lore search ... --entities <a,b>, lore docs list --entities ..., and MCP search / list_sources accept entity IDs or names.lore entities CLI — list, show <id|name>, merge <a,b> --into <target>, rename, archive, and backfill --project <slug> for stamping pre-registry sources (per-project, budget-capped).list_entities / get_entity — browse the registry; get_entity returns the entity plus the sources that mention it ("everything about X").Entities have no brief on purpose — they're a bridge to specialist tools (CRM, address book) that already own that synthesis, not a CRM replica.
Lore now distinguishes who performed a write. Every source and brief is attributed to an actor — a human or a named agent.
lore agent install <name>, run a process under LORE_AGENT_TOKEN, and every write attributes to that agent.lore whoami and the whoami MCP tool report the acting identity.lore docs list --actor <name> / --kind agent, lore audit --actor <name>, the actor field on MCP get_source / list_sources, and an actor chip in the lore browse TUI.See the agent guide for the full model.
CLI vocabulary cleanup + a few small completeness items. The legacy lore corrections * namespace is gone — replaced by lore status, lore diff, and lore changes apply/discard/merge modeled on git's lifecycle. Hard cut-over, no aliases.
The mental model: .lore/sources/ is your working tree, .lore/base/ is the last fetch from canonical, Lore Cloud is origin/main.
| Old | New | git analogue |
|---|---|---|
lore corrections list | lore status | git status |
lore corrections diff <id> | lore diff <id> | git diff |
lore corrections approve | lore changes apply | git push |
lore corrections reject | lore changes discard | git restore |
lore corrections reconcile | lore changes merge | git merge |
lore status is the new "where am I, what's next" command. One unified view: workspace, attached repos, pending changes (with conflict markers), daemon state, pending push queue, and a "Suggested next" footer that adapts to state.
$ lore status
Workspace
Personal · 2 attached repos
Attached repos
/Users/me/repo-A → ridekick, gnar [3 pending]
/Users/me/repo-B → marketing [clean]
Pending changes (run `lore diff <id>` to inspect)
modified foo-a1b2 "User interview with Sarah"
conflict bar-d4e5 "Project plan v2" (run `lore changes merge`)
Daemon
Running, PID 31845, 2m uptime, v0.19.0
Last sync 30s ago · 0 errors
Pending pushes: 4 (oldest 1m ago)
Suggested next
lore diff <id> review a change
lore changes apply --all publish all clean modifications
lore changes merge <id> resolve a conflict
lore status --terse returns a one-line summary suitable for shell prompts and scripts.
The skip-embed path on byte-trivial edits (v0.18) reused stored vectors to save API calls. Safe today because everyone runs text-embedding-3-small at 1536 dims, but a model rotation would have silently degraded search.
embedding_model_version column on every embedded row, format <model>@<dim>.enqueuePush falls back to inline gitCommitAndPush so the change still lands. Slow path, no data loss. Once-per-process warning surfaces the queue health.storeSources race protection. v0.18.1's content_hash conditional UPDATE protected addSource per-row; the bulk path now does the same per-record. Two machines hitting the same row via the bulk path can no longer last-writer-win.One-time silent migration on first interaction with the changes flow: <dataDir>/context-corrections/ → <dataDir>/context-changes/. Pre-v0.19 history.json + merge backups survive intact.
Cross-machine race protection for the agents-on-many-machines world.
ingest action 'update' returns a structured conflict block on race-loss: { type: 'concurrent_write', source_id, expected_content_hash, current_content_hash, message }. Agents pattern-match on conflict.type and re-fetch + retry.lore corrections approve --all partial-progress preserved on per-item conflicts: successful items still apply; conflicts go into a failed list.Briefs no longer silently reference deleted sources, and ingest is fast at scale.
lore brief <project> shows a warning banner with up to 5 phrases (and their location in the brief) so you can see exactly where the leakage shows up before you trust the synthesis.lore brief generate <project> after a delete uses a new deletion-aware incremental path. Surgical scrub at $0.05–$0.20 instead of the $5+ full regen the previous fallback required.get_brief adds a top-level source_stale: { since, count, source_ids, suspect_phrases } field so agents incorporate the warning into their reasoning.lore docs create returns in ~2s instead of ~10s. Git push is now amortized: hot writes enqueue into a pending log; the daemon flushes accumulated changes into a single commit/push every 30s.lore corrections approve --all over many items completes in seconds instead of minutes — single lock acquisition, single manifest write, single git push.lore sync status line: Pending pushes: N (oldest 2m ago) so you can see the daemon's queue at a glance.lore docs create --sync-push or LORE_SYNC_PUSH=1.LORE_CONTEXT_REFRESH_TIMEOUT_MS.)context-base/, context-manifests/, context-corrections/) is no longer tracked in the data-dir git history.Hotfix for a daemon deadlock observed during v0.17 dogfooding.
fetch failed retry loop, holding the write lock for >2 minutes and blocking everything that needed it.LORE_CONTEXT_REFRESH_TIMEOUT_MS) releases the lock cleanly when the network is unreachable. Next refresh cycle resumes when connectivity returns.LLM cost is now visible, bounded, and tuned for incremental work.
lore cost [--since|--feature|--workspace|--by] shows token usage and dollar cost over any time window, broken down by feature (auto-router, brief generation, sync metadata, etc.).llm_usage table — RLS-protected, scoped to your workspace.LORE_MAX_DAILY_TOKEN_SPEND_CENTS to refuse new LLM calls past the limit. 80% warning fires once per process.lore brief generate <project> --full is the only path that triggers a full rebuild. The CLI estimates the cost (input/output tokens, calls, USD) before running and requires typing regen to confirm. Pass --yes to bypass interactively; non-interactive without --yes refuses outright.This release simplifies the repo-local context vocabulary around add and remove.
lore context add <project> is now the command for creating and registering a repo-local .lore/ working copy.lore context remove removes that generated working copy and unregisters daemon refresh.context add creates the scaffold now, and daemon refresh populates it after sources for that project exist..lore/ working copy currently tracks one Lore project. Adding another project replaces clean context, while active proposals require review or explicit --force.This release makes Lore easier to use from code repos and safer to keep running in the background.
.lore/ working copies can register the current repo for daemon-managed context refresh.--limit <n> only for deliberately smaller task packs..lore/ working copies use copied snapshots, not symlinks..lore/sources/ remain proposed corrections and are never approved automatically.lore context list shows repos with Lore context and their last refresh result.lore context remove removes only the generated .lore/ folder.LORE_DATA_DIR is optional local history.lore sync repair rebuilds generated data-repo caches, imports deletion identities into Supabase, and untracks cache files that should not participate in Git merges.lore sync repair, and still refreshes project .lore/ working copies where safe.deleted-hashes.json is a rebuildable cache/fallback.db:types script for future migrations..lore/ working copies.llms.txt output for the new operating model.