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
- •
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
- •
- •
ApprovalChecker (
silver/src/approval/approval_checker.py)- •
poll_for_approvals()→ List[ApprovalRequest] - •
check_approval_status(request_id)→ status (pending/approved/rejected)
- •
- •
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
- •
Create test approval request:
bashpython silver/scripts/test_approval.py --create-test-request
- •
Verify desktop notification appears
- •
Open
Pending_Approval/folder and find the request file - •
Edit YAML frontmatter: change
status: pendingtostatus: approved - •
Save file
- •
Verify file moves to
Approved/within 10 seconds - •
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.mdfor detailed approval rule configuration - •See
references/notification_api.mdfor desktop notification API details
Examples
- •See
examples/approval_request_example.mdfor approval request format - •See
examples/approved_action_example.mdfor approved action format - •See
examples/rejected_action_example.mdfor rejected action format
Changelog
- •1.0.0 (2026-01-13): Initial implementation for Silver tier MVP