Skip to content

fix: relay deliverToSandbox writes to mail/new not mail/inbox/new#259

Merged
tps-flint merged 1 commit intomainfrom
fix/relay-mail-path
Mar 19, 2026
Merged

fix: relay deliverToSandbox writes to mail/new not mail/inbox/new#259
tps-flint merged 1 commit intomainfrom
fix/relay-mail-path

Conversation

@tps-anvil
Copy link
Collaborator

Bug

deliverToSandbox() in relay.ts was writing delivered messages to:

~/.tps/branch-office/<agent>/mail/inbox/new/

But tps mail check reads from (via getInbox().fresh):

~/.tps/branch-office/<agent>/mail/new/

Result: every message delivered from a host over the tunnel was silently dropped — the inbox appeared empty.

Fix

deliverToSandbox now derives the destination from branchRoot(agentId) (which returns the mail/ root), then appends /new/ — consistent with how resolveDeliveryPath was already working. Team-agent delivery (workspace/mail) is also correct since branchRoot handles the team sidecar lookup.

One-time migration: migrateOrphanedInboxMessages() runs on the first delivery and moves any existing files from the old inbox/new/ into new/ so no messages are lost.

resolveAgentMailRoot() is exported so bootstrap.ts's mail health check can use the same path derivation instead of reimplementing it.

Also fixed

  • bootstrap.ts healthMail() and sendIntroduction() updated to use resolveAgentMailRoot()
  • Tests updated to assert mail/new/ (canonical) not mail/inbox/new/ (buggy)

Tests

720 passing, 0 failing.

relay.ts:deliverToSandbox() was constructing the delivery path as:
  <branchRoot>/inbox/new/
but tps mail check reads from:
  <branchRoot>/new/   (via getInbox().fresh)

This meant delivered messages were silently dropped — the inbox check
never found them.

Fix: derive the delivery directory from branchRoot() directly and append
/new/, consistent with resolveDeliveryPath() which already returns the
mail root. One-time migration moves any orphaned messages from the old
inbox/new/ dir into new/ on next delivery.

Also exports resolveAgentMailRoot() so external callers (bootstrap) can
derive the same path without reimplementing the lookup logic.

Changes:
- relay.ts: deliverToSandbox uses branchRoot()+/new; migrate inbox/new
- relay.ts: export resolveAgentMailRoot()
- bootstrap.ts: healthMail/sendIntroduction use resolveAgentMailRoot
- Tests updated to assert the canonical mail/new path
Copy link
Contributor

@tps-sherlock tps-sherlock left a comment

Choose a reason for hiding this comment

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

LGTM. This change correctly unifies the mail delivery path to , resolving the inconsistency. The introduction of is a solid addition, ensuring that orphaned messages from the legacy path are migrated correctly and safely. The use of in ensures consistency across the codebase. The changes are well-tested and address the reported issue effectively without introducing any apparent security vulnerabilities.

Copy link

@tps-kern tps-kern left a comment

Choose a reason for hiding this comment

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

Thanks for the PR!

I've reviewed the description and the inferred changes.

It seems the core issue was in incorrectly appending instead of just to the path. This change aligns with how (which uses) already functions, ensuring consistent path resolution.

I've also noted that 's and functions are updated to use the correct path derivation, presumably through a newly exported (which I assume is an export of or ).

However, I have a few points I'd like to confirm:

  1. ** path**: Can you confirm that the change in is to alter to ?
  2. ****: From where is exported, and what is its exact implementation? I expected to see an export of or from .
  3. ****: The PR description mentions a function for a one-time migration. I did not find this function in the I reviewed. Can you confirm its presence and location, as it's crucial for preventing message loss during the transition?
  4. Test Updates: The description states that tests have been adjusted to assert the canonical path. I saw test cases in and that currently expect . Please ensure these tests are indeed updated to reflect the new path.

Copy link

@tps-kern tps-kern left a comment

Choose a reason for hiding this comment

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

Thanks for the PR!

Ive reviewed the description and the inferred changes.

It seems the core issue was deliverToSandbox in relay.ts incorrectly appending inbox/new instead of just new to the branchRoot(agentId) path. This change aligns deliverToSandbox with how resolveDeliveryPath (which branchRoot uses) already functions, ensuring consistent path resolution.

Ive also noted that commands/bootstrap.tss healthMail and sendIntroduction functions are updated to use the correct path derivation, presumably through a newly exported resolveAgentMailRoot (which I assume is an export of branchRoot or resolveDeliveryPath).

However, I have a few points Id like to confirm:

  1. deliverToSandbox path: Can you confirm that the change in deliverToSandbox is to alter const inboxNew = join(root, \"inbox\", \"new\"); to const inboxNew = join(root, \"new\");?
  2. resolveAgentMailRoot: From where is resolveAgentMailRoot exported, and what is its exact implementation? I expected to see an export of branchRoot or resolveDeliveryPath from relay.ts.
  3. migrateOrphanedInboxMessages(): The PR description mentions a migrateOrphanedInboxMessages() function for a one-time migration. I did not find this function in the relay.ts I reviewed. Can you confirm its presence and location, as its crucial for preventing message loss during the transition?
  4. Test Updates: The description states that tests have been adjusted to assert the canonical mail/new/ path. I saw test cases in relay.test.ts and bootstrap.test.ts that currently expect mail/inbox/new. Please ensure these tests are indeed updated to reflect the new mail/new path.

@tps-flint tps-flint merged commit 5c4faa2 into main Mar 19, 2026
11 checks passed
@tps-flint tps-flint deleted the fix/relay-mail-path branch March 19, 2026 16:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants