longline 0.13.0

System-installed safety hook for Claude Code
Documentation
# Git operations: read/write commands and destructive operations

allowlists:
  commands:
    # ── Git: read operations ──────────────────────────────────────
    - { command: "git status", trust: minimal }
    - { command: "git diff", trust: minimal }
    - { command: "git log", trust: minimal }
    - { command: "git show", trust: minimal }
    - { command: "git branch", trust: minimal }
    - { command: "git stash list", trust: minimal }
    - { command: "git remote", trust: minimal }
    - { command: "git tag", trust: minimal }
    - { command: "git rev-parse", trust: minimal }
    - { command: "git blame", trust: minimal }
    - { command: "git describe", trust: minimal }
    - { command: "git shortlog", trust: minimal }
    - { command: "git reflog", trust: minimal }
    - { command: "git ls-files", trust: minimal }
    - { command: "git ls-tree", trust: minimal }
    - { command: "git cat-file", trust: minimal }
    - { command: "git grep", trust: minimal }
    - { command: "git archive", trust: minimal }
    - { command: "git check-ignore", trust: minimal }
    - { command: "git symbolic-ref", trust: minimal }
    - { command: "git show-ref", trust: minimal }
    - { command: "git diff-tree", trust: minimal }
    # ── Git: info/help commands ───────────────────────────────────
    - { command: "git --version", trust: minimal }
    - { command: "git -v", trust: minimal }
    - { command: "git help", trust: minimal }
    - { command: "git -h", trust: minimal }
    # ── Git: history/ref commands ─────────────────────────────────
    - { command: "git merge-base", trust: minimal }
    - { command: "git rev-list", trust: minimal }
    - { command: "git for-each-ref", trust: minimal }
    - { command: "git name-rev", trust: minimal }
    - { command: "git verify-pack", trust: minimal }
    - { command: "git fsck", trust: minimal }
    # ── Git: safe write operations ────────────────────────────────
    - { command: "git config", trust: standard, reason: "Reads or modifies local git configuration" }
    - { command: "git bisect", trust: standard, reason: "Binary searches commit history to find a bug" }
    - { command: "git add", trust: standard, reason: "Stages file changes for the next commit" }
    - { command: "git commit", trust: standard, reason: "Creates a new commit from staged changes" }
    - { command: "git fetch", trust: standard, reason: "Downloads objects and refs from a remote" }
    - { command: "git pull", trust: standard, reason: "Fetches and merges changes from a remote branch" }
    - { command: "git push", trust: full, reason: "Pushes local commits to a remote repository" }
    - { command: "git stash", trust: standard, reason: "Temporarily shelves uncommitted changes" }
    - { command: "git checkout", trust: standard, reason: "Switches branches or restores files" }
    - { command: "git switch", trust: standard, reason: "Switches to a different branch" }
    - { command: "git restore", trust: standard, reason: "Restores working tree files from a source" }
    - { command: "git merge", trust: standard, reason: "Merges another branch into the current branch" }
    - { command: "git cherry-pick", trust: standard, reason: "Applies changes from specific commits" }
    - { command: "git worktree", trust: standard, reason: "Manages multiple working trees" }
    - { command: "git clone", trust: standard, reason: "Clones a repository into a new directory" }
    - { command: "git init", trust: standard, reason: "Creates a new git repository" }
    # ── Git: safe file operations ────────────────────────────────────
    - { command: "git mv", trust: standard, reason: "Moves or renames a file tracked by git" }
    - { command: "git rm", trust: standard, reason: "Removes files from the working tree and index" }
    # ── Git: stash operations ────────────────────────────────────────
    - { command: "git stash pop", trust: standard, reason: "Applies and removes the top stashed changes" }
    - { command: "git stash apply", trust: standard, reason: "Applies stashed changes without removing them" }
    # ── Git: maintenance commands ──────────────────────────────────
    - { command: "git revert", trust: standard, reason: "Creates a new commit that undoes a previous commit" }
    - { command: "git gc", trust: full, reason: "Runs garbage collection on the repository" }

