Class: Aidp::Watch::RepositorySafetyChecker

Inherits:
Object
  • Object
show all
Includes:
MessageDisplay
Defined in:
lib/aidp/watch/repository_safety_checker.rb

Overview

Validates watch mode safety requirements for public repositories and enforces author allowlists to prevent untrusted input execution.

Defined Under Namespace

Classes: UnauthorizedAuthorError, UnsafeRepositoryError

Constant Summary

Constants included from MessageDisplay

MessageDisplay::COLOR_MAP

Instance Method Summary collapse

Methods included from MessageDisplay

#display_message, included, #message_display_prompt

Constructor Details

#initialize(repository_client:, config: {}) ⇒ RepositorySafetyChecker

Returns a new instance of RepositorySafetyChecker.



18
19
20
21
22
# File 'lib/aidp/watch/repository_safety_checker.rb', line 18

def initialize(repository_client:, config: {})
  @repository_client = repository_client
  @config = config
  @repo_visibility_cache = {}
end

Instance Method Details

#author_authorized?(issue) ⇒ Boolean

Check if an issue author is allowed to trigger automated work

Parameters:

  • issue (Hash)

    Issue data with :author or :assignees

Returns:

  • (Boolean)

    true if authorized



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/aidp/watch/repository_safety_checker.rb', line 56

def author_authorized?(issue)
  author = extract_author(issue)
  return false unless author

  # If no allowlist configured, allow all (backward compatible)
  return true if author_allowlist.empty?

  # Check if author is in allowlist
  authorized = author_allowlist.include?(author)

  Aidp.log_debug("repository_safety", "check author authorization",
    author: author,
    authorized: authorized,
    allowlist_size: author_allowlist.size)

  authorized
end

#should_process_issue?(issue, enforce: true) ⇒ Boolean

Check if an issue should be processed based on author authorization

Parameters:

  • issue (Hash)

    Issue data

  • enforce (Boolean) (defaults to: true)

    Raise error if unauthorized

Returns:

  • (Boolean)

    true if should process



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/aidp/watch/repository_safety_checker.rb', line 78

def should_process_issue?(issue, enforce: true)
  unless author_authorized?(issue)
    author = extract_author(issue)
    if enforce && author_allowlist.any?
      raise UnauthorizedAuthorError,
        "Issue ##{issue[:number]} author '#{author}' not in allowlist. " \
        "Add to watch.safety.author_allowlist in aidp.yml to allow."
    end

    display_message("⏭️  Skipping issue ##{issue[:number]} - author '#{author}' not authorized",
      type: :muted)
    return false
  end

  true
end

#validate_watch_mode_safety!(force: false) ⇒ Boolean

Check if watch mode is safe to run for this repository

Parameters:

  • force (Boolean) (defaults to: false)

    Skip safety checks (dangerous!)

Returns:

  • (Boolean)

    true if safe, raises error otherwise



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/aidp/watch/repository_safety_checker.rb', line 27

def validate_watch_mode_safety!(force: false)
  Aidp.log_debug("repository_safety", "validate watch mode safety",
    repo: @repository_client.full_repo,
    force: force)

  # Skip checks if forced (user takes responsibility)
  if force
    display_message("⚠️  Watch mode safety checks BYPASSED (--force)", type: :warning)
    return true
  end

  # Check repository visibility
  unless repository_safe_for_watch_mode?
    raise UnsafeRepositoryError, unsafe_repository_message
  end

  # Check if running in safe environment
  unless safe_environment?
    display_message("⚠️  Watch mode running outside container/sandbox", type: :warning)
    display_message("   Consider using a containerized environment for additional safety", type: :muted)
  end

  display_message("✅ Watch mode safety checks passed", type: :success)
  true
end