A demonstration consumer for Google's Open Knowledge Format (OKF v0.2), using LangGraph for LLM-guided graph traversal over fictional legal contracts, with an offline keyword fallback.
This is a partial implementation, not a conformance-certified consumer. The bundled agreements and human review records are fictional fixtures. See bundle scope for missing evidence and calculation limits.
Scope Note: This repository focuses exclusively on the OKF Consumer setup. Ingestion/producer logic will be addressed in a separate project.
Conventional RAG chops legal documents into isolated vector chunks, losing:
- Contract Structure: Agreements, sections, clauses, and exhibits are flattened.
- Cross-References: Clauses referencing definitions (e.g. "Confidential Information", "Fees") or addenda (e.g. DPA supercaps) are severed.
- Trust & Provenance: Cannot distinguish attorney-reviewed clauses from AI drafts.
- Freshness: Outdated or superseded terms pollute similarity search.
OKF (Open Knowledge Format v0.2) represents legal knowledge as a directory tree of Markdown files with YAML frontmatter:
- Progressive Disclosure: Agents navigate using
index.mdfiles at each level, loading only what is needed. - Trust Tiers:
human-reviewed,machine-confirmed, andunverifiedare inferred from frontmatter actor signals. - Relational Links: Standard Markdown links (
[Fees](/definitions/fees.md)) create explicit, traversable graph edges. - Attested Computations: Deterministic formulas (e.g., liability caps, cure periods) are evaluated mathematically rather than guessed.
flowchart TD
Plan[Plan: LLM selects sections] --> Navigate[Navigate: LLM selects concepts]
Navigate --> Inspect[Inspect: load evidence and check trust]
Inspect --> Review[Review: LLM selects more linked evidence]
Review -->|More evidence, within depth limit| Inspect
Review -->|Enough evidence or limit reached| Compute[Compute: registered Python rules]
Compute --> Synthesize[Synthesize: LLM writes cited answer]
Without an LLM, selection and link expansion use deterministic fallbacks and
synthesis produces an evidence report. The review step runs inside expand.py.
langgraph-okf/
├── bundles/
│ └── legal_sample/ # Fictional OKF demonstration bundle
│ ├── index.md # Root progressive disclosure index
│ ├── log.md # Bundle update history (§3.1 & §9)
│ ├── definitions/ # Legal definition concepts
│ ├── contracts/ # Agreements & Addenda
│ │ ├── msa/ # Master Services Agreement & Clauses
│ │ ├── dpa/ # Data Processing Addendum (2x Supercap)
│ │ └── sla/ # Service Level Agreement
│ └── computations/ # Attested Computations (Liability, Notice)
├── src/
│ └── langgraph_okf/ # OKF v0.2 Consumer Core
│ │── models.py # Pydantic models for Concept, Frontmatter, TrustTier
│ │── parser.py # Permissive YAML+Markdown parser (§4 & §11)
│ │── bundle.py # Bundle reader, index traversal, link resolution
│ │── trust.py # Trust tier evaluator & freshness checker
│ ├── agent/ # LangGraph Workflow Layer
│ │ ├── state.py # LegalDiscoveryState schema
│ │ ├── context.py # Per-run bundle, LLM, and policy dependencies
│ │ ├── reasoning.py # Validated LLM selections and usage accounting
│ │ ├── llm.py # OpenRouter ChatOpenAI factory with custom headers
│ │ ├── tools.py # Attested computation execution tools
│ │ ├── nodes/ # Individual Node Files
│ │ │ ├── plan.py # Planning & root index evaluation
│ │ │ ├── navigate.py # Progressive disclosure index traversal
│ │ │ ├── inspect.py # Concept inspection & trust evaluation
│ │ │ ├── expand.py # Relational link graph expansion
│ │ │ ├── compute.py # Deterministic Attested Computation execution
│ │ │ └── synthesize.py # Grounded legal synthesis with citations
│ │ └── graph.py # Compiled LangGraph workflow
│ ├── cli.py # Interactive query & inspection CLI
│ └── settings.py # OpenRouter & OKF configuration settings
└── tests/
├── test_okf_parser.py # Permissive parsing conformance tests
├── test_trust_evaluator.py # Trust signal & lifecycle verification tests
├── test_bundle_traversal.py # Progressive disclosure & link resolution tests
├── test_agent_workflow.py # End-to-end LangGraph agent discovery tests
├── test_agent_reasoning.py # Semantic selection and bounded evidence review
├── test_runtime_context.py # Per-run dependency and policy isolation
├── test_usage_metrics.py # Token, cost, timing, and fallback reporting
└── test_audit_regressions.py # Security and consumer behavior regressions
- Python >= 3.14
- uv
git clone https://github.com/ConceptCodes/langgraph-okf.git
cd langgraph-okf
uv syncCreate a .env file (optional, defaults to deterministic fallback if no API key is provided):
OPENROUTER_API_KEY=your_openrouter_api_key_here
OPENROUTER_MODEL=google/gemini-3.8-flashQueries end with a Run Metrics table showing total time (setup and graph execution), LLM time, the returned model name, input/output/total tokens, and request cost in USD. Cost uses OpenRouter usage accounting, not a hard-coded price estimate. Unreported usage or failed calls show unavailable values; offline runs show zero tokens and cost. Metrics aggregate all planning, navigation, evidence-review, and synthesis calls, with a per-call breakdown. They do not cover account-wide usage or separately billed SDK retry attempts. If any call lacks usage, the corresponding aggregate is unavailable rather than undercounted.
uv run langgraph-okf query 'What is the liability cap under the MSA, what exceptions apply, and how does a data breach affect it with $100,000 in fees?'uv run langgraph-okf inspect contracts/msa/clauses/limitation_of_liabilityuv run langgraph-okf listuv run langgraph-okf query 'What remedies are available if the platform goes dark?'
OPENROUTER_API_KEY='' uv run langgraph-okf query 'What notice is required for termination?'The final answer appears in the Grounded Evidence & Synthesis panel, followed by Run Metrics and, for live runs, LLM Calls. The traversal log records model selections and fallbacks. Keep dollar amounts inside single quotes to prevent shell expansion.
uv run pytest -v
uv run ruff check src testsTests force offline mode and use the sample bundle, regardless of local .env credentials.
With an LLM configured, planning selects sections from directory indexes and navigation selects concepts from index titles/descriptions. After inspection, the LLM reviews retrieved evidence and can request more offered linked concepts or stop. Each selection is checked against the candidate IDs; arbitrary paths are rejected. Malformed or failed selection calls use deterministic traversal as a fallback. Empty planning/navigation selections also fall back; an empty review selection stops expansion. Trust checks and registered Python calculations remain deterministic.
There are at most MAX_TRAVERSAL_DEPTH + 3 application-level LLM calls: planning,
navigation, one review per expansion round, and synthesis. Phases without candidates
are skipped. SDK retries may add network requests. Offline mode uses no LLM calls.
The graph uses LangGraph runtime context.
Every node accepts Runtime[Context]. Each invocation supplies one bundle instance,
an optional chat model (None means offline), and fixed trust/traversal policy.
Nodes do not read global settings. Query progress and results remain in graph state.
from langgraph_okf.agent import Context, build_legal_discovery_graph
from langgraph_okf.bundle import OKFBundle
graph = build_legal_discovery_graph()
context = Context(bundle=OKFBundle("bundles/legal_sample"), max_traversal_depth=3)
result = graph.invoke(
{"query": "What is the standard liability cap with $100,000 in fees?"},
context=context,
config=context.invocation_config,
)The CLI constructs Context.from_settings(settings) once per query. Python callers
must now pass context explicitly; get_openrouter_llm also requires an explicit
Settings argument. Supply config=context.invocation_config so LangGraph's step
limit accommodates the selected traversal depth. One compiled graph can be reused
with different contexts, including concurrent calls.
- Paths and symlinks must remain inside the bundle. Index navigation follows nested
directories; relational expansion uses
MAX_TRAVERSAL_DEPTHas a link-hop limit. MIN_TRUST_TIERselects evidence for this application's workflow.STRICT_VALIDATION=trueadditionally excludes stale/deprecated concepts. The underlying parser remains permissive; these settings are application policy, not OKF validity checks.- Verification mappings and lists are supported. Trust is inferred from declared actors; identities and signatures are not authenticated.
- Only two registered sample computations run. They require explicit inputs and reject unknown executors and invalid numeric values. Query classification is heuristic, with assumptions shown in the output. Arbitrary bundle code is never executed.
- Calculation outputs are local results, not independently attested receipts.
- Offline output includes the retrieved text and citations; it is an evidence report, not a substitute for legal interpretation. Configuring an API key enables sending the query, index metadata, and retrieved evidence to OpenRouter for selection, evidence review, and synthesis.
- The parser supports inline Markdown links, not the full CommonMark link grammar. Legacy v0.1 provenance conversion and external computation runtimes are not implemented.
- Run CLI examples from the repository root, or set
BUNDLE_PATHto an absolute directory. The sample bundle is not installed as package data.