longline 0.11.0

System-installed safety hook for Claude Code
Documentation
# Filesystem: destructive operations (commands are in core-allowlist)

allowlists:
  commands: []

rules:
  # ============================================================
  # CRITICAL: Filesystem destruction
  # ============================================================
  - id: rm-recursive-root
    level: critical
    match:
      command: rm
      flags:
        any_of: ["-r", "-R", "--recursive", "-rf", "-fr", "-Rf", "-fR"]
      args:
        any_of: ["/", "/*"]
    decision: deny
    reason: "Recursive delete targeting root filesystem"

  - id: rm-recursive-system
    level: critical
    match:
      command: rm
      flags:
        any_of: ["-r", "-R", "--recursive", "-rf", "-fr", "-Rf", "-fR"]
      args:
        any_of: ["/etc", "/etc/*", "/usr", "/usr/*", "/var", "/var/*", "/bin",
                  "/bin/*", "/sbin", "/sbin/*", "/lib", "/lib/*", "/boot",
                  "/boot/*", "/sys", "/sys/*", "/proc", "/proc/*"]
    decision: deny
    reason: "Recursive delete targeting system directory"

  - id: rm-recursive-home
    level: critical
    match:
      command: rm
      flags:
        any_of: ["-r", "-R", "--recursive", "-rf", "-fr", "-Rf", "-fR"]
      args:
        any_of: ["~", "~/", "$HOME", "$HOME/"]
    decision: deny
    reason: "Recursive delete targeting home directory"

  - id: dd-disk-device
    level: critical
    match:
      command: dd
      args:
        any_of: ["of=/dev/sd*", "of=/dev/nvme*", "of=/dev/hd*",
                  "of=/dev/vd*", "of=/dev/xvd*", "of=/dev/disk*"]
    decision: deny
    reason: "dd writing directly to disk device"

  - id: mkfs-any
    level: critical
    match:
      command:
        any_of: [mkfs, "mkfs.ext4", "mkfs.xfs", "mkfs.btrfs", "mkfs.vfat", "mkfs.ntfs"]
    decision: deny
    reason: "Formatting a filesystem"

  - id: fork-bomb
    level: critical
    match:
      command: ":"
    decision: ask
    reason: "Potential fork bomb pattern"

  # ============================================================
  # HIGH: Disk / partition
  # ============================================================
  - id: fdisk
    level: high
    match:
      command:
        any_of: [fdisk, gdisk, parted, partprobe]
    decision: deny
    reason: "Disk partitioning tool"

  - id: mount-unmount
    level: high
    match:
      command:
        any_of: [mount, umount]
    decision: ask
    reason: "Filesystem mount/unmount"

  # ============================================================
  # HIGH: Destructive find/xargs patterns
  # ============================================================
  - id: find-delete
    level: high
    match:
      command: find
      flags:
        any_of: ["-delete"]
    decision: ask
    reason: "find -delete recursively removes matching files"

  - id: find-exec-rm
    level: high
    match:
      command: find
      args:
        any_of: ["-exec"]
      flags:
        any_of: ["rm"]
    decision: ask
    reason: "find -exec with rm can delete files"

  - id: xargs-rm
    level: high
    match:
      command: xargs
      args:
        any_of: ["rm"]
    decision: ask
    reason: "xargs executing rm on piped input"

  # ============================================================
  # HIGH: Filesystem destructive operations (allowlist bypass)
  # ============================================================
  - id: ln-force
    level: high
    match:
      command: ln
      flags:
        any_of: ["-f", "--force", "-sf", "-fs", "-fn", "-nf"]
    decision: ask
    reason: "ln -f can overwrite existing files"

  - id: cp-force
    level: high
    match:
      command: cp
      flags:
        any_of: ["-f", "--force", "-rf", "-fr"]
    decision: ask
    reason: "cp -f overwrites without prompting"

  - id: mv-any
    level: high
    match:
      command: mv
    decision: ask
    reason: "mv removes source and can overwrite destination"

  - id: tar-extract
    level: high
    match:
      command: tar
      flags:
        starts_with: ["-x", "--extract"]
    decision: ask
    reason: "tar extraction can overwrite files"

  - id: unzip-extract
    level: high
    match:
      command: unzip
      flags:
        none_of: ["-l", "-t", "-Z", "-v"]
    decision: ask
    reason: "unzip extraction can overwrite files"

  - id: sed-inplace
    level: high
    match:
      command: sed
      flags:
        starts_with: ["-i", "--in-place"]
    decision: ask
    reason: "sed -i modifies files in place"

  - id: patch-apply
    level: high
    match:
      command: patch
      flags:
        none_of: ["--dry-run", "-C", "--check"]
    decision: ask
    reason: "patch modifies files"

  - id: gzip-no-keep
    level: high
    match:
      command: gzip
      flags:
        none_of: ["-k", "--keep", "-c", "--stdout", "-t", "--test", "-l", "--list"]
    decision: ask
    reason: "gzip removes original file by default"

  - id: gunzip-no-keep
    level: high
    match:
      command: gunzip
      flags:
        none_of: ["-k", "--keep", "-c", "--stdout", "-t", "--test", "-l", "--list"]
    decision: ask
    reason: "gunzip removes original file by default"

  - id: tee-any
    level: high
    match:
      command: tee
    decision: ask
    reason: "tee writes to files"