apexe 0.6.1

Outside-In CLI-to-Agent Bridge
{
  "schema_version": "1.0",
  "command": "sort",
  "variant": "apple",
  "match": {
    "platform": ["macos"],
    "probe": {
      "args": ["--version"],
      "expect": "success",
      "output_contains": "Apple"
    },
    "binary_globs": ["/usr/bin/sort", "/bin/sort"]
  },
  "mode": "authoritative",
  "confidence": "verified",
  "provenance": {
    "platform": "macos",
    "tool_version": "macOS 26.3",
    "source": "man-page",
    "checked_on": "2026-07-27",
    "command": "man -P cat sort | col -b",
    "environment": "macOS 26.3 (Darwin arm64), system /usr/bin/sort, banner '2.3-Apple (197)'",
    "notes": "Flags transcribed from the four option blocks that follow 'The command line options are as follows:' -- the general block, 'The following options override the default ordering rules.', 'The treatment of field separators can be altered using these options:' and 'Other options:'. This page has no COMPATIBILITY or LEGACY DESCRIPTION section; STANDARDS was read for flags documented outside those blocks and only records which flags are POSIX extensions and that the obsolete +pos1/-pos2 key notation is still supported. That notation is a family of numeric operands rather than a named option, so the overlay format cannot carry it. The option set is closed by the binary: the getopt(3) option string is 'bcCdfghik:Mmno:RrsS:t:T:uVz' and the long option table carries batch-size, buffer-size, check, compress-program, debug, dictionary-order, field-separator, files0-from, general-numeric-sort, help, human-numeric-sort, ignore-leading-blanks, ignore-case, ignore-nonprinting, key, merge, mmap, month-sort, numeric-sort, output, parallel, qsort, radixsort, mergesort, heapsort, random-sort, random-source, reverse, sort, stable, temporary-directory, unique, version, version-sort and zero-terminated. Every one of those long forms was run against the binary and accepted, and unknown ones are rejected with \"unrecognized option `--bogus'\", so mode is authoritative. Two long forms are accepted by the binary but shown by neither the man page's option blocks nor its SYNOPSIS: --stable (the man page documents -s with no long form) and --key (documented as --key= but absent from the long option strings until run). Both exit 0. --sort=WORD takes exactly five values here -- general-numeric, human-numeric, month, numeric and random. 'sort --sort=version' is REJECTED with 'Unknown feature: version' even though -V exists, which is a real difference from GNU sort, whose --sort does accept version; the enum below therefore has five members, not six. --check accepts diagnose-first, quiet and silent, may be given with no value, and rejects anything else ('Unknown feature: bogus'). conflicts_with was read off the running binary, which diagnoses each clash by name, and NOT from the SYNOPSIS: -g, -h, -M, -n, -R and -V are pairwise incompatible ('h:g: mutually exclusive flags'), all 15 pairs confirmed; -m is incompatible with -c, -C and --check ('m:c: mutually exclusive flags'); --radixsort is incompatible with the same six ordering options ('Radix sort cannot be used with these sort options'), retested under LC_ALL=C so the locale restriction in its description is not what produced the failure; --qsort and --heapsort are incompatible with -s and -u ('The chosen sort method cannot be used with stable and/or unique sort'), which the man page also states. Note how much narrower this is than GNU sort, where -d and -i also clash with the numeric ordering options: here 'sort -d -n' is accepted, so no such conflict is declared. -c with -C is accepted at exit 0, with -C winning silently in both orders -- an override group, now recorded as a conflict. Candidates tested and REJECTED: -c and -C with -o (accepted -- GNU sort diagnoses this pairing and this one does not); -d and -i with every ordering option (all accepted); --mergesort and --mmap with everything (no clash at all); --sort=WORD with the single-letter ordering options ('sort --sort=numeric -g' is accepted here, while GNU sort rejects it). Two more were rejected after a false positive of exactly the kind sort@gnu records: 'sort -c -r' and 'sort -c -R' exit 1 on ascending input because -c is reporting disorder, not because the options clash -- rerun on reverse-sorted input 'sort -c -r' exits 0. --files0-from=F replaces the FILE operands: 'sort --files0-from=f0 other.txt' silently ignores other.txt rather than failing, which is recorded on the operand because conflicts_with can only name flags. The probe deliberately keys on the Apple banner rather than on platform plus path: Homebrew coreutils installs a GNU sort that can sit at the same place, and the whole point of a probe is to catch that. This binary answers --version with '2.3-Apple (197)' at exit 0, which is also what makes the scanner classify it apple rather than bsd. annotations: readonly is false because -o FILE truncates and rewrites the named file, verified against a pre-existing file. conflicts_with was extended in a later pass, after the field's definition widened to cover override groups as well as diagnosed errors: apexe's input is a JSON object, which carries no ordering, so for a last-one-wins group which flag actually wins is decided by the order the caller happened to write the keys in. Every pair added then was run in BOTH orders against the reference build recorded above, and only pairs whose outcome depends on that order, or where one side is silently discarded, were added. value_optional was added on 2026-08-24 and established behaviourally on the build recorded above, since a BSD man page has no notation for an optional option argument: each candidate was run in BOTH spellings and marked only when the separated form demonstrably lost the value. `sort --check quiet s.txt` is \"sort: No such file or directory\" (exit 2) while `sort --check=quiet s.txt` succeeds. --sort was tested and deliberately NOT marked even though it is enum-valued and looks like the same shape: `sort --sort general-numeric s.txt` is accepted, so its value is required -- an enum is not evidence of optionality. --output, --buffer-size, --temporary-directory, --key, --field-separator, --batch-size, --compress-program, --random-source, --parallel and --files0-from were each run the same way and none is optional-valued."
  },
  "description": "The sort utility sorts text and binary files by lines. A line is a record separated from the subsequent record by a newline (default) or NUL '\\0' character (-z option). A record can contain any printable or unprintable characters. Comparisons are based on one or more sort keys extracted from each line of input, and are performed lexicographically, according to the current locale's collating rules and the specified command-line options that can tune the actual sorting behavior. By default, if keys are not given, sort uses entire lines for comparison. The arguments field1 and field2 of -k have the form m.n (m,n > 0) and can be followed by one or more of the modifiers b, d, f, i, n, g, M and r, which correspond to the ordering options. This is Apple's port; it exits 0 on --version and reports a version of the form 2.3-Apple (197).",
  "flags": [
    { "short": "-b", "long": "--ignore-leading-blanks", "type": "boolean", "description": "Ignore leading blank characters when comparing lines, and when determining the start and end of a restricted sort key (see -k). If -b is specified before the first -k option, it applies globally to all key specifications. Otherwise, -b can be attached independently to each field argument of the key specifications." },
    { "short": "-c", "type": "boolean", "conflicts_with": ["-m", "-C"], "description": "Check that the single input file is sorted. If the file is not sorted, sort produces the appropriate error messages and exits with code 1, otherwise returns 0. Equivalent to --check=diagnose-first." },
    { "short": "-C", "type": "boolean", "conflicts_with": ["-m", "-c"], "description": "Like -c, but produces no output. This is a \"silent\" version of -c. Equivalent to --check=silent or --check=quiet." },
    { "long": "--check", "type": "enum", "value_name": "WORD", "value_optional": true, "enum_values": ["diagnose-first", "quiet", "silent"], "conflicts_with": ["-m"], "description": "Check that the single input file is sorted; do not sort. The value may be omitted, which means diagnose-first (the same as -c); quiet and silent produce no output (the same as -C). Any other value is rejected with 'Unknown feature'." },
    { "short": "-m", "long": "--merge", "type": "boolean", "conflicts_with": ["-c", "-C", "--check"], "description": "Merge only. The input files are assumed to be pre-sorted. If they are not sorted the output order is undefined." },
    { "short": "-o", "long": "--output", "type": "path", "value_name": "output", "description": "Print the output to the output file instead of the standard output." },
    { "short": "-S", "long": "--buffer-size", "type": "string", "value_name": "size", "description": "Use size for the maximum size of the memory buffer. Size modifiers %,b,K,M,G,T,P,E,Z,Y can be used. If a memory limit is not explicitly specified, sort takes up to about 90% of available memory. If the file size is too big to fit into the memory buffer, the temporary disk files are used to perform the sorting." },
    { "short": "-T", "long": "--temporary-directory", "type": "path", "value_name": "dir", "description": "Store temporary files in the directory dir. The default path is the value of the environment variable TMPDIR or /var/tmp if TMPDIR is not defined." },
    { "short": "-u", "long": "--unique", "type": "boolean", "conflicts_with": ["--qsort", "--heapsort"], "description": "Unique keys. Suppress all lines that have a key that is equal to an already processed one. This option, similarly to -s, implies a stable sort. If used with -c or -C, sort also checks that there are no lines with duplicate keys." },
    { "short": "-s", "long": "--stable", "type": "boolean", "conflicts_with": ["--qsort", "--heapsort"], "description": "Stable sort. This option maintains the original record order of records that have an equal key. This is a non-standard feature, but it is widely accepted and used. The man page documents no long form for -s; --stable is accepted by the binary." },
    { "short": "-d", "long": "--dictionary-order", "type": "boolean", "description": "Consider only blank spaces and alphanumeric characters in comparisons." },
    { "short": "-f", "long": "--ignore-case", "type": "boolean", "description": "Convert all lowercase characters to their uppercase equivalent before comparison, that is, perform case-independent sorting." },
    { "short": "-g", "long": "--general-numeric-sort", "type": "boolean", "conflicts_with": ["-h", "-M", "-n", "-R", "-V", "--radixsort"], "description": "Sort by general numerical value. As opposed to -n, this option handles general floating points. It has a more permissive format than that allowed by -n but it has a significant performance drawback." },
    { "short": "-h", "long": "--human-numeric-sort", "type": "boolean", "conflicts_with": ["-g", "-M", "-n", "-R", "-V", "--radixsort"], "description": "Sort by numerical value, but take into account the SI suffix, if present. Sort first by numeric sign (negative, zero, or positive); then by SI suffix (either empty, or 'k' or 'K', or one of 'MGTPEZY', in that order); and finally by numeric value. The SI suffix must immediately follow the number." },
    { "short": "-i", "long": "--ignore-nonprinting", "type": "boolean", "description": "Ignore all non-printable characters." },
    { "short": "-M", "long": "--month-sort", "type": "boolean", "conflicts_with": ["-g", "-h", "-n", "-R", "-V", "--radixsort"], "description": "Sort by month abbreviations. Unknown strings are considered smaller than the month names." },
    { "short": "-n", "long": "--numeric-sort", "type": "boolean", "conflicts_with": ["-g", "-h", "-M", "-R", "-V", "--radixsort"], "description": "Sort fields numerically by arithmetic value. Fields are supposed to have optional blanks in the beginning, an optional minus sign, zero or more digits (including decimal point and possible thousand separators)." },
    { "short": "-R", "long": "--random-sort", "type": "boolean", "conflicts_with": ["-g", "-h", "-M", "-n", "-V", "--radixsort"], "description": "Sort by a random order. This is a random permutation of the inputs except that the equal keys sort together. It is implemented by hashing the input keys and sorting the hash values. The hash function is chosen randomly, randomized by /dev/random content or by the file named with --random-source. Even if multiple sort fields are specified, the same random hash function is used for all of them." },
    { "short": "-r", "long": "--reverse", "type": "boolean", "description": "Sort in reverse order." },
    { "short": "-V", "long": "--version-sort", "type": "boolean", "conflicts_with": ["-g", "-h", "-M", "-n", "-R", "--radixsort"], "description": "Sort version numbers. The input lines are treated as file names in form PREFIX VERSION SUFFIX, where SUFFIX matches the regular expression \"(.([A-Za-z~][A-Za-z0-9~]*)?)*\". The files are compared by their prefixes and versions (leading zeros are ignored in version numbers). If an input string does not match the pattern, then it is compared using the byte compare function. All string comparisons are performed in C locale, the locale environment setting is ignored." },
    { "long": "--sort", "type": "enum", "value_name": "WORD", "enum_values": ["general-numeric", "human-numeric", "month", "numeric", "random"], "description": "Sort according to WORD: general-numeric is -g, human-numeric is -h, month is -M, numeric is -n and random is -R. Unlike GNU sort there is no version value here; 'sort --sort=version' is rejected with 'Unknown feature: version'. Unlike GNU sort this form does not clash with the single-letter ordering options: 'sort --sort=numeric -g' is accepted." },
    { "short": "-k", "long": "--key", "type": "string", "value_name": "field1[,field2]", "repeatable": true, "description": "Define a restricted sort key that has the starting position field1, and optional ending position field2 of a key field. The -k option may be specified multiple times, in which case subsequent keys are compared when earlier keys compare equal. The -k option replaces the obsolete options +pos1 and -pos2, but the old notation is also supported." },
    { "short": "-t", "long": "--field-separator", "type": "string", "value_name": "char", "description": "Use char as a field separator character. The initial char is not considered to be part of a field when determining key offsets. Each occurrence of char is significant (for example, \"charchar\" delimits an empty field). If -t is not specified, the default field separator is a sequence of blank space characters. To use NUL as field separator, use -t '\\0'." },
    { "short": "-z", "long": "--zero-terminated", "type": "boolean", "description": "Use NUL as record separator. By default, records in the files are supposed to be separated by the newline characters." },
    { "long": "--batch-size", "type": "integer", "value_name": "num", "description": "Specify maximum number of files that can be opened by sort at once. This option affects behavior when having many input files or using temporary files. The default value is 16." },
    { "long": "--compress-program", "type": "string", "value_name": "PROGRAM", "description": "Use PROGRAM to compress temporary files. PROGRAM must compress standard input to standard output, when called without arguments. When called with argument -d it must decompress standard input to standard output. If PROGRAM fails, sort must exit with error. An example of PROGRAM that can be used here is bzip2." },
    { "long": "--random-source", "type": "path", "value_name": "filename", "description": "In random sort, the file content is used as the source of the 'seed' data for the hash function choice. Two invocations of random sort with the same seed data will use the same hash function and will produce the same result if the input is also identical. By default, file /dev/random is used." },
    { "long": "--debug", "type": "boolean", "description": "Print some extra information about the sorting process to the standard output." },
    { "long": "--parallel", "type": "integer", "value_name": "thread_no", "description": "Set the maximum number of execution threads. Default number equals to the number of CPUs." },
    { "long": "--files0-from", "type": "path", "value_name": "filename", "description": "Take the input file list from the file filename. The file names must be separated by NUL (like the output produced by the command \"find ... -print0\"). This replaces the FILE operands rather than adding to them; a FILE operand given as well is silently ignored." },
    { "long": "--radixsort", "type": "boolean", "conflicts_with": ["-g", "-h", "-M", "-n", "-R", "-V"], "description": "Try to use radix sort, if the sort specifications allow. The radix sort can only be used for trivial locales (C and POSIX), and it cannot be used for numeric or month sort. Radix sort is very fast and stable. The binary rejects it together with any of -g, -h, -M, -n, -R and -V, with 'Radix sort cannot be used with these sort options'." },
    { "long": "--mergesort", "type": "boolean", "description": "Use mergesort. This is a universal algorithm that can always be used, but it is not always the fastest." },
    { "long": "--qsort", "type": "boolean", "conflicts_with": ["-s", "-u"], "description": "Try to use quick sort, if the sort specifications allow. This sort algorithm cannot be used with -u and -s." },
    { "long": "--heapsort", "type": "boolean", "conflicts_with": ["-s", "-u"], "description": "Try to use heap sort, if the sort specifications allow. This sort algorithm cannot be used with -u and -s." },
    { "long": "--mmap", "type": "boolean", "description": "Try to use file memory mapping system call. It may increase speed in some cases." },
    { "long": "--help", "type": "boolean", "description": "Print the help text and silently exits. The text is a single usage line, not a per-option description." },
    { "long": "--version", "type": "boolean", "description": "Print the version and silently exits. This port answers with a banner of the form '2.3-Apple (197)'." }
  ],
  "positional_args": [
    { "name": "file", "type": "path", "variadic": true, "required": false, "description": "The pathname of a file to be sorted, merged, or checked. If no file operands are specified, or if a file operand is -, the standard input is used. Not given when --files0-from is used, which replaces the operands and silently ignores any that are supplied." }
  ],
  "annotations": {
    "readonly": false,
    "destructive": true,
    "idempotent": true,
    "requires_approval": true
  }
}