# Package managers: safe invocations and installation rules

allowlists:
  commands:
    # ── pip/pip3: safe invocations ────────────────────────────────
    # pip install - covered by rules (ask for confirmation)
    - { command: "pip list", trust: minimal }
    - { command: "pip show", trust: minimal }
    - { command: "pip freeze", trust: minimal }
    - { command: "pip check", trust: minimal }
    - { command: "pip3 list", trust: minimal }
    - { command: "pip3 show", trust: minimal }
    - { command: "pip3 freeze", trust: minimal }
    - { command: "pip3 check", trust: minimal }
    # ── gem: safe invocations ─────────────────────────────────────
    # gem install - covered by rules (ask for confirmation)
    - { command: "gem list", trust: minimal }
    - { command: "gem info", trust: minimal }
    - { command: "gem search", trust: minimal }
    - { command: "gem --version", trust: minimal }
    - { command: "gem -v", trust: minimal }
    # ── bundler: safe invocations ─────────────────────────────────
    # bundle install/add - covered by rules (ask for confirmation)
    - { command: "bundle list", trust: minimal }
    - { command: "bundle show", trust: minimal }
    - { command: "bundle info", trust: minimal }
    - { command: "bundle check", trust: minimal }
    - { command: "bundle --version", trust: minimal }
    - { command: "bundle -v", trust: minimal }
    - { command: "bundler --version", trust: minimal }
    # ── go: safe invocations ──────────────────────────────────────
    # go get/install - covered by rules (ask for confirmation)
    - { command: "go build", trust: standard, reason: "Compiles Go packages" }
    - { command: "go test", trust: standard, reason: "Runs Go tests" }
    - { command: "go run", trust: standard, reason: "Compiles and runs a Go program" }
    - { command: "go vet", trust: standard, reason: "Reports likely mistakes in Go code" }
    - { command: "go fmt", trust: standard, reason: "Formats Go source code" }
    - { command: "go mod", trust: standard, reason: "Manages Go module dependencies" }
    - { command: "go generate", trust: standard, reason: "Runs code generation directives" }
    - { command: "go doc", trust: minimal }
    - { command: "go clean", trust: standard, reason: "Removes build cache and output files" }
    - { command: "go env", trust: minimal }
    - { command: "go version", trust: minimal }
    - { command: "go work", trust: standard, reason: "Manages Go workspace configuration" }
    # ── yarn: safe invocations ────────────────────────────────────
    # yarn add/install - covered by rules (ask for confirmation)
    - { command: "yarn --version", trust: minimal }
    - { command: "yarn -v", trust: minimal }
    - { command: "yarn list", trust: minimal }
    - { command: "yarn info", trust: minimal }
    - { command: "yarn why", trust: minimal }
    - { command: "yarn run", trust: standard, reason: "Runs a script defined in package.json" }
    - { command: "yarn test", trust: standard, reason: "Runs the project's test suite" }
    - { command: "yarn build", trust: standard, reason: "Runs the project's build script" }
    - { command: "yarn start", trust: standard, reason: "Starts the application" }
    - { command: "yarn lint", trust: standard, reason: "Runs the project's linter" }
    # ── pnpm: safe invocations ────────────────────────────────────
    # pnpm add/install - covered by rules (ask for confirmation)
    - { command: "pnpm --version", trust: minimal }
    - { command: "pnpm -v", trust: minimal }
    - { command: "pnpm list", trust: minimal }
    - { command: "pnpm ls", trust: minimal }
    - { command: "pnpm why", trust: minimal }
    - { command: "pnpm audit", trust: minimal }
    - { command: "pnpm run", trust: standard, reason: "Runs a script defined in package.json" }
    - { command: "pnpm test", trust: standard, reason: "Runs the project's test suite" }
    - { command: "pnpm build", trust: standard, reason: "Runs the project's build script" }
    - { command: "pnpm start", trust: standard, reason: "Starts the application" }
    - { command: "pnpm lint", trust: standard, reason: "Runs the project's linter" }
    - { command: "pnpm dev", trust: standard, reason: "Starts the development server" }
    - { command: "pnpm check", trust: standard, reason: "Runs project checks" }
    - { command: "pnpm format", trust: standard, reason: "Formats project source files" }
    - { command: "pnpm typecheck", trust: standard, reason: "Runs TypeScript type checking" }
    # ── bun: safe invocations ─────────────────────────────────────
    # bun add/install - covered by rules (ask for confirmation)
    - { command: "bun --version", trust: minimal }
    - { command: "bun -v", trust: minimal }
    - { command: "bun run", trust: standard, reason: "Runs a script or file with Bun" }
    - { command: "bun test", trust: standard, reason: "Runs tests with Bun's test runner" }
    - { command: "bun build", trust: standard, reason: "Bundles files with Bun's bundler" }
    # ── poetry: safe invocations ──────────────────────────────────
    # poetry add/install - covered by rules (ask for confirmation)
    - { command: "poetry --version", trust: minimal }
    - { command: "poetry -V", trust: minimal }
    - { command: "poetry show", trust: minimal }
    - { command: "poetry list", trust: minimal }
    - { command: "poetry check", trust: minimal }
    - { command: "poetry lock", trust: standard, reason: "Resolves and locks Python dependencies" }
    - { command: "poetry shell", trust: standard, reason: "Activates the Poetry virtual environment" }
    - { command: "poetry env", trust: standard, reason: "Manages Poetry virtual environments" }
    # ── pipx: safe invocations ────────────────────────────────────
    # pipx install - covered by rules (ask for confirmation)
    - { command: "pipx --version", trust: minimal }
    - { command: "pipx list", trust: minimal }
    - { command: "pipx run", trust: standard, reason: "Runs a Python application in isolation" }
    # ── pdm: safe invocations ─────────────────────────────────────
    # pdm add/install - covered by rules (ask for confirmation)
    - { command: "pdm --version", trust: minimal }
    - { command: "pdm -V", trust: minimal }
    - { command: "pdm list", trust: minimal }
    - { command: "pdm show", trust: minimal }
    - { command: "pdm lock", trust: standard, reason: "Resolves and locks Python dependencies" }
    # ── rye: safe invocations ─────────────────────────────────────
    # rye add - covered by rules (ask for confirmation)
    - { command: "rye --version", trust: minimal }
    - { command: "rye -V", trust: minimal }
    - { command: "rye list", trust: minimal }
    - { command: "rye show", trust: minimal }
    - { command: "rye lock", trust: standard, reason: "Resolves and locks Python dependencies" }
    - { command: "rye sync", trust: standard, reason: "Syncs project dependencies with the lockfile" }
    # ── conda/mamba: safe invocations ─────────────────────────────
    # conda/mamba install - covered by rules (ask for confirmation)
    - { command: "conda --version", trust: minimal }
    - { command: "conda -V", trust: minimal }
    - { command: "conda list", trust: minimal }
    - { command: "conda info", trust: minimal }
    - { command: "conda env", trust: minimal }
    - { command: "mamba --version", trust: minimal }
    - { command: "mamba list", trust: minimal }
    - { command: "mamba info", trust: minimal }
    # ── composer: safe invocations ────────────────────────────────
    # composer require/install - covered by rules (ask for confirmation)
    - { command: "composer --version", trust: minimal }
    - { command: "composer -V", trust: minimal }
    - { command: "composer show", trust: minimal }
    - { command: "composer list", trust: minimal }
    - { command: "composer info", trust: minimal }
    - { command: "composer check-platform-reqs", trust: minimal }
    # ── brew: safe invocations ────────────────────────────────────
    # brew install - covered by rules (ask for confirmation)
    - { command: "brew --version", trust: minimal }
    - { command: "brew list", trust: minimal }
    - { command: "brew info", trust: minimal }
    - { command: "brew search", trust: minimal }
    - { command: "brew doctor", trust: minimal }
    - { command: "brew outdated", trust: minimal }
    - { command: "brew services list", trust: minimal }
    - { command: "brew deps", trust: minimal }
    - { command: "brew config", trust: minimal }
    - { command: "brew leaves", trust: minimal }
    - { command: "brew desc", trust: minimal }
    - { command: "brew cat", trust: minimal }
    - { command: "brew home", trust: minimal }
    # ── deno: safe invocations ────────────────────────────────────
    # deno install/add - covered by rules (ask for confirmation)
    - { command: "deno --version", trust: minimal }
    - { command: "deno -V", trust: minimal }
    - { command: "deno run", trust: standard, reason: "Runs a Deno script" }
    - { command: "deno test", trust: standard, reason: "Runs Deno tests" }
    - { command: "deno lint", trust: standard, reason: "Lints Deno source files" }
    - { command: "deno fmt", trust: standard, reason: "Formats Deno source files" }
    - { command: "deno check", trust: standard, reason: "Type-checks Deno source files" }
    - { command: "deno info", trust: standard, reason: "Shows dependency information" }
    - { command: "deno doc", trust: standard, reason: "Generates documentation from source" }
    # ── dotnet: safe invocations ──────────────────────────────────
    # dotnet add - covered by rules (ask for confirmation)
    - { command: "dotnet --version", trust: minimal }
    - { command: "dotnet --info", trust: minimal }
    - { command: "dotnet list", trust: minimal }
    - { command: "dotnet build", trust: standard, reason: "Builds a .NET project" }
    - { command: "dotnet run", trust: standard, reason: "Runs a .NET project" }
    - { command: "dotnet test", trust: standard, reason: "Runs .NET tests" }
    - { command: "dotnet clean", trust: standard, reason: "Cleans build output" }
    - { command: "dotnet restore", trust: standard, reason: "Restores .NET project dependencies" }
    # ── nuget: safe invocations ───────────────────────────────────
    # nuget install - covered by rules (ask for confirmation)
    - { command: "nuget --version", trust: minimal }
    - { command: "nuget list", trust: minimal }
    - { command: "nuget sources", trust: minimal }
    # ── mix (Elixir): safe invocations ────────────────────────────
    # mix deps.get - covered by rules (ask for confirmation)
    - { command: "mix --version", trust: minimal }
    - { command: "mix help", trust: minimal }
    - { command: "mix compile", trust: standard, reason: "Compiles an Elixir project" }
    - { command: "mix test", trust: standard, reason: "Runs Elixir tests" }
    - { command: "mix format", trust: standard, reason: "Formats Elixir source files" }
    # ── pub (Dart): safe invocations ──────────────────────────────
    # pub get/add - covered by rules (ask for confirmation)
    - { command: "dart pub --version", trust: minimal }
    - { command: "dart pub deps", trust: minimal }
    - { command: "dart pub outdated", trust: minimal }
    - { command: "flutter pub deps", trust: minimal }
    - { command: "flutter pub outdated", trust: minimal }
    # ── cabal (Haskell): safe invocations ─────────────────────────
    # cabal install - covered by rules (ask for confirmation)
    - { command: "cabal --version", trust: minimal }
    - { command: "cabal -V", trust: minimal }
    - { command: "cabal list", trust: minimal }
    - { command: "cabal info", trust: minimal }
    - { command: "cabal build", trust: standard, reason: "Builds a Haskell project with Cabal" }
    - { command: "cabal test", trust: standard, reason: "Runs Haskell tests with Cabal" }
    - { command: "cabal run", trust: standard, reason: "Runs a Haskell executable with Cabal" }
    # ── stack (Haskell): safe invocations ─────────────────────────
    # stack install - covered by rules (ask for confirmation)
    - { command: "stack --version", trust: minimal }
    - { command: "stack list-dependencies", trust: minimal }
    - { command: "stack build", trust: standard, reason: "Builds a Haskell project with Stack" }
    - { command: "stack test", trust: standard, reason: "Runs Haskell tests with Stack" }
    - { command: "stack run", trust: standard, reason: "Runs a Haskell executable with Stack" }