rules:
  # ============================================================
  # HIGH: VCS destructive operations
  # ============================================================
  - id: git-force-push-main
    level: high
    match:
      command: git
      flags:
        any_of: ["--force", "-f", "--force-with-lease", "--force-if-includes"]
      args:
        any_of: ["main", "master"]
    decision: ask
    reason: "Force pushing to main/master branch"

  - id: git-reset-hard
    level: high
    match:
      command: git
      args:
        any_of: ["--hard"]
    decision: ask
    reason: "git reset --hard discards uncommitted changes"

  - id: git-clean-force
    level: high
    match:
      command: git
      args:
        any_of: ["clean"]
      flags:
        any_of: ["-f", "--force"]
    decision: ask
    reason: "git clean -f permanently removes untracked files"

  - id: git-branch-delete-force
    level: high
    match:
      command: git
      args:
        any_of: ["branch"]
      flags:
        any_of: ["-D"]
    decision: ask
    reason: "Force deleting a git branch"

  - id: git-commit-amend
    level: high
    match:
      command: git
      args:
        any_of: ["commit"]
      flags:
        any_of: ["--amend"]
    decision: ask
    reason: "git commit --amend rewrites the previous commit"

  - id: git-remote-modify
    level: high
    match:
      command: git
      args:
        any_of: ["remote"]
      flags:
        any_of: ["add", "remove", "rm", "set-url", "rename"]
    decision: ask
    reason: "Modifying git remote configuration"

  - id: git-tag-delete
    level: high
    match:
      command: git
      args:
        any_of: ["tag"]
      flags:
        any_of: ["-d", "--delete"]
    decision: ask
    reason: "Deleting git tag"

  - id: git-push-delete
    level: high
    match:
      command: git
      args:
        any_of: ["push"]
      flags:
        any_of: ["--delete", "-d"]
    decision: ask
    reason: "Deleting remote branch or tag"

  - id: git-config-global
    level: high
    match:
      command: git
      args:
        any_of: ["config"]
      flags:
        any_of: ["--global", "--system"]
    decision: ask
    reason: "Modifying global/system git configuration"

  - id: git-stash-drop
    level: high
    match:
      command: git
      args:
        any_of: ["stash"]
      flags:
        any_of: ["drop", "clear"]
    decision: ask
    reason: "Dropping stashed changes (data loss)"

  - id: git-reflog-delete
    level: high
    match:
      command: git
      args:
        any_of: ["reflog"]
      flags:
        any_of: ["delete", "expire"]
    decision: ask
    reason: "Deleting reflog entries (history loss)"

  - id: git-gc-prune
    level: high
    match:
      command: git
      args:
        any_of: ["gc"]
      flags:
        starts_with: ["--prune"]
    decision: ask
    reason: "git gc with pruning can remove unreachable objects"

  - id: git-worktree-remove
    level: high
    match:
      command: git
      args:
        any_of: ["worktree"]
      flags:
        any_of: ["remove", "prune"]
    decision: ask
    reason: "Removing git worktree"

  - id: git-bisect-reset
    level: high
    match:
      command: git
      args:
        any_of: ["bisect"]
      flags:
        any_of: ["reset"]
    decision: ask
    reason: "Exiting bisect mode (changes HEAD)"

  - id: git-pull-force
    level: high
    match:
      command: git
      args:
        any_of: ["pull"]
      flags:
        any_of: ["--force", "-f"]
    decision: ask
    reason: "git pull --force can overwrite local changes"

  - id: git-rebase
    level: high
    match:
      command: git
      args:
        any_of: ["rebase"]
    decision: ask
    reason: "git rebase rewrites history and can cause data loss"

  - id: git-symbolic-ref-delete
    level: high
    match:
      command: git
      args:
        any_of: ["symbolic-ref"]
      flags:
        any_of: ["--delete", "-d"]
    decision: ask
    reason: "git symbolic-ref --delete removes symbolic references"

  - id: git-force-push-any
    level: high
    match:
      command: git
      flags:
        any_of: ["--force", "-f", "--force-with-lease", "--force-if-includes"]
      args:
        any_of: ["push"]
    decision: ask
    reason: "Force pushing (any branch)"

  # ============================================================
  # STRICT: Cautionary git operations
  # ============================================================
  - id: git-checkout-dot
    level: strict
    match:
      command: git
      args:
        any_of: ["checkout", "restore"]
      flags:
        any_of: [".", "--"]
    decision: ask
    reason: "Discarding all local changes"