Skip to content

Library

The Library is a read-only virtual filesystem projected over three stores you already have: memory, workspace, and artifacts. It stores nothing of its own. It resolves paths like /ring/dev/skills into the underlying rows and adds two LLM features on top: ask (RAG over a path) and eval (an eval-set runner with drift detection). Source: .audit gap-1 §7.

Two scopes only (src/library/resolver.ts:74-116):

/ring/<name>[/<section>][/<remainder…>]
/agent/<name>/memory # exactly this shape — nothing deeper

Relative segments (., ..) are rejected. /ring/<name> alone is valid — it resolves to the section listing (src/library/resolver.ts:89-91, 391-407); a section is required-to-be-known only if one is present. A ring has ten sections (src/library/resolver.ts:23-34), each backed by a specific store and filter:

Section Backed by Filter
charter memory memory_type=charter (singleton per ring)
skills memory memory_type=skill
instructions memory memory_type=instruction
resources memory memory_type=resource
decisions memory memory_type=decision
policies memory memory_type=policy
protocols memory memory_type=protocol
memories memory general types (semantic/episodic/emotional/reflective)
workspace workspace items folder tree, walked into via remainder; cycle-detected
artifacts artifacts filename-prefix match on remainder

ACL is enforced via canAccessNamespace. A ring that doesn’t exist and a ring you can’t see both surface as the same LIBRARY_PATH_NOT_FOUND (a deliberate stealth 404), so you can’t probe for ring names you lack access to (src/library/resolver.ts:118-151).

  • list / tree (buildLibraryTree, src/library/resolver.ts:489-513) resolves a path to its nodes at a given depth. Max depth is CHORUS_LIBRARY_MAX_DEPTH (default 5; src/library/validation.ts:5).
  • drilldown (buildLibraryDrilldown, src/library/resolver.ts:648-679) expands recursively under caps: max_depth (default 3), max_items_per_level (20), max_total_tokens (4000), circuit_breaker (200) (src/library/validation.ts:18-29). It reports why it stopped — completed, max_depth, max_items_per_level, max_total_tokens, or circuit_breaker — so a truncated tree is never silent.

ask answers a question over a path; eval runs a whole eval set against the library and scores the answers.

answerLibraryQuestion (src/library/ask.ts:360-466) embeds the question once, then for each context path (src/library/ask.ts:135-194): vector-searches the resolved memory scope for the top 5, expands the graph over supersedes/derives_from edges, merges by id, sorts, and feeds the result to the LLM. Optional shape (JSON-Schema validation, 2 attempts) and ground mode (extract claims[].evidence[].memory_id citations) are available; latency_budget_ms short-circuits to evidence-only with truncated=true.

eval loads an eval set (/<ring>/eval-set.md workspace item, or a workspace_item_id — exactly one required, src/library/validation.ts:31-39), runs library.ask per question, and scores against expected fragments. llm_judge defaults true → one LLM call per expected fragment (cost scales with fragments × evals); set it false for substring scoring. Pass threshold is hardcoded at 0.7, drift threshold at 0.05 (.audit gap-1 §9).

Library ask memory.query
Entry point a path (/ring/<name>/<section>) a namespace + query
Ranking synthetic ranks + graph hop cosine × decayed confidence (+ opt-in stack)
Retrieval limit hardcoded 5 per context request limit, 3× KNN over-fetch
Scope one or more library paths one namespace (with optional circle filter)
Reads beyond memory yes — workspace + artifacts too memory only

If you want raw recall with tunable ranking, use memory.query. Use the Library when you want a path-addressable view of a ring’s whole context (memory + workspace + artifacts), or a question answered against that view.