v0.22.0 - the “scale” release
The rac-core "scale" release: retrieval that stops growing with corpus size — and now warm by default, so a caller who types nothing gets the fast path. Plus tags as a first-class search signal, decisions that know the code they govern, and team-scale MCP serving. Every scale feature is byte-identical to the uncached path.
This is the first PyPI release after
v0.19.0. Versioning reverted from a brief CalVer detour back to SemVer (ADR-111 supersedes ADR-076), and the three intervening releases — Hardening (v0.20.0), unlock (v0.21.0), rename (v0.21.1) — ship only as git tags; their CalVer PyPI dists are yanked. Sopip install -U rac-corefromv0.19.0lands here and delivers all four releases' worth of change at once. The "scale" work is below; everything folded in sincev0.19.0is in § Also included. Compatibility still lives onschema_version(ADR-007), never the release number.
Highlights — "scale"
- The cache is on by default (ADR-112).
rac find,rac validate, andrac mcpnow reuse the persistent memory-mapped index and per-file result caches without a flag — repeated queries against an unchanged corpus are bound by query selectivity, not corpus size. Freshness is verified by a fast(size, mtime_ns)stat scan; a one-shotrac findnow persists a stat manifest, so a warm run reads zero artifact bytes (enumeration + stats only). Byte-identical to the uncached walk. Escapes:--no-cacheper invocation,RAC_NO_CACHE=1per environment, and--verify(onfind/validate) to force the full byte re-hash floor. A homeless environment degrades to a temp-dir cache — a missing cache location never fails a query. - Search by tags. The frontmatter
tagsyou already write are now a retrieval signal: a query term matches them (a metadata tier between title and path), and a repeatable--tagfacet onrac find/ atagsargument onsearch_artifactsnarrows to artifacts carrying every requested tag. Deterministic and lexical throughout, never an embedding (ADR-037/038/109). - Single-node scale. For large corpora the derived index — repository index, resolved relationship graph, and search token vectors — is a persistent, memory-mapped segment store; search is served from term-major postings; freshness is tracked incrementally; and the cold build parallelises across cores. Keyed on a corpus content hash, byte-identical to the uncached path, and safe to delete — the cache can only change speed, never an answer (ADR-103/104/105/107/108).
- Decisions know the code they govern. A decision can declare an
## Applies Toscope;rac relationships --validateexistence-checks literal paths (newapplies-to-target-not-foundfinding). Ask the inverse withrac decisions-for <path>, thefind_decisionsMCP tool's newpathargument, and Explorer's/decisions-for— declared and validated, never inferred; deterministic and offline. - Lore at team scale.
rac mcp --transport httpserves one always-current, read-only endpoint for a whole team (stdio stays the default); a content-addressed cache (on by default) stops per-call latency scaling with corpus size; per-callerX-Lore-Principalaudit attribution answers "who read what, when"; and a new Shared Server operator guide. Servers and caches over git — no database (ADR-098/099). - Note-tool ingest.
rac ingestnow imports Obsidian, Logseq, Notion, and Roam exports, carrying each source's link graph in as candidate## Relatedreferences to promote — never asserted edges. Deterministic, offline, lossless, and it never overwrites (ADR-079). - Freshness where you pick artifacts.
rac findandsearch_artifactscarry a git-derivedrecencyobject (last_committed,age_days,stale) per match;rac doctor/rac reviewsurface asuspect-artifactdrift finding when a target was committed more recently than its referrer. Advisory beside the date, never a verdict; derived from git, never a stored frontmatter date (ADR-045). - Lean, measured context delivery. The five-tool MCP surface is now a regression-checked token budget (~915 against a 1000 cap, deterministic and offline), plus new Context Cost guidance on selective-by-default retrieval and the CLI as the lowest-tax delivery path (ADR-033/066).
- Harness integration recipes. A recipe template + authoring guide and the first four client recipes (Windsurf, Cline, Zed, opencode), each with a fixed post-edit-enforcement shape and zero engine diff (ADR-067).
Also included since v0.19.0
The releases folded into this one — full detail in the CHANGELOG.
Hardening (v0.20.0) — grounding you can see and trust:
- Explainable retrieval — every result shows why it matched (field, term, edge) on
search_artifacts/get_related/rac find --explain. rac doctor— one command diagnoses a corpus and emits paste-ready fixes.- Provenance on
get_artifact— git-derived author, dates, and reconstructed status history. - Documented trust model (
SECURITY.md) and a gated grounding benchmark (rac eval --check: deterministic Precision@k / Recall@k with a committed baseline).
unlock (v0.21.0) — the accumulated user-facing wave:
- Reimagined Explorer TUI — three themes, a sortable portfolio list view with live fuzzy search, and a split master-detail layout.
- Exportable corpus —
rac export --documents(ingestion-ready JSONL for RAG/memory backends) andrac export --graph(typed node+edge graph with real, validated relationship kinds) (ADR-074). - Visible grounding & coverage — content-free telemetry, a coverage view for gaps in the graph, and a bounded multi-hop
get_related. - Fail-closed publish gate (
python -m rac.release) rejecting a malformed or undocumented release before PyPI.
rename (v0.21.1) — the package rename + first enterprise wave:
- PyPI package renamed
requirements-as-code→rac-core(ADR-092); import nameracand the CLI unchanged. - Enterprise, all opt-in and content-free by default — telemetry hard-lock (
rac telemetry off --enterprise, ADR-086), a read-access audit recorder (ADR-084), external ticket references (## Related Tickets, ADR-087),rac init --profilescaffolding (ADR-088), and therac-captureinterview skill (ADR-077).
Upgrade notes
- The cache is now on by default (ADR-112, behavioral change).
rac find/rac validate/rac mcpreuse the persistent derived-index and per-file caches without a flag, byte-identical to the uncached walk. Opt out per-call with--no-cacheor environment-wide withRAC_NO_CACHE=1. The default freshness check is a(size, mtime_ns)stat scan;--verifyforces the full byte re-hash — the one case stats can miss is a size- and mtime-preserving in-place rewrite between two warm runs. - Package renamed →
rac-core. If you're coming fromv0.19.0you were onrequirements-as-code; installpip install rac-corenow. The old name still works via a transitional redirect, and pinnedrequirements-as-code==installs still resolve to their historical builds. Import nameracand theracCLI are unchanged (ADR-092). - License changed MIT → Apache-2.0. The package and CLI carry
Apache-2.0metadata with aNOTICEfile; it adds an express patent grant and stays permissive, so usage rights are unaffected. Contributions now require a DCO sign-off (git commit -s) — no CLA (ADR-071). - Search
evidence.tierintegers shifted by one (tags added at rank 2): path2→3, heading3→4, body4→5. Ranking order is unchanged (BM25F-driven) and the matched field name is unchanged — a consumer reading the field name is unaffected; one that pinned the integer should re-read it (ADR-109). - The persisted index-store format bumped. An index built by an older
racfails the version gate closed and is transparently rebuilt on next use — a one-time rebuild of a disposable structure, never a different result (ADR-104/109).
Install
pip install --upgrade rac-core # 0.22.0
# or, no Python:
docker run --rm -v "$PWD:/work" ghcr.io/itsthelore/rac:v0.22.0 validate rac/Full detail in the CHANGELOG.