# Fix Delegate-Task Subagent Permissions ## TL;DR > Summary: Fix OMO `task` so delegated subagents can use repo exploration tools in their child sessions without permission prompts or denials. Match OpenCode native Task semantics by deriving child-session permissions and prompt tools from the delegated agent instead of only denying `question`. > Deliverables: > - Shared subagent permission/tool builder with unit coverage > - Sync delegate-task child-session permission fix > - Background and unstable delegate-task permission fix > - Regression coverage for `read`/`bash`/search access and write/tool delegation denial > - Module QA plus real tmux/non-interactive QA evidence > Effort: Medium > Risk: Medium — permission rules affect delegated child-session execution and can accidentally over-allow tools if not scoped. ## Scope ### Must have - Subagents launched through OMO `task` can call repo exploration tools such as `read`, `bash`, `grep`, and `glob` in child sessions. - Sync child sessions are created with `parentID`, OpenCode-compatible title, model fields, directory route, and a derived permission ruleset. - Background child sessions receive the same derived permission ruleset through `LaunchInput.sessionPermission`. - Prompt bodies for sync, background launch, background resume, and fallback-agent retry use the same derived prompt tool map so `session.prompt` does not overwrite useful child-session permissions with deny-only rules. - `question` remains denied for delegated child sessions. - Read-only subagents still cannot write or recursively delegate: `write`, `edit`, `apply_patch`, `task`, and `call_omo_agent` remain denied where the delegated agent restrictions deny them. - Existing task metadata contract remains intact: `sessionId` is published and visible task metadata still includes `session_id`. - Regression tests prove both sync and background paths include explicit `allow` rules for exploration tools and explicit `deny` rules for restricted tools. - Real tmux/manual QA proves an `explore` subagent launched by `task` can inspect files and run a harmless shell command without `"Permission required"` output. ### Must NOT have (guardrails, anti-slop, scope boundaries) - Do not disable OpenCode permission checks globally. - Do not add `permission: "*", action: "allow"` or any broad wildcard allow. - Do not grant write/edit/apply_patch to `explore`, `librarian`, or `oracle`. - Do not refactor background polling, concurrency, wake gating, model fallback, or tmux layout. - Do not change agent prompts, category model selection, metadata formatting, or task output text except where tests require permission metadata. - Do not remove `getAgentToolRestrictions`; centralize the new derived session permission behavior around it or a closely related shared helper. - Do not change the native OpenCode source under `../opencode`. ## Verification strategy > Zero human intervention — all verification is agent-executed. - Test decision: TDD + Bun test - QA policy: every task has agent-executed scenarios - Evidence: `evidence/task--.` ## Execution strategy ### Parallel execution waves > Target 5-8 tasks per wave. <3 per wave (except final) = under-splitting. > Extract shared dependencies as Wave-1 tasks to maximize parallelism. Wave 1 (no dependencies): - Task 1: Add shared subagent permission/tool builder and focused unit tests - Task 2: Add native-reference contract tests around existing permission fixtures Wave 2 (after Wave 1): - Task 3: depends [1, 2] - Wire sync delegate-task session creation and prompt body - Task 4: depends [1, 2] - Wire background and unstable delegate-task launch path - Task 5: depends [1] - Wire background resume and fallback-agent prompt bodies Wave 3 (after Wave 2): - Task 6: depends [3, 4, 5] - Run module QA and lock regression output - Task 7: depends [3, 4, 5] - Run real tmux/manual QA for delegated exploration Critical path: Task 1 -> Task 3 -> Task 6 ### Dependency matrix | Task | Depends on | Blocks | Can parallelize with | |------|------------|--------|----------------------| | 1 | none | 3, 4, 5, 6, 7 | 2 | | 2 | none | 3, 4, 6, 7 | 1 | | 3 | 1, 2 | 6, 7 | 4, 5 | | 4 | 1, 2 | 6, 7 | 3, 5 | | 5 | 1 | 6, 7 | 3, 4 | | 6 | 3, 4, 5 | none | 7 | | 7 | 3, 4, 5 | none | 6 | ## Todos > Implementation + Test = ONE task. Never separate. > Every task MUST have: References + Acceptance Criteria + QA Scenarios + Commit. - [ ] 1. Add shared subagent permission/tool builder What to do: Create one focused helper, preferably `src/shared/subagent-session-permission.ts`, plus `src/shared/subagent-session-permission.test.ts`. The helper must produce both: - `buildSubagentSessionPermission(agentName, options): SessionPermissionRule[]` - `buildSubagentPromptTools(agentName, options): Record` Required behavior: - Convert OMO permission-map values (`"allow" | "deny" | "ask"`) into OpenCode session rules (`{ permission, action, pattern: "*" }`). - Always include `{ permission: "question", action: "deny", pattern: "*" }`. - Add explicit `allow` rules for repo exploration tools when not denied by the agent: `read`, `bash`, `grep`, `glob`, `lsp_symbols`, `lsp_goto_definition`, `lsp_find_references`, `lsp_diagnostics`, `ast_grep_search`. - Apply agent/tool deny rules last so read-only restrictions win over defaults. - Preserve team-tool denylist behavior when `includeTeamToolDenylist` is true. - Do not add wildcard allow rules. Must NOT do: Do not change any call sites yet. Do not change agent definitions. Do not add a generic `utils.ts` or `helpers.ts`. Parallelization: Can parallel: YES | Wave 1 | Blocks: [3, 4, 5, 6, 7] | Blocked by: [] References (executor has NO interview context — be exhaustive): - Pattern: `src/shared/agent-tool-restrictions.ts:24` — current read-only denylist omits explicit `read`/`bash` allows, which leaves child sessions in ask/permission-required state. - Pattern: `src/shared/agent-tool-restrictions.ts:66` — current `getAgentToolRestrictions()` is the source of prompt-body deny rules and team-tool deny rules. - Pattern: `src/shared/question-denied-session-permission.ts:1` — current ruleset shape and `QUESTION_DENIED_SESSION_PERMISSION`. - Pattern: `src/shared/permission-compat.ts:6` — OMO agent permission map value type. - Pattern: `src/agents/explore.ts:27` — `explore` denies write/edit/apply_patch/task/call_omo_agent and explicitly allows some LSP/AST tools. - Pattern: `src/agents/librarian.ts:24` — `librarian` denies write/edit/apply_patch/task/call_omo_agent. - External: `../opencode/packages/opencode/src/agent/subagent-permissions.ts:17` — native Task derives child-session permissions from parent and subagent rules. - External: `../opencode/packages/opencode/src/permission/evaluate.ts:9` — missing rule defaults to `ask`, which is the source of permission prompts/denials. - Test: `src/agents/tool-restrictions.test.ts` — existing assertions around agent permission maps. Acceptance criteria (agent-executable only): - [ ] `bun test src/shared/subagent-session-permission.test.ts --bail` passes. - [ ] Test asserts `buildSubagentSessionPermission("explore")` contains `allow` for `read`, `bash`, `grep`, and `glob`. - [ ] Test asserts `buildSubagentSessionPermission("explore")` contains `deny` for `write`, `edit`, `apply_patch`, `task`, `call_omo_agent`, and `question`. - [ ] Test asserts no generated rule is `{ permission: "*", action: "allow", pattern: "*" }`. - [ ] Test asserts prompt tools mirror the permission intent: exploration tools `true`, restricted tools `false`. QA scenarios (MANDATORY — task incomplete without these): ``` Scenario: explore permission builder allows read-only repo exploration Tool: bash Steps: mkdir -p evidence && bun test src/shared/subagent-session-permission.test.ts --bail > evidence/task-1-permission-builder.txt Expected: Exit 0, and test names mention read/bash exploration allow plus write/edit denial. Evidence: evidence/task-1-permission-builder.txt Scenario: builder rejects overbroad wildcard allow Tool: bash Steps: rg -n 'permission: "\\*", action: "allow"|\\["\\*", true\\]' src/shared/subagent-session-permission.ts src/shared/subagent-session-permission.test.ts > evidence/task-1-wildcard-scan.txt; test ! -s evidence/task-1-wildcard-scan.txt Expected: Exit 0 and evidence file is empty. Evidence: evidence/task-1-wildcard-scan.txt ``` Commit: YES | Message: `fix(task): derive subagent exploration permissions` | Files: [`src/shared/subagent-session-permission.ts`, `src/shared/subagent-session-permission.test.ts`] - [ ] 2. Add native-reference contract tests around current fixtures What to do: Update current permission tests so they describe the native-compatible contract before wiring code: - `src/tools/delegate-task/sync-session-creator.test.ts` - `src/tools/delegate-task/background-task.test.ts` - `src/features/background-agent/manager-session-permission.test.ts` The tests must assert that child session creation receives a permission ruleset with explicit exploration allows and restricted-tool denies. Keep existing title, `parentID`, and directory assertions. Must NOT do: Do not make broad behavior changes in this task except the minimal helper import needed if Task 1 already exists. Do not delete the old `question` denial assertion; update it into the larger ruleset. Parallelization: Can parallel: YES | Wave 1 | Blocks: [3, 4, 6, 7] | Blocked by: [] References (executor has NO interview context — be exhaustive): - Pattern: `src/tools/delegate-task/sync-session-creator.test.ts:5` — current sync child-session test only expects `question` deny. - Pattern: `src/tools/delegate-task/background-task.test.ts:209` — current delegate background launch test only expects `question` deny in `sessionPermission`. - Pattern: `src/features/background-agent/manager-session-permission.test.ts:84` — manager-level test asserts explicit session permission rules are passed into `session.create`. - External: `../opencode/packages/opencode/src/tool/task.ts:152` — native Task creates child session with `parentID`, title, and derived permission. - External: `../opencode/packages/opencode/src/tool/task.ts:178` — native Task metadata includes child `sessionId`. Acceptance criteria (agent-executable only): - [ ] `bun test src/tools/delegate-task/sync-session-creator.test.ts src/tools/delegate-task/background-task.test.ts src/features/background-agent/manager-session-permission.test.ts --bail` initially fails before Tasks 3 and 4 if run after only test edits. - [ ] Tests assert `parentID` and title stay unchanged. - [ ] Tests assert permission arrays contain `allow` for `read` and `bash`. - [ ] Tests assert permission arrays contain `deny` for `question`, `write`, `edit`, `apply_patch`, and `task`. QA scenarios (MANDATORY — task incomplete without these): ``` Scenario: contract tests capture the regression Tool: bash Steps: mkdir -p evidence && bun test src/tools/delegate-task/sync-session-creator.test.ts src/tools/delegate-task/background-task.test.ts src/features/background-agent/manager-session-permission.test.ts --bail > evidence/task-2-contract-tests.txt || true Expected: Evidence shows the new expectations before implementation, or passes if Task 3/4 are already applied by parallel execution. Evidence: evidence/task-2-contract-tests.txt Scenario: existing metadata contract remains present Tool: bash Steps: rg -n 'session_id|sessionId|parentID|@\\$\\{.*subagent|@explore subagent' src/tools/delegate-task/sync-session-creator.test.ts src/tools/delegate-task/background-task.test.ts src/features/background-agent/manager-session-permission.test.ts > evidence/task-2-metadata-contract.txt Expected: Evidence includes session lineage/title assertions, not only permission assertions. Evidence: evidence/task-2-metadata-contract.txt ``` Commit: YES | Message: `test(task): pin subagent session permission contract` | Files: [`src/tools/delegate-task/sync-session-creator.test.ts`, `src/tools/delegate-task/background-task.test.ts`, `src/features/background-agent/manager-session-permission.test.ts`] - [ ] 3. Wire sync delegate-task session creation and prompt body What to do: - Update `createSyncSession()` to accept an optional `sessionPermission` argument and use it instead of hardcoded `QUESTION_DENIED_SESSION_PERMISSION`. - Update `executeSyncTask()` to pass `buildSubagentSessionPermission(agentToUse, ...)` on initial child session creation and retry child session creation. - Update `sendSyncPrompt()` to use `buildSubagentPromptTools(agentToUse, { allowTask })` rather than assembling a deny-only map inline. - Keep `setSessionTools()` and `applySessionPromptParams()` behavior. - Keep `routePromptRetry()` and `routePromptSyncRetry()` behavior unchanged. Must NOT do: Do not alter polling, fetch result, fallback selection, metadata formatting, or `promptAsync` gate behavior. Parallelization: Can parallel: YES | Wave 2 | Blocks: [6, 7] | Blocked by: [1, 2] References (executor has NO interview context — be exhaustive): - Pattern: `src/tools/delegate-task/sync-session-creator.ts:20` — current sync child session creation hardcodes `QUESTION_DENIED_SESSION_PERMISSION`. - Pattern: `src/tools/delegate-task/sync-task.ts:88` — initial sync child session is created here. - Pattern: `src/tools/delegate-task/sync-task.ts:264` — fallback retry creates another sync child session and must receive the same derived permission rules. - Pattern: `src/tools/delegate-task/sync-prompt-sender.ts:70` — prompt body currently builds tools from `getAgentToolRestrictions()` only. - Pattern: `src/tools/delegate-task/sync-prompt-route.test.ts:16` — existing route tests must keep passing. - External: `../opencode/packages/opencode/src/tool/task.ts:194` — native Task prompts `nextSession.id`, not parent session. - External: `../opencode/packages/opencode/src/session/prompt.ts:1622` — prompt `tools` are converted into session permission rules, so prompt body must not erase exploration allows. Acceptance criteria (agent-executable only): - [ ] `bun test src/tools/delegate-task/sync-session-creator.test.ts src/tools/delegate-task/sync-prompt-sender.test.ts src/tools/delegate-task/sync-prompt-route.test.ts src/tools/delegate-task/sync-task.test.ts --bail` passes. - [ ] `createSyncSession()` tests prove sync child session body includes `allow` rules for `read` and `bash`. - [ ] `sendSyncPrompt()` tests prove prompt body tools include `read: true`, `bash: true`, `grep: true`, `glob: true`, `question: false`, and `write/edit/apply_patch/task` false for `explore`. - [ ] Sync route tests still prove prompts are routed to the child session directory. - [ ] Retry path tests prove fallback child sessions also receive derived permission rules. QA scenarios (MANDATORY — task incomplete without these): ``` Scenario: sync task creates an exploration-capable child session Tool: bash Steps: mkdir -p evidence && bun test src/tools/delegate-task/sync-session-creator.test.ts src/tools/delegate-task/sync-prompt-sender.test.ts src/tools/delegate-task/sync-prompt-route.test.ts src/tools/delegate-task/sync-task.test.ts --bail > evidence/task-3-sync-permissions.txt Expected: Exit 0; evidence contains passing sync permission and prompt-body tests. Evidence: evidence/task-3-sync-permissions.txt Scenario: sync prompt still denies recursive delegation and writes Tool: bash Steps: bun test src/tools/delegate-task/sync-prompt-sender.test.ts --bail > evidence/task-3-sync-denies.txt Expected: Exit 0; tests assert `task`, `call_omo_agent`, `write`, `edit`, and `apply_patch` are false for read-only subagents. Evidence: evidence/task-3-sync-denies.txt ``` Commit: YES | Message: `fix(task): pass derived permissions to sync subagents` | Files: [`src/tools/delegate-task/sync-session-creator.ts`, `src/tools/delegate-task/sync-task.ts`, `src/tools/delegate-task/sync-prompt-sender.ts`, related tests] - [ ] 4. Wire background and unstable delegate-task launch path What to do: - Update `executeBackgroundTask()` to pass `buildSubagentSessionPermission(normalizedAgent, ...)` into `manager.launch()`. - Update `executeUnstableAgentTask()` to pass the same derived permission builder into `manager.launch()`. - Update `BackgroundManager`/`startTask()` permission tests to expect derived session permissions. - Keep `LaunchInput.sessionPermission` optional for other callers. - Keep background metadata and `buildTaskMetadataBlock()` output unchanged. Must NOT do: Do not change background task concurrency, polling, idle detection, parent wake notification, or cancellation behavior. Parallelization: Can parallel: YES | Wave 2 | Blocks: [6, 7] | Blocked by: [1, 2] References (executor has NO interview context — be exhaustive): - Pattern: `src/tools/delegate-task/background-task.ts:116` — background delegate-task launch currently passes only `QUESTION_DENIED_SESSION_PERMISSION`. - Pattern: `src/tools/delegate-task/unstable-agent-task.ts:32` — unstable-agent path also passes only `QUESTION_DENIED_SESSION_PERMISSION`. - Pattern: `src/features/background-agent/types.ts:102` — `LaunchInput.sessionPermission` type is already the correct extension point. - Pattern: `src/features/background-agent/spawner.ts:100` — `startTask()` passes `input.sessionPermission` into `client.session.create`. - Test: `src/tools/delegate-task/background-task.test.ts:209` — update this existing background permission assertion. - Test: `src/tools/delegate-task/unstable-agent-permission.test.ts` — update unstable path assertion. - Test: `src/features/background-agent/manager-session-permission.test.ts:84` — manager-level permission passthrough coverage. Acceptance criteria (agent-executable only): - [ ] `bun test src/tools/delegate-task/background-task.test.ts src/tools/delegate-task/unstable-agent-permission.test.ts src/features/background-agent/manager-session-permission.test.ts --bail` passes. - [ ] Background launch tests assert `manager.launch().sessionPermission` includes `read`/`bash` allows for `explore`. - [ ] Background launch tests assert write/edit/apply_patch/task/call_omo_agent/question denies remain. - [ ] Manager passthrough test proves `client.session.create().body.permission` receives the derived ruleset exactly. QA scenarios (MANDATORY — task incomplete without these): ``` Scenario: background launch passes derived permissions through manager Tool: bash Steps: mkdir -p evidence && bun test src/tools/delegate-task/background-task.test.ts src/tools/delegate-task/unstable-agent-permission.test.ts src/features/background-agent/manager-session-permission.test.ts --bail > evidence/task-4-background-permissions.txt Expected: Exit 0; evidence shows background and unstable permission tests pass. Evidence: evidence/task-4-background-permissions.txt Scenario: background metadata remains OpenCode-compatible Tool: bash Steps: bun test src/tools/delegate-task/background-task.test.ts --bail > evidence/task-4-background-metadata.txt Expected: Exit 0; existing metadata tests still pass and visible output contains `session_id`. Evidence: evidence/task-4-background-metadata.txt ``` Commit: YES | Message: `fix(task): pass derived permissions to background subagents` | Files: [`src/tools/delegate-task/background-task.ts`, `src/tools/delegate-task/unstable-agent-task.ts`, `src/features/background-agent/manager-session-permission.test.ts`, related tests] - [ ] 5. Wire background resume and fallback prompt bodies What to do: - Update `src/features/background-agent/spawner.ts` initial prompt body, resume prompt body, and fallback-agent prompt body to use `buildSubagentPromptTools()`. - Keep `includeTeamToolDenylist: input.teamRunId === undefined` behavior. - Keep fallback agent behavior, `releasePromptAsyncReservation()`, and `task.agent = FALLBACK_AGENT` unchanged. - Add tests that `promptAsync` body for launch and resume includes `read: true`, `bash: true`, and restricted-tool denies for `explore`. Must NOT do: Do not change session creation, concurrency release, tmux callback timing, or fallback-agent selection. Parallelization: Can parallel: YES | Wave 2 | Blocks: [6, 7] | Blocked by: [1] References (executor has NO interview context — be exhaustive): - Pattern: `src/features/background-agent/spawner.ts:158` — initial background prompt body currently builds tool map inline. - Pattern: `src/features/background-agent/spawner.ts:29` — fallback prompt body currently builds a second inline tool map. - Pattern: `src/features/background-agent/spawner.ts:299` — resume prompt body currently builds another inline tool map. - Test: `src/features/background-agent/manager-session-permission.test.ts:9` — already captures prompt route and can be extended or paired with a new focused test. - External: `../opencode/packages/opencode/src/session/prompt.ts:1622` — prompt body tools become session permission rules. Acceptance criteria (agent-executable only): - [ ] `bun test src/features/background-agent/manager-session-permission.test.ts src/features/background-agent/manager.test.ts src/features/background-agent/spawner.test.ts --bail` passes, or if `manager.test.ts` is too broad/slow, record the narrower replacement command in evidence. - [ ] A launch prompt test asserts exploration tools are explicitly true and restricted tools false. - [ ] A resume prompt test asserts the same tool map contract. - [ ] Existing fallback-agent retry tests still pass. QA scenarios (MANDATORY — task incomplete without these): ``` Scenario: background launch prompt keeps exploration tools enabled Tool: bash Steps: mkdir -p evidence && bun test src/features/background-agent/manager-session-permission.test.ts --bail > evidence/task-5-background-prompt-tools.txt Expected: Exit 0; evidence includes prompt body assertions for read/bash and restricted-tool denies. Evidence: evidence/task-5-background-prompt-tools.txt Scenario: no prompt gate or fallback routing regression Tool: bash Steps: bun test src/features/background-agent/manager.test.ts src/features/background-agent/spawner.test.ts --bail > evidence/task-5-background-manager.txt Expected: Exit 0, or if pre-existing unrelated failures occur, evidence includes exact failing test names and a narrower passing command that covers spawner prompt behavior. Evidence: evidence/task-5-background-manager.txt ``` Commit: YES | Message: `fix(background-agent): keep exploration tools enabled in subagent prompts` | Files: [`src/features/background-agent/spawner.ts`, `src/features/background-agent/manager-session-permission.test.ts`, related tests] - [ ] 6. Run module QA and lock regression evidence What to do: - Run focused delegate-task/background-agent tests. - Run typecheck. - Run the full root test suite if focused tests and typecheck pass. - Capture evidence files and summarize failures only if unrelated/pre-existing. Must NOT do: Do not fix unrelated failures. Do not weaken tests to pass. Do not skip typecheck. Parallelization: Can parallel: YES | Wave 3 | Blocks: [] | Blocked by: [3, 4, 5] References (executor has NO interview context — be exhaustive): - Command: `bun test src/tools/delegate-task/sync-session-creator.test.ts src/tools/delegate-task/sync-prompt-sender.test.ts src/tools/delegate-task/sync-prompt-route.test.ts src/tools/delegate-task/sync-task.test.ts src/tools/delegate-task/background-task.test.ts src/tools/delegate-task/unstable-agent-permission.test.ts src/features/background-agent/manager-session-permission.test.ts --bail` - Command: `bun run typecheck` - Command: `bun test` - Pattern: `package.json` — scripts use Bun only; no npm/yarn/pnpm. Acceptance criteria (agent-executable only): - [ ] Focused delegate-task/background-agent test command exits 0. - [ ] `bun run typecheck` exits 0. - [ ] `bun test` exits 0, or evidence documents exact unrelated pre-existing failures with focused command still green. - [ ] No `as any`, `@ts-ignore`, or `@ts-expect-error` introduced. QA scenarios (MANDATORY — task incomplete without these): ``` Scenario: focused module regression suite Tool: bash Steps: mkdir -p evidence && bun test src/tools/delegate-task/sync-session-creator.test.ts src/tools/delegate-task/sync-prompt-sender.test.ts src/tools/delegate-task/sync-prompt-route.test.ts src/tools/delegate-task/sync-task.test.ts src/tools/delegate-task/background-task.test.ts src/tools/delegate-task/unstable-agent-permission.test.ts src/features/background-agent/manager-session-permission.test.ts --bail > evidence/task-6-focused-tests.txt Expected: Exit 0. Evidence: evidence/task-6-focused-tests.txt Scenario: typecheck and anti-suppression scan Tool: bash Steps: bun run typecheck > evidence/task-6-typecheck.txt && rg -n 'as any|@ts-ignore|@ts-expect-error' src/shared/subagent-session-permission.ts src/tools/delegate-task src/features/background-agent > evidence/task-6-suppression-scan.txt || true Expected: Typecheck exits 0; suppression scan contains no new suppressions in changed files. Evidence: evidence/task-6-typecheck.txt ``` Commit: NO | Message: `test(task): verify delegate-task permission regression` | Files: [`evidence/task-6-focused-tests.txt`, `evidence/task-6-typecheck.txt`, `evidence/task-6-suppression-scan.txt`] - [ ] 7. Run real tmux/manual QA for delegated exploration What to do: - Build the local plugin. - Run a real OMO non-interactive session inside tmux from this repo that forces `task(subagent_type="explore", run_in_background=false or true)` to inspect a known file and run a harmless shell command. - Confirm output contains the expected file fact and does not contain `"Permission required"`, `"missing permission"`, or `"permission denied"` for `read`/`bash`. - Repeat with background mode and collect `background_output` after system completion. - Capture tmux pane output and `/tmp/oh-my-opencode.log` excerpts. Must NOT do: Do not run destructive shell commands. Do not use `sleep`; use tmux capture/polling loops with bounded attempts. Parallelization: Can parallel: YES | Wave 3 | Blocks: [] | Blocked by: [3, 4, 5] References (executor has NO interview context — be exhaustive): - Command: `bun run build` — local plugin build. - Command: `bun src/cli/index.ts run --agent Sisyphus --directory /Users/yeongyu/local-workspaces/omo --json ""` - Pattern: `src/cli/cli-program.ts:74` — local CLI supports `run `. - Pattern: `src/cli/run/AGENTS.md` — run command waits for todos/background tasks. - Pattern: `src/tools/delegate-task/tools.ts:21` — `run_in_background` controls sync/background delegation. - Pattern: `/tmp/oh-my-opencode.log` — project logger destination. Acceptance criteria (agent-executable only): - [ ] `bun run build` exits 0. - [ ] tmux sync QA output includes an `explore` result referencing `src/tools/delegate-task/sync-session-creator.ts`. - [ ] tmux sync QA output has no case-insensitive match for `Permission required|missing permission|permission denied`. - [ ] tmux background QA output includes a background task ID and collected result. - [ ] `/tmp/oh-my-opencode.log` has no child-session permission rejection for the QA session. QA scenarios (MANDATORY — task incomplete without these): ``` Scenario: sync delegated explore can read and run harmless bash Tool: tmux Steps: mkdir -p evidence && bun run build > evidence/task-7-build.txt && tmux new-session -d -s omo-delegate-sync-qa 'cd /Users/yeongyu/local-workspaces/omo && bun src/cli/index.ts run --agent Sisyphus --directory /Users/yeongyu/local-workspaces/omo --json "Use task with subagent_type=explore, run_in_background=false, load_skills=[] to inspect src/tools/delegate-task/sync-session-creator.ts and run pwd. Report the permission field behavior and the cwd."' ; poll `tmux capture-pane -pt omo-delegate-sync-qa` until the command exits or the pane shows JSON; save final capture. Expected: Capture includes a useful exploration result and no permission-required text. Evidence: evidence/task-7-sync-tmux.txt Scenario: background delegated explore can read and run harmless bash Tool: tmux Steps: tmux new-session -d -s omo-delegate-bg-qa 'cd /Users/yeongyu/local-workspaces/omo && bun src/cli/index.ts run --agent Sisyphus --directory /Users/yeongyu/local-workspaces/omo --json "Launch task subagent_type=explore with run_in_background=true and load_skills=[] to inspect src/shared/agent-tool-restrictions.ts. Wait for completion notification, collect background_output, and report whether read/bash were usable."' ; poll `tmux capture-pane -pt omo-delegate-bg-qa` until JSON or completion; save final capture and relevant log excerpt. Expected: Capture includes background result and no permission-required text. Evidence: evidence/task-7-background-tmux.txt ``` Commit: NO | Message: `test(task): capture real delegate-task permission QA` | Files: [`evidence/task-7-build.txt`, `evidence/task-7-sync-tmux.txt`, `evidence/task-7-background-tmux.txt`] ## Final verification wave (MANDATORY — after all implementation tasks) > Runs in PARALLEL. ALL must APPROVE. Surface results to the caller and wait for an explicit "okay" before declaring complete. - [ ] F1. Plan compliance audit — every task done, every acceptance criterion met - [ ] F2. Code quality review — diagnostics clean, idioms match, no dead code - [ ] F3. Real manual QA — every QA scenario executed with evidence captured - [ ] F4. Scope fidelity — nothing extra shipped beyond Must-Have, nothing Must-NOT-Have introduced ## Commit strategy - One logical change per commit. Conventional Commits (`(): ` body + footer). - Atomic: every commit builds and passes tests on its own. - No "WIP" / "fix typo squash later" commits on the final branch — clean up before merge. - Reference the plan file path in the final commit footer: `Plan: plans/fix-delegate-task-subagent-permissions.md`. ## Success criteria - All Must-Have shipped; all QA scenarios pass with captured evidence; F1–F4 approved; commit history clean.