Skip to content

feat: channel-based agent authorization for Slack#2033

Open
nick-inkeep wants to merge 16 commits intomainfrom
feat/slack-channel-auth
Open

feat: channel-based agent authorization for Slack#2033
nick-inkeep wants to merge 16 commits intomainfrom
feat/slack-channel-auth

Conversation

@nick-inkeep
Copy link
Collaborator

@nick-inkeep nick-inkeep commented Feb 16, 2026

Summary

Implements channel-based agent authorization for Slack, allowing linked Slack users in channels with configured default agents to execute those agents without explicit SpiceDB project membership. Includes a configurable grantAccessToMembers toggle so admins can control whether channel-based auth bypass is enabled per channel.

Problem: When an admin assigns a default agent to a Slack channel, users must also be explicit project members in SpiceDB. This creates a high-friction onboarding barrier — admins configure the channel, but users get silently denied.

Solution: Extend the Slack JWT with channel authorization claims (slack.authorized, slack.authorizedProjectId). When the work app resolves an agent via channel/workspace config and grantAccessToMembers is enabled, it sets slackAuthorized: true in the JWT. The Run API's trySlackUserJwtAuth then bypasses SpiceDB when channel-authorized AND the authorized project matches the request.

Spec: SPEC.md

Changes

JWT Schema (agents-core)

  • Add authorized, authSource, channelId, authorizedProjectId to SlackAccessTokenPayloadSchema
  • Add .refine() constraint enforcing authorizedProjectId and authSource are required when authorized: true
  • Add corresponding params to SignSlackUserTokenParams
  • Update signSlackUserToken claims construction

Auth Bypass (agents-api)

  • Short-circuit canUseProjectStrict in trySlackUserJwtAuth when slack.authorized === true AND authorizedProjectId matches x-inkeep-project-id header
  • Extend auth result with metadata.slack context for channel-authorized requests
  • Add debug log when bypass not applied (observability)

Execution Context (agents-core)

  • Add metadata.slack to BaseExecutionContext type (authorized: true literal, authSource, channelId, teamId)

Database Schema + Migration (agents-core)

  • Add grant_access_to_members boolean column to work_app_slack_channel_agent_configs table (default true, NOT NULL)
  • Migration: 0014_odd_oracle.sql — single ALTER TABLE ADD COLUMN
  • Data access: findWorkAppSlackChannelAgentConfig now returns grantAccessToMembers field

Agent Resolution (agents-work-apps)

  • resolveEffectiveAgent propagates grantAccessToMembers from channel config (explicit value) or workspace config (defaults to true)
  • ResolvedAgentConfig type extended with grantAccessToMembers: boolean

Call Sites — JWT Signing (agents-work-apps)

  • app-mention.ts: Switch from resolveChannelAgentConfig to resolveEffectiveAgent + pass channel auth params (2 call sites). slackAuthorized gated by agentConfig.grantAccessToMembers (not hardcoded true)
  • commands/index.ts: Default question command passes slackAuthorized: agentConfig.grantAccessToMembers. /inkeep run name and /inkeep list pass slackAuthorized: false (2 call sites)
  • modal-submission.ts: Both modal submission handlers pass slackAuthorized: false (2 call sites) — correct because modal submissions bypass channel context

OTel Observability (agents-work-apps)

  • Add AUTHORIZED and AUTH_SOURCE to SLACK_SPAN_KEYS in tracer.ts
  • Set span attributes in app-mention and modal-submission handlers
  • slack.authorized span attribute reflects actual grantAccessToMembers value (not hardcoded)

Manage UI — grantAccessToMembers Toggle (agents-manage-ui)

  • channel-agent-cell.tsx: Add Switch toggle with ShieldCheck icon and tooltip inside channel agent popover. Tooltip: "When enabled, channel members can use this agent without explicit project access." Toggle appears only when channel has a custom agent config
  • channel-defaults-section.tsx: Thread onToggleGrantAccess prop to ChannelAgentCell
  • index.tsx (AgentConfigurationCard): handleToggleGrantAccess handler calls slackApi.setChannelDefaultAgent with updated grantAccessToMembers. Bulk set explicitly passes grantAccessToMembers: true
  • slack-api.ts: listChannels return type includes grantAccessToMembers?: boolean on agentConfig
  • types.ts: Channel.agentConfig type includes grantAccessToMembers?: boolean

