{
  "report_info": {
    "version": "9.0.1",
    "generated_at": "2026-07-21T01:54:30Z",
    "binary_name": "ai-scheduler"
  },
  "binary": {
    "name": "ai-scheduler",
    "path": "/opt/kodachi/dashboard/hooks/ai-scheduler",
    "timestamp": "2026-07-21T01:54:30Z",
    "file_info": {
      "size": 5784784,
      "sha256": "000394a8c271863dd308c1d70dc25e1aa45602b6e08a23c31edd61aae5e7bc0d"
    },
    "flag_n": {
      "status": "success",
      "timestamp": "2026-07-21T01:54:30.419300409Z",
      "command": "info",
      "version": "9.8.4",
      "data": {
        "name": "ai-scheduler",
        "version": "9.8.4",
        "author": "Warith Al Maawali",
        "description": "Kodachi Scheduler Daemon - Cron-based command scheduling with security whitelist",
        "copyright": "© 2026 Kodachi OS",
        "website": "https://www.digi77.com",
        "license": "Proprietary",
        "features": [
          "Cron expression parsing, 6 fields: second minute hour day month weekday (\"0 0 * * * *\" = hourly)",
          "Event-driven triggers",
          "Command whitelist validation",
          "Execution history tracking"
        ],
        "securityFeatures": {
          "inputValidation": "Argument parsing via clap; per-command validation is the consumer's responsibility",
          "rateLimiting": "Not provided by cli-core",
          "authentication": "Not provided by cli-core (see online-auth)",
          "encryption": "Not provided by cli-core"
        },
        "systemRequirements": {
          "os": "Linux (Debian-based)",
          "privileges": "root/sudo for system operations",
          "dependencies": [
            "OpenSSL",
            "libcurl"
          ]
        }
      },
      "errors": [],
      "warnings": [],
      "metadata": {
        "executionTime": 0,
        "hostname": "REDACTED-BUILD-HOST",
        "user": "REDACTED-BUILD-USER"
      }
    },
    "flag_v": {
      "status": "success",
      "timestamp": "2026-07-21T01:54:30.609774958Z",
      "command": "version",
      "version": "9.8.4",
      "data": {
        "name": "ai-scheduler",
        "version": "9.8.4",
        "buildDate": "REDACTED-BUILD-TIME",
        "gitCommit": "unknown",
        "rustVersion": "1.82.0"
      },
      "errors": [],
      "warnings": [],
      "metadata": {
        "executionTime": 0,
        "hostname": "REDACTED-BUILD-HOST",
        "user": "REDACTED-BUILD-USER"
      }
    },
    "flag_h": {
      "status": "success",
      "timestamp": "2026-07-21T01:54:30.784231581Z",
      "command": "help",
      "version": "9.8.4",
      "data": {
        "name": "ai-scheduler",
        "description": "Kodachi Scheduler Daemon - Cron-based command scheduling with security whitelist",
        "usage": "ai-scheduler [OPTIONS] [COMMAND] [ARGS]",
        "commandCategories": [
          {
            "category": "Daemon Control",
            "commands": [
              {
                "name": "start",
                "description": "Start the scheduler daemon",
                "usage": "ai-scheduler start [OPTIONS]",
                "options": [
                  {
                    "flag": "-f, --foreground",
                    "description": "Run the scheduler loop in this terminal instead of detaching (blocks until Ctrl+C)",
                    "default": "false (daemonize)"
                  },
                  {
                    "flag": "--json",
                    "description": "Emit status, mode, schedules_loaded, executions, pid and already_running as a JSON envelope"
                  }
                ],
                "requires_sudo": true,
                "examples": [
                  "sudo ai-scheduler start",
                  "sudo ai-scheduler start --foreground",
                  "sudo ai-scheduler start --json"
                ]
              }
            ]
          },
          {
            "category": "Schedule Management",
            "commands": [
              {
                "name": "add",
                "description": "Add a new scheduled task",
                "usage": "ai-scheduler add [OPTIONS]",
                "options": [
                  {
                    "flag": "--name <NAME>",
                    "description": "Unique name for the schedule",
                    "required": true
                  },
                  {
                    "flag": "--command <COMMAND>",
                    "description": "Command to execute. The binary must be whitelisted, a subcommand is required, and the subcommand plus arguments must pass the shared gateway policy validator",
                    "required": true
                  },
                  {
                    "flag": "--cron <EXPRESSION>",
                    "description": "Six mandatory fields: second minute hour day-of-month month day-of-week (optional 7th field is the year). Weekday ordinals are 1=Sunday through 7=Saturday. A five-field crontab string does not parse",
                    "required": true
                  },
                  {
                    "flag": "--json",
                    "description": "Emit schedule_id, name, command, cron_expression and schedule_description as a JSON envelope"
                  }
                ],
                "requires_sudo": false,
                "examples": [
                  "ai-scheduler add --name \"hourly-tor\" --command \"tor-switch tor-status\" --cron \"0 0 * * * *\"",
                  "ai-scheduler add --name \"dns-check\" --command \"dns-leak test\" --cron \"0 */30 * * * *\"",
                  "ai-scheduler add --name \"daily-check\" --command \"health-control net-check\" --cron \"0 0 8 * * *\" --json",
                  "ai-scheduler add --name \"weekly-memory-clean\" --command \"health-control memory-clean\" --cron \"0 0 2 * * 1\""
                ]
              },
              {
                "name": "list",
                "description": "List all scheduled tasks",
                "usage": "ai-scheduler list [OPTIONS]",
                "options": [
                  {
                    "flag": "--json",
                    "description": "Emit count and the schedules array as a JSON envelope"
                  }
                ],
                "requires_sudo": false,
                "examples": [
                  "ai-scheduler list",
                  "ai-scheduler list --json"
                ]
              },
              {
                "name": "remove",
                "description": "Remove a scheduled task",
                "usage": "ai-scheduler remove [OPTIONS]",
                "options": [
                  {
                    "flag": "<ID>",
                    "description": "Numeric schedule ID to delete, as shown by `ai-scheduler list`. Irreversible",
                    "required": true
                  },
                  {
                    "flag": "--json",
                    "description": "Emit status, schedule_id and deleted as a JSON envelope"
                  }
                ],
                "requires_sudo": false,
                "examples": [
                  "ai-scheduler remove 1",
                  "ai-scheduler remove 2 --json"
                ]
              }
            ]
          }
        ],
        "globalOptions": [
          {
            "flag": "-h, --help",
            "description": "Print help information"
          },
          {
            "flag": "-v, --version",
            "description": "Print version information"
          },
          {
            "flag": "-n, --info",
            "description": "Display detailed information"
          },
          {
            "flag": "-e, --examples",
            "description": "Show usage examples"
          },
          {
            "flag": "--json",
            "description": "Output in JSON format"
          },
          {
            "flag": "-o, --output-format <FORMAT>",
            "description": "Force output format (text|json)"
          },
          {
            "flag": "--json-pretty",
            "description": "Pretty-print JSON output with indentation"
          },
          {
            "flag": "--json-human",
            "description": "Enhanced JSON output with improved formatting (like jq)"
          },
          {
            "flag": "--json-filter <FIELD1,FIELD2>",
            "description": "Return only specified JSON fields (comma-separated)"
          },
          {
            "flag": "--fields <FIELD_LIST>",
            "description": "Select specific fields to include in output (comma-separated)"
          },
          {
            "flag": "--limit <NUMBER>",
            "description": "Limit number of results returned"
          },
          {
            "flag": "--offset <NUMBER>",
            "description": "Skip first N results (for pagination)"
          },
          {
            "flag": "-d, --work-dir <PATH>",
            "description": "Working directory (defaults to auto-detected base directory)"
          },
          {
            "flag": "--port <PORT>",
            "description": "Set custom port number (1024-65535)"
          },
          {
            "flag": "--log-level <LEVEL>",
            "description": "Set log level (error|warn|info|debug)"
          },
          {
            "flag": "--verbose",
            "description": "Enable verbose output"
          },
          {
            "flag": "--quiet",
            "description": "Suppress non-essential output"
          },
          {
            "flag": "--no-color",
            "description": "Disable colored output"
          },
          {
            "flag": "--config <FILE>",
            "description": "Use custom configuration file"
          },
          {
            "flag": "--timeout <SECS>",
            "description": "Set operation timeout in seconds (optional; no default applied)"
          }
        ],
        "environmentVariables": [
          {
            "name": "NO_COLOR",
            "description": "Disable all colored output when set",
            "default": "unset",
            "values": "1|true|yes (any value disables color)"
          }
        ],
        "exitCodes": {
          "3": "Permission denied",
          "2": "Invalid arguments",
          "1": "General error",
          "4": "Network error",
          "5": "File not found",
          "0": "Success"
        }
      },
      "errors": [],
      "warnings": [],
      "metadata": {
        "executionTime": 0,
        "hostname": "REDACTED-BUILD-HOST",
        "user": "REDACTED-BUILD-USER"
      }
    },
    "flag_e": {
      "status": "success",
      "timestamp": "2026-07-21T01:54:31.100099553Z",
      "command": "examples",
      "version": "9.8.4",
      "data": {
        "name": "ai-scheduler",
        "description": "Usage examples for ai-scheduler",
        "categories": [
          {
            "id": "0_cron_syntax",
            "title": "Cron Syntax (read this first)",
            "description": "Every --cron expression takes SIX mandatory fields: second minute hour day-of-month month day-of-week (an optional seventh field is the year). A five-field crontab-style string does not parse. Weekday ordinals run 1 to 7 where 1 is Sunday and 7 is Saturday, and the names Sun through Sat are also accepted. `add` validates the expression before it writes anything, so a bad expression is rejected up front.",
            "examples": [
              {
                "command": "ai-scheduler add --name \"hourly-tor\" --command \"tor-switch tor-status\" --cron \"0 0 * * * *\"",
                "description": "Every hour, on the hour",
                "expectedOutput": "Schedule added successfully, with its ID, name, command, cron string and the next run times",
                "notes": "Requires a prior `online-auth` login. \"0 0 * * * *\" is second 0, minute 0, every hour."
              },
              {
                "command": "ai-scheduler add --name \"dns-check\" --command \"dns-leak test\" --cron \"0 */30 * * * *\"",
                "description": "Every 30 minutes",
                "expectedOutput": "Schedule added successfully with the next run time roughly 30 minutes out",
                "notes": "Requires a prior `online-auth` login."
              },
              {
                "command": "ai-scheduler add --name \"daily-check\" --command \"health-control net-check\" --cron \"0 0 8 * * *\"",
                "description": "Once a day at 08:00",
                "expectedOutput": "Schedule added successfully with tomorrow 08:00 as the next run",
                "notes": "Requires a prior `online-auth` login. Times are evaluated in UTC."
              },
              {
                "command": "ai-scheduler add --name \"weekly-memory-clean\" --command \"health-control memory-clean\" --cron \"0 0 2 * * 1\"",
                "description": "Once a week, Sunday at 02:00",
                "expectedOutput": "Schedule added successfully with the coming Sunday 02:00 as the next run",
                "notes": "Requires a prior `online-auth` login. Weekday 1 IS Sunday in this cron dialect (1 to 7, Sunday through Saturday). Ordinal 0 is out of range and is rejected."
              }
            ]
          },
          {
            "id": "1_daemon_control",
            "title": "Daemon Control",
            "description": "Run the scheduler loop that actually fires the tasks. Nothing you add with `add` runs until the daemon is running.",
            "examples": [
              {
                "command": "sudo ai-scheduler start",
                "description": "Start the scheduler in the background",
                "expectedOutput": "Scheduler daemon started successfully, with mode Background, schedules loaded, executions and the PID",
                "notes": "Requires a prior `online-auth` login (start is not on the read-only exempt list). Needs root: the PID file is written under the install directory."
              },
              {
                "command": "sudo ai-scheduler start --foreground",
                "description": "Run the scheduler loop in this terminal so you can watch tasks fire",
                "expectedOutput": "The scheduler stays attached and prints each execution as it happens",
                "notes": "Requires a prior `online-auth` login. Blocks until Ctrl+C. -f is the short form."
              },
              {
                "command": "sudo ai-scheduler start --json",
                "description": "Start in the background and capture the result as JSON",
                "expectedOutput": "Envelope with status, mode, schedules_loaded, executions, pid and already_running",
                "notes": "Requires a prior `online-auth` login."
              }
            ]
          },
          {
            "id": "2_schedule_management",
            "title": "Schedule Management",
            "description": "Add, list and remove scheduled tasks. --name, --command and --cron are all required on `add`.",
            "examples": [
              {
                "command": "ai-scheduler add --name \"dns-check\" --command \"dns-leak test\" --cron \"0 */30 * * * *\" --json",
                "description": "Schedule a DNS leak test every 30 minutes and get the task ID back as JSON",
                "expectedOutput": "Envelope with schedule_id, name, command, cron_expression and schedule_description",
                "notes": "Requires a prior `online-auth` login."
              },
              {
                "command": "ai-scheduler list",
                "description": "See every scheduled task and when it next runs",
                "expectedOutput": "One block per task: [ID] name, command, cron, next run, last run and execution count. 'No scheduled tasks found.' when the table is empty"
              },
              {
                "command": "ai-scheduler list --json",
                "description": "Machine-readable task list for the dashboard",
                "expectedOutput": "Envelope with count and the schedules array"
              },
              {
                "command": "ai-scheduler remove 1",
                "description": "Delete the task with ID 1",
                "expectedOutput": "'Schedule 1 removed successfully', or 'Schedule 1 not found' if the ID does not exist",
                "notes": "Requires a prior `online-auth` login. Irreversible: the schedule row is deleted. Get the ID from `ai-scheduler list`."
              },
              {
                "command": "ai-scheduler remove 2 --json",
                "description": "Delete a task and confirm the result in JSON",
                "expectedOutput": "Envelope with status, schedule_id and deleted (true or false)",
                "notes": "Requires a prior `online-auth` login. Irreversible."
              }
            ]
          },
          {
            "id": "3_command_whitelist",
            "title": "Command Whitelist",
            "description": "A scheduled command must name an allowlisted Kodachi service, include a subcommand, pass argument sanitization, and be allowed by the shared ai-gateway policy before the schedule is written.",
            "examples": [
              {
                "command": "ai-scheduler add --name \"tor-health\" --command \"tor-switch tor-status\" --cron \"0 */15 * * * *\" --json",
                "description": "An allowlisted service and policy-approved subcommand are accepted",
                "expectedOutput": "Envelope with the new schedule_id",
                "notes": "Requires a prior `online-auth` login. Unknown or policy-blocked subcommands are rejected before the schedule is saved."
              },
              {
                "command": "ai-scheduler add --name \"blocked-test\" --command \"malicious-binary run\" --cron \"0 0 * * * *\" --json",
                "description": "A binary that is not on the whitelist is refused before anything is written",
                "expectedOutput": "An error envelope saying the command is not whitelisted, and no schedule is created",
                "notes": "Requires a prior `online-auth` login."
              }
            ]
          }
        ],
        "quickReference": [
          "ai-scheduler --help",
          "ai-scheduler --version",
          "ai-scheduler --info --json",
          "ai-scheduler --examples",
          "ai-scheduler list",
          "ai-scheduler add --name <NAME> --command <COMMAND> --cron <EXPRESSION>",
          "ai-scheduler remove <ID>",
          "sudo ai-scheduler start"
        ]
      },
      "errors": [],
      "warnings": [],
      "metadata": {
        "executionTime": 0,
        "hostname": "REDACTED-BUILD-HOST",
        "user": "REDACTED-BUILD-USER"
      }
    }
  }
}
