Skip to content

Integration event delivery defects: doubled paths, tmp-file leaks, duplicate alias delivery, self-echo of writeback files #99

Description

@kjgbot

Observed live on 2026-06-05 ~14:09–14:18 UTC during a historical resync flood in workspace agentrelayworkspace (Slack channel C0AD7UU0J1G / #proj-cloud), injected into a Claude Code agent session as relayfile.changed events. The flood/backpressure architecture is covered by #82 (see the live-repro comment there); this issue tracks the discrete delivery defects that are independent of backpressure work.

1. Malformed doubled event paths

Many events arrived with the channel/message path duplicated inside itself, in two variants:

# variant A: doubled after the message ts segment
/slack/channels/C0AD7UU0J1G/messages/1780019742_971719/slack/channels/C0AD7UU0J1G/messages/1780019742_971719/meta.json

# variant B: doubled directly under messages/
/slack/channels/C0AD7UU0J1G/messages/slack/channels/C0AD7UU0J1G/messages/1779632411_869369/meta.json

Looks like a path-join defect (relative path appended to an already-resolved root) somewhere in the event emit or mount-relative translation. These paths don't resolve to real records, so consumers can't fetch context for them.

2. Sync-internal temp files delivered as events

/slack/channels/C0AD7UU0J1G/messages/1780666494_028989/.meta.json.tmp-3507823867

Atomic-write temp artifacts (dotfiles, *.tmp-*) should be filtered before event emission/injection.

3. Duplicate delivery across channel alias paths

The same logical record was delivered under both the raw id path (/slack/channels/C0AD7UU0J1G/...) and the aliased path (/slack/channels/C0AD7UU0J1G__proj-cloud/...), and the same meta.json was re-delivered 3+ times within minutes without content changes. Consumers should receive one event per logical change.

4. Self-echo of writeback files

An agent's own writeback command files (e.g. claude-1-codex-spawned.json, claude-1-issue82-ack.json written to the messages/replies writeback surface) were delivered back to that same agent as incoming integration events. Without origin filtering this is a feedback-loop primitive: an agent that responds to events by writing writeback files triggers new events to itself.

Acceptance criteria

  • No event paths containing a duplicated provider/channel segment (add a regression test on the path-construction code).
  • No events for dotfiles or *.tmp-* artifacts.
  • One event per logical record change — alias and raw paths deduped to a canonical path.
  • Events caused by an agent's own writeback are not injected back into the originating agent (or are marked with origin so the bridge can filter).

Related: #82 (Tracks B/C cover flood coalescing and historical-replay suppression; this issue is the correctness layer underneath).

Activity

  1. kjgbot commented on Jun 5, 2026

    @kjgbot
    ContributorAuthor

    PR ready: #101

    Acceptance mapping for #99:

    • Doubled provider/channel path segments: fixed in Pear by normalizing local Relayfile watcher filenames before translating to remote paths. Added regression coverage for both observed doubled variants.
    • Dotfile / *.tmp-* artifacts: filtered at the bridge boundary, alongside existing discovery/index/schema suppression. Added regression coverage for .meta.json.tmp-* and dotfile paths.
    • Duplicate alias/raw delivery: canonical mount-relative dedupe is preserved and now also keys same logical changes by revision/content fingerprint so raw and alias paths for the same record change inject once. Added same-revision raw/alias regression.
    • Self-echo of writeback files: Pear now suppresses Relayfile agent_write events and filters local Slack/chat writeback command filenames before injection. Added regressions for both origin filtering and command filename filtering.

    All four defect classes were root-caused to Pear event bridge behavior; no cloud or Relayfile SDK changes were required.

    Validation on the rebased branch after PR #98 landed:

    • node --experimental-strip-types --no-warnings --test src/main/__tests__/integration-event-bridge.test.ts
    • npm test
    • npm run build
    • git diff --check
  2. kjgbot commented on Jun 5, 2026

    @kjgbot
    ContributorAuthor

    Merged PR #101: #101

    Shipped fixes per acceptance criterion:

    • Doubled event paths: Pear now normalizes local Relayfile watcher filenames before remote path translation, covering both observed doubled variants. Regression test covers absolute/already-rooted filenames under a message root and remote-root-relative filenames under messages/.
    • Dotfile / temp artifacts: Pear filters dotfile leaves and *.tmp-* artifacts before event fanout; tests assert no sends and no listAgents lookup for those filtered paths.
    • Alias/raw duplicate delivery: Pear dedupes by canonical mount-relative path and uses revision/content fingerprints to suppress same logical changes delivered under both raw and alias paths. Regression covers same-revision raw + __proj-cloud alias delivery.
    • Self-echo of writeback files: Pear suppresses Relayfile origin=agent_write events and filters the observed Slack/chat writeback command filenames before injection. Regression covers both origin-based and filename-based suppression.

    Validation before merge at approved head 7abc2f4:

    • node --experimental-strip-types --no-warnings --test src/main/__tests__/integration-event-bridge.test.ts
    • npm test
    • npm run build
    • git diff --check
    • GitHub CI checks and packaged-mcp-smoke green

    Follow-up note from review, not included in #101 because it was non-blocking and explicitly dispositioned as follow-up: isLikelyLocalWritebackCommandPath currently matches messages/replies at any depth. Concrete failure mode to test/fix later: a legitimate nested non-numeric .json provider record under a message subtree, for example messages/<ts>/files/<name>.json, could be silently suppressed even though the observed self-echo files were direct children of messages/ or replies/. A tighter follow-up should require the leaf parent segment to be messages or replies and add a nested-record regression.

  3. kjgbot commented on Jun 5, 2026

    @kjgbot
    ContributorAuthor

    Follow-up PR: #111

    This tightens the writeback self-echo heuristic to direct-child messages/replies only, preserving the observed direct-child Slack echo suppression while keeping the nested non-numeric Slack record injection regression green in the replay window.

    Validation:

    • node --experimental-strip-types --no-warnings --test src/main/__tests__/integration-event-bridge.test.ts
    • npm test
    • npm run build
    • git diff --check
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions