After Dark Systems / Service Automation HubCompletely Programmable Infrastructure

OpenSAH / Utility guides

Missing Utils.

A suite of small, single-purpose Go commands that collect evidence, emit versioned JSON, and say what they could not see.

Unreleased No tags MIT

What it is

Missing Utils is one Go module that builds 48 separate command-line tools. Each command makes one narrow promise: walk a tree, hash a file set, explain who owns a listening port, normalize a Terraform plan, read a TLS peer certificate. Commands meant for automation print versioned JSON or JSON Lines, where each record names its schema (for example missing-utils/jwalk/v1), so they compose in shell pipelines and CI jobs without parsing human text. The README describes the shared contract they work toward: data on stdout, diagnostics on stderr, stable exit codes and explicit true, false and unknown conclusions.

The project rests on two ideas from its README: make routine operational work fast, safe and JSON-native, and explain why a system behaves as it does, with evidence and explicit uncertainty. The diagnostic commands report partial visibility instead of guessing. A result can be partial, and a missing collector is named in the output.

Unreleased. The README states that the commands are implemented at bounded scopes and remain unreleased, and that building successfully does not establish production readiness. There are no tags and no GitHub releases. Command names are provisional and may change before a first release.

Requirements

  • Go 1.24 or later to build (from go.mod). The project pins Go 1.24.6 in .tool-versions for asdf users, and CI uses Go 1.24.x.
  • Linux is the primary runtime platform for the diagnostic collectors. Many of them read /proc, systemd, SELinux or Docker and return partial evidence elsewhere.
  • The macOS security suite and osx target macOS. osx reports a runtime error on other systems.
  • CI builds every command for Linux amd64, macOS arm64 and Windows amd64. A successful build on a platform does not mean every collector works there.
  • Python 3 only for the repository's helper scripts (the capability generator and the demonstrations). The commands themselves are Go binaries.

Build and install

Build every command from a clone. Both the Makefile and build.sh put one binary per cmd/ directory under dist/:

git clone https://github.com/afterdarksys/ads-missing-utils.git
cd ads-missing-utils
make build            # or: ./build.sh build
make test             # unit and integration tests
make check            # go vet plus the tests

Build a single command with its Make target, for example make dist/jsonprobe. ./build.sh list prints every command that build and install operate on, and ./build.sh check also verifies gofmt.

Install the binaries and man pages

build.sh installs every binary into prefix/bin. The default prefix is /usr/local; install under your home directory instead:

./build.sh install prefix="$HOME/.local"
./build.sh man-install prefix="$HOME/.local"

Every command has a roff man page in man/. make man-build or ./build.sh man-build writes gzip-compressed pages to dist/man, and man-install copies them to PREFIX/share/man/man1. The Makefile reads the prefix from PREFIX=; build.sh takes prefix=.

Install one command with go install

The module path is github.com/afterdarksys/ads-missing-utils, so a single command can be installed directly:

go install github.com/afterdarksys/ads-missing-utils/cmd/jwalk@latest

With no tags, @latest resolves to the newest commit on the default branch, and --version prints the development version 0.1.0-dev.

Companion tools

contrib/ links two separate security utilities as Git submodules: ads-codedetective and vibedetector. They keep their own releases and issue trackers. Fetch them with git clone --recurse-submodules or, in an existing checkout, make contrib.

Quick start

These examples are read-only. They come from the README and the commands' help text, and assume you built into dist/.

Walk a tree and emit one JSON record per file, then build and verify a manifest without parsing file names in the shell:

./dist/jwalk ./release --type file --format ndjson
./dist/jwalk ./release --type file \
  | ./dist/hashsum create --from-jwalk --root ./release --output release.hashes.json
./dist/hashsum verify --root ./release release.hashes.json

Inspect structure and evidence:

./dist/binparse ./dist/logic                 # ELF, Mach-O or PE structure; never executes the input
./dist/certwhy --address example.com:443     # live TLS peer certificate and validation result
./dist/netwhy --host example.com             # DNS, default route and proxy evidence
./dist/portwhy --port 22                     # Linux listener ownership, with partial visibility reported

Read a man page through the Logic Manual tools:

./dist/man2logic man/logic.1 --output logic.logic
./dist/logic logic.logic

Every command accepts --version, and commands print their flags with --help. The README also shows a gate for Terraform plans; validate the gate policy against your own requirements before you rely on it:

terraform show -json tfplan \
  | tfchanges --format ndjson \
  | jsongate --policy deployment-gate.yaml

The commands

The authoritative inventory is docs/commands.json, and CI checks that it covers every cmd/ directory. It lists 48 commands, all marked implemented-unreleased. The tables below reproduce its scope and boundary text, grouped by purpose. For 17 commands the inventory gives no specific boundary and points to the command's help; read that help before relying on one of them.

Diagnostics: the “why” commands (14)

CommandScopeBoundary
accesswhyReport path mode and local identity evidence, with explicit access-control gaps.Mode and local identity evidence; ACL and policy evaluation are incomplete.
authwhyReport local account and group evidence, with explicit authentication-policy gaps.Local account evidence; authentication policy is not evaluated.
binarywhyReport executable metadata and a SHA-256 integrity observation.Metadata and hash observation; no trust or malware verdict.
certwhyInspect a live TLS peer certificate, negotiated connection, and validation result.Live TLS connection; failed verification stays failed.
driftwhyCapture a current file-content fingerprint for later drift comparison.Current fingerprint only; needs prior evidence to establish drift.
eventwhyGroup bounded Docker event evidence by resource, action, and exit code.Historical evidence only; limited Docker retention is reported as incomplete. No root-cause inference.
netwhyCollect DNS, default-route, and redacted proxy evidence for a destination.DNS, route and proxy evidence; no reachability or firewall conclusion.
patchwhyCapture a current binary/library identity for restart analysis.Current fingerprint only; no process mapping or restart recommendation.
pcapwhyTurn offline PCAP/PCAPNG captures into bounded flow, VLAN, ICMP, and reset evidence.Offline, bounded capture analysis; no live capture.
portwhyExplain visible Linux listener ownership and report partial visibility.Linux; reports partial process visibility.
restartwhyFind visible processes still mapping deleted files after updates.Linux visible deleted mappings only; no automatic restart.
selinuxwhySummarize SELinux enforcement state and bounded AVC denial evidence.Linux enforcement and AVC evidence; no policy changes.
servicewhyCollect passive process-health evidence for a service PID.Linux process evidence; no service dependency or restart analysis.
unitwhyExplain systemd unit state, selected hardening controls, and bounded journal evidence.Linux systemd and bounded journal evidence; no mutation.

Linux runtime and host evidence (4)

CommandScopeBoundary
exposeReport local listener exposure, with explicit firewall/reachability gaps.Linux listeners; firewall and remote reachability are not evaluated.
incidentsnapCapture a bounded read-only host and boot-context snapshot.Host and boot context only; not a forensic acquisition.
portsProduce a Linux TCP/UDP listener map with best-effort process ownership.Linux listener inventory; process ownership is best effort.
pwatchPassively sample Linux process state, RSS, and thread count.Linux process sampling only.

macOS security research suite (11)

CommandScopeBoundary
aaasAudit and explicitly revoke macOS Accessibility TCC grants.macOS TCC audit; revocation requires explicit apply.
amtmMap AppleScript automation text into a static permission graph without execution.Static AppleScript text analysis; no script execution.
bundleinfoInventory .app and .pkg structure and metadata without executing bundle contents.See command help for supported inputs and platform constraints.
cdedDetect sensitive clipboard patterns and explicitly drain unauthorized content.macOS clipboard inspection; draining requires explicit apply.
cltCorrelate hidden executables with identical content and optionally quarantine them.See command help for supported inputs and platform constraints.
dtpCompare daemon executable trees with an HMAC-authenticated baseline.See command help for supported inputs and platform constraints.
homestateIndex a home or mapped directory, report changes and moves, and safely repair or restore problematic names.See command help for supported inputs and platform constraints.
metascoreScore file metadata and extended-attribute-name changes against a saved baseline.See command help for supported inputs and platform constraints.
pllLint XML property lists and flag malformed or risky launchd logic.XML property lists only; not a launchd runtime validator.
tjtSample and report transient processes and deleted executable paths.See command help for supported inputs and platform constraints.
webkit-toolStatically flag risky WebKit settings and native script bridges.Static heuristics; no exploitability verdict.

