Where Is the Claude-Obsidian Source Ledger Stored? Schema and Fields Explained
The Claude-Obsidian source ledger is stored at wiki/meta/ledgers/source-ledger.json inside each vault and contains fields including uri, type, retrieved, refresh_due, sha256, pages_created, and optional metadata.
Claude-Obsidian tracks provenance for every ingested source in a structured source ledger that lives within your vault's file system. According to the AgriciDaniel/claude-obsidian source code, this JSON file follows a strict schema to ensure data integrity across remote URLs and local files. Understanding its location and field structure is essential for developing plugins, debugging ingestion pipelines, or manually auditing source provenance.
File Location and Schema Version
The source ledger persists as a JSON file at a canonical path relative to your vault root. As referenced in the test suite at tests/test_lint_engine.py (lines 460–465), the expected location is:
wiki/meta/ledgers/source-ledger.json
This file conforms to the schema identifier claude-obsidian.source-ledger.v1, with validation logic implemented in claude_obsidian/ledgers.py (lines 421–514). The top-level structure contains a single key, "sources", which maps stable source identifiers to their respective provenance records.
Field Definitions and Data Types
Each entry under the sources object is a dictionary containing the following fields. According to the validation routine in claude_obsidian/ledgers.py, the schema distinguishes between remote URLs, local files, and raw manifest entries through the type field.
uri (string): The absolute HTTPS URL for remote resources or the file path for ingested local files. Remote sources must use absolute HTTPS URIs (validated at line 542).
type (string): Specifies the source origin. Valid values include "url" for remote HTTP(S) resources, "file" for local ingested files, and "raw" for raw manifest entries.
retrieved (string, ISO-8601 datetime): The timestamp when the content was fetched or ingested. Required for active remote sources and file sources (enforced at line 646).
refresh_due (string, ISO-8601 datetime): The scheduled refresh timestamp for active remote sources. Required alongside retrieved for any source marked as active (lines 646–652).
sha256 (string): The SHA-256 hash of the retrieved content. Mandatory for ingested file sources and active remote sources (required at line 633).
pages_created (array of strings): Paths to wiki pages generated from this source during ingestion. Tracks which vault files depend on the source record.
metadata (object, optional): Container for additional provenance data such as HTTP headers, ETags, or custom skill attachments.
Validation Logic and Constraints
The validate_source_ledger function in claude_obsidian/ledgers.py enforces structural integrity through type-specific rules. At line 421, it first verifies that sources is an object. Then, for each record, it applies conditional requirements based on the type field (lines 542–652).
Remote sources undergo strict URI validation to ensure they use absolute HTTPS paths. File sources must provide both a SHA-256 hash and a retrieval timestamp. Active sources require both retrieved and refresh_due fields to prevent stale data from persisting indefinitely.
When validation fails, the system emits structured error objects containing a JSON Pointer path (e.g., "sources.<source_id>.uri") and a human-readable message. This error-building logic resides at line 914 in claude_obsidian/ledgers.py.
Working with the Source Ledger in Python
The claude_obsidian.ledgers module provides functions to load, modify, and validate the ledger programmatically. The stable_source_id helper generates deterministic identifiers by hashing the URI, ensuring consistent source tracking across sessions.
import json
from pathlib import Path
from claude_obsidian.ledgers import (
load_source_ledger,
validate_source_ledger,
stable_source_id,
)
# Load the ledger from the current vault
vault_root = Path.cwd()
ledger_path = vault_root / "wiki" / "meta" / "ledgers" / "source-ledger.json"
ledger = load_source_ledger(ledger_path)
# Add a new remote source with a stable ID
new_source = {
"uri": "https://example.com/article.html",
"type": "url",
"retrieved": "2026-08-26T12:34:56Z",
"refresh_due": "2026-09-26T12:34:56Z",
}
source_id = stable_source_id(new_source["uri"])
ledger["sources"][source_id] = new_source
# Validate before saving
errors = validate_source_ledger(ledger)
if errors:
for error in errors:
print(f"Validation error at {error['path']}: {error['message']}")
else:
ledger_path.write_text(json.dumps(ledger, indent=2))
print("Source ledger updated successfully")
Summary
- The Claude-Obsidian source ledger resides at
wiki/meta/ledgers/source-ledger.jsonwithin each vault. - It follows the
claude-obsidian.source-ledger.v1schema defined inclaude_obsidian/ledgers.py. - The top-level
sourceskey maps stable IDs to provenance records containing fields likeuri,type,sha256, and timestamps. validate_source_ledgerenforces type-specific requirements (HTTPS for URLs, hashes for files) and reports errors with JSON Pointer paths.- Use helper functions like
stable_source_idandload_source_ledgerto interact with the ledger programmatically.
Frequently Asked Questions
What is the exact file path for the Claude-Obsidian source ledger?
The source ledger is stored at wiki/meta/ledgers/source-ledger.json relative to your vault root directory. This path is hardcoded in the validation tests at tests/test_lint_engine.py (lines 460–465) and is the canonical location the ingestion pipeline reads from and writes to.
What schema version does the source ledger use?
The ledger conforms to the claude-obsidian.source-ledger.v1 schema. This version identifier is referenced in the validation logic within claude_obsidian/ledgers.py (lines 421–514) and governs the structure of the JSON document.
Which fields are required for remote URL sources versus local files?
Remote URL sources require an absolute HTTPS uri, type: "url", retrieved timestamp, refresh_due timestamp, and sha256 hash. Local file sources require type: "file", sha256, and retrieved, but do not require refresh_due. These constraints are enforced in claude_obsidian/ledgers.py between lines 542 and 652.
How does the validation system report schema errors?
The validate_source_ledger function returns a list of error objects, each containing a path field with a JSON Pointer (e.g., "sources.abc123.uri") and a message field describing the constraint violation. This structured format, built by the helper at line 914, enables precise debugging of malformed ledger entries.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →