# How Claude-Obsidian Handles Offline-First Source Ingestion: A Technical Deep Dive

> Explore how Claude Obsidian manages offline-first source ingestion. Discover its read-only workflow and atomic draft bundle application.

- Repository: [Agrici.Daniel/claude-obsidian](https://github.com/AgriciDaniel/claude-obsidian)
- Tags: deep-dive
- Published: 2026-08-28

---

**Claude-Obsidian treats source ingestion as a read-only, offline-first workflow where a dedicated `wiki-ingest` agent processes local files without mutating the vault, returning structured draft bundles that are applied atomically only after user approval.**

The **AgriciDaniel/claude-obsidian** repository implements a robust knowledge management pipeline that prioritizes data integrity and offline availability. This article examines the architectural patterns that enable **offline-first source ingestion**, detailing how the system processes captured sources without network dependencies while maintaining strict provenance guarantees.

## Bounded, Read-Only Ingestion Workers

At the core of the ingestion pipeline lies the **`wiki-ingest` agent**, defined in [`agents/wiki-ingest.md`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/agents/wiki-ingest.md). This worker operates under a strict **read-only contract**: it receives locally available source files (typically from `inbox/` or `.raw/`) and performs analysis without ever writing to the vault.

The agent computes **SHA-256 hashes** of source content, extracts entities, claims, and concepts, then returns an evidence-grounded draft packet. As specified in the agent definition:

> "Read-only ingestion worker … reads the assigned source … then returns evidence-grounded page drafts, expected hashes, and proposed paths … It never writes or applies the shared transaction."

This separation ensures that all mutation operations remain deferred until the orchestrator assembles a complete transaction bundle.

## Immutable Source Archives and Provenance

Raw source payloads reside in the **`.raw/`** directory under a **create-only** policy. The ingestion workflow enforces immutability: new captures generate fresh entries with unique identifiers rather than overwriting existing files.

The skill definition in [`skills/wiki-ingest/SKILL.md`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/skills/wiki-ingest/SKILL.md) mandates:

> "External source payloads added under `.raw/` must use transaction mode `create`. Never replace or edit an existing raw payload."

This preserves **provenance chains** by maintaining original source artifacts alongside their derived knowledge representations.

### Claim Tracking and Evidence Fidelity

During analysis, the worker records **exact source locators** (page numbers, section headers, line indices) within a structured claim ledger. This ledger captures falsifiable statements, identified contradictions, and open questions—critical for maintaining epistemic rigor in offline environments where source materials cannot be re-fetched.

The agent explicitly prohibits fabrication:

> "Preserve evidence fidelity. Record exact source-relative locators … Never invent a quotation, locator, date, confidence score, or corroborating source."

## Transactional Apply and Atomic Commits

The transition from draft to persisted knowledge occurs through the **`claude-obsidian.transaction.v1`** protocol defined in [`skills/wiki-references/operation-transactions.md`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/skills/wiki-references/operation-transactions.md). After the `wiki-ingest` agent returns its draft packet, the orchestrator constructs a transaction bundle listing every intended write, target path, and expected SHA-256 hash.

### Bundle Inspection and Approval Flow

Users interact with the core CLI entry point ([`scripts/claude-obsidian.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/scripts/claude-obsidian.py)) to inspect and approve bundles:

```bash

# Resolve the product core

PRODUCT_ROOT=/absolute/path/to/installed/claude-obsidian
CORE="$PRODUCT_ROOT/scripts/claude-obsidian.py"

# Inspect the prepared bundle

python3 "$CORE" transaction inspect /path/to/ingest-bundle.json --vault /path/to/vault

# Apply with approved hash (replace <HASH> with the printed SHA256)

python3 "$CORE" transaction apply /path/to/ingest-bundle.json \
  --vault /path/to/vault --approved-plan-sha256 <HASH>

```

This **two-phase commit** ensures the entire ingestion operation succeeds or fails atomically, preventing partial writes that could corrupt the knowledge graph during offline usage.

### Handling Vault Divergence (Exit 75)

The system detects external modifications through **exit code 75**. If the vault changes between bundle creation and application, the transaction aborts:

> "Exit 75 means the vault changed … Re-read, rebuild, and inspect a new bundle."

This mechanism guarantees that no stale offline data overwrites concurrent changes, maintaining consistency across distributed or intermittent workflows.

## Mode-Aware Content Routing

The ingest worker delegates path resolution to **[`scripts/wiki-mode.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/scripts/wiki-mode.py)**, which serves as a single source of truth for vault organization. This **mode configuration** maps content types (sources, entities, concepts) to folder structures based on active methodologies (generic, PARA, Zettelkasten).

For example, determining where to place a new concept:

```bash

# Query the router for concept placement

wiki-mode.py route concept "Distributed Ledger"

# Output: wiki/concepts/distributed-ledger.md

```

The skill definition notes:

> "Single source of truth for 'which mode is this vault in' and 'where should new content of type X be filed under mode Y' … consumed by [`skills/wiki-ingest/SKILL.md`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/skills/wiki-ingest/SKILL.md)."

## Example Draft Packet Structure

When the `wiki-ingest` agent completes analysis, it returns a YAML-structured draft packet:

```yaml
status: complete
source:
  id: src-001
  path: inbox/research-paper.pdf
  sha256: a3f5c9...
  title: "Scalable Consensus"
proposals:
  - path: wiki/concepts/scalable-consensus.md
    action: create
    expected_sha256: null
    purpose: "Introduce a reusable concept page"
    content: |
      # Scalable Consensus

      … (generated markdown) …
evidence:
  - claim: "Consensus algorithms can scale linearly."
    source_id: src-001
    locator: "page 3, line 12"
    excerpt: "…"

```

This packet includes hashes for idempotency checks and explicit locators for verification, enabling the orchestrator to construct valid transaction bundles without re-processing source content.

## Summary

- **Read-only workers**: The `wiki-ingest` agent analyzes sources without file system mutations, ensuring safe offline operation.
- **Immutable archives**: Raw sources in `.raw/` follow create-only semantics, preserving original payloads for provenance.
- **Atomic transactions**: The `claude-obsidian.transaction.v1` protocol requires user-approved bundles applied via [`scripts/claude-obsidian.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/scripts/claude-obsidian.py), preventing partial writes.
- **Conflict detection**: Exit code 75 signals vault divergence, forcing bundle rebuilds rather than risking data corruption.
- **Mode-aware routing**: [`wiki-mode.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/wiki-mode.py) provides methodology-specific path resolution without hardcoding folder structures in the ingestion logic.

## Frequently Asked Questions

### How does Claude-Obsidian ensure data integrity when working offline?

The system enforces **SHA-256 hashing** at every stage: sources are hashed on capture, draft bundles include expected target hashes, and the transaction apply step verifies these hashes against current vault state. If any mismatch occurs (indicating external modification), the operation aborts with exit code 75, requiring a fresh bundle rebuild before proceeding.

### Can the ingestion worker modify files during processing?

No. The `wiki-ingest` agent defined in [`agents/wiki-ingest.md`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/agents/wiki-ingest.md) operates under a strict read-only contract. It processes source files, extracts knowledge structures, and returns draft proposals, but all file system writes are deferred to the orchestrator's transaction apply phase, which requires explicit user approval via the `transaction apply` command.

### What happens if I edit my vault while a transaction is pending?

The transaction apply command detects vault changes through **hash validation** and exits with code 75. This signals the orchestrator to discard the stale bundle, re-read the current vault state, and generate a new transaction proposal. This prevents race conditions and ensures offline-first consistency even with concurrent access patterns.

### How does the system decide where to place new knowledge pages?

Path resolution is delegated to **[`scripts/wiki-mode.py`](https://github.com/AgriciDaniel/claude-obsidian/blob/main/scripts/wiki-mode.py)**, which maps content types (concepts, entities, sources) to vault locations based on the active methodology configuration (generic, PARA, Zettelkasten). The ingest worker queries this router during drafting, ensuring new pages align with the user's organizational scheme without requiring manual path specification.