macOS subsystem utility (1)

CommandScopeBoundary
osxInspect and manage macOS subsystems through structured commands.macOS; state changes require --apply.

Binary inspection and manuals (4)

CommandScopeBoundary
binparseRead ELF, Mach-O, and PE structure safely using Go debug readers.ELF, Mach-O and PE structure; does not execute input.
info2logicConvert GNU Info source into Logic Manual v1.See command help for supported inputs and platform constraints.
logicRead Logic Manual v1, roff man-page, and GNU Info source files.See command help for supported inputs and platform constraints.
man2logicConvert roff man source into Logic Manual v1.See command help for supported inputs and platform constraints.

File and pipeline primitives (5)

CommandScopeBoundary
envsubRender environment-backed templates with strict types, defaults, validation, and secret-aware diagnostics.See command help for supported inputs and platform constraints.
hashsumCompute SHA-256 and BLAKE3 concurrently and create verifiable manifests for large file sets.See command help for supported inputs and platform constraints.
jsondiffCompare structured desired and observed state with JSON Pointer paths and machine-readable changes.See command help for supported inputs and platform constraints.
jwalkWalk large directory trees with regex, age, size, and type filters, emitting JSON Lines.See command help for supported inputs and platform constraints.
varmergeMerge environment, JSON, YAML, and defaults under a typed schema with value provenance.See command help for supported inputs and platform constraints.

Automation, IaC and accessible operations (8)

CommandScopeBoundary
contextsnapCollect or normalize AWS and AliCloud caller identity with explicit profile and region.Read-only STS identity; selected region is not proof of resource location. Saved inputs retain a supplied timestamp.
jsongateConvert JSON findings into consistent pass, deny, or approval-required decisions.See command help for supported inputs and platform constraints.
jsonprobeRun declarative TCP, HTTP, process, and filesystem readiness checks.TCP, HTTP and file checks; process checks require Linux. No root-cause verdict.
regocheckDetect a local OPA engine and report policy-evaluation readiness.Detects OPA readiness only; does not evaluate policies.
runreceiptPreview or explicitly execute local commands and pipelines with private per-stage execution receipts.Local process evidence only; no automatic retry or remote outcome verification.
sandboxdiffCompare two JSON workload snapshots.JSON comparison only; does not launch or observe a sandbox.
spacelift-helperNormalize allowlisted Spacelift hook context.Allowlisted environment context only; no hook execution or retention.
tfchangesNormalize Terraform/OpenTofu plan JSON into concise resource-change records and evidence-based risk facts.See command help for supported inputs and platform constraints.

Other (1)

CommandScopeBoundary
meowWhimsical cat sound text transformer with translation, prefix, emphasis, and pitch controls.See command help for supported inputs and platform constraints.

The osx utility and the --apply rule

osx gives structured, Go-native access to macOS subsystems. It takes the form osx [--apply] [--duration DURATION] <subsystem> <action> [arguments] and prints a versioned JSON response that names the native program and arguments it ran, and whether anything changed.

KindActions
Read-onlyinfo show; battery status; power settings; network quality|interfaces; spotlight search QUERY; dns status; security filevault|gatekeeper|firewall|sip; updates list; defaults read; clipboard read; volume get
Requires --applycaffeinate start; launch open; dns flush; updates install; defaults write|delete; speech say; clipboard write; files copy; automation run; volume set|mute|unmute
osx security gatekeeper
osx defaults read com.apple.finder AppleShowAllFiles
osx defaults write com.apple.finder AppleShowAllFiles bool true --apply
osx caffeinate start --duration 45m --apply

