When Claude Code writes a file, it reports success based on the tool call completing. But tool calls can silently fail — partial writes, encoding issues, permission errors that get swallowed. x closes this gap with a three-stage verification pipeline.

The verification pipeline

Every file write in x passes through three stages before it's considered successful:

  1. Pre-write snapshot — Before any write, x captures a SHA-256 hash of the target file (or notes it doesn't exist yet). This is the rollback anchor.
  2. Post-write verification — After the write tool returns, x re-reads the file from disk and hashes it. The new hash must differ from the pre-write hash (confirming something changed) and the content must match what the agent intended.
  3. AST validation — For supported languages, x parses the written file through Tree-sitter. If parsing fails (syntax error), the write is flagged and the agent is notified in the same turn.
src/claude.ts — verification flow
// Simplified from the actual implementation
const before = hashFile(targetPath);
const result = await claudeWrite(targetPath, content);
const after  = hashFile(targetPath);

if (before === after) {
  // Write was silently dropped — file unchanged
  agent.notify("WRITE_FAILED_SILENT", targetPath);
  return rollback(targetPath, before);
}

const ast = treeSitterParse(targetPath);
if (ast.hasErrors) {
  agent.notify("WRITE_SYNTAX_ERROR", ast.errors);
}

Failure modes

The pipeline catches three categories of failure:

What happens on failure

When verification fails, x does not silently continue. The agent receives a structured error in its context window, including:

This lets Claude self-correct in the same turn rather than building on a broken foundation. A caught error on turn 3 is far cheaper than discovering it on turn 30.

Key design principle: The goal isn't to prevent all errors — it's to make errors visible immediately. Strict-write is a feedback mechanism, not a safety net.

Supported languages

AST validation (stage 3) is available for any language with a Tree-sitter grammar. Currently supported:

For unsupported languages, stages 1 and 2 still run — you get hash verification without syntax checking.

Performance

The verification pipeline adds ~5-15ms per write operation. SHA-256 hashing and Tree-sitter parsing are both fast enough to be imperceptible. The cost is negligible compared to the API round-trip time for each agent turn.