{
  "report_info": {
    "version": "9.0.1",
    "generated_at": "2026-07-21T01:54:18Z",
    "binary_name": "permission-guard"
  },
  "binary": {
    "name": "permission-guard",
    "path": "/opt/kodachi/dashboard/hooks/permission-guard",
    "timestamp": "2026-07-21T01:54:18Z",
    "file_info": {
      "size": 2041152,
      "sha256": "1937fd33120b9e9f7f7d89995b13c7128994e85fa3d289faf69ed05c428f1a51"
    },
    "flag_n": {
      "command": "info",
      "data": {
        "author": "Warith Al Maawali",
        "copyright": "© 2026 Kodachi OS",
        "description": "A robust permission management service for Kodachi OS that monitors and corrects file ownership to prevent root-owned files in user directories",
        "features": [
          "Real-time file permission monitoring",
          "Automatic permission correction",
          "Configurable watch directories",
          "Pattern-based exclusions",
          "Daemon mode for background operation",
          "JSON and text output formats",
          "Field filtering and pagination",
          "Comprehensive error handling"
        ],
        "license": "Proprietary",
        "name": "permission-guard",
        "securityFeatures": {
          "authentication": "Integrates with system user permissions",
          "encryption": "Secure configuration storage",
          "inputValidation": "All paths and inputs are sanitized and validated",
          "rateLimiting": "Configurable scan intervals prevent resource exhaustion"
        },
        "systemRequirements": {
          "dependencies": [
            "systemd",
            "inotify support"
          ],
          "os": "Linux (Debian-based)",
          "privileges": "root/sudo"
        },
        "version": "9.8.4 (build 320)",
        "website": "https://digi77.com"
      },
      "errors": [],
      "metadata": {
        "executionTime": 0,
        "hostname": "REDACTED-BUILD-HOST",
        "user": "REDACTED-BUILD-USER"
      },
      "status": "success",
      "timestamp": "2026-07-21T01:54:18.493221018Z",
      "version": "9.8.4 (build 320)",
      "warnings": []
    },
    "flag_v": {
      "command": "version",
      "data": {
        "buildDate": "REDACTED-BUILD-TIME",
        "gitCommit": "unknown",
        "name": "permission-guard",
        "rustVersion": "unknown",
        "version": "9.8.4 (build 320)"
      },
      "errors": [],
      "metadata": {
        "executionTime": 1,
        "hostname": "REDACTED-BUILD-HOST",
        "user": "REDACTED-BUILD-USER"
      },
      "status": "success",
      "timestamp": "2026-07-21T01:54:18.603932975Z",
      "version": "9.8.4 (build 320)",
      "warnings": []
    },
    "flag_h": {
      "command": "help",
      "data": {
        "commandCategories": [
          {
            "category": "Monitoring Commands",
            "commands": [
              {
                "description": "Start continuous monitoring with auto-fix (runs until interrupted)",
                "examples": [
                  "sudo permission-guard watch",
                  "sudo permission-guard watch /opt/kodachi/dashboard/hooks --scan-interval 60",
                  "permission-guard watch --no-auto-fix --json",
                  "sudo permission-guard --daemon watch"
                ],
                "name": "watch",
                "options": [
                  {
                    "default": "execution folder",
                    "description": "Directories to monitor. Defaults to the binary's own execution folder. Rejected: /etc /bin /sbin /usr /lib /lib64 /boot /proc /sys /dev /var /run /root /srv /opt (only /opt/kodachi is allowed) and any path containing '..'",
                    "flag": "[DIRECTORIES]..."
                  },
                  {
                    "default": "true",
                    "description": "Enable automatic fixing",
                    "flag": "--auto-fix"
                  },
                  {
                    "description": "Disable automatic fixing",
                    "flag": "--no-auto-fix"
                  },
                  {
                    "default": "30",
                    "description": "Re-scan interval in seconds for recently active paths. Falls back to the global --timeout value when omitted",
                    "flag": "--scan-interval <SECS>"
                  },
                  {
                    "default": "true",
                    "description": "Enable recursive monitoring",
                    "flag": "--recursive"
                  },
                  {
                    "description": "Disable recursive monitoring",
                    "flag": "--no-recursive"
                  }
                ],
                "requires_sudo": true,
                "usage": "permission-guard watch [OPTIONS] [DIRECTORIES]..."
              },
              {
                "description": "Perform a one-time scan (report-only unless --fix is passed)",
                "examples": [
                  "permission-guard scan --dry-run",
                  "sudo permission-guard scan --fix",
                  "sudo permission-guard scan /opt/kodachi/dashboard/hooks --fix --json",
                  "permission-guard scan \"$HOME/kodachi\" --no-recursive"
                ],
                "name": "scan",
                "options": [
                  {
                    "default": "execution folder",
                    "description": "Directories to scan. Defaults to the binary's own execution folder. Rejected: /etc /bin /sbin /usr /lib /lib64 /boot /proc /sys /dev /var /run /root /srv /opt (only /opt/kodachi is allowed) and any path containing '..'",
                    "flag": "[DIRECTORIES]..."
                  },
                  {
                    "description": "Correct ownership and modes (needs root; ignored when --dry-run is also passed)",
                    "flag": "--fix"
                  },
                  {
                    "description": "Preview changes without applying",
                    "flag": "--dry-run"
                  },
                  {
                    "default": "true",
                    "description": "Enable recursive scanning",
                    "flag": "--recursive"
                  },
                  {
                    "description": "Disable recursive scanning",
                    "flag": "--no-recursive"
                  }
                ],
                "requires_sudo": true,
                "usage": "permission-guard scan [OPTIONS] [DIRECTORIES]..."
              }
            ]
          },
          {
            "category": "Management Commands",
            "commands": [
              {
                "description": "Show current status and configuration",
                "examples": [
                  "permission-guard status",
                  "permission-guard status --detailed",
                  "permission-guard status --json",
                  "permission-guard status --detailed --json"
                ],
                "name": "status",
                "options": [
                  {
                    "description": "Show detailed information",
                    "flag": "--detailed"
                  }
                ],
                "requires_sudo": false,
                "usage": "permission-guard status [OPTIONS]"
              },
              {
                "description": "Manage configuration",
                "examples": [
                  "permission-guard config show",
                  "permission-guard config show --json"
                ],
                "name": "config",
                "options": [
                  {
                    "description": "Display current embedded configuration",
                    "flag": "show"
                  }
                ],
                "requires_sudo": false,
                "usage": "permission-guard config <SUBCOMMAND>"
              }
            ]
          }
        ],
        "description": "A robust permission management service for Kodachi OS",
        "environmentVariables": [
          {
            "default": "info",
            "description": "Set logging level",
            "name": "RUST_LOG",
            "values": "error|warn|info|debug|trace"
          },
          {
            "default": "unset",
            "description": "Disable all colored output when set",
            "name": "NO_COLOR",
            "values": "1|true|yes (any value disables color)"
          },
          {
            "default": "unset",
            "description": "HTTP proxy for network requests",
            "name": "HTTP_PROXY",
            "values": "http://proxy:port"
          },
          {
            "default": "unset",
            "description": "HTTPS proxy for secure requests",
            "name": "HTTPS_PROXY",
            "values": "https://proxy:port"
          },
          {
            "default": "~/.config/permission-guard/config.json",
            "description": "Path to configuration file",
            "name": "PERMISSION_GUARD_CONFIG",
            "values": "/path/to/config.json"
          }
        ],
        "exitCodes": {
          "0": "Success",
          "1": "General error",
          "10": "Command error",
          "2": "Invalid arguments",
          "3": "Permission denied",
          "4": "Network error",
          "5": "File not found",
          "6": "Timeout",
          "7": "Authentication error",
          "8": "Internal error",
          "9": "Validation error"
        },
        "globalOptions": [
          {
            "description": "Print help information",
            "flag": "-h, --help"
          },
          {
            "description": "Print version information",
            "flag": "-v, --version"
          },
          {
            "description": "Display detailed information",
            "flag": "-n, --info"
          },
          {
            "description": "Show usage examples",
            "flag": "-e, --examples"
          },
          {
            "description": "Output in JSON format",
            "flag": "--json"
          },
          {
            "description": "Force output format (default: text)",
            "flag": "-o, --output-format <text|json>"
          },
          {
            "description": "Enable verbose output",
            "flag": "--verbose"
          },
          {
            "description": "Suppress non-essential output",
            "flag": "--quiet"
          },
          {
            "description": "Disable colored output",
            "flag": "--no-color"
          },
          {
            "description": "Set operation timeout in seconds",
            "flag": "--timeout <SECS>"
          },
          {
            "description": "Return only specified fields in JSON output",
            "flag": "--json-filter <FIELD1,FIELD2>"
          },
          {
            "description": "Pretty-print JSON output with indentation",
            "flag": "--json-pretty"
          },
          {
            "description": "Enhanced human-friendly JSON output",
            "flag": "--json-human"
          },
          {
            "description": "Select specific fields to include in output",
            "flag": "--fields <FIELD_LIST>"
          },
          {
            "description": "Limit number of results returned",
            "flag": "--limit <NUMBER>"
          },
          {
            "description": "Skip first N results (for pagination)",
            "flag": "--offset <NUMBER>"
          },
          {
            "description": "Override target user (username or UID)",
            "flag": "--user-override <USER>"
          },
          {
            "description": "Run as daemon (background process)",
            "flag": "-d, --daemon"
          },
          {
            "description": "Custom PID file location",
            "flag": "--pid-file <FILE>"
          },
          {
            "description": "Stop running daemon",
            "flag": "--stop-daemon"
          },
          {
            "description": "Show daemon status",
            "flag": "--daemon-status"
          }
        ],
        "name": "permission-guard",
        "usage": "permission-guard [OPTIONS] [COMMAND] [ARGS]"
      },
      "errors": [],
      "metadata": {
        "executionTime": 1,
        "hostname": "REDACTED-BUILD-HOST",
        "user": "REDACTED-BUILD-USER"
      },
      "status": "success",
      "timestamp": "2026-07-21T01:54:18.726481803Z",
      "version": "9.8.4 (build 320)",
      "warnings": []
    },
    "flag_e": {
      "command": "examples",
      "data": {
        "categories": [
          {
            "description": "The first three commands on a fresh box. With no directory argument, scan and watch target the binary's own execution folder (on an installed system that is /opt/kodachi/dashboard/hooks).",
            "examples": [
              {
                "command": "permission-guard scan --dry-run",
                "description": "Report what is wrong in the hooks tree, change nothing",
                "expectedOutput": "Performing dry-run scan (no changes will be made) / Files scanned: N / Files needing correction: N"
              },
              {
                "command": "sudo permission-guard scan --fix",
                "description": "Correct the ownership and modes that the dry run reported",
                "expectedOutput": "Scan completed: Files corrected: N, Files failed to correct: 0",
                "notes": "Needs root: correcting ownership calls chown."
              },
              {
                "command": "permission-guard status",
                "description": "Check whether the guard daemon is running and which directories it covers",
                "expectedOutput": "Daemon state, target user, watched directories and scan intervals currently in effect"
              },
              {
                "command": "permission-guard config show",
                "description": "Print the compiled-in configuration defaults and security constraints",
                "expectedOutput": "Embedded defaults: watch directories, exclude patterns, scan intervals, permission modes",
                "notes": "These are the embedded defaults, not the live values. Use 'status --detailed' for what is actually running."
              }
            ],
            "id": "0_quick_start",
            "title": "Quick Start"
          },
          {
            "description": "Which paths permission-guard accepts. Every directory you pass is checked against a denylist before any work starts, so most system paths are refused outright.",
            "examples": [
              {
                "command": "sudo permission-guard scan /opt/kodachi/dashboard/hooks --fix",
                "description": "Scan and fix the installed Kodachi hooks tree by explicit path",
                "expectedOutput": "Scan completed with per-directory counts for the hooks tree",
                "notes": "/opt/kodachi is the ONLY subtree under /opt the validator accepts; every other /opt path is refused. Needs root."
              },
              {
                "command": "permission-guard scan \"$HOME/kodachi\" --dry-run",
                "description": "Preview a scan of a Kodachi checkout in your home directory",
                "expectedOutput": "Dry-run counts for the given directory, nothing modified",
                "notes": "Home paths are outside the denylist, and reporting on files you already own needs no root."
              },
              {
                "command": "sudo permission-guard scan /opt/kodachi/dashboard/hooks \"$HOME/kodachi\" --fix",
                "description": "Scan several directories in one run",
                "expectedOutput": "Combined counts across both directories",
                "notes": "Every directory in the list must pass the denylist; one bad path aborts the whole run."
              },
              {
                "command": "permission-guard scan /etc",
                "description": "What a refused path looks like, so you recognise it",
                "expectedOutput": "Error: Directory path is not in a safe location: /etc (exit code 2)",
                "notes": "Refused roots: /etc /bin /sbin /usr /lib /lib64 /boot /proc /sys /dev /var /run /root /srv /opt (except /opt/kodachi) and bare /. Any path containing '..' is refused as well."
              }
            ],
            "id": "1_choosing_directories",
            "title": "Choosing Directories"
          },
          {
            "description": "Single-pass scans. Without --fix nothing is changed; --dry-run wins if both are passed.",
            "examples": [
              {
                "command": "permission-guard scan",
                "description": "Report-only scan: count problems, change nothing, print the hint to use --fix",
                "expectedOutput": "Performing scan without fixes (use --fix to enable corrections), then the file counts"
              },
              {
                "command": "permission-guard scan --dry-run --verbose",
                "description": "Preview every correction the guard would make, with per-file detail",
                "expectedOutput": "Verbose per-file listing plus the summary counts, nothing written"
              },
              {
                "command": "sudo permission-guard scan --fix --no-recursive",
                "description": "Fix only the top level of the directory, do not descend into subdirectories",
                "expectedOutput": "Scan completed covering the directory itself only",
                "notes": "--no-recursive conflicts with --recursive; pass only one. Needs root."
              },
              {
                "command": "sudo permission-guard --user-override \"$USER\" scan --fix",
                "description": "Hand ownership to a specific user rather than the auto-detected one",
                "expectedOutput": "Scan completed with files chowned to the named user",
                "notes": "--user-override must come BEFORE the subcommand (it is not a global flag). UID 0 and numeric UIDs below 1000 are refused; pass a real username for a system account."
              },
              {
                "command": "sudo permission-guard --user-override 1001 scan --fix",
                "description": "Same, using a numeric UID when the username is not known",
                "expectedOutput": "Scan completed with files chowned to UID 1001",
                "notes": "Numeric UIDs must be 1000 or above. Unknown users fail with \"User not found\"."
              }
            ],
            "id": "2_one_off_scans",
            "title": "One-off Scans"
          },
          {
            "description": "Keep the guard running and re-check permissions as files change. watch runs in the foreground until you interrupt it, unless you add --daemon.",
            "examples": [
              {
                "command": "sudo permission-guard watch",
                "description": "Monitor the hooks tree with auto-fix and recursion on (the defaults)",
                "expectedOutput": "Watcher starts and prints correction events as they happen; runs until Ctrl-C",
                "notes": "Needs root: auto-fix is on by default and chowns files. Blocks the terminal; use --daemon to background it."
              },
              {
                "command": "sudo permission-guard watch /opt/kodachi/dashboard/hooks --scan-interval 60",
                "description": "Re-check recently active paths every 60 seconds instead of the 30 second default",
                "expectedOutput": "Watcher running with a 60 second rescan interval",
                "notes": "If --scan-interval is omitted, watch falls back to the global --timeout value. --timeout has no effect on any other command."
              },
              {
                "command": "permission-guard watch --no-auto-fix --scan-interval 120",
                "description": "Report-only monitoring: log what is wrong, never change it",
                "expectedOutput": "Watcher logs permission violations without correcting them",
                "notes": "--no-auto-fix conflicts with --auto-fix; pass only one. Report-only monitoring needs no root."
              },
              {
                "command": "sudo permission-guard watch \"$HOME/kodachi\" --no-recursive",
                "description": "Watch one directory level only",
                "expectedOutput": "Watcher covering the named directory, ignoring its subdirectories"
              },
              {
                "command": "permission-guard watch --no-auto-fix --json",
                "description": "Stream watch events as JSON so a log processor can consume them",
                "expectedOutput": "JSON event objects on stdout instead of human text",
                "notes": "Good for piping. Drop --no-auto-fix and add sudo if you also want corrections applied."
              }
            ],
            "id": "3_continuous_monitoring",
            "title": "Continuous Monitoring"
          },
          {
            "description": "Inspect the live configuration and the compiled-in defaults. Neither command changes anything, and neither needs root.",
            "examples": [
              {
                "command": "permission-guard status --detailed",
                "description": "Full runtime view: target user, watched and excluded directories, every interval",
                "expectedOutput": "Expanded text report of the active runtime configuration and daemon state"
              },
              {
                "command": "permission-guard status --detailed --json",
                "description": "The same detailed view as a single JSON object for a script",
                "expectedOutput": "JSON envelope whose data block holds the runtime status and active configuration"
              },
              {
                "command": "permission-guard config show --json",
                "description": "Read the embedded configuration template as JSON",
                "expectedOutput": "JSON with the embedded defaults and the security constraints they must satisfy",
                "notes": "Embedded defaults only. 'status --detailed --json' is the one that reflects the running configuration."
              }
            ],
            "id": "4_status_and_config",
            "title": "Status and Configuration"
          },
          {
            "description": "Run the guard detached. --daemon, --pid-file, --stop-daemon and --daemon-status are root-level flags: they must appear BEFORE the subcommand. The default PID file is <execution folder>/tmp/permission-guard.pid.",
            "examples": [
              {
                "command": "sudo permission-guard --daemon watch",
                "description": "Start monitoring the hooks tree in the background and return to the shell",
                "expectedOutput": "Daemon started with PID <N>, then the terminal is free",
                "notes": "Needs root (auto-fix chowns files). Check it afterwards with --daemon-status."
              },
              {
                "command": "permission-guard --daemon-status",
                "description": "Ask whether a guard daemon is running and under which PID",
                "expectedOutput": "Running with PID <N>, or a message that no daemon is running"
              },
              {
                "command": "permission-guard --daemon-status --json",
                "description": "Same check, machine readable, for a monitoring script",
                "expectedOutput": "JSON with the running flag, the PID and the PID file path"
              },
              {
                "command": "sudo permission-guard --stop-daemon",
                "description": "Stop the daemon recorded in the default PID file",
                "expectedOutput": "Confirmation that the daemon was signalled and stopped",
                "notes": "Stopping the guard means permissions stop being corrected until you start it again."
              },
              {
                "command": "sudo permission-guard --daemon --pid-file /opt/kodachi/dashboard/hooks/tmp/pg-instance1.pid watch /opt/kodachi/dashboard/hooks",
                "description": "Run a second, independently addressable daemon instance",
                "expectedOutput": "Daemon started with its own PID file and lock file",
                "notes": "The PID path goes through the SAME denylist as directories: /var/run and /run are refused with \"PID file path is not in a safe location\". Keep instance PID files under /opt/kodachi or in your home directory."
              },
              {
                "command": "permission-guard --daemon-status --pid-file /opt/kodachi/dashboard/hooks/tmp/pg-instance1.pid",
                "description": "Check that one named instance specifically",
                "expectedOutput": "Running state and PID for the daemon recorded in that PID file"
              },
              {
                "command": "sudo permission-guard --stop-daemon --pid-file /opt/kodachi/dashboard/hooks/tmp/pg-instance1.pid",
                "description": "Stop that one named instance and leave the others running",
                "expectedOutput": "Confirmation that the named instance was stopped"
              },
              {
                "command": "sudo permission-guard --daemon scan --fix",
                "description": "Run a one-time fix in the background",
                "expectedOutput": "Scan runs, then the process prints a heartbeat every 60 seconds",
                "notes": "The daemon deliberately STAYS ALIVE after the scan finishes; end it with --stop-daemon."
              }
            ],
            "id": "5_daemon",
            "title": "Background Daemon"
          },
          {
            "description": "Machine-readable output. Field paths are resolved against the JSON envelope, so a bare name such as scan_results is looked up inside the data block automatically. --limit and --offset only reshape list-shaped payloads and have no useful effect on permission-guard, whose scan and status payloads are single objects.",
            "examples": [
              {
                "command": "permission-guard --json status",
                "description": "Runtime status as a compact JSON envelope",
                "expectedOutput": "{\"status\":\"success\",\"command\":\"status\",\"data\":{...}}",
                "notes": "--json is global: 'status --json' parses identically. This corpus puts it before the subcommand throughout."
              },
              {
                "command": "permission-guard --json scan --dry-run",
                "description": "Dry-run results as JSON for a pre-flight check in a script",
                "expectedOutput": "JSON with scan_results (files_scanned, files_needing_correction, success_rate) and the configuration used"
              },
              {
                "command": "sudo permission-guard --json scan --fix",
                "description": "Apply fixes and capture the outcome as JSON",
                "expectedOutput": "JSON with files_corrected, files_failed and any per-file errors",
                "notes": "Needs root."
              },
              {
                "command": "permission-guard --json-pretty --fields scan_results,configuration scan --dry-run",
                "description": "Indented JSON reduced to just the scan results and the configuration used",
                "expectedOutput": "Pretty-printed JSON containing only the scan_results and configuration blocks",
                "notes": "Bare field names are resolved inside the data block. Use dotted paths for anything deeper."
              },
              {
                "command": "sudo permission-guard --json-filter scan_results.files_corrected,scan_results.files_failed scan --fix",
                "description": "Cut the JSON down to the two counters a deployment script cares about",
                "expectedOutput": "{\"scan_results\":{\"files_corrected\":N,\"files_failed\":0}}",
                "notes": "Nested values need the dotted path. A bare 'files_corrected' does NOT resolve, because it lives under scan_results."
              },
              {
                "command": "permission-guard --quiet --json status",
                "description": "JSON only, with warnings and progress chatter suppressed",
                "expectedOutput": "The JSON envelope on stdout and nothing else"
              },
              {
                "command": "permission-guard --output-format json config show",
                "description": "Select JSON with the explicit format flag instead of --json",
                "expectedOutput": "The same output as 'permission-guard --json config show'"
              }
            ],
            "id": "6_json_automation",
            "title": "JSON for Automation"
          },
          {
            "description": "What to run when the guard is not doing what you expect, and what its refusals look like.",
            "examples": [
              {
                "command": "permission-guard --verbose scan --dry-run",
                "description": "See exactly which files the guard considers wrong, before touching anything",
                "expectedOutput": "Per-file expected versus actual owner and mode, plus the summary"
              },
              {
                "command": "permission-guard --verbose --no-color scan --dry-run",
                "description": "The same detail as plain text, safe to redirect into a log file",
                "expectedOutput": "Verbose scan output with no ANSI escape codes"
              },
              {
                "command": "permission-guard --user-override nonexistent scan",
                "description": "What an unknown target user looks like",
                "expectedOutput": "Error: User 'nonexistent' not found (exit code 2)"
              },
              {
                "command": "permission-guard --pid-file /var/run/pg.pid --daemon-status",
                "description": "What a refused PID path looks like, so you do not lose time on it",
                "expectedOutput": "Error: PID file path is not in a safe location (exit code 2)",
                "notes": "/var and /run are on the denylist. Put instance PID files under /opt/kodachi or in your home directory."
              }
            ],
            "id": "7_troubleshooting",
            "title": "Troubleshooting"
          }
        ],
        "description": "Usage examples for permission-guard",
        "name": "permission-guard",
        "quickReference": [
          "permission-guard --help",
          "permission-guard --version",
          "permission-guard --info --json",
          "permission-guard --examples --json",
          "permission-guard scan --dry-run",
          "sudo permission-guard scan --fix",
          "sudo permission-guard watch",
          "permission-guard status --detailed",
          "permission-guard config show",
          "sudo permission-guard --daemon watch",
          "permission-guard --daemon-status",
          "sudo permission-guard --stop-daemon"
        ]
      },
      "errors": [],
      "metadata": {
        "executionTime": 1,
        "hostname": "REDACTED-BUILD-HOST",
        "user": "REDACTED-BUILD-USER"
      },
      "status": "success",
      "timestamp": "2026-07-21T01:54:18.910847155Z",
      "version": "9.8.4 (build 320)",
      "warnings": []
    }
  }
}