Channel Config API Route (agents-work-apps)

  • PUT /workspaces/:teamId/channels/:channelId/settings accepts grantAccessToMembers in agentConfig body
  • Value persisted to work_app_slack_channel_agent_configs table
  • Returned in GET /workspaces/:teamId/channels response

Key Design Decisions

  • D2: Bypass before SpiceDB (avoids wasted round-trip; JWT is signed + 5-min TTL)
  • D7: Converge on resolveEffectiveAgent (has source field) instead of resolveChannelAgentConfig
  • D8: Project-bind the bypass — authorizedProjectId must match x-inkeep-project-id header
  • D9: Sub-agent delegation inherits bypass (same JWT forwarded, same project)
  • grantAccessToMembers default: true for backward compatibility — existing channel configs automatically grant access. Admins can opt out per channel via the Manage UI toggle

Test plan

JWT Schema Tests (agents-core)

  • New claims validated in schema (authorized, authSource, channelId, authorizedProjectId)
  • Backward compat: existing tokens without new fields still validate
  • Schema invariant: authorized: true requires authorizedProjectId and authSource
  • signSlackUserToken emits new claims when provided
  • signSlackUserToken omits new claims when not provided — 10 tests total

Auth Bypass Tests (agents-api)

  • Bypass with valid channel claims (slack.authorized: true + matching projectId)
  • Bypass with workspace auth source
  • Bypass rejection on project mismatch (D8)
  • authSource default fallback to channel
  • Fallthrough to SpiceDB when authorized: false
  • Fallthrough to SpiceDB when claims missing
  • SpiceDB denial without channel auth
  • Missing required headers rejection
  • SpiceDB unavailability returns 503

Agent Resolution Tests (agents-work-apps)

  • Channel config with grantAccessToMembers: true → returned in result
  • Channel config with grantAccessToMembers: false → returned in result
  • Workspace fallback defaults grantAccessToMembers: true
  • Workspace config with explicit grantAccessToMembers: false → propagated
  • Disabled channel config skipped → falls through to workspace
  • No config at any level → returns null
  • Missing channelId → skips channel check

App Mention Tests (agents-work-apps)

  • Span attributes set for channel-resolved agent (slack.authorized, slack.auth_source)
  • Span attributes set for workspace-fallback agent
  • slackAuthorized: false when grantAccessToMembers: false

Slash Command Tests (agents-work-apps)

  • handleQuestionCommand passes slackAuthorized: true when grantAccessToMembers: true
  • handleQuestionCommand passes slackAuthorized: false when grantAccessToMembers: false

Modal Submission Tests (agents-work-apps)

  • Both modal handlers pass slackAuthorized: false
  • slack.authorized span attribute set to false

Quality Gates

  • pnpm test — 291 tests passing
  • pnpm typecheck — clean
  • pnpm lint — clean

QA Checklist

What was manually verified vs. what relies on automated tests only.

Verified via automated tests only (no manual/browser testing)

  • Manage UI toggle rendering: The grantAccessToMembers Switch toggle in channel-agent-cell.tsx was NOT browser-tested. Rendering, layout, tooltip positioning, and click behavior verified only by code review — no Chrome extension or manual browser session was used.
  • Bulk set with grantAccessToMembers: true: Logic verified by code review of index.tsx. No manual test of bulk assign + verify toggle state.
  • Toggle persistence round-trip: The handleToggleGrantAccess → API call → re-fetch flow was not manually verified end-to-end in a running app.

