-
Notifications
You must be signed in to change notification settings - Fork 0
fix(core): address the Slack gate to the workspace that owns the integration #33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+271
−2
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
92 changes: 92 additions & 0 deletions
92
packages/core/src/__tests__/integration-workspace-choice.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| /** | ||
| * Which workspace a Slack human-assistance gate should address. | ||
| * | ||
| * Slack lives on a real OAuth connection owned by one of the operator's | ||
| * registered workspaces. A run's provisioned workspace is a throwaway for agent | ||
| * file scope and has no integrations, so asking it to post a Slack question can | ||
| * never work — that was the actual cause of a gate that parked forever. | ||
| */ | ||
| import { describe, it, expect } from 'vitest'; | ||
| import { chooseIntegrationWorkspace } from '../runner.js'; | ||
|
|
||
| const REGISTRY = { defaultId: 'rw_7ccfea89', ids: ['rw_7ccfea89', 'rw_31684d8c', 'rw_fc7b534b'] }; | ||
|
|
||
| describe('chooseIntegrationWorkspace', () => { | ||
| it('redirects an unregistered (provisioned) workspace to the registered default', () => { | ||
| // rw_84e3ff6b is the per-run workspace; it is absent from workspaces.json. | ||
| const choice = chooseIntegrationWorkspace({ | ||
| resolvedWorkspaceId: 'rw_84e3ff6b', | ||
| registry: REGISTRY, | ||
| }); | ||
| expect(choice.workspaceId).toBe('rw_7ccfea89'); | ||
| expect(choice.reason).toContain('rw_84e3ff6b'); | ||
| expect(choice.reason).toContain('no Slack integration'); | ||
| // The operator needs to know how to override the decision. | ||
| expect(choice.reason).toContain('integrations.relayfile.workspaceId'); | ||
| }); | ||
|
|
||
| it('keeps a workspace that is registered', () => { | ||
| const choice = chooseIntegrationWorkspace({ | ||
| resolvedWorkspaceId: 'rw_31684d8c', | ||
| registry: REGISTRY, | ||
| }); | ||
| expect(choice.workspaceId).toBe('rw_31684d8c'); | ||
| expect(choice.reason).toBeUndefined(); | ||
| }); | ||
|
|
||
| it('an explicitly configured workspace always wins, even if unregistered', () => { | ||
| // Naming a workspace is a decision, not a guess to second-guess. | ||
| const choice = chooseIntegrationWorkspace({ | ||
| resolvedWorkspaceId: 'rw_84e3ff6b', | ||
| configuredWorkspaceId: 'rw_deliberate', | ||
| registry: REGISTRY, | ||
| }); | ||
| expect(choice.workspaceId).toBe('rw_deliberate'); | ||
| expect(choice.reason).toBeUndefined(); | ||
| }); | ||
|
|
||
| it('is a no-op with no registry — headless and cloud runs keep their workspace', () => { | ||
| // There is no ~/.relayfile/workspaces.json in cloud; the deploy's workspace | ||
| // is the integration-owning one already. | ||
| const choice = chooseIntegrationWorkspace({ resolvedWorkspaceId: 'rw_cloud_deploy' }); | ||
| expect(choice.workspaceId).toBe('rw_cloud_deploy'); | ||
| expect(choice.reason).toBeUndefined(); | ||
| }); | ||
|
|
||
| it('is a no-op when the registry records no default', () => { | ||
| const choice = chooseIntegrationWorkspace({ | ||
| resolvedWorkspaceId: 'rw_84e3ff6b', | ||
| registry: { ids: ['rw_a', 'rw_b'] }, | ||
| }); | ||
| expect(choice.workspaceId).toBe('rw_84e3ff6b'); | ||
| expect(choice.reason).toBeUndefined(); | ||
| }); | ||
|
|
||
| it('does not redirect a workspace that already IS the default but is missing from ids', () => { | ||
| // Duplicate/absent id entries are common in workspaces.json; matching the | ||
| // default is enough. | ||
| const choice = chooseIntegrationWorkspace({ | ||
| resolvedWorkspaceId: 'rw_7ccfea89', | ||
| registry: { defaultId: 'rw_7ccfea89', ids: [] }, | ||
| }); | ||
| expect(choice.workspaceId).toBe('rw_7ccfea89'); | ||
| expect(choice.reason).toBeUndefined(); | ||
| }); | ||
|
|
||
| it('ignores a blank configured workspace rather than treating it as a choice', () => { | ||
| const choice = chooseIntegrationWorkspace({ | ||
| resolvedWorkspaceId: 'rw_84e3ff6b', | ||
| configuredWorkspaceId: ' ', | ||
| registry: REGISTRY, | ||
| }); | ||
| expect(choice.workspaceId).toBe('rw_7ccfea89'); | ||
| }); | ||
|
|
||
| it('trims a configured workspace id', () => { | ||
| const choice = chooseIntegrationWorkspace({ | ||
| resolvedWorkspaceId: 'rw_x', | ||
| configuredWorkspaceId: ' rw_padded ', | ||
| }); | ||
| expect(choice.workspaceId).toBe('rw_padded'); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1: When the target credential is expired, this code redirects to it and then fails or retries against that unusable token instead of preserving the original runtime. Validate target credential usability before accepting the redirect and fall back when validation fails.
Prompt for AI agents