Skip to content

feat(weave): WAL tee middleware for durable API writes#6387

Closed
andrewtruong wants to merge 37 commits intomasterfrom
andrew/wal-tee-writes
Closed

feat(weave): WAL tee middleware for durable API writes#6387
andrewtruong wants to merge 37 commits intomasterfrom
andrew/wal-tee-writes

Conversation

@andrewtruong
Copy link
Copy Markdown
Collaborator

@andrewtruong andrewtruong commented Mar 18, 2026

Summary

  • Adds WALTeeTraceServer middleware that tees all write operations to a local JSONL WAL file before delegating to the trace server
  • Adds enable_wal / WEAVE_ENABLE_WAL setting (default off) to opt in
  • Wired into weave_init.py as the outermost middleware layer, so the WAL captures all write intents

Depends on:

How it works

The tee sits in the middleware chain: WALTee → Cache → RemoteHTTPTraceServer. For every intercepted write method (call_start/end, obj_create, table_create, file_create, feedback_create, cost_create, etc.), it:

  1. Serializes the request to a JSON-safe dict (handles bytes→base64, datetime→isoformat)
  2. Appends {"type": "<method_name>", "req": {...}} to the WAL
  3. Delegates to the next server in the chain

WAL writes are fire-and-forget — if WAL I/O fails, the error is logged and the request proceeds normally. This ensures the WAL never blocks normal operation.

Test plan

  • 30 unit tests covering all intercepted methods, delegation, error handling, bytes serialization
  • All 86 durability tests pass (existing + new)
  • Lint clean

🤖 Generated with Claude Code


Open with Devin

andrewtruong and others added 7 commits March 18, 2026 14:22
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… 'origin/andrew/durable-wal-client' into andrew/wal-tee-writes
Introduces WALTeeTraceServer, a middleware that intercepts all write
operations (calls, objects, tables, files, feedback, costs) and appends
them to a local JSONL WAL before delegating to the underlying trace
server. This is the "tee" layer that makes writes durable — if the
process crashes, the WAL can be replayed to recover unacknowledged data.

- New `WALTeeTraceServer` using `DelegatingTraceServerMixin` pattern
- New `enable_wal` / `WEAVE_ENABLE_WAL` setting (default: off)
- Wired into `weave_init.py` as outermost middleware
- WAL writes are fire-and-forget (never block the real request)
- 30 unit tests covering tee, delegation, error handling, serialization

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@andrewtruong andrewtruong requested a review from a team as a code owner March 18, 2026 19:23
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 18, 2026

@wandbot-3000
Copy link
Copy Markdown

wandbot-3000 bot commented Mar 18, 2026

Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 6 additional findings in Devin Review.

Open in Devin Review

Comment thread weave/trace/weave_init.py
Comment on lines +247 to +251
from pathlib import Path

from weave.durability.wal_directory_manager import FileWALDirectoryManager
from weave.durability.wal_tee_trace_server import WALTeeTraceServer
from weave.durability.wal_writer import JSONLWALWriter
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Imports inside function body violate mandatory AGENTS.md import rule

The _wrap_with_wal function places four imports inside the function body (from pathlib import Path, and three weave.durability imports). AGENTS.md explicitly requires all imports at the module level and states the only exceptions are circular import avoidance (documented with a comment), optional dependencies (wrapped in try/except), and TYPE_CHECKING. None of these exceptions apply here: pathlib is stdlib, and the weave.durability modules are part of the same package — not optional dependencies that may not be installed. The AGENTS.md specifically warns that "Imports inside functions are not caught by linting. Agents must self-enforce this rule."

Prompt for agents
Move the four imports inside _wrap_with_wal (lines 247-251 of weave/trace/weave_init.py) to the top of the file, alongside the other top-level imports. Specifically, move:

  from pathlib import Path
  from weave.durability.wal_directory_manager import FileWALDirectoryManager
  from weave.durability.wal_tee_trace_server import WALTeeTraceServer
  from weave.durability.wal_writer import JSONLWALWriter

to the import section at the top of weave/trace/weave_init.py (around lines 1-27). The function body should then reference them directly without any local imports.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@github-actions github-actions bot locked and limited conversation to collaborators Mar 19, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant