Skip to content

Commit 8a31a54

Browse files
srijanskclaude
andcommitted
docs: pre-launch honesty + accuracy pass
Aligns the docs with what the code actually does and what the data actually shows — the audit's most damaging findings were claims a skeptic could disprove in seconds. - Drop the synthetic "67% rediscovery" masthead badge; the demo NOTE now labels it illustrative n=3 demo data, not a validated rate (HN-1). - Correct the pydantic-ai example counts everywhere: 9 scope groupings and 6 topics, matching the committed claims.jsonl / book.md (the data was right; the prose was stale) (DATA-1/2/3). - Fidelity claim now states what the gate certifies (the citation is real) and what it does not (that the statement is fully entailed — that's human/PR review) (HN-2). "Compile" is described honestly as an LLM-extraction step wrapped in deterministic verify/dedup/score (HN-3). "vs RAG" no longer implies semantic retrieval — retrieval is lexical today (HN-4). - Document the real `local` provider + `base_url`, the [openai]/[serve] extras, and the "secrets never travel" claim now precisely covers message content + tool-call args (DOC-4, SEC-1, install notes). - docs/scrub.md: meta scrubbing + broadened patterns + an honest "what is NOT redacted" note (raw AWS secret without its env-var name). - docs/mcp.md: stale `active.jsonl` path and nonexistent `--verbose`/`--debug` flags removed (DOC-2/3). README book sample now matches what render_book actually emits (DOC-5). Genericized a leaked local username; softened the premature "available on PyPI" wording. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent e13fbae commit 8a31a54

7 files changed

Lines changed: 50 additions & 31 deletions

File tree

CHANGELOG.md

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@
44

55
First working vertical slice — capture → compile → serve → actuate → measure, built test-first.
66

7+
### Pre-launch hardening
8+
9+
A full adversarial audit before going public surfaced a cluster of fixes, all landed here:
10+
11+
- **Incremental compile cost.** `lore watch` now caches extraction per session (sessions are immutable, so the id is a safe key) — each interval only LLM-extracts newly-ingested sessions instead of re-running the whole corpus against your key. `--rebuild` ignores the cache. The watch loop is now incremental in *cost*, not just idempotent in *output*.
12+
- **First-run works out of the box.** `anthropic` (the default provider) is now a base dependency, and SDK imports are guarded with an actionable message instead of a raw `ModuleNotFoundError`. `pipx install crewlore``lore compile` just works with a key.
13+
- **Local models are real.** `model.provider: local` + `model.base_url` routes to any OpenAI-compatible endpoint (Ollama, LM Studio, vLLM). Previously "local" was advertised but unimplemented and produced a dead-end error.
14+
- **`lore serve --mcp`** — the documented MCP flag now exists (it was missing; the copy-paste `mcp.json` failed to launch).
15+
- **Tool-call arguments are scrubbed.** Secrets passed as tool-call args live in event `meta`, which previously bypassed the scrubber; `meta` is now walked recursively. Coverage broadened (AWS `ASIA`/secret-key assignments, all `xox?-` Slack tokens, quoted multi-word secrets). See [`docs/scrub.md`](docs/scrub.md).
16+
- **Usage stats moved to a gitignored sidecar** so `lore query` no longer rewrites the git-tracked `claims.jsonl` on every call — `git log .lore/` stays clean.
17+
- **Robustness:** timestamps are always timezone-aware (a timestampless transcript no longer crashes the actuation loop); a single failing session no longer aborts the whole compile pass.
18+
- **`lore --version`** flag; one canonical-form definition shared between the fidelity gate and the reported fidelity number; honesty passes on the README (the synthetic rediscovery metric is labelled demo data, the fidelity claim states what the gate does and does not certify, retrieval is described as lexical).
19+
- Corrected the pydantic-ai example counts (9 scope groupings / 6 topics, matching the committed data).
20+
721
### Added
822

923
- **Schemas** — content-addressed `Claim` IDs (idempotent compile, clean merges); `NSFEvent`, `Anchor`, `Provenance`, `Conflict`, `UsageStats`. Actuation fields (`action`, `status`, `usage`) and a conflict-grouping `topic` baked in.
@@ -40,7 +54,7 @@ Compilation is now automatic by default — no human has to remember to run it:
4054
- **`lore watch`** runs that pass on an interval (`--once` for cron/CI); `lore compile` is the manual escape hatch.
4155
- **Signal gate** widened to capture procedures/conventions/team-norms, not only friction (was silently dropping "how we do X" / "the rule is Y" sessions).
4256

