Protected Paths in Claude-Obsidian Transaction Bundles: Security Boundaries Explained

TLDR: In claude-obsidian, user-authored transaction bundles cannot overwrite reserved system paths such as .git, .vault-meta/transactions, or any path prefixed by .vault-meta/embed-cache, with enforcement handled by the validation logic in claude_obsidian/transaction.py.

The claude-obsidian repository (AgriciDaniel/claude-obsidian) implements a strict portability envelope to prevent user-authored transaction bundles from corrupting implementation-owned artifacts. Understanding which paths are protected—and how the transaction engine validates these restrictions—is essential for developing secure vault automation that respects platform boundaries.

Reserved Write Paths (Exact Match Protection)

The transaction engine maintains a definitive list of reserved write paths that user bundles cannot modify. According to claude_obsidian/transaction.py (lines 63-73), these exact paths represent implementation-owned artifacts including journals, lock files, and runtime caches:

  • .git
  • .vault-meta/transactions
  • .vault-meta/mutation.lock
  • .vault-meta/locks
  • .vault-meta/capture
  • .vault-meta/chunks
  • .vault-meta/bm25
  • .vault-meta/orchestration
  • .vault-meta/hook.log

Any attempt to target these specific paths results in an immediate TransactionValidationError before filesystem operations commence.

Reserved Write Prefixes and Pattern Protection

Beyond exact matches, the system protects resource families through prefix matching defined at lines 74-83 of transaction.py. If a user bundle targets any path starting with the following prefixes, the transaction is rejected:

  • .vault-meta/.address.lock
  • .vault-meta/.bm25.lock
  • .vault-meta/.embed-cache.lock
  • .vault-meta/.tiling.lock
  • .vault-meta/.transport
  • .vault-meta/.wiki-lock.meta
  • .vault-meta/embed-cache
  • .vault-meta/tiling-cache
  • .vault-meta/transport

This pattern matching safeguards quarantine variants, reaper locks, and temporary cache files generated during runtime operations.

Platform-Managed Metadata Files

Two additional files fall outside the portable write envelope despite not following the standard .vault-meta prefix pattern. As defined in transaction.py (lines 99-102), the following managed metadata files are strictly protected:

These files maintain the manifest of raw payloads and address counters, ensuring platform integrity during bundle execution.

Validation Logic and Error Handling

The enforcement mechanism resides in the transaction validation layer. When apply_bundle() processes a user-authored bundle, it cross-references each write operation against the reserved constants. If a match occurs, the engine raises:

raise TransactionValidationError(
    "UNSUPPORTED_PLATFORM",
    "transaction paths must fit the portability envelope"
)

This validation occurs prior to any disk write, ensuring atomic rejection of non-compliant transactions. The protection behavior is verified by the test suite in tests/test_transaction.py, which asserts that attempts to write protected paths trigger validation failures.

Code Example: Attempting to Write Protected Paths

The following example demonstrates the protection mechanism in action:

from pathlib import Path
from claude_obsidian.transaction import apply_bundle, TransactionValidationError

# Example bundle that attempts to overwrite a protected path

bundle = {
    "schema": "claude-obsidian.transaction.v1",
    "operation": "generic",
    "writes": [
        {"path": ".vault-meta/transactions/evil.txt", "content": "malicious"},
    ],
}

vault = Path("/path/to/vault")
try:
    apply_bundle(vault, bundle)  # Raises TransactionValidationError

except TransactionValidationError as exc:
    print(f"Rejected: {exc.code} – {exc}")

Attempting to write to a reserved prefix produces identical rejection behavior:

bundle["writes"][0]["path"] = ".vault-meta/embed-cache/evil.json"

# Raises TransactionValidationError with code UNPROTECTED_WRITE_PATH

Summary

  • Reserved write paths in claude_obsidian/transaction.py (lines 63-73) protect implementation artifacts like .git and .vault-meta/transactions through exact string matching.
  • Reserved write prefixes (lines 74-83) use path-starts-with logic to secure cache directories and lock file families from user modification.
  • Managed metadata files (lines 99-102) including .raw/.manifest.json remain under platform control and outside the portable envelope.
  • Any violation raises TransactionValidationError with codes such as UNSUPPORTED_PLATFORM or UNPROTECTED_WRITE_PATH, ensuring atomic rejection before filesystem mutation.

Frequently Asked Questions

What error does claude-obsidian raise when a bundle targets a protected path?

The transaction engine raises TransactionValidationError with error codes such as UNSUPPORTED_PLATFORM or UNPROTECTED_WRITE_PATH. This occurs during the validation phase in claude_obsidian/transaction.py before any disk writes execute, ensuring implementation-owned files remain immutable.

Can user-authored bundles write to paths under .vault-meta/embed-cache?

No. .vault-meta/embed-cache is a reserved write prefix defined in transaction.py (lines 74-83). Any path starting with this prefix—including subdirectories or temporary variants—is automatically rejected to prevent cache corruption and maintain platform stability.

Are Git directories protected from transaction bundle modifications?

Yes. The .git directory appears in the RESERVED_WRITE_PATHS constant at lines 63-73 of transaction.py. User bundles cannot modify Git internals, preventing repository corruption through the transaction API.

Where are the protected path constants defined in the source code?

The protection constants reside in claude_obsidian/transaction.py. Lines 63-73 define exact reserved paths, lines 74-83 specify reserved prefixes, and lines 99-102 enumerate managed metadata files. These constants collectively enforce the portability envelope that restricts user-authored transaction bundles.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →