Manage Approvals

VerifiedSafe

Implements a human-in-the-loop approval workflow for sensitive actions, ensuring compliance before execution.

Sby Skills Guide Bot
SecurityIntermediate
7/24/2026
Claude Code
#human-in-the-loop#approval-workflow#audit-logging#desktop-notifications#compliance

Recommended for

Automated summary

This skill implements a human-in-the-loop approval workflow that gates sensitive actions — sending emails, LinkedIn posts, payments, file deletions, external API calls — until a user explicitly approves them.

Strengths

  • Classifies actions as sensitive or not through an editable approval_rules.yaml, with per-action timeouts
  • Materializes each request in a Pending_Approval folder whose YAML frontmatter the user edits to approve or reject
  • Sends desktop notifications and logs every decision and execution result for auditing
  • Executes approved actions with retry logic and error handling, and records the rejection reason when declined

Limitations

  • Approval depends on manually editing YAML frontmatter; there is no dedicated review interface
  • Polling and notifications assume a local vault and a desktop notification environment
  • The provided excerpt cuts off inside check_approval_status, so parts of the API still need verification
When to use it

Use it when an agent performs externally visible or irreversible actions and explicit human sign-off is required before execution.

When not to use it

Avoid it for read-only operations or fully automated tasks where an approval gate adds delay without any compliance benefit.

Security analysis

Safe
Quality score78/100

The skill describes a human-in-the-loop approval workflow with code snippets and configuration examples, but does not contain direct instructions to execute destructive, exfiltrating, or obfuscated actions. It does not declare or use any tools that would perform network, shell, or file operations beyond conceptual Python code. The content is instructional and focused on implementing approval mechanisms, not on executing sensitive actions autonomously.

No concerns found

How this analysis is made

Examples

Gate an outbound email
Draft and send the project update email to client@example.com, but create an approval request first so I can review it before it goes out.
Review pending approvals
Check the Pending_Approval folder and tell me which approval requests are still waiting, then execute any that I've marked as approved.
Configure sensitive actions
Add delete_file and api_call to the sensitive actions in approval_rules.yaml with a 60-minute timeout, and confirm emails and LinkedIn posts can never be auto-approved.

Manage Approvals Skill

Skill ID: manage-approvals Version: 1.0.0 User Story: US2 - Human-in-the-Loop Approval Workflow Priority: P1 (MVP)

Purpose

Implement human-in-the-loop (HITL) approval workflow for sensitive actions. This skill ensures 100% compliance with the constitution requirement that all sensitive actions (emails, posts, payments) require explicit human approval before execution.

Capabilities

  • Approval Request Creation: Create structured approval requests in Pending_Approval folder
  • Approval Status Checking: Poll for user responses (Approved/Rejected)
  • Desktop Notifications: Notify user of pending approvals using system notifications
  • Action Execution: Execute approved actions with retry logic and error handling
  • Audit Logging: Log all approval decisions and action results

Architecture

Core Components

  1. ApprovalManager (silver/src/approval/approval_manager.py)

    • create_approval_request(action_type, action_details, risk_assessment) → request_id
    • is_sensitive_action(action_type) → bool
    • execute_approved_action(request_id) → result
  2. ApprovalChecker (silver/src/approval/approval_checker.py)

    • poll_for_approvals() → List[ApprovalRequest]
    • check_approval_status(request_id) → status (pending/approved/rejected)
  3. ApprovalNotifier (silver/src/approval/approval_notifier.py)

    • send_notification(title, message, urgency) → success

Approval Workflow

1. Action Detected → Is Sensitive? → Yes → Create Approval Request
                                   → No → Execute Directly

2. Approval Request Created → Move to Pending_Approval/
                           → Send Desktop Notification
                           → Poll for User Response

3. User Reviews → Edit YAML frontmatter → Set status: approved/rejected
                                        → Add reason (if rejected)

4. Status Detected → Approved → Move to Approved/ → Execute Action
                  → Rejected → Move to Rejected/ → Log Reason

Configuration

Approval Rules (silver/config/approval_rules.yaml)

sensitive_actions:
  # Email sending
  - action_type: send_email
    requires_approval: true
    auto_approve_threshold: null  # Never auto-approve
    timeout_minutes: 1440  # 24 hours

  # LinkedIn posting
  - action_type: post_linkedin
    requires_approval: true
    auto_approve_threshold: null
    timeout_minutes: 1440

  # File operations
  - action_type: delete_file
    requires_approval: true
    auto_approve_threshold: null
    timeout_minutes: 60

  # External API calls
  - action_type: api_call
    requires_approval: true
    auto_approve_threshold: null
    timeout_minutes: 120

non_sensitive_actions:
  # Read-only operations
  - action_type: read_file
    requires_approval: false

  - action_type: search_vault
    requires_approval: false

  - action_type: create_plan
    requires_approval: false

notification_settings:
  enabled: true
  urgency: normal  # low, normal, critical
  sound: true
  desktop: true

Usage

Create Approval Request

from silver.src.approval.approval_manager import ApprovalManager

manager = ApprovalManager(vault_path="/path/to/vault")

# Create approval request for email sending
request_id = manager.create_approval_request(
    action_type="send_email",
    action_details={
        "to": "client@example.com",
        "subject": "Project Update",
        "body": "Here's the latest update...",
        "attachments": []
    },
    risk_assessment={
        "sensitivity": "high",
        "reversible": False,
        "impact": "external_communication"
    }
)

print(f"Approval request created: {request_id}")
# Desktop notification sent to user

Check Approval Status

from silver.src.approval.approval_checker import ApprovalChecker

checker = ApprovalChecker(vault_path="/path/to/vault")

# Check status of specific request
status = checker.check_approval_status(request_id)

if status["status"] == "approved":
    print("Action approved by user")
    # Execute action
elif status["status"] == "rejected":
    print(f"Action rejected: {status['reason']}")
    # Log rejection
else:
    print("Still pending approval")

Execute Approved Action

# Execute action with retry logic
result = manager.execute_approved_action(request_id)

if result["success"]:
    print(f"Action executed successfully: {result['message_id']}")
else:
    print(f"Action failed: {result['error']}")
    # Retry logic: max 3 attempts, exponential backoff (2s, 4s, 8s)

Output Format

Approval Request File

Created in Pending_Approval/ folder:

---
id: approval_20260113_103045_abc123
action_type: send_email
status: pending
created_at: 2026-01-13T10:30:45Z
timeout_at: 2026-01-14T10:30:45Z
risk_level: high
---

# Approval Request: Send Email

**Action**: Send Email
**Status**: ⏳ Pending Approval
**Created**: 2026-01-13 10:30 AM
**Timeout**: 2026-01-14 10:30 AM (24 hours)

## Action Details

- **To**: client@example.com
- **Subject**: Project Update
- **Body Preview**: Here's the latest update...
- **Attachments**: None

## Risk Assessment

- **Sensitivity**: High
- **Reversible**: No
- **Impact**: External Communication
- **Consequences**: Email will be sent to external recipient

## Instructions

To approve this action:
1. Change `status: pending` to `status: approved` in the YAML frontmatter above
2. Save the file
3. The action will execute automatically within 1 minute

To reject this action:
1. Change `status: pending` to `status: rejected` in the YAML frontmatter above
2. Add `rejection_reason: "Your reason here"` to the YAML frontmatter
3. Save the file
4. The action will be cancelled

## Timeout

If no response within 24 hours, this request will expire and the action will be cancelled.

After Approval

File moves to Approved/ folder with updated frontmatter:

---
id: approval_20260113_103045_abc123
action_type: send_email
status: approved
created_at: 2026-01-13T10:30:45Z
approved_at: 2026-01-13T10:35:12Z
executed_at: 2026-01-13T10:35:15Z
execution_result: success
message_id: <abc123@smtp.gmail.com>
---

After Rejection

File moves to Rejected/ folder with rejection reason:

---
id: approval_20260113_103045_abc123
action_type: send_email
status: rejected
created_at: 2026-01-13T10:30:45Z
rejected_at: 2026-01-13T10:35:12Z
rejection_reason: "Not ready to send yet, need to review content first"
---

Dependencies

Python Packages

[tool.poetry.dependencies]
plyer = "^2.1.0"  # Desktop notifications
pyyaml = "^6.0.1"
python-dotenv = "^1.0.0"
watchdog = "^4.0.0"  # File system monitoring (optional)

System Requirements

  • Python 3.13+
  • Desktop notification support (Linux: libnotify, Windows: native, macOS: native)

Setup Instructions

1. Configure Approval Rules

# Edit approval rules
nano silver/config/approval_rules.yaml

# Customize sensitive actions, timeouts, notification settings

2. Create Vault Folders

# Create approval folders
mkdir -p Pending_Approval Approved Rejected

# Verify folders exist
ls -la | grep -E "Pending_Approval|Approved|Rejected"

3. Test Notifications

# Test desktop notifications
python silver/scripts/test_approval.py --test-notification

# Should see desktop notification appear

4. Start Approval Checker

# Start approval checker (polls every 10 seconds)
python -m silver.src.approval.approval_checker &

# Or use startup script
./silver/scripts/start_watchers.sh

Error Handling

Timeout Handling

  • Default timeout: 24 hours for most actions
  • Expired requests: Automatically moved to Rejected/ with reason "Timeout"
  • Notification: User notified 1 hour before timeout

File System Errors

  • Permission denied: Log error, notify user
  • File not found: Assume request was manually deleted, skip
  • Invalid YAML: Notify user, keep in Pending_Approval/

Notification Errors

  • Notification failed: Log error, continue (user can still check folder manually)
  • No notification support: Graceful degradation (file-based only)

Performance

  • Polling interval: 10 seconds (configurable)
  • Memory: ~20MB per checker process
  • CPU: Minimal (<1% on modern systems)
  • Disk I/O: Low (only reads changed files)

Testing

Unit Tests

pytest silver/tests/unit/test_approval_manager.py
pytest silver/tests/unit/test_approval_checker.py
pytest silver/tests/unit/test_approval_notifier.py

Integration Tests

pytest silver/tests/integration/test_approval_workflow.py

Manual Testing

  1. Create test approval request:

    python silver/scripts/test_approval.py --create-test-request
    
  2. Verify desktop notification appears

  3. Open Pending_Approval/ folder and find the request file

  4. Edit YAML frontmatter: change status: pending to status: approved

  5. Save file

  6. Verify file moves to Approved/ within 10 seconds

  7. Check audit log in Logs/YYYY-MM-DD.json

Success Criteria

  • ✅ 100% approval compliance for sensitive actions
  • ✅ Desktop notifications delivered within 1 second
  • ✅ Approval status detected within 10 seconds
  • ✅ Approved actions executed within 1 minute
  • ✅ Audit log entry created for every approval decision
  • ✅ Graceful handling of timeouts and errors

Related Skills

  • monitor-communications: Creates action files that may require approval
  • execute-actions: Executes approved actions via MCP server
  • create-plans: Plans may include actions requiring approval

References

  • See references/approval_rules.md for detailed approval rule configuration
  • See references/notification_api.md for desktop notification API details

Examples

  • See examples/approval_request_example.md for approval request format
  • See examples/approved_action_example.md for approved action format
  • See examples/rejected_action_example.md for rejected action format

Changelog

  • 1.0.0 (2026-01-13): Initial implementation for Silver tier MVP

From the file to a first result

The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.

View the source and supporting files

This download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.

1. Download the file

Download SKILL.md

From the root of a test project, save the file as .skill-downloads/manage-approvals-mryiqhvi/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.

Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.

mkdir -p '.skill-downloads/manage-approvals-mryiqhvi' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/manage-approvals-mryiqhvi/download' --output '.skill-downloads/manage-approvals-mryiqhvi/SKILL.md.part' && mv '.skill-downloads/manage-approvals-mryiqhvi/SKILL.md.part' '.skill-downloads/manage-approvals-mryiqhvi/SKILL.md'

2. Check prerequisites

Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.

Original excerpt: Dependencies

Python Packages

[tool.poetry.dependencies]
plyer = "^2.1.0"  # Desktop notifications
pyyaml = "^6.0.1"
python-dotenv = "^1.0.0"
watchdog = "^4.0.0"  # File system monitoring (optional)

System Requirements

  • Python 3.13+
  • Desktop notification support (Linux: libnotify, Windows: native, macOS: native)

The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.

3. Load the skill

This file does not provide a usable name/description header for this native procedure. It remains available to download and inspect; use the manual method below.

Manual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.

4. Try a first task

Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:

Read .skill-downloads/manage-approvals-mryiqhvi/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.

Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.

Related skills