# Validation Rules for Active File Sources in Claude‑Obsidian: 5 Critical Integrity Checks

> Discover the 5 critical validation rules for active file sources in Claude-Obsidian. Ensure data integrity with essential checks for file existence, SHA-256 hashes, and valid page strings.

- Repository: [Agrici.Daniel/claude-obsidian](https://github.com/AgriciDaniel/claude-obsidian)
- Tags: how-to-guide
- Published: 2026-08-26

---

**Claude‑Obsidian enforces five strict validation rules on active file sources: the referenced file must exist in the vault, a SHA‑256 hash must be provided in the `content_sha256` field, the hash must be a 64‑character hexadecimal string, the hash must match the current file bytes (case‑insensitive), and the `pages` array must contain valid non‑empty strings without null bytes or line breaks.**

The claude‑obsidian repository implements a robust ledger validation system to ensure filesystem integrity across vault observations. When a source object specifies `"kind": "file"` and `"review_status": "active"`, the validator applies specific **validation rules for active file sources in claude‑obsidian** to verify that files exist and remain unmodified since recording. These checks live in [`claude_obsidian/ledgers.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/ledgers.py) within the `validate_source` function (lines 678‑690) and are orchestrated through [`claude_obsidian/package_validation.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/package_validation.py).

## What Defines an Active File Source?

An active file source is identified by two required fields: `"kind": "file"` and `"review_status": "active"`. According to the source code in [`claude_obsidian/ledgers.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/ledgers.py), these sources undergo rigorous integrity verification that inactive or pending sources skip, ensuring the ledger accurately reflects the current vault state.

## The Five Core Validation Rules

### 1. File Existence Verification

The validator confirms that the file referenced by `origin.locator` actually exists within the vault filesystem. During validation, the code attempts to read and hash the file at the specified locator. If `actual_hash` returns `None`, indicating the file is missing, the system appends an error via `_error(errors, f"{prefix}.origin.locator", "active file source does not exist")`.

### 2. Mandatory SHA‑256 Hash

Every active file source must include a `content_sha256` field containing the expected hash value. If this field is `None` or missing, the validator immediately flags the violation with `_error(errors, f"{prefix}.content_sha256", "active file sources require SHA-256")`. This requirement ensures that all active sources maintain a verifiable integrity checkpoint.

### 3. Hash Format Validation

While implicitly enforced during comparison, the SHA‑256 value must conform to standard formatting: a 64‑character hexadecimal string. The validation logic only proceeds with hash comparison when this length requirement is satisfied, effectively rejecting malformed or truncated hash values before integrity checking.

### 4. Content Integrity Matching

The validator calculates the current SHA‑256 hash of the file using helper utilities such as `_safe_hash` from [`claude_obsidian/paths.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/paths.py), then compares it against the stored `content_sha256`. This comparison is **case‑insensitive**. If the hashes differ, indicating the file has been modified since the source was recorded, the system reports: `_error(errors, f"{prefix}.content_sha256", "does not match current file bytes")`.

### 5. Pages Array Structure

The `pages` field must contain an array of non‑empty scalar strings that exclude null bytes and line breaks. This validation occurs earlier in the `validate_source` function (lines 502‑510) and prevents malformed metadata from propagating through the ledger system.

## Implementation Example

The following Python example demonstrates a valid active file source configuration and the validation workflow:

```python

# Example of a valid active file source (Python dict)

source = {
    "kind": "file",
    "review_status": "active",
    "origin": {
        "locator": "wiki/pages/example.md"
    },
    "content_sha256": "a3b1c4d5e6f7890a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4",  # 64‑char hex

    "pages": ["wiki/pages/example.md"]
}

```

To invoke the validator against this source:

```python
from claude_obsidian.ledgers import validate_source

errors = []
validate_source(
    source, 
    prefix="source[0]", 
    errors=errors, 
    planned_files=None,
    hash_reader=None, 
    root="/path/to/vault"
)
assert not errors  # passes if all rules are satisfied

```

When a file is missing, the validator captures the specific violation:

```python

# Demonstrating a failure when the file is missing

source["origin"]["locator"] = "nonexistent/file.md"
errors = []
validate_source(source, "source[0]", errors, None, None, "/path/to/vault")
print(errors)   # → ["source[0].origin.locator: active file source does not exist"]

```

## Key Source Files

The validation architecture spans three critical modules:

- **[`claude_obsidian/ledgers.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/ledgers.py)**: Contains the `validate_source` function implementing the active file source rules (lines 678‑690).
- **[`claude_obsidian/paths.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/paths.py)**: Provides helper utilities such as `_safe_hash` for computing file hashes during validation.
- **[`claude_obsidian/package_validation.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/package_validation.py)**: Orchestrates overall ledger validation, invoking source‑specific checks within the broader package context.

## Summary

The **validation rules for active file sources in claude‑obsidian** enforce filesystem integrity through five specific checks:

- **File existence**: The `origin.locator` must reference an existing file in the vault.
- **SHA‑256 requirement**: The `content_sha256` field cannot be null.
- **Hash format**: The hash must be a valid 64‑character hexadecimal string.
- **Content matching**: The provided hash must match the current file bytes (case‑insensitive).
- **Pages validation**: The `pages` array must contain clean, non‑empty scalar strings without null bytes or line breaks.

These rules ensure that active sources accurately reflect the current state of vault files and prevent data corruption in downstream processing.

## Frequently Asked Questions

### What happens if an active file source references a missing file?

The validator detects missing files when the hash computation returns `None` for `actual_hash`. It then appends an error message `"active file source does not exist"` to the `origin.locator` field path using the `_error` helper function. This prevents the ledger from accepting references to deleted or moved files.

### Is the SHA‑256 hash comparison case‑sensitive?

No. According to the implementation in [`claude_obsidian/ledgers.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/ledgers.py), the hash comparison between the stored `content_sha256` and the calculated `actual_hash` is performed case‑insensitively. This ensures that hashes are validated correctly regardless of whether they use uppercase or lowercase hexadecimal characters.

### What are the requirements for the `pages` field in active file sources?

The `pages` field must be an array containing only non‑empty scalar strings. These strings cannot include null bytes (`\0`) or line break characters. This validation is handled separately within the same `validate_source` function (lines 502‑510) earlier in the execution flow.

### Which module orchestrates the overall ledger validation process?

While [`claude_obsidian/ledgers.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/ledgers.py) contains the specific `validate_source` logic, [`claude_obsidian/package_validation.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/claude_obsidian/package_validation.py) serves as the orchestration layer. It coordinates the broader ledger validation workflow and invokes the source‑specific checks when reviewing package integrity.