rules:
  # ============================================================
  # HIGH: Package installation (supply chain risk)
  # ============================================================
  # All package installation commands require confirmation.
  # Packages can contain arbitrary code that runs at install time.
  # Risk: typosquatting, malicious packages, supply chain attacks.
  #
  # Future: --allow-package-install flag could bypass this section.

  # ── Python package managers ──────────────────────────────────
  - id: pip-install
    level: high
    match:
      command:
        any_of: [pip, pip3]
      args:
        any_of: ["install"]
    decision: ask
    reason: "Installing Python packages"

  - id: pip-download
    level: high
    match:
      command:
        any_of: [pip, pip3]
      args:
        any_of: ["download"]
    decision: ask
    reason: "Downloading Python packages"

  - id: python-m-pip-install
    level: high
    match:
      command:
        any_of: [python, python3]
      args:
        any_of: ["-m"]
      flags:
        any_of: ["pip"]
    decision: ask
    reason: "Installing Python packages via python -m pip"

  - id: uv-pip-install
    level: high
    match:
      command: uv
      args:
        any_of: ["pip"]
      flags:
        any_of: ["install"]
    decision: ask
    reason: "Installing Python packages via uv"

  - id: uv-add
    level: high
    match:
      command: uv
      args:
        any_of: ["add"]
    decision: ask
    reason: "Adding Python dependency via uv"

  - id: poetry-add
    level: high
    match:
      command: poetry
      args:
        any_of: ["add"]
    decision: ask
    reason: "Adding Python dependency via Poetry"

  - id: poetry-install
    level: high
    match:
      command: poetry
      args:
        any_of: ["install"]
    decision: ask
    reason: "Installing Python dependencies via Poetry"

  - id: pipx-install
    level: high
    match:
      command: pipx
      args:
        any_of: ["install"]
    decision: ask
    reason: "Installing Python application via pipx"

  - id: pdm-add
    level: high
    match:
      command: pdm
      args:
        any_of: ["add"]
    decision: ask
    reason: "Adding Python dependency via PDM"

  - id: pdm-install
    level: high
    match:
      command: pdm
      args:
        any_of: ["install"]
    decision: ask
    reason: "Installing Python dependencies via PDM"

  - id: rye-add
    level: high
    match:
      command: rye
      args:
        any_of: ["add"]
    decision: ask
    reason: "Adding Python dependency via Rye"

  - id: conda-install
    level: high
    match:
      command:
        any_of: [conda, mamba]
      args:
        any_of: ["install"]
    decision: ask
    reason: "Installing packages via Conda/Mamba"

  # ── JavaScript/Node package managers ─────────────────────────
  - id: npm-install
    level: high
    match:
      command: npm
      args:
        any_of: ["install", "i", "ci"]
    decision: ask
    reason: "Installing npm packages"

  - id: npm-audit-fix
    level: high
    match:
      command: npm
      args:
        any_of: ["audit"]
      flags:
        any_of: ["fix"]
    decision: ask
    reason: "npm audit fix modifies package dependencies"

  - id: npm-exec
    level: high
    match:
      command: npm
      args:
        any_of: ["exec"]
    decision: ask
    reason: "npm exec runs arbitrary package code"

  - id: yarn-add
    level: high
    match:
      command: yarn
      args:
        any_of: ["add"]
    decision: ask
    reason: "Adding npm package via Yarn"

  - id: yarn-install
    level: high
    match:
      command: yarn
      args:
        any_of: ["install"]
    decision: ask
    reason: "Installing npm packages via Yarn"

  - id: pnpm-add
    level: high
    match:
      command: pnpm
      args:
        any_of: ["add"]
    decision: ask
    reason: "Adding npm package via pnpm"

  - id: pnpm-install
    level: high
    match:
      command: pnpm
      args:
        any_of: ["install", "i"]
    decision: ask
    reason: "Installing npm packages via pnpm"

  - id: bun-add
    level: high
    match:
      command: bun
      args:
        any_of: ["add"]
    decision: ask
    reason: "Adding npm package via Bun"

  - id: bun-install
    level: high
    match:
      command: bun
      args:
        any_of: ["install", "i"]
    decision: ask
    reason: "Installing npm packages via Bun"

  # ── Ruby package managers ────────────────────────────────────
  - id: gem-install
    level: high
    match:
      command: gem
      args:
        any_of: ["install"]
    decision: ask
    reason: "Installing Ruby gems"

  - id: bundle-install
    level: high
    match:
      command:
        any_of: [bundle, bundler]
      args:
        any_of: ["install"]
    decision: ask
    reason: "Installing Ruby gems via Bundler"

  - id: bundle-add
    level: high
    match:
      command:
        any_of: [bundle, bundler]
      args:
        any_of: ["add"]
    decision: ask
    reason: "Adding Ruby gem via Bundler"

  # ── Rust package managers ────────────────────────────────────
  - id: cargo-add
    level: high
    match:
      command: cargo
      args:
        any_of: ["add"]
    decision: ask
    reason: "Adding Rust crate dependency"

  - id: cargo-install
    level: high
    match:
      command: cargo
      args:
        any_of: ["install"]
    decision: ask
    reason: "Installing Rust binary"

  # ── Go package managers ──────────────────────────────────────
  - id: go-get
    level: high
    match:
      command: go
      args:
        any_of: ["get"]
    decision: ask
    reason: "Fetching Go module"

  - id: go-install
    level: high
    match:
      command: go
      args:
        any_of: ["install"]
    decision: ask
    reason: "Installing Go binary"

  # ── PHP package managers ─────────────────────────────────────
  - id: composer-require
    level: high
    match:
      command: composer
      args:
        any_of: ["require"]
    decision: ask
    reason: "Adding PHP package via Composer"

  - id: composer-install
    level: high
    match:
      command: composer
      args:
        any_of: ["install"]
    decision: ask
    reason: "Installing PHP packages via Composer"

  # ── System package managers ──────────────────────────────────
  - id: brew-install
    level: high
    match:
      command: brew
      args:
        any_of: ["install"]
    decision: ask
    reason: "Installing package via Homebrew"

  - id: brew-upgrade
    level: high
    match:
      command: brew
      args: { any_of: ["upgrade"] }
    decision: ask
    reason: "Upgrading packages via Homebrew"

  - id: brew-uninstall
    level: high
    match:
      command: brew
      args: { any_of: ["uninstall", "remove", "rm"] }
    decision: ask
    reason: "Uninstalling package via Homebrew"

  - id: brew-update
    level: high
    match:
      command: brew
      args: { any_of: ["update"] }
    decision: ask
    reason: "Updating Homebrew package index"

  - id: brew-tap
    level: high
    match:
      command: brew
      args: { any_of: ["tap", "untap"] }
    decision: ask
    reason: "Modifying Homebrew taps"

  - id: brew-services-mutate
    level: high
    match:
      command: brew
      args: { any_of: ["start", "stop", "restart"] }
    decision: ask
    reason: "Managing Homebrew services"

  - id: brew-link
    level: high
    match:
      command: brew
      args: { any_of: ["link", "unlink"] }
    decision: ask
    reason: "Linking/unlinking Homebrew packages"

  - id: brew-cleanup
    level: high
    match:
      command: brew
      args: { any_of: ["cleanup", "autoremove"] }
    decision: ask
    reason: "Cleaning up Homebrew packages"

  - id: apt-install
    level: high
    match:
      command:
        any_of: [apt, apt-get]
      args:
        any_of: ["install"]
    decision: ask
    reason: "Installing system package via apt"

  - id: dnf-install
    level: high
    match:
      command:
        any_of: [dnf, yum]
      args:
        any_of: ["install"]
    decision: ask
    reason: "Installing system package via dnf/yum"

  - id: pacman-install
    level: high
    match:
      command: pacman
      flags:
        any_of: ["-S", "--sync"]
    decision: ask
    reason: "Installing system package via pacman"

  - id: apk-add
    level: high
    match:
      command: apk
      args:
        any_of: ["add"]
    decision: ask
    reason: "Installing Alpine package"

  - id: snap-install
    level: high
    match:
      command: snap
      args:
        any_of: ["install"]
    decision: ask
    reason: "Installing Snap package"

  - id: flatpak-install
    level: high
    match:
      command: flatpak
      args:
        any_of: ["install"]
    decision: ask
    reason: "Installing Flatpak application"

  - id: nix-env-install
    level: high
    match:
      command: nix-env
      flags:
        any_of: ["-i", "--install"]
    decision: ask
    reason: "Installing package via Nix"

  # ── Deno package managers ────────────────────────────────────
  - id: deno-install
    level: high
    match:
      command: deno
      args:
        any_of: ["install"]
    decision: ask
    reason: "Installing Deno package"

  - id: deno-add
    level: high
    match:
      command: deno
      args:
        any_of: ["add"]
    decision: ask
    reason: "Adding Deno dependency"

  # ── .NET package managers ────────────────────────────────────
  - id: dotnet-add-package
    level: high
    match:
      command: dotnet
      args:
        any_of: ["add"]
    decision: ask
    reason: "Adding .NET package"

  - id: nuget-install
    level: high
    match:
      command: nuget
      args:
        any_of: ["install"]
    decision: ask
    reason: "Installing NuGet package"

  # ── Elixir package managers ──────────────────────────────────
  - id: mix-deps-get
    level: high
    match:
      command: mix
      args:
        any_of: ["deps.get"]
    decision: ask
    reason: "Fetching Elixir dependencies"

  - id: mix-archive-install
    level: high
    match:
      command: mix
      args:
        any_of: ["archive.install", "escript.install"]
    decision: ask
    reason: "Installing Elixir archive/escript"

  # ── Dart/Flutter package managers ────────────────────────────
  - id: dart-pub-get
    level: high
    match:
      command: dart
      args:
        any_of: ["pub"]
      flags:
        any_of: ["get", "add"]
    decision: ask
    reason: "Installing Dart packages"

  - id: flutter-pub-get
    level: high
    match:
      command: flutter
      args:
        any_of: ["pub"]
      flags:
        any_of: ["get", "add"]
    decision: ask
    reason: "Installing Flutter packages"

  - id: pub-get
    level: high
    match:
      command: pub
      args:
        any_of: ["get", "add"]
    decision: ask
    reason: "Installing Dart packages via pub"

  # ── Haskell package managers ─────────────────────────────────
  - id: cabal-install
    level: high
    match:
      command: cabal
      args:
        any_of: ["install", "v2-install"]
    decision: ask
    reason: "Installing Haskell package via Cabal"

  - id: stack-install
    level: high
    match:
      command: stack
      args:
        any_of: ["install"]
    decision: ask
    reason: "Installing Haskell package via Stack"

  # ── Lua package managers ─────────────────────────────────────
  - id: luarocks-install
    level: high
    match:
      command: luarocks
      args:
        any_of: ["install"]
    decision: ask
    reason: "Installing Lua rock"

  # ── sudo/privilege escalation wrappers ───────────────────────
  - id: sudo-package-install
    level: high
    match:
      command: sudo
      args:
        any_of: ["pip", "pip3", "npm", "gem", "apt", "apt-get", "dnf", "yum",
                 "pacman", "apk", "brew", "snap", "flatpak"]
    decision: ask
    reason: "Package installation with sudo"

  - id: doas-package-install
    level: high
    match:
      command: doas
      args:
        any_of: ["pip", "pip3", "npm", "gem", "apt", "apt-get", "dnf", "yum",
                 "pacman", "apk", "brew", "snap", "flatpak"]
    decision: ask
    reason: "Package installation with doas"