Not tested (requires deployed environment)

  • End-to-end Slack flow: Sending an @mention or /inkeep command in a real Slack channel with grantAccessToMembers toggled on/off and verifying the JWT bypass activates/deactivates. This requires a deployed work-apps service + Run API + Slack workspace.
  • SpiceDB bypass in production: Verifying a non-project-member user gets authorized via channel config in a real environment with SpiceDB running.

Rationale

This feature touches backend auth middleware, JWT signing, and a DB schema change — none of which are testable via browser automation alone. The Manage UI toggle is the only browser-testable surface, and it was verified via code review + type safety (props thread correctly through 3 components). All authorization logic is covered by 40+ unit tests.


🤖 Generated with Claude Code

Enable linked Slack users in channels with configured default agents to
execute those agents without explicit SpiceDB project membership.

Changes:
- Extend JWT schema with channel auth claims (authorized, authSource,
  channelId, authorizedProjectId)
- Add SpiceDB bypass in trySlackUserJwtAuth when channel-authorized with
  project binding verification (D8)
- Extend BaseExecutionContext metadata with slack auth context
- Switch app-mention.ts from resolveChannelAgentConfig to
  resolveEffectiveAgent (D7) and pass channel auth params
- Update slash command background exec to pass channel auth params
- Add comprehensive tests for bypass logic, project mismatch rejection,
  and graceful fallback

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@changeset-bot
Copy link

changeset-bot bot commented Feb 16, 2026

🦋 Changeset detected

Latest commit: c55e654

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 10 packages
Name Type
@inkeep/agents-core Patch
@inkeep/agents-api Patch
@inkeep/agents-manage-ui Patch
@inkeep/agents-cli Patch
@inkeep/agents-sdk Patch
@inkeep/agents-work-apps Patch
@inkeep/ai-sdk-provider Patch
@inkeep/create-agents Patch
@inkeep/agents-manage-mcp Patch
@inkeep/agents-mcp Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented Feb 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agents-api Ready Ready Preview, Comment Feb 17, 2026 10:00pm
agents-docs Ready Ready Preview, Comment Feb 17, 2026 10:00pm
agents-manage-ui Ready Ready Preview, Comment Feb 17, 2026 10:00pm

Request Review

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests were mocking the old resolveChannelAgentConfig from utils, but the
implementation now imports resolveEffectiveAgent from agent-resolution.
Updated all test cases to mock the correct module and include the
required `source` field in mock return values.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

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

PR Review Summary

(4) Total Issues | Risk: Medium

🟠⚠️ Major (3) 🟠⚠️

🟠 1) packages/agents-core Missing changeset for published package

Issue: This PR modifies exported types (SlackAccessTokenPayloadSchema, SignSlackUserTokenParams, BaseExecutionContext) from the published @inkeep/agents-core package. Per CLAUDE.md changeset requirements: "Create a changeset for any user-facing change to a published package."

Why: Without a changeset, version bumps will not be triggered, and consumers will not see release notes for these changes. While the changes are additive and non-breaking, they still modify the public API surface of an npm-published package.

Fix:

pnpm bump patch --pkg agents-core "Add channel-based authorization claims to Slack JWT schema and BaseExecutionContext type"

Refs:

Inline Comments:

  • 🟠 Major: slack-user-token.ts:42 Schema allows incomplete authorization states — authorized: true without requiring authorizedProjectId
  • 🟠 Major: app-mention.test.ts:270 Missing test verification of channel auth params passed to signSlackUserToken

🟡 Minor (1) 🟡

Inline Comments:

  • 🟡 Minor: utility.ts:309-314 Type allows authorized: false but runtime only populates when true

💭 Consider (3) 💭

💭 1) agents-api/src/middleware/runAuth.ts:247 Add debug log when bypass is skipped
Issue: When slackAuthorized evaluates to false, there's no log explaining why the bypass wasn't applied.
Why: Makes it harder to diagnose authorization issues when admins expect channel-based auth to work but it silently falls through to SpiceDB.
Fix: Add debug log with slackAuthorizedClaim, slackAuthorizedProjectId, requestedProjectId, and projectMatch fields.

