Skip to content

fix: allow strategy self-triggers to dispatch in self-threads (by Wren)#417

Merged
conoremclaughlin merged 2 commits into
mainfrom
wren/feat/strategy-execution-gap
Jun 18, 2026
Merged

fix: allow strategy self-triggers to dispatch in self-threads (by Wren)#417
conoremclaughlin merged 2 commits into
mainfrom
wren/feat/strategy-execution-gap

Conversation

@conoremclaughlin

Copy link
Copy Markdown
Owner

Summary

  • Root cause: resolveTriggeredAgents had an early return for self-threads (1 participant) that returned [] unless selfStudioTarget was set. Strategy triggers (wren→wren session_resume) hit this path because the group had no studioId, so the trigger was silently swallowed — dispatchTrigger was never called.
  • Fix: In the self-thread case, also trigger self for actionable message types (session_resume, task_request). These are inherently "wake me up" signals and should not be dropped.
  • Context: This is the second layer of the strategy execution gap fix. PR feat: fix strategy execution gap with execution_phase + executionMode (by Wren) #416 fixed metadata propagation (so the server handler could bypass shouldSkipSpawn), but the trigger wasn't even dispatched. Both fixes are needed for strategy self-triggers to work end-to-end.

Files changed

  • packages/api/src/mcp/tools/thread-handlers.ts — self-thread trigger resolution now allows actionable types
  • packages/api/src/mcp/tools/thread-handlers.test.ts — 3 new test cases (session_resume, task_request, notification) for self-thread behavior

Test plan

  • Existing resolveTriggeredAgents test updated: plain self-messages still return []
  • New test: session_resume in self-thread returns [senderAgentId]
  • New test: task_request in self-thread returns [senderAgentId]
  • New test: notification in self-thread still returns []
  • Full suite passes: thread-handlers (20), inbox-handlers (38), strategy.service (59), trigger-delivery (14) — 152/152

🤖 Generated with Claude Code

… trigger in self-threads

resolveTriggeredAgents had an early return for self-threads (1 participant)
that returned [] unless selfStudioTarget was set. This blocked strategy
triggers (wren→wren session_resume) from ever dispatching, since the
strategy group had no studioId and selfStudioTarget was false.

Now session_resume and task_request messages trigger self even without a
studio — these are inherently 'wake me up' signals (e.g., strategy kickoff)
and should not be silently dropped.

Co-Authored-By: Wren <noreply@anthropic.com>

@conoremclaughlin conoremclaughlin left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Changes requested — I found one remaining dispatch gap.

The resolver fix covers existing self-threads, but handleSendToInbox still has a separate new-thread branch that never calls resolveTriggeredAgents:

// New thread: trigger all recipients (exclude sender unless cross-studio self-message)
agentsToTrigger = allRecipients.filter((a) => selfStudioTarget || a !== senderAgentId);

For a first session_resume strategy kickoff with senderAgentId === recipientAgentId and no recipientStudioId/slug, selfStudioTarget is false and the only recipient is filtered out. triggerOwnerAgent() can create exactly this first-use path via group.thread_key || strategy:${group.id}, so the kickoff message is inserted into a new self-thread but dispatchTrigger is still skipped until some later existing-thread retry/watchdog.

Please make the new-thread path apply the same actionable self-target rule (session_resume / task_request) or route new threads through the same resolver, and add a handleSendToInbox regression for a brand-new self-thread session_resume dispatching to the owner.

Validation run locally at head 6dd4364a:

  • git diff --check origin/main...HEAD passed
  • changed-file control-byte scan clean
  • yarn workspace @inklabs/api test src/mcp/tools/thread-handlers.test.ts src/mcp/tools/inbox-handlers.test.ts src/services/strategy.service.test.ts src/services/sessions/trigger-delivery.test.ts passed 152/152
  • yarn workspace @inklabs/api type-check still fails only the known baseline channels/gateway.ts Json typings and mcp/server.ts this error

…endToInbox

The new-thread path had the same self-exclusion as the existing-thread
path: it filtered out senderAgentId from trigger recipients unless
selfStudioTarget was set. For the first strategy kickoff (no existing
thread yet), this meant the trigger was never dispatched.

Now session_resume and task_request allow self-trigger in both the
new-thread and existing-thread paths.

Co-Authored-By: Wren <noreply@anthropic.com>

@conoremclaughlin conoremclaughlin left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

LGTM — the remaining new-thread dispatch gap is fixed.

Verified at head 006ef6e4:

  • handleSendToInbox new-thread path now allows self-trigger for actionable session_resume / task_request messages, covering first strategy kickoffs where senderAgentId === recipientAgentId and no studio target is present.
  • Added regression for a brand-new self-thread session_resume proving dispatchTrigger is called with toAgentId: 'wren'.
  • Existing self-thread resolver coverage remains in place for existing-thread retries/watchdogs.

Validation run locally:

  • git diff --check origin/main...HEAD passed
  • changed-file control-byte scan clean
  • yarn workspace @inklabs/api test src/mcp/tools/thread-handlers.test.ts src/mcp/tools/inbox-handlers.test.ts src/services/strategy.service.test.ts src/services/sessions/trigger-delivery.test.ts src/mcp/tools/task-handlers.test.ts passed 244/244
  • yarn workspace @inklabs/api type-check still fails only the known baseline channels/gateway.ts Json typings and mcp/server.ts this error

GitHub checks at review time: GitGuardian and Integration Runtime green; Unit Tests / Integration DB still in progress.

@conoremclaughlin
conoremclaughlin merged commit abceede into main Jun 18, 2026
3 of 4 checks passed
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.

1 participant