Repository navigation
feat: add requester-approved delegation to registered runners - #37
Merged
Merged
Conversation
added 4 commits
October 7, 2026 14:57
Let allowlisted requesters hand a captured thread to a registered runner without letting thread content or another user authorize the task. Use state and runner compare-and-set transitions, recoverable hashed task tokens, and per-instance expiry so dispatch failures stay queued and progress stays scoped to the approved thread until completion.
…t task tokens With delegation configured, POST /progress, GET /progress/replies and GET /progress/channels answered 403 token_scope to any request whose bearer was absent or unknown, where the base answered 401 unauthorized. The contract reserves 403 token_scope for a live task token used outside its own channel, thread and task; a bearer that is no task token, or a revoked one, is no credential and stays 401, as on the /delegation routes. Closes the review P1 on the unrequested change to the existing progress refusal; the new assertions fail with 403 without this change.
Only an allowlisted Slack user may hand a thread to a runner, yet removing the allowedUserIds condition in mountDelegationTool left every test green. The operator config in the agent test now carries delegation and an allowlist, and a DM from a user outside it must mount no tool. Closes the review P1 at apps/slack-agent/src/agent.ts:137; the new test fails with the condition removed.
Section 8 dispatches the approved task with the configured runner headers, and without them the access gateway answers 403 in production, yet dropping them from POST /tasks left every test green because only the health probe asserted them. Closes the review P1 at apps/slack-agent/test/delegation.test.ts:413; the dispatch assertions fail with the headers removed from POST /tasks.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
An allowlisted Slack requester can delegate a bug thread to a registered runner after approving its button.
The worker captures the raw thread, binds decisions to the requester, and keeps a refused dispatch approved and queued until the runner returns.
Changes
delegate_to_conductorfor a bound channel thread or an admitted channel from an owner's DM.waitUntil, and post Started only after the runner reports running.Verification
Verify: PASS at
084f2fec1e310416f60537adc0fbb5f842be3b8cwith Bun 1.4.2, 358 tests passed and 0 failed.bun install --frozen-lockfilebun run format:checkbun run lintbun run typecheckbun testbun run knipbun run deploy:drybun audit --ignore=GHSA-vfj7-8cjw-p6xm(no vulnerabilities, one ignored advisory)bun run verifyCoverage includes opt-in configuration/instructions, migration persistence, code-owned capture, requester decisions, queued and refused sends, instance expiry, approval/cancellation/expiry races, competing claims, holder recovery and token revocation, runner transitions, scoped progress/replies, verbatim completion, and a fetch double rejecting object receivers and
redirect: "error"on injected and default global fetch paths.Eleven temporary behavior removals each produced a regression failure and were restored; separate red/green cases cover retention preceding task expiry and long summaries with a 300-character title.
No dependency, lockfile, deployment configuration or CI changes.
CI: PASS at
084f2fec1e310416f60537adc0fbb5f842be3b8c, verify run completed successfully in 51 seconds with the workflow-pinned Bun 1.3.14.Not covered
Live Slack, Access and a real runner (wave-end pass).