Skip to content

Formula instantiation needs two-phase commit for atomic batch posting #21

Description

@cameronsjo

Problem

instantiate_formula posts tasks to the postoffice sequentially. The daemon watches the postoffice via fsnotify and routes files immediately. If a later postMessage call fails mid-batch:

  1. Earlier tasks may already be routed to expert inboxes
  2. The cleanup only removes unrouted postoffice files
  3. The caller gets an error but partial work is already in flight

The taskboard's dependency evaluation prevents premature execution of downstream steps (they stay blocked), but the partial state requires manual cleanup.

Current Mitigation

Best-effort rollback with documented limitation (see architect_tools.go comment on Phase 2). Dependency edges protect against incorrect execution order.

Proposed Solution

Two-phase commit:

  1. Stage: Write all messages to a staging directory (e.g., postoffice/.staging-{prefix}/) that the watcher ignores
  2. Validate: Verify all files written successfully
  3. Commit: Atomically move all files from staging to postoffice (rename is atomic per-file on POSIX)
  4. Rollback: On failure, remove the staging directory

The watcher already ignores .routing-* temp files — extending this to .staging-* directories follows the same pattern.

Alternatives Considered

  • Pre-compose all messages in memory, write all at once: Current approach. Fails on I/O errors mid-write.
  • Transactional postoffice: Over-engineered for the current scale.

Context

Raised by CodeRabbit on PR #20 (v0.9 formulas). The current approach is acceptable for v0.9 — this is a hardening improvement for a future version.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions