{
  "report_info": {
    "version": "9.0.1",
    "generated_at": "2026-07-21T01:54:34Z",
    "binary_name": "global-launcher"
  },
  "binary": {
    "name": "global-launcher",
    "path": "/opt/kodachi/dashboard/hooks/global-launcher",
    "timestamp": "2026-07-21T01:54:34Z",
    "file_info": {
      "size": 2056992,
      "sha256": "eb9bea3916defb0252124193b6a86f1284a61167d04bfc5662f9d15f50c9aa6f"
    },
    "flag_n": {
      "command": "info",
      "data": {
        "author": "Warith Al Maawali",
        "copyright": "© 2026 Kodachi OS",
        "description": "Global launcher for Kodachi dashboard binaries with execution folder containment",
        "features": [
          "Dynamic binary discovery and deployment",
          "Execution folder containment for security",
          "Symlink-based global access",
          "Comprehensive error handling and logging",
          "Support for both Rust and Gambas binaries",
          "Deployment verification and rollback",
          "JSON and text output formats",
          "Zero hardcoded paths - fully dynamic"
        ],
        "license": "Proprietary",
        "name": "global-launcher",
        "securityFeatures": {
          "authentication": "Uses OS filesystem permissions; symlink ownership verified by comparing symlink target to current executable path",
          "encryption": "No encryption; configuration is statically embedded in the binary to prevent tampering via external config files",
          "inputValidation": "All binary names and paths are validated against security rules",
          "rateLimiting": "Configurable timeouts prevent resource exhaustion"
        },
        "systemRequirements": {
          "dependencies": [
            "cli-core library",
            "logs-hook service",
            "symlink support in filesystem"
          ],
          "os": "Linux (Debian-based, specifically Kodachi OS)",
          "privileges": "root/sudo for global deployment"
        },
        "version": "9.8.4 (build 320)",
        "website": "https://digi77.com"
      },
      "errors": [],
      "metadata": {
        "executionTime": 1,
        "hostname": "REDACTED-BUILD-HOST",
        "user": "REDACTED-BUILD-USER"
      },
      "status": "success",
      "timestamp": "2026-07-21T01:54:34.294728403Z",
      "version": "9.8.4 (build 320)",
      "warnings": []
    },
    "flag_v": {
      "command": "version",
      "data": {
        "buildDate": "REDACTED-BUILD-TIME",
        "gitCommit": "926929be",
        "name": "global-launcher",
        "rustVersion": "rustc 1.97.0 (2d8144b78 2026-07-07)",
        "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:34.414597207Z",
      "version": "9.8.4 (build 320)",
      "warnings": []
    },
    "flag_h": {
      "command": "help",
      "data": {
        "commandCategories": [
          {
            "category": "Management Commands",
            "commands": [
              {
                "description": "Deploy global symlinks for all dashboard binaries",
                "examples": [
                  "sudo ./global-launcher deploy",
                  "sudo ./global-launcher deploy --force",
                  "sudo ./global-launcher deploy --no-verify",
                  "sudo ./global-launcher deploy --save-hashes --json"
                ],
                "name": "deploy",
                "options": [
                  {
                    "default": "false",
                    "description": "Force deployment even if binaries exist",
                    "flag": "--force"
                  },
                  {
                    "default": "false",
                    "description": "Skip the post-deployment check that every new symlink resolves and is executable. Faster, but a broken symlink will not be reported until you run 'verify' yourself",
                    "flag": "--no-verify"
                  },
                  {
                    "default": "false",
                    "description": "Write results/deployment-hashes.json (SHA256 of each source binary plus the launcher)",
                    "flag": "--save-hashes"
                  }
                ],
                "requires_sudo": true,
                "usage": "global-launcher deploy [OPTIONS]"
              },
              {
                "description": "Verify deployed symlinks are working",
                "examples": [
                  "./global-launcher verify",
                  "./global-launcher verify --detailed",
                  "./global-launcher verify --save-hashes --json"
                ],
                "name": "verify",
                "options": [
                  {
                    "default": "false",
                    "description": "Show detailed verification info",
                    "flag": "--detailed"
                  },
                  {
                    "default": "false",
                    "description": "Write results/verification-hashes.json (SHA256 of each source binary plus the launcher)",
                    "flag": "--save-hashes"
                  }
                ],
                "requires_sudo": false,
                "usage": "global-launcher verify [OPTIONS]"
              },
              {
                "description": "Remove all deployed symlinks",
                "examples": [
                  "sudo ./global-launcher cleanup",
                  "sudo ./global-launcher cleanup --json"
                ],
                "name": "cleanup",
                "options": [
                  {
                    "default": "false",
                    "description": "No effect. Cleanup is always non-interactive and never prompts, so this flag is accepted only so existing scripts keep working. It is not a safety gate",
                    "flag": "--yes"
                  }
                ],
                "requires_sudo": true,
                "usage": "global-launcher cleanup [OPTIONS]"
              }
            ]
          }
        ],
        "description": "Global launcher for Kodachi dashboard binaries",
        "environmentVariables": [
          {
            "default": "900",
            "description": "Execution-mode timeout in seconds: how long the launcher waits for a target binary invoked through its symlink before giving up. This is the only way to change that timeout (--timeout does not do it)",
            "name": "GLOBAL_LAUNCHER_TIMEOUT",
            "values": "positive integer (seconds)"
          },
          {
            "default": "/usr/local/bin",
            "description": "Directory the symlinks are created in and removed from. Overrides the built-in /usr/local/bin target for deploy, verify and cleanup",
            "name": "GLOBAL_BIN_DIR",
            "values": "absolute path to a directory on PATH"
          },
          {
            "default": "auto-detected from the launcher's own location",
            "description": "Override the hooks directory. Decides where results/deployment-hashes.json and results/verification-hashes.json are written, and is propagated to every binary the launcher runs",
            "name": "KODACHI_BASE_DIR",
            "values": "absolute path to the hooks directory"
          },
          {
            "default": "unset",
            "description": "Disable colored output when set to any value",
            "name": "NO_COLOR",
            "values": "any value disables color"
          }
        ],
        "exitCodes": {
          "0": "Success",
          "1": "General error",
          "10": "Security violation",
          "2": "Invalid arguments",
          "3": "Permission denied",
          "4": "Binary not found",
          "5": "Directory not found",
          "6": "Timeout",
          "7": "Deployment or verification failure (deploy could not create every symlink, or verify found broken symlinks). Recovery: sudo ./global-launcher cleanup && sudo ./global-launcher deploy",
          "8": "Execution 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": "Pretty-print JSON output with indentation",
            "flag": "--json-pretty"
          },
          {
            "description": "Enhanced JSON output with improved human-readable formatting (like jq)",
            "flag": "--json-human"
          },
          {
            "description": "Enable verbose output",
            "flag": "--verbose"
          },
          {
            "description": "Suppress non-essential output",
            "flag": "--quiet"
          },
          {
            "description": "Disable colored output",
            "flag": "--no-color"
          },
          {
            "description": "No effect on the launcher itself. Management mode (deploy/verify/cleanup) ignores it, and in symlink execution mode every argument is forwarded verbatim to the target binary, so --timeout is consumed by that binary. To bound the launcher's own execution timeout use the GLOBAL_LAUNCHER_TIMEOUT environment variable (default: 900 seconds)",
            "flag": "--timeout <SECONDS>"
          },
          {
            "description": "No effect today. The value is parsed and then discarded; it does not change path or user resolution, including under sudo. Do not rely on it",
            "flag": "--user-override <USERNAME>"
          },
          {
            "description": "Force output format: text (default) or json. '-o json' is equivalent to --json",
            "flag": "-o, --output-format <FORMAT>"
          }
        ],
        "name": "global-launcher",
        "usage": "global-launcher [OPTIONS] [COMMAND]"
      },
      "errors": [],
      "metadata": {
        "executionTime": 1,
        "hostname": "REDACTED-BUILD-HOST",
        "user": "REDACTED-BUILD-USER"
      },
      "status": "success",
      "timestamp": "2026-07-21T01:54:34.523832383Z",
      "version": "9.8.4 (build 320)",
      "warnings": []
    },
    "flag_e": {
      "command": "examples",
      "data": {
        "categories": [
          {
            "description": "Create the /usr/local/bin symlinks so every hook binary is callable from anywhere. Run these from the hooks directory.",
            "examples": [
              {
                "command": "sudo ./global-launcher deploy",
                "description": "Deploy global access for all discovered dashboard binaries",
                "expectedOutput": "✅ SUCCESS: Deployed <COUNT> binaries to /usr/local/bin",
                "notes": "Needs root: it writes symlinks into /usr/local/bin. Set GLOBAL_BIN_DIR to deploy somewhere else."
              },
              {
                "command": "sudo ./global-launcher deploy --force",
                "description": "Redeploy over names that already exist in the target directory",
                "expectedOutput": "✅ SUCCESS: Deployed <COUNT> binaries to /usr/local/bin",
                "notes": "Without --force, a name already taken by a real file (not a launcher symlink) is left alone and the deploy is reported as failed."
              },
              {
                "command": "sudo ./global-launcher deploy --no-verify",
                "description": "Deploy without the post-deployment symlink check",
                "expectedOutput": "✅ SUCCESS: Deployed <COUNT> binaries to /usr/local/bin",
                "notes": "Skips the check that each new symlink resolves and is executable. A broken link will then go unnoticed until you run './global-launcher verify' yourself."
              },
              {
                "command": "sudo ./global-launcher deploy --save-hashes --json",
                "description": "Deploy, write the hash report, and print the machine-readable result",
                "expectedOutput": "JSON envelope with total_symlinks_created and failed_deployments, plus results/deployment-hashes.json on disk",
                "notes": "The report lands in the hooks directory under results/, not in the current working directory."
              }
            ],
            "id": "1_deployment",
            "title": "Deployment Operations"
          },
          {
            "description": "Check that the deployed symlinks still resolve to the current binaries.",
            "examples": [
              {
                "command": "./global-launcher verify",
                "description": "Check every deployed symlink",
                "expectedOutput": "✅ SUCCESS: <COUNT> verified, 0 broken",
                "notes": "No root needed: this only reads. Exits 7 if any symlink is broken."
              },
              {
                "command": "./global-launcher verify --detailed",
                "description": "List each symlink with its target path and source hash",
                "expectedOutput": "One '+ name -> /path/to/hooks/name (hash: ...)' line per verified symlink"
              },
              {
                "command": "./global-launcher verify --save-hashes --json",
                "description": "Verify, write results/verification-hashes.json, and print the JSON result",
                "expectedOutput": "JSON envelope with verified_symlinks[] (each carrying source_binary_hash and launcher_hash) and broken_symlinks[]"
              }
            ],
            "id": "2_verification",
            "title": "Verification Operations"
          },
          {
            "description": "The --save-hashes reports are written for transparency and audit. They are never read back to make a trust decision: all hash checking happens in memory. Compare two reports over time to spot a binary that changed underneath you.",
            "examples": [
              {
                "command": "cat results/verification-hashes.json",
                "description": "Read the report left by the last 'verify --save-hashes'",
                "expectedOutput": "JSON with a SHA256 for every source binary plus the launcher hash",
                "notes": "Path is relative to the hooks directory (or to KODACHI_BASE_DIR when set), which is where the launcher writes it."
              },
              {
                "command": "cat results/deployment-hashes.json",
                "description": "Read the report left by the last 'deploy --save-hashes'",
                "expectedOutput": "Same shape as the verification report, captured at deploy time",
                "notes": "Each report overwrites the previous one; keep a copy yourself if you want history."
              },
              {
                "command": "./global-launcher verify --save-hashes --json | jq '.data.verified_symlinks[0] | {name, source_binary_hash, launcher_hash}'",
                "description": "Pull one binary's hashes straight out of the verification run",
                "expectedOutput": "{\"name\": \"ip-fetch\", \"source_binary_hash\": \"...\", \"launcher_hash\": \"...\"}"
              }
            ],
            "id": "3_hash_integrity",
            "title": "Hash Reports and Integrity"
          },
          {
            "description": "After deploy, calling a binary by name from any directory goes through the launcher, which runs the real binary inside the hooks directory and forwards your arguments untouched. You do not type 'global-launcher' for this.",
            "examples": [
              {
                "command": "health-control internet-status",
                "description": "Run a hook binary from any working directory",
                "expectedOutput": "health-control's internet status output, exactly as if you had run it from the hooks directory",
                "notes": "Every argument is passed through as-is, so the target binary's own flags keep working."
              },
              {
                "command": "ip-fetch --json",
                "description": "Run ip-fetch globally with JSON output",
                "expectedOutput": "ip-fetch's JSON envelope with the current IP information"
              },
              {
                "command": "dns-switch list",
                "description": "List DNS servers from anywhere",
                "expectedOutput": "dns-switch's server list with the current configuration"
              },
              {
                "command": "GLOBAL_LAUNCHER_TIMEOUT=60 health-control security-score",
                "description": "Bound how long the launcher will wait for a slow binary",
                "expectedOutput": "The target binary's normal output, or a timeout error after 60 seconds",
                "notes": "GLOBAL_LAUNCHER_TIMEOUT (default 900 seconds) is the only way to change this. --timeout is forwarded to the target binary instead, deliberately, so it does not collide with the target's own --timeout."
              }
            ],
            "id": "4_usage",
            "title": "Execution Mode: Using the Global Binaries"
          },
          {
            "description": "Remove the global symlinks. Only symlinks the launcher owns are touched; unrelated files in the target directory are left alone.",
            "examples": [
              {
                "command": "sudo ./global-launcher cleanup",
                "description": "Remove every deployed symlink",
                "expectedOutput": "✅ SUCCESS: Removed <COUNT> symlinks",
                "notes": "Needs root, and runs immediately without asking. After this the binaries are only callable from the hooks directory again; the binaries themselves are not deleted."
              },
              {
                "command": "sudo ./global-launcher cleanup --json",
                "description": "Remove the symlinks and print a machine-readable result",
                "expectedOutput": "JSON envelope with removed_count and a timestamp",
                "notes": "--yes is accepted but does nothing: cleanup never prompts, with or without it."
              }
            ],
            "id": "5_cleanup",
            "title": "Cleanup Operations"
          },
          {
            "description": "Flags accepted by every management command.",
            "examples": [
              {
                "command": "./global-launcher -h",
                "description": "Show the full help: commands, flags, environment variables and exit codes",
                "expectedOutput": "The help screen. Add --json for the same content as structured data"
              },
              {
                "command": "./global-launcher -v",
                "description": "Print the version",
                "expectedOutput": "global-launcher version <VERSION>"
              },
              {
                "command": "./global-launcher -n --json",
                "description": "Print the program information block as JSON (features, security model, requirements)",
                "expectedOutput": "JSON envelope with the ProgramInfo fields"
              },
              {
                "command": "./global-launcher verify -o json --json-pretty",
                "description": "Force JSON output and indent it for reading",
                "expectedOutput": "Indented JSON verification result",
                "notes": "'-o json' is the same as --json. --json-human formats it further, jq-style."
              },
              {
                "command": "./global-launcher verify --quiet --no-color",
                "description": "Suppress non-essential output and strip ANSI color, for logs and pipes",
                "expectedOutput": "Plain, uncolored output. NO_COLOR=1 in the environment does the same"
              }
            ],
            "id": "6_core_flags",
            "title": "Core Flags and Output Formats"
          },
          {
            "description": "Both deploy and verify exit with code 7 when they fail, so a script can tell a real deployment from a silently degraded one. The standard recovery is to remove the launcher's symlinks and lay them down again.",
            "examples": [
              {
                "command": "./global-launcher verify || (sudo ./global-launcher cleanup && sudo ./global-launcher deploy)",
                "description": "Repair the deployment whenever verification reports a broken symlink",
                "expectedOutput": "Either '✅ SUCCESS: <COUNT> verified, 0 broken', or a cleanup followed by a fresh deploy",
                "notes": "verify exits 7 on broken symlinks and deploy exits 7 on a failed deploy, which is what makes this loop work in a script."
              },
              {
                "command": "GLOBAL_BIN_DIR=\"$HOME/.local/bin\" ./global-launcher deploy",
                "description": "Deploy into a user-writable directory instead of /usr/local/bin",
                "expectedOutput": "✅ SUCCESS: Deployed <COUNT> binaries to /home/<user>/.local/bin",
                "notes": "No root needed for a directory you own. GLOBAL_BIN_DIR must also be set for the later verify and cleanup, otherwise they look in /usr/local/bin."
              }
            ],
            "id": "7_troubleshooting",
            "title": "Troubleshooting a Broken Deployment"
          }
        ],
        "description": "global-launcher has two modes. Run directly (./global-launcher deploy|verify|cleanup) it MANAGES the symlinks in /usr/local/bin that make every Kodachi hook binary callable from any directory. Invoked THROUGH one of those symlinks (for example 'ip-fetch --json') it becomes that binary's launcher: it re-enters the hooks directory, forwards your arguments unchanged and runs the real binary there. Management examples below are written to be run from the hooks directory.",
        "name": "global-launcher",
        "quickReference": [
          "./global-launcher -h",
          "./global-launcher -e",
          "./global-launcher -n --json",
          "sudo ./global-launcher deploy",
          "./global-launcher verify --detailed",
          "sudo ./global-launcher cleanup",
          "ip-fetch --json"
        ]
      },
      "errors": [],
      "metadata": {
        "executionTime": 1,
        "hostname": "REDACTED-BUILD-HOST",
        "user": "REDACTED-BUILD-USER"
      },
      "status": "success",
      "timestamp": "2026-07-21T01:54:34.800968473Z",
      "version": "9.8.4 (build 320)",
      "warnings": []
    }
  }
}