43-
Live end-to-end on public-safe data (Haiku): 6 transcripts ingested, 2 secrets redacted, 7 compiled claims (decisions/gotchas/procedures), a rendered team-knowledge book, and a 67% preventable-rediscovery rate (2/3 held-out sessions).
57+
Live end-to-end on public-safe data (Haiku): 6 transcripts ingested, 2 secrets redacted, 7 compiled claims (decisions/gotchas/procedures), a rendered team-knowledge book, and 2 of 3 held-out sessions re-deriving known knowledge (illustrative demo data, n=3).
4458

4559
### Fidelity-gate contract made explicit (`_canonical_form`)
4660

@@ -58,14 +72,14 @@ The fidelity gate's tolerance shape — what counts as a "verbatim" anchor — i
5872
`docs/examples/pydantic-ai/` now reflects three captured sessions (G1 #5679, G3 #5358, D1 #5536):
5973

6074
- **18 active claims** (7 gotchas, 7 decisions, 3 procedures, 1 style)
61-
- **8 distinct scope groupings** spanning UI adapters, decorator introspection, durable-execution threat modeling, toolsets, tests, and version policy
75+
- **9 distinct scope groupings** spanning UI adapters, decorator introspection, durable-execution threat modeling, toolsets, tests, and version policy
6276
- **100% per-session canonical fidelity** — every anchor verified against its session's content under the explicit contract
6377
- **0 conflicts** (sessions disjoint in scope)
6478
- Provenance documents five real-data bugs the capture process found and fixed before publication.
6579

6680
### Renamed from `agent-lore` to `crewlore`
6781

68-
The original working name `agent-lore` collided on PyPI and on GitHub (taken by an unrelated 2018 project). Renamed to `crewlore` — two familiar words, instant comprehension, available on PyPI + GitHub. The importable package, CLI command, and `.lore/` directory layout stay the same; only the distribution and GitHub URL change.
82+
The original working name `agent-lore` collided on PyPI and on GitHub (taken by an unrelated 2018 project). Renamed to `crewlore` — two familiar words, instant comprehension, with the name free on PyPI and the repo live on GitHub. The importable package, CLI command, and `.lore/` directory layout stay the same; only the distribution and GitHub URL change. (Not yet published to PyPI; install from git until the first release is cut.)
6983

7084
### README hero GIF rework
7185

README.md

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
55
[![fidelity 100%](https://img.shields.io/badge/fidelity-100%25-success.svg)](docs/examples/pydantic-ai/)
66
[![claims compiled 18](https://img.shields.io/badge/claims_compiled-18-informational.svg)](docs/examples/pydantic-ai/)
7-
[![rediscovery prevented 67%](https://img.shields.io/badge/rediscovery_prevented-67%25-blueviolet.svg)](docs/examples/pydantic-ai/)
87

98
> **Your coding agents keep relearning what your team already figured out.**
109
> `crewlore` compiles agent sessions into a citable, plaintext team-knowledge layer that lives in your git repo. Local-first.
@@ -56,14 +55,14 @@ The demo runs the full loop on bundled public-safe sessions and prints what it f
5655
> [!NOTE]
5756
> **Fidelity — 100%.** Every claim's citation resolves verbatim back to its source.
5857
> **Conflicts surfaced — 1.** A real disagreement kept with both provenances, not silently merged.
59-
> **Preventable rediscovery — 67%.** Two of three held-out follow-up sessions re-derived knowledge the layer already had.
58+
> **Preventable rediscovery — 2 of 3.** Two of the three held-out follow-up sessions re-derived knowledge the layer already had. (Illustrative demo data — n=3, not a benchmark.)
6059
6160
## See it run on a real codebase: pydantic-ai (17.3k ⭐)
6261

6362
[`docs/examples/pydantic-ai/`](docs/examples/pydantic-ai/) is a committed snapshot of `crewlore` compiled on the public [`pydantic/pydantic-ai`](https://github.com/pydantic/pydantic-ai) repo — 3 Claude Code sessions on real issues, no synthetic data.
6463

65-
- **18 claims** compiled across 8 scope groupings (UI adapters, decorator introspection, durable-execution threat modeling, toolsets, tests, version policy)
66-
- **100% fidelity** under the explicit [canonical-form contract](docs/anchors.md) — every anchor canonically resolves to a substring of its source session
64+
- **18 claims** compiled across 9 scope groupings (UI adapters, decorator introspection, durable-execution threat modeling, toolsets, tests, version policy)
65+
- **100% fidelity** under the explicit [canonical-form contract](docs/anchors.md) — every anchor's quote canonically resolves to a substring of its source session. (Fidelity certifies the *citation* is real, not that the model's *statement* is fully entailed by it — that's what human/PR review of the book is for.)
6766
- **0 conflicts** because the three sessions covered disjoint scopes — the conflict detector wasn't given anything to flag
6867
- **Receipts:** the rendered [`book.md`](docs/examples/pydantic-ai/book.md), the raw [`claims.jsonl`](docs/examples/pydantic-ai/claims.jsonl), and full [`provenance.md`](docs/examples/pydantic-ai/provenance.md) (session ids, commit hashes, compile cost, scrub redactions, five real-data bugs the capture surfaced and we fixed before publishing)
6968

@@ -82,15 +81,18 @@ Raw, messy sessions go in. Out comes a structured, citable **compiled claim**
8281
A human can verify it (the anchor points back to the exact session line); an agent can trust it (the citation is real, not hallucinated). Claims roll up into a knowledge book at `.lore/knowledge/README.md`, grouped by area and committed to your repo alongside your code:
8382

8483
```markdown
85-
## billing/webhook
86-
- [gotcha] Billing webhook handler lacks idempotency check; dedupe on the Stripe key.
87-
- [decision] Use Stripe idempotency key for webhook dedup, not global locks.
84+
# Team knowledge (compiled by crewlore)
85+
86+
## services/billing
87+
88+
- **[gotcha]** Billing webhook handler lacks an idempotency check; dedupe on the Stripe key.
89+
- *Do:* Dedupe on the Stripe idempotency key before processing.
90+
- _anchor_ `ses_1#1`: "the handler has no idempotency check, so when Stripe retries a webhook the charge is processed again."
8891

8992
## deployment
90-
- [procedure] Always run migrations before deploy to prevent missing columns.
9193

92-
## .
93-
- [procedure] Write the failing test first; PRs without one are rejected in review.
94+
- **[procedure]** Run migrations before deploy to prevent missing columns.
95+
- *Do:* Run `make migrate` before every deploy.
9496
```
9597

9698
## How it works
@@ -119,14 +121,14 @@ flowchart LR
119121
- **Serve** — writes a human- and agent-readable knowledge book to `.lore/knowledge/`, and exposes a query tool (including an optional MCP server) so any agent can pull the relevant slice on demand.
120122
- **Actuation loop** — every retrieval is recorded, and that usage drives a lifecycle: unused claims decay and archive, contradicted claims are retired, useful claims are reinforced. The store stays small and fresh instead of growing into a pile nobody reads.
121123

122-
The intelligence is in **compile**; ingest and serve are deliberately thin, so supporting another coding agent is a small adapter, not a rewrite.
124+
The intelligence is in **compile**; ingest and serve are deliberately thin, so supporting another coding agent is a small adapter, not a rewrite. To be precise about the word "compile": extraction is an LLM step (the only non-deterministic part), wrapped in deterministic stages — verbatim-anchor verification, content-addressed dedup, conflict recording, and authority scoring. "Compile" means the repeatable session → claims transform, not that an LLM is absent.
123125

124126
## How it differs
125127

126128
- **vs. hosted memory (Letta, mem0)** — their store lives in someone else's cloud and you can't `git log` it; `crewlore`'s lives in your repo as plaintext.
127129
- **vs. per-IDE memory (Cursor rules, Claude memory, Continue, Cody)** — tied to one developer, one IDE; `crewlore` is a *team* artifact, committed and reviewed like code.
128130
- **vs. hand-curated `CLAUDE.md` / `.cursorrules`** — humans write those by hand and they go stale; `crewlore` compiles + reinforces from real sessions and retires what stops being used.
129-
- **vs. RAG over a vector DB** — RAG retrieves *documents*; `crewlore` compiles atomic, citable *claims* with verbatim anchors, so a human or agent can verify the source line in two seconds, and so the same claim survives across phrasing variance.
131+
- **vs. RAG over a vector DB** — RAG retrieves *document chunks*; `crewlore` compiles atomic, citable *claims* with verbatim anchors, so a human or agent can verify the cited source in seconds. (Retrieval today is deterministic lexical overlap, not embeddings — simpler and dependency-free; semantic ranking is on the roadmap.)
130132

131133
## Why this exists
132134

@@ -140,9 +142,9 @@ Knowledge discovered inside an agent session is private by default and lost by d
140142

141143
## Your data stays yours
142144

143-
- **Local-first.** Capture, compile, and serve all run on infrastructure you control. Point the compiler at your own model provider or a local model — nothing routes through any `crewlore`-operated service, because there is none.
145+
- **Local-first.** Capture, compile, and serve all run on infrastructure you control. Point the compiler at your own model provider or a local OpenAI-compatible model (Ollama, LM Studio, vLLM) via `provider: local` — nothing routes through any `crewlore`-operated service, because there is none.
144146
- **Plaintext, in your repo.** The knowledge layer is human-readable Markdown and JSONL under `.lore/`, versioned by git. `git log .lore/` is your audit trail.
145-
- **Secrets never travel.** Scrubbing happens at ingest, before storage or any model call. Raw session captures are git-ignored by default.
147+
- **Secrets never travel.** Scrubbing — of both message content and tool-call arguments — happens at ingest, before storage or any model call. It's a high-precision pattern set (a floor, not a DLP guarantee; see [`docs/scrub.md`](docs/scrub.md)), and raw session captures are git-ignored by default regardless.
146148

147149
## CLI
148150

@@ -161,16 +163,18 @@ Knowledge discovered inside an agent session is private by default and lost by d
161163

162164
```yaml
163165
model:
164-
provider: anthropic # anthropic | openai | (local)
166+
provider: anthropic # anthropic | openai | local
165167
name: claude-sonnet-4-6
168+
# For provider: local — point at any OpenAI-compatible endpoint you run:
169+
# base_url: http://localhost:11434/v1 # e.g. Ollama, LM Studio, vLLM
166170
capture:
167171
transcripts: ~/.claude/projects
168172
compile:
169173
cadence: auto # `lore watch` interval below
170174
watch_interval_seconds: 300
171175
```
172176
173-
Bring your own key (`ANTHROPIC_API_KEY` / `OPENAI_API_KEY`); `crewlore` never ships keys anywhere.
177+
Bring your own key (`ANTHROPIC_API_KEY` / `OPENAI_API_KEY`); `crewlore` never ships keys anywhere. The default Anthropic provider works out of the box. For OpenAI or a local OpenAI-compatible model, add the SDK: `pipx inject crewlore openai` (or `pip install 'crewlore[openai]'`). With `provider: local` nothing leaves your machine at all — the compile call hits your own endpoint.
174178

175179
## Roadmap & limitations
176180

docs/evaluating-on-your-codebase.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,5 +114,5 @@ After 4–6 sessions and one compile:
114114
For sensitive codebases (regulated industries, IP-heavy work):
115115

116116
1. Review the `claims.jsonl` diff in every PR that compiles new sessions, exactly like reviewing code. The plaintext format makes this practical.
117-
2. Use a local model (configured in `.lore/config.yaml`) instead of a hosted API if your compliance posture forbids sending code context to a third party. Quality tracks the model; Sonnet-class is the current sweet spot.
117+
2. Use a local model instead of a hosted API if your compliance posture forbids sending code context to a third party: set `model.provider: local` and `model.base_url` (any OpenAI-compatible endpoint — Ollama, LM Studio, vLLM) in `.lore/config.yaml`. Quality tracks the model; Sonnet-class is the current sweet spot.
118118
3. The on-disk format is plaintext + git; no proprietary store; no phone-home. The audit trail is `git log .lore/`.

docs/examples/pydantic-ai/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Real-data evidence of `crewlore` working on a public codebase. Every claim in `b
99
| **Target repo** | [`pydantic/pydantic-ai`](https://github.com/pydantic/pydantic-ai) (17.3k ⭐, MIT) |
1010
| **Sessions captured** | 3 Claude Code sessions on real open issues ([#5679](https://github.com/pydantic/pydantic-ai/issues/5679), [#5358](https://github.com/pydantic/pydantic-ai/issues/5358), [#5536](https://github.com/pydantic/pydantic-ai/issues/5536)) |
1111
| **Compiled claims** | **18** (7 gotchas · 7 decisions · 3 procedures · 1 style) |
12-
| **Distinct scopes** | **8 groupings** spanning UI adapters, decorator introspection, durable execution, toolsets, tests, and the version policy |
12+
| **Distinct scopes** | **9 groupings** spanning UI adapters, decorator introspection, durable execution, toolsets, tests, and the version policy |
1313
| **Fidelity** | **100%** — every anchor's quote canonically resolves against its session's content. See [`docs/anchors.md`](../../anchors.md) for the canonical-form spec. |
1414
| **Conflicts** | 0 (the three sessions cover different scopes; no cross-session disagreement to record) |
1515
| **Compile cost** | ~$0.60 with Sonnet 4.6 (deterministic at temperature=0) |

docs/examples/pydantic-ai/provenance.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ All three sessions ran in Claude Code, in the cloned target repo directory.
2323
| Session id (Claude Code) | `a8fa3beb-ec13-4ba2-8f68-9c745eecfaa2` |
2424
| Captured | 2026-05-28 |
2525
| Wall-clock duration | ~35 minutes |
26-
| NSF events extracted | 179 (1 user_message, 38 agent_message, 67 tool_call, 67 tool_result) |
26+
| NSF events extracted | 173 (1 user_message, 38 agent_message, 67 tool_call, 67 tool_result) |
2727
| Signal-gate reasons fired | `correction · error · gotcha · convention` |
2828
| Claims contributed | 8 |
2929

@@ -58,13 +58,13 @@ All three sessions ran in Claude Code, in the cloned target repo directory.
5858
| Model | `claude-sonnet-4-6` via Anthropic API |
5959
| Temperature | `0` (deterministic structured-output extraction) |
6060
| Max tokens | `8192` |
61-
| Compile command | equivalent to `lore compile --repo ~/demos/pydantic-ai --transcripts ~/.claude/projects/-Users-srijansaket-demos-pydantic-ai` |
61+
| Compile command | equivalent to `lore compile --repo ~/demos/pydantic-ai --transcripts ~/.claude/projects/-Users-you-demos-pydantic-ai` |
6262
| Compile cost | ~$0.60 (combined input + output across three sessions) |
6363
| Scrub redactions | 0 (no secrets in any of the three sessions) |
6464

6565
## Result stats
6666

67-
- **18 active claims** across **8 scope groupings** and **5 distinct topics**.
67+
- **18 active claims** across **9 scope groupings** and **6 distinct topics**.
6868
- **100% fidelity** under the canonical-form contract defined in [`docs/anchors.md`](../../anchors.md). Every anchor's quote canonically resolves to a substring of its source session's content. The canonical form tolerates whitespace, case, and Markdown decoration; it rejects content drift, fabrication, paraphrase, and out-of-order stitching.
6969
- **0 conflicts** — the three sessions cover disjoint scopes (UI adapter round-tripping, decorator introspection, and durable-execution threat modeling), so no `(scope, kind, topic)` group has claims from ≥2 sessions disagreeing.
7070

docs/mcp.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ The instrumentation closes the loop: the more the layer is *used*, the more its
6868

6969
**`lore: command not found` after install**`pipx ensurepath` and restart your shell, or use the absolute path to the binary in `mcp.json`'s `command` field.
7070

71-
**The tool list doesn't show `lore_query`** — your client may be caching the previous tool list. Restart the client. If still not listed, run `lore serve --mcp` manually in a terminal and verify it stays running (i.e. it's waiting on stdin); if it exits immediately, run with `--verbose` to see the error.
71+
**The tool list doesn't show `lore_query`** — your client may be caching the previous tool list. Restart the client. If still not listed, run `lore serve --mcp` manually in a terminal and verify it stays running (i.e. it's waiting on stdin); if it exits immediately, the error prints to stderr.
7272

73-
**Returns empty claims** — the repo's `.lore/claims/active.jsonl` is empty or your query doesn't overlap with any compiled claim's scope/statement/topic vocabulary. Run `lore status` to see how many active claims you have, and `lore query "<your task>" --debug` to see ranking scores.
73+
**Returns empty claims** — the repo's `.lore/claims/claims.jsonl` is empty or your query doesn't overlap with any compiled claim's scope/statement/topic vocabulary. Run `lore status` to see how many active claims you have, and `lore query "<your task>"` to check what the same ranking returns from the CLI.
7474

7575
## Privacy posture
7676

0 commit comments

Comments
 (0)