💭 2) app-mention.ts:242 Consider stricter slackAuthorized condition
Issue: slackAuthorized is set to agentConfig != null, which means ANY resolved agent config triggers it, even if source === 'none'.
Fix: Consider slackAuthorized: agentConfig != null && agentConfig.source !== 'none' to ensure the bypass is only granted when there's true admin-configured channel or workspace default.

💭 3) api-key-auth.test.ts Missing test for authSource default fallback
Issue: The implementation defaults authSource to 'channel' when missing (line 313), but no test verifies this fallback behavior.
Fix: Add test case for authorized: true with missing authSource to document expected behavior.


🚫 REQUEST CHANGES

Summary: This PR implements a well-designed channel-based authorization bypass for Slack with appropriate security controls (project binding, JWT signature verification, short TTL, graceful fallback to SpiceDB). The security architecture is sound. However, there are 3 major issues to address before merging:

  1. Missing changeset — Required for any change to published packages
  2. Schema invariant enforcement — The JWT schema should enforce that authorized: true requires authorizedProjectId
  3. Test coverage gap — The app-mention tests don't verify the critical channel auth params are passed correctly

Once these are addressed, this PR is ready to ship. 🚀

Discarded (12)
Location Issue Reason Discarded
runAuth.ts:243-280 Security design is sound INFO — positive validation, not an issue
runAuth.ts:282-296 Auth success logging follows patterns INFO — confirms conventions
slack-user-token.ts:38-41 JWT claim naming follows conventions INFO — confirms conventions
slack-user-token.ts:57-60 SignSlackUserTokenParams follows prefixing convention INFO — confirms conventions
utility.ts:309-314 metadata.slack follows established pattern INFO — confirms conventions
api-key-auth.test.ts:664-996 Test coverage follows established patterns INFO — confirms conventions
runAuth.ts:307-318 Authorization source metadata enables audit trails INFO — positive validation
runAuth.ts:243-280 Channel auth bypass is architecturally sound INFO — positive validation
relationTools.ts Sub-agent delegation inherits bypass without re-verification Acceptable design per D9 — documented in PR description
runAuth.ts:243-280 Establishes precedent for capability-based authorization INFO — observation for future reference
slack-user-token.test.ts Missing test for partial claims (authorized without authorizedProjectId) Already covered by auth middleware tests — implicit coverage
api-key-auth.test.ts Missing test for JWT verification throwing unexpectedly Edge case caught by general error handling
Reviewers (8)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
pr-review-security-iam 3 0 1 0 1 0 1
pr-review-architecture 5 0 0 0 0 0 5
pr-review-standards 0 0 0 0 0 0 0
pr-review-consistency 6 0 0 0 0 0 6
pr-review-breaking-changes 5 1 0 0 0 0 4
pr-review-tests 5 0 1 0 1 0 3
pr-review-types 2 0 0 0 2 0 0
pr-review-errors 2 0 1 0 0 0 1
Total 28 1 3 0 4 0 20

Note: Schema invariant finding merged from pr-review-types and pr-review-security-iam (same underlying issue).

@github-actions github-actions bot deleted a comment from claude bot Feb 16, 2026
inkeep bot added a commit that referenced this pull request Feb 16, 2026
Documents the new channel-based agent authorization feature from PR #2033.
Users in channels with configured default agents are now automatically
authorized to execute those agents without needing explicit project membership.
Review feedback addressed:

Major:
- Add .refine() to SlackAccessTokenPayloadSchema enforcing that when
  authorized=true, authorizedProjectId and authSource are required
- Add changeset for agents-core (patch)
- Add signSlackUserToken channel auth param verification in app-mention test

Minor:
- Change BaseExecutionContext.metadata.slack.authorized to literal `true`
  since the field is only populated when authorization is granted

