cordance-llm 0.1.1

Cordance LLM adapters. Bounded candidate prose only. No hard rules from LLM.
Documentation

cordance-llm

Bounded candidate-prose adapters for local LLM endpoints (Ollama, …). Every claim must cite a source-ID from the input pack. Hard rules cannot originate here.

crates.io docs.rs license

Part of the Cordance workspace.

Discoverability

Search terms: Cordance LLM, Ollama adapter, grounded candidate prose, LLM source citations, AI agent summaries, no LLM authority, local model adapter.

What it does

ADR 0002 of Cordance forbids LLM-laundered authority. This crate enforces that at the adapter level:

  • Local-only by default. The Ollama adapter rejects non-loopback URLs unless CORDANCE_ALLOW_REMOTE_LLM=1 is set in the operator's environment.
  • Schema-bounded responses. Outputs deserialise into a fixed LlmCandidate shape; arbitrary text never escapes the adapter.
  • 4-gram source grounding. Every claim's text is split into 4-grams and must match a 4-gram in one of its cited source bodies; ungrounded claims are rejected before the candidate leaves the adapter.
  • Hard rules are filtered out. Claims tagged hard_rule or project_invariant are dropped regardless of grounding — those classes can only come from doctrine, ADRs, or schemas.

LLM output is never authority. It is candidate_only evidence that the operator can review and discard.

Install

[dependencies]
cordance-llm = "0.1"

Quick start

use cordance_llm::{OllamaAdapter, OllamaSettings};
use std::collections::HashMap;

struct Cfg;
impl OllamaSettings for Cfg {
    fn base_url(&self) -> &str { "http://localhost:11434" }
    fn model(&self) -> &str { "qwen2.5-coder:14b" }
    fn temperature(&self) -> f32 { 0.1 }
    fn num_ctx(&self) -> u32 { 8192 }
}

let adapter = OllamaAdapter::from_config(&Cfg);
if !adapter.is_available() {
    eprintln!("Ollama not reachable at {}", adapter.base_url);
    return;
}

let prompt = "Summarise this project's main purpose in one paragraph as a candidate observation.";
let cited_ids = vec!["project_readme:README.md".to_string()];
let source_bodies: HashMap<String, String> = HashMap::new(); // populate with the cited source contents

let candidate = adapter.generate_with_grounding(prompt, &cited_ids, &source_bodies)
    .expect("ollama generate (grounded)");
println!("got {} grounded claims", candidate.claims.len());

See also

License

Dual-licensed under MIT OR Apache-2.0.