---
mode: subagent
---

<!-- SPDX-License-Identifier: MIT -->
<!-- SPDX-FileCopyrightText: 2025-2026 Marcus Quinn -->
# t1327.10: Exec approval flow for remote chat commands

## Origin

- **Created:** 2026-02-26
- **Session:** claude-code:feature/exec-approval-flow
- **Created by:** ai-interactive
- **Parent task:** t1327 (SimpleX bot framework plan p032)
- **Conversation context:** Issue #2261 requested an approval flow for the /run command in the SimpleX bot, requiring explicit user confirmation before executing dangerous commands via chat.

## What

A three-tier exec approval system for the SimpleX bot's `/run` command:

1. **Allowlist**: Safe commands (e.g., `aidevops status`) execute immediately without approval
2. **Approval-required**: Unknown commands send an approval request back to chat with a unique ID; user must `/approve <id>` within a configurable timeout (default 60s) or the request auto-rejects
3. **Blocklist**: Dangerous patterns (e.g., `rm -rf`, `shutdown`) are always rejected

New chat commands: `/approve <id>`, `/reject <id>`, `/pending`

## Why

The `/run` command was a scaffold placeholder (t1327.4) that refused all execution. Without an approval flow, the bot cannot safely execute remote commands — either everything is blocked (useless) or everything is allowed (dangerous). This implements the security boundary that makes remote command execution viable.

## How (Approach)

- New `approval.ts` module: `ApprovalManager` class with classify/create/approve/reject/timeout lifecycle
- Extended `types.ts`: `ExecApprovalConfig`, `PendingApproval`, `ApprovalState` types added to `BotConfig`
- Updated `commands.ts`: `/run` now classifies and routes through approval; new `/approve`, `/reject`, `/pending` commands
- Updated `index.ts`: Initialises `ApprovalManager` from config, supports env var configuration, cleans up on shutdown
- Pattern: `commands.ts:11` — existing command handler pattern with `CommandContext`
- Tests: `approval.test.ts` — 23 tests covering classification, lifecycle, timeout, config

## Acceptance Criteria

- [ ] Allowlisted commands execute immediately via /run

  ```yaml
  verify:
    method: codebase
    pattern: "case \"allowed\""
    path: ".agents/scripts/simplex-bot/src/commands.ts"
  ```

- [ ] Blocklisted commands are always rejected

  ```yaml
  verify:
    method: codebase
    pattern: "case \"blocked\""
    path: ".agents/scripts/simplex-bot/src/commands.ts"
  ```

- [ ] Unknown commands require explicit /approve before execution

  ```yaml
  verify:
    method: codebase
    pattern: "case \"approval-required\""
    path: ".agents/scripts/simplex-bot/src/commands.ts"
  ```

- [ ] Pending approvals auto-expire after configurable timeout

  ```yaml
  verify:
    method: codebase
    pattern: "expireRequest"
    path: ".agents/scripts/simplex-bot/src/approval.ts"
  ```

- [ ] Configuration via environment variables (SIMPLEX_EXEC_ALLOWLIST, SIMPLEX_EXEC_BLOCKLIST, SIMPLEX_EXEC_TIMEOUT)

  ```yaml
  verify:
    method: codebase
    pattern: "SIMPLEX_EXEC_"
    path: ".agents/scripts/simplex-bot/src/index.ts"
  ```

- [ ] Tests pass (`bun test`)

  ```yaml
  verify:
    method: bash
    run: "cd .agents/scripts/simplex-bot && ~/.bun/bin/bun test"
  ```

- [ ] TypeScript typecheck passes

  ```yaml
  verify:
    method: bash
    run: "cd .agents/scripts/simplex-bot && ~/.bun/bin/bun x tsc --noEmit"
  ```

## Context & Decisions

- Blocklist takes priority over allowlist (safety-first: if a pattern appears in both, it's blocked)
- Allowlist uses prefix matching (e.g., "aidevops status" matches "aidevops status --verbose")
- Blocklist uses substring matching (e.g., "rm -rf" matches "sudo rm -rf /tmp")
- Only the original requester can approve their own commands (prevents social engineering in shared contexts)
- Custom blocklist entries from env vars are merged with defaults, not replaced (safety patterns persist)
- Shell command execution has a 30s per-command timeout to prevent runaway processes
- Output is truncated to 2000 chars to prevent chat flooding

## Relevant Files

- `.agents/scripts/simplex-bot/src/approval.ts` — new: ApprovalManager + executeShellCommand
- `.agents/scripts/simplex-bot/src/approval.test.ts` — new: 23 tests for approval flow
- `.agents/scripts/simplex-bot/src/types.ts:159-230` — new types: ExecApprovalConfig, PendingApproval
- `.agents/scripts/simplex-bot/src/commands.ts:139-280` — updated /run + new /approve, /reject, /pending
- `.agents/scripts/simplex-bot/src/index.ts:23-37,152-162,225-237,533-575` — approval manager init, config, cleanup

## Dependencies

- **Blocked by:** t1327.4 (bot framework) — completed
- **Blocks:** t1327.11+ (future remote execution features)
- **External:** None

## Estimate Breakdown

| Phase | Time | Notes |
|-------|------|-------|
| Research/read | 15m | Read bot framework, understand command flow |
| Implementation | 1h | approval.ts, types, commands, index integration |
| Testing | 30m | 23 unit tests + typecheck |
| **Total** | **~2h** | |