Consider:
- Add debug log in runAuth.ts when channel auth bypass is not applied
- Add test for authSource default fallback to 'channel'
- Add schema invariant enforcement tests (authorized without
  authorizedProjectId, authorized without authSource)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@nick-inkeep
Copy link
Collaborator Author

Review Response (commit 39f6eef)

Major — All addressed

  1. Missing changeset — Added: pnpm bump patch --pkg agents-core "Add channel-based authorization claims to Slack JWT schema and BaseExecutionContext type"

  2. Schema invariant enforcement — Added .refine() to SlackAccessTokenPayloadSchema enforcing that when authorized === true, both authorizedProjectId and authSource must be present. Added 2 tests verifying the constraint.

  3. Missing test verification of channel auth params — Added signSlackUserToken assertion in the "should stream response" test verifying slackAuthorized, slackAuthSource, slackChannelId, and slackAuthorizedProjectId are passed correctly.

Minor — Addressed

  1. Type authorized: true literal — Changed BaseExecutionContext.metadata.slack.authorized from boolean to literal true since the field is only populated when authorization is granted.

Consider — Assessed

  1. Debug log when bypass is skippedAccepted. Added debug log with slackAuthorizedClaim, slackAuthorizedProjectId, requestedProjectId, and projectMatch fields.

  2. Stricter slackAuthorized condition (source !== 'none')Declined. Investigated resolveEffectiveAgent — it returns null when no agent is configured (neither channel nor workspace). It never returns source: 'none'. The condition agentConfig != null is already correct because a non-null return always has source: 'channel' or source: 'workspace'.

  3. Test for authSource default fallbackAccepted. Added test case in api-key-auth tests verifying that when authorized: true with missing authSource, the metadata defaults to 'channel'.

Copy link
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

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

PR Review Summary

(0) Total Issues | Risk: Low


Re-Review Assessment

This is a re-review scoped to the 2 commits since the last automated review (786a3317, 39f6eef1). The delta addresses all 5 issues raised in the prior review:

Prior Issue Status Verification
🟠 Missing changeset for @inkeep/agents-core RESOLVED .changeset/christian-lime-piranha.md added with correct content
🟠 Schema allows incomplete authorization states RESOLVED .refine() added to enforce authorized: true requires both authorizedProjectId and authSource
🟠 Missing test verification of channel auth params RESOLVED app-mention.test.ts now verifies signSlackUserToken is called with correct params
🟡 Type allows authorized: false but runtime only populates when true RESOLVED Changed to authorized: true literal type
💭 Add debug log when bypass is skipped RESOLVED Debug log added with slackAuthorizedClaim, slackAuthorizedProjectId, requestedProjectId, and projectMatch fields

Delta Quality Assessment

The delta changes are well-implemented:

  • Schema invariant (.refine()) is clean and follows Zod best practices
  • Debug logging includes all relevant fields for debugging authorization issues
  • Type narrowing (authorized: true literal) accurately reflects runtime behavior
  • Test coverage verifies the critical integration point between work app and JWT signing
  • Two new tests for schema invariant enforcement (authorized without authorizedProjectId, authorized without authSource)

No New Issues

The delta introduces no new concerns. All changes are focused remediation of prior feedback.


✅ APPROVE

Summary: All prior review feedback has been addressed comprehensively. The implementation is well-designed with appropriate security controls (project binding, JWT signature verification, short TTL, graceful fallback to SpiceDB), proper schema invariants, and good observability. Ready to ship! 🚀

Reviewers (0)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
(none dispatched — delta is remediation only)

Note: Reviewer dispatch skipped because the delta consists entirely of remediation for prior review feedback. No new functional changes to review.

@github-actions github-actions bot deleted a comment from claude bot Feb 16, 2026
…+ OTel spans

- Modal submissions (call sites 3-4): explicit slackAuthorized: false
- /inkeep run and /inkeep list (call sites 6-7): explicit slackAuthorized: false
- OTel: add AUTHORIZED and AUTH_SOURCE to SLACK_SPAN_KEYS
- Set slack.authorized and slack.auth_source span attributes in app-mention and modal-submission handlers
- Add modal-submission test file verifying slackAuthorized: false and span attributes
- Add workspace auth source test to app-mention tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

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