A state-changing action without --apply is refused with a message such as osx dns flush changes system state; rerun with --apply, and nothing runs. According to its specification, osx never passes input through a shell, never escalates privileges and never makes an implicit remote request.

The same rule, that a change needs an explicit flag, holds across the suite, but the flag differs by command. Check each command's help:

  • clt moves candidates into quarantine only with --apply and --quarantine-dir.
  • aaas resets an Accessibility grant only with --revoke BUNDLE_ID --apply.
  • cded clears sensitive clipboard content only with --drain. File input is always read-only.
  • homestate renames files only with --fix-names and keeps reversible mappings for --restore-names.
  • runreceipt previews by default and runs commands only with --execute, which requires a new --receipt file.

Accessible operations

A shared roadmap with RCDO aims to make Linux, cloud, IaC and automation work independently navigable and verifiable by blind and low-vision engineers. Missing Utils provides the bounded collection and normalization; RCDO provides nonvisual navigation, review state and handoffs.

The project status file records what exists locally today:

  • contextsnap collects AWS or AliCloud caller identity through read-only CLI calls with an explicit profile and region, or normalizes dated input you supply.
  • eventwhy groups finite Docker event evidence by resource, action and exit code.
  • runreceipt records per-stage execution receipts, so an early failed pipeline stage cannot be hidden by a successful last stage.

A credential-free demonstration runs both toolkits against synthetic fixtures. It contacts no cloud, Docker daemon or AI provider and never applies infrastructure. It needs a sibling RCDO checkout:

make dist/contextsnap dist/eventwhy
make -C ../rcdo build
python3 scripts/demo-accessible-operations.py

Workplace acceptance is pending. The status file says no live employer credentials, Docker daemon, Spacelift account or Ansible inventory was used, and that screen-reader, braille-display and magnification usability has not been measured. Relationship graphs, deeper IaC semantics, Ansible and Spacelift integration, continuous event streams and fleet comparison are planned work, not current capabilities. docs/COMMANDS.txt is a linear, 72-column version of the command inventory for speech and magnification.

Safety and limits

  • Read-only by default. Quarantine, clipboard draining, grant revocation, name repair, command execution and every osx state change require an explicit flag.
  • No trust or malware verdicts. binarywhy reports metadata and a hash, webkit-tool and amtm are static heuristics, and the macOS suite does not represent static evidence as proof of malicious behavior.
  • No root-cause or remediation inference. eventwhy does not label exit 137 as out-of-memory, restartwhy does not restart anything, and driftwhy and patchwhy capture a current fingerprint only.
  • Partial evidence is normal. Platform-specific collectors return partial results when they lack visibility or privileges, even when the binary builds.
  • Process exit is not a verified outcome. A clean runreceipt or jsonprobe result does not establish deployment success.
  • Unreleased. There are no tags or published binaries, command names are provisional, and the README notes that contribution guidelines, a code of conduct and a security policy are still to be added.

How it fits with the other tools

Missing Utils collects observations; RCDO reads them. The repository's RCDO readiness workflow feeds the aggregate output of jsonprobe into RCDO's jsonprobe-check, which returns an accessible review with coverage and freshness checks. That workflow is local and advisory: it does not execute deployments or certify that they are safe. Both projects carry the same accessibility roadmap, and the copy in Missing Utils is the authoritative one.

Missing Utils has no integration with the farm tools. It does not read or write the state of badfarm, oos or the others; it runs as standalone binaries on the machine you are inspecting.

Built from the public ads-missing-utils repository (README.md, ROADMAP.md, docs/commands.json, docs/COMMANDS.txt, docs/RCDO_WORKFLOW.md, docs/accessible-operations/STATUS.md and DEMO.md, specs/OSX.md, specs/MACOS_SECURITY_SUITE.md, Makefile, build.sh, go.mod, .tool-versions, .github/workflows/ci.yml, .goreleaser.yaml, LICENSE, and command help text) at commit 59c1b92.