PR Review Summary

(0) Total Issues | Risk: Low


Re-Review Assessment

This is a re-review scoped to 2 commits since the last automated review (83099d7e). The delta is a merge from main only — it brings in CI/infrastructure improvements but contains no changes to the PR's feature code.

Delta Change Source Assessment
.github/workflows/ci.yml main merge ✅ Unrelated — Next.js build cache setup
.github/workflows/cypress.yml main merge ✅ Unrelated — Next.js build cache setup
agents-manage-ui/next.config.ts main merge ✅ Unrelated — Turbopack filesystem cache

None of the PR's actual files have changed since the last review:

  • JWT schema (slack-user-token.ts) — unchanged
  • Auth middleware (runAuth.ts) — unchanged
  • Agent resolution (agent-resolution.ts) — unchanged
  • UI toggle (channel-agent-cell.tsx) — unchanged
  • All tests — unchanged
  • Documentation — unchanged

Prior Review Status

This PR has been reviewed 9 times by automated review, with all issues resolved:

Review Outcome Notes
Initial REQUEST CHANGES 4 issues raised
Re-review 1 ✅ APPROVE All issues resolved
Re-review 2–8 ✅ APPROVE Clean deltas, 0 new issues
This review ✅ APPROVE Merge-only delta, no feature changes

No New Issues

The delta introduces no functional changes to review. All PR files remain unchanged from the previously approved state.


✅ APPROVE

Summary: This is a routine merge of main into the feature branch bringing in CI/build improvements (Next.js build caching, Turbopack filesystem cache). The PR's channel-based Slack authorization feature is complete and unchanged from the prior approved state. All 9 prior review rounds have confirmed the implementation is well-designed with appropriate security controls (project binding, JWT signature verification, short TTL, graceful SpiceDB fallback), comprehensive test coverage (40+ tests), and proper documentation. Ship it! 🚀

Reviewers (0)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
(none dispatched — delta contains no feature changes)

Note: Reviewer dispatch skipped because the delta consists entirely of a merge from main with no changes to PR files.

Copy link
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

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

PR Review Summary

(0) Total Issues | Risk: Low


Re-Review Assessment

This is a re-review scoped to 1 commit (3b999da3e) since the last automated review (206b342fd). The delta is a merge from main only — it brings in CI/infrastructure improvements but contains no changes to the PR's feature code.

Delta Change Source Assessment
.changeset/*.md main merge ✅ Unrelated — version packages cleanup
.github/workflows/*.yml main merge ✅ Unrelated — CI workflow improvements
agents-api/src/__tests__/*.ts main merge ✅ Unrelated — test infrastructure improvements
agents-api/src/domains/manage/routes/signoz.ts main merge ✅ Unrelated — SigNoz route additions
agents-manage-ui/* main merge ✅ Unrelated — UI improvements and bug fixes
packages/agents-core/src/utils/mock-provider.ts main merge ✅ Unrelated — mock provider for testing

None of the PR's actual files have changed since the last review:

  • JWT schema (slack-user-token.ts) — unchanged
  • Auth middleware (runAuth.ts) — unchanged
  • Agent resolution (agent-resolution.ts) — unchanged
  • UI toggle (channel-agent-cell.tsx) — unchanged
  • All tests — unchanged
  • Documentation — unchanged

Prior Review Status

This PR has been reviewed 10 times by automated review, with all issues resolved:

Review Outcome Notes
Initial REQUEST CHANGES 4 issues raised
Re-review 1 ✅ APPROVE All issues resolved
Re-review 2–9 ✅ APPROVE Clean deltas, 0 new issues
This review ✅ APPROVE Merge-only delta, no feature changes

No New Issues

The delta introduces no functional changes to review. All PR files remain unchanged from the previously approved state.


✅ APPROVE

Summary: This is a routine merge of main into the feature branch bringing in CI/build improvements (mock provider for testing, SigNoz routes, workflow optimizations). The PR's channel-based Slack authorization feature is complete and unchanged from the prior approved state. All 10 prior review rounds have confirmed the implementation is well-designed with appropriate security controls (project binding, JWT signature verification, short TTL, graceful SpiceDB fallback), comprehensive test coverage (40+ tests), and proper documentation. Ship it! 🚀

Reviewers (0)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
(none dispatched — delta contains no feature changes)

Note: Reviewer dispatch skipped because the delta consists entirely of a merge from main with no changes to PR files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolve conflicts in app-mention.ts and app-mention.test.ts:
- Keep resolveEffectiveAgent from PR branch
- Adopt timedOp pattern from main for consistent timing instrumentation
- Keep separate agent-resolution mock in tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@claude claude bot left a comment

Choose a reason for hiding this comment

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

PR Review Summary

(0) Total Issues | Risk: Low


Re-Review Assessment

This is a re-review scoped to 6 commits since the last automated review (3b999da3e). The delta contains:

Delta Change Source Assessment
.changeset/yabbering-teal-squirrel.md PR #2072 merge ✅ Unrelated — changeset for Slack message formatting
.github/workflows/ci.yml PR #2092 merge ✅ Unrelated — CI build/test phase splitting
agents-manage-ui/.../form.browser.test.tsx PR #2088 merge ✅ Unrelated — Monaco waitFor timeout increase
src/slack/services/client.ts PR #2072 merge ✅ Compatible — new getSlackChannelInfo() helper
src/slack/services/events/app-mention.ts PR #2072 merge ✅ Compatible — channel/user context enrichment
src/slack/services/events/utils.ts PR #2072 merge ✅ Compatible — new helpers (timedOp, formatChannelContext)
src/__tests__/slack/*.test.ts PR #2072 merge ✅ Compatible — test updates for new message formats

Authorization Path Verification

The channel authorization feature code is unchanged in this delta:

Location Code Status
app-mention.ts:167 span.setAttribute(SLACK_SPAN_KEYS.AUTHORIZED, agentConfig.grantAccessToMembers) ✅ Unchanged
app-mention.ts:250-254 JWT signing with slackAuthorized: agentConfig?.grantAccessToMembers ?? false ✅ Unchanged
app-mention.ts:352-356 JWT signing with channel auth context ✅ Unchanged

The merged changes from PR #2072 enhance the Slack message context (adding channel names, user display names, structured thread formatting) without modifying the authorization logic. The new helpers have proper error handling with graceful fallbacks:

  • getSlackChannelInfo() returns null on error
  • formatChannelContext() falls back to 'Slack' when channel info unavailable
  • timedOp() logs slow operations without affecting execution

Prior Review Status

Review Outcome Notes
Initial REQUEST CHANGES 4 issues raised
Re-review 1 ✅ APPROVE All issues resolved
Re-review 2–10 ✅ APPROVE Clean deltas, 0 new issues
This review ✅ APPROVE Merged improvements, no authorization changes

No New Issues

The delta introduces no concerns affecting the channel-based authorization feature. All PR files related to authorization remain unchanged from the previously approved state.


✅ APPROVE

Summary: This delta merges improvements from main including enhanced Slack message context (PR #2072) and CI optimizations (PR #2088, #2092). The channel-based authorization feature is complete and unchanged — JWT schema with .refine() invariant, SpiceDB bypass logic, grantAccessToMembers toggle, and all 40+ tests remain intact. The merged changes are additive enhancements that improve message readability without affecting security controls. Ship it! 🚀

Reviewers (0)
Reviewer Returned Main Findings Consider While You're Here Inline Comments Pending Recs Discarded
(none dispatched — delta review)

Note: No sub-reviewers dispatched for this delta re-review. The changes are merged improvements from main that don't touch the authorization feature code, so specialized review was not warranted.

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

Comments