<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/rss.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>#Standards — Seconds to Midnight</title><description>Content tagged with #Standards.</description><link>https://dbuho.me</link><language>en</language><copyright>© 2026 Damián Búho</copyright><managingEditor>damian.buho@proton.me (Damián Búho)</managingEditor><webMaster>damian.buho@proton.me (Damián Búho)</webMaster><lastBuildDate>Thu, 12 Nov 2026 16:25:25 GMT</lastBuildDate><category>Resilience</category><ttl>60</ttl><image><url>https://dbuho.me/favicon-48x48.png</url><title>#Standards — Seconds to Midnight</title><link>https://dbuho.me</link></image><atom:link rel="self" type="application/rss+xml" href="https://dbuho.me/tags/standards.rss"/><item><title>Post: CLI Checklist</title><link>https://dbuho.me/post/cli-checklist/?utm_source=tag-standards&amp;utm_medium=rss</link><guid isPermaLink="false">01M71WTZ45Y79APJ0TDDC4MKTZ</guid><description>Sharing here my checklist that I use for CLI apps (was assembled manually and suffered by real usage). You can feed it to your agent (it will probably forget half of the rules, so use multiple passes or split it). LLM was used only to fix ESL mistakes. 154 rules.</description><pubDate>Wed, 22 Jul 2026 02:59:00 GMT</pubDate><content:encoded>&lt;p&gt;Sharing here my checklist that I use for CLI apps (was assembled manually and suffered by real usage).
You can feed it to your agent (it will probably forget half of the rules, so use multiple passes or split it).&lt;/p&gt;
&lt;p&gt;LLM was used only to fix ESL mistakes.&lt;/p&gt;
&lt;p&gt;154 rules.&lt;/p&gt;
&lt;p&gt;The key words MUST, MUST NOT, SHOULD and MAY are to be read as described in RFC 2119 and RFC 8174. A rule about a feature binds only a tool that has that feature: a tool without remote accounts needs no &lt;code&gt;login&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Discovery and help&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MUST have &lt;code&gt;--help&lt;/code&gt; and &lt;code&gt;-h&lt;/code&gt; on the top level and on every subcommand&lt;/li&gt;
&lt;li&gt;MUST NOT overload &lt;code&gt;-h&lt;/code&gt; with anything but help&lt;/li&gt;
&lt;li&gt;MUST accept &lt;code&gt;--help&lt;/code&gt; appended to any invocation, ignoring the rest of the arguments&lt;/li&gt;
&lt;li&gt;MUST show a concise summary when invoked with no arguments, unless the tool reads stdin by default (&lt;code&gt;cat&lt;/code&gt;, &lt;code&gt;jq&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;MUST keep the concise help to a one-line description of what the tool does, one or two example invocations, the most common flags, and a pointer to &lt;code&gt;--help&lt;/code&gt; for the rest&lt;/li&gt;
&lt;li&gt;MUST open the help text with the one-line description, then examples (with the real output when it clarifies), then the most common flags and commands&lt;/li&gt;
&lt;li&gt;MUST group commands logically, each group in alphabetical order&lt;/li&gt;
&lt;li&gt;MUST link to the web version of the documentation from the top-level help text, and link the exact page or anchor per subcommand&lt;/li&gt;
&lt;li&gt;MUST link to the issue tracker or website so feedback and bug reports have a path&lt;/li&gt;
&lt;li&gt;MUST NOT check for updates implicitly on a normal run, and MUST NOT block on it&lt;/li&gt;
&lt;li&gt;MUST have a &lt;code&gt;check-updates&lt;/code&gt; command the user invokes explicitly, reporting the current version against the latest released one, unless a package manager owns the tool’s updates&lt;/li&gt;
&lt;li&gt;SHOULD also expose help as &lt;code&gt;myapp help&lt;/code&gt; and &lt;code&gt;myapp help &amp;lt;subcommand&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SHOULD provide tab completion for bash and zsh, documented in a format the shell understands&lt;/li&gt;
&lt;li&gt;SHOULD keep exhaustive or advanced examples in a dedicated cheat-sheet command or web page instead of the help text&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Output&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MUST send primary and machine-readable output to stdout&lt;/li&gt;
&lt;li&gt;MUST send logs, progress and errors to stderr&lt;/li&gt;
&lt;li&gt;MUST return zero on success and non-zero on failure&lt;/li&gt;
&lt;li&gt;MUST keep human-readable output paramount: humans first, machines second&lt;/li&gt;
&lt;li&gt;MUST print output on success, but keep it brief&lt;/li&gt;
&lt;li&gt;MUST tell the user when a command changed state, and show the current state&lt;/li&gt;
&lt;li&gt;MUST NOT print developer-only information by default: it belongs behind verbose mode&lt;/li&gt;
&lt;li&gt;MUST NOT use stderr as a log file: level labels (&lt;code&gt;ERR&lt;/code&gt;, &lt;code&gt;WARN&lt;/code&gt;) and extra context appear only in verbose mode&lt;/li&gt;
&lt;li&gt;MUST have mutually exclusive &lt;code&gt;--verbose&lt;/code&gt; and &lt;code&gt;--quiet&lt;/code&gt; flags&lt;/li&gt;
&lt;li&gt;MUST make &lt;code&gt;-q&lt;/code&gt; suppress all non-essential output, so scripts need no &lt;code&gt;2&amp;gt;/dev/null&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;MUST offer &lt;code&gt;--plain&lt;/code&gt; (one record per line, no wrapping or decoration: banners, ASCII art, table borders, divider rows, &lt;code&gt;[+]&lt;/code&gt;/&lt;code&gt;[-]&lt;/code&gt; status prefixes) whenever human-readable formatting breaks machine parsing or a screen reader&lt;/li&gt;
&lt;li&gt;MUST display indented JSON when &lt;code&gt;--json&lt;/code&gt; is passed, or one JSON object per line when the output is a stream of records&lt;/li&gt;
&lt;li&gt;MUST NOT pack several records or sentences onto one long line&lt;/li&gt;
&lt;li&gt;MUST make a TTY check per stream: colour and human decoration on stdout may go when piped while stderr keeps them&lt;/li&gt;
&lt;li&gt;MUST respect &lt;code&gt;NO_COLOR&lt;/code&gt;, &lt;code&gt;FORCE_COLOR&lt;/code&gt;, &lt;code&gt;TERM=dumb&lt;/code&gt; and &lt;code&gt;--color=auto|always|never&lt;/code&gt;, and provide a &lt;code&gt;&amp;lt;TOOL&amp;gt;_NO_COLOR&lt;/code&gt; override&lt;/li&gt;
&lt;li&gt;MUST NOT carry meaning in colour alone, and MUST NOT impose a custom colour scheme over the terminal’s own palette&lt;/li&gt;
&lt;li&gt;MUST have progress bars for long/network operations, with one bar per parallel task when possible&lt;/li&gt;
&lt;li&gt;MUST NOT emit animations or progress bars on a stream that is not a TTY&lt;/li&gt;
&lt;li&gt;MUST print the logs behind a progress bar when the run fails&lt;/li&gt;
&lt;li&gt;MUST report the time spent and the external requests made (HTTP and others) at the end of a long or network operation&lt;/li&gt;
&lt;li&gt;SHOULD keep the default output short enough to listen to through a screen reader, with filler behind &lt;code&gt;--verbose&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SHOULD use colour with intention and sparingly, since colour everywhere means colour nowhere&lt;/li&gt;
&lt;li&gt;SHOULD suggest the next command to run when several commands form a workflow&lt;/li&gt;
&lt;li&gt;SHOULD increase information density so a glance suffices, growing into detail on study&lt;/li&gt;
&lt;li&gt;SHOULD offer a flag that prints only hits when a run reports one line per checked item&lt;/li&gt;
&lt;li&gt;SHOULD page long output through &lt;code&gt;$PAGER&lt;/code&gt;, defaulting to &lt;code&gt;less -FIRX&lt;/code&gt;, only when stdin and stdout are both TTYs&lt;/li&gt;
&lt;li&gt;SHOULD parallelise work where it helps, keeping concurrent output from interleaving confusingly&lt;/li&gt;
&lt;li&gt;SHOULD show an estimated time remaining or at least an animated component on long operations&lt;/li&gt;
&lt;li&gt;SHOULD use symbols where they clarify, without turning the output into a toy&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Errors&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MUST rewrite expected errors for humans, in plain language, with the exact fix (&lt;code&gt;Can’t write to file.txt. Run chmod +w file.txt.&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;MUST NOT print scary stack traces for expected failures&lt;/li&gt;
&lt;li&gt;MUST give debug output, a traceback and bug-report instructions on an unexpected error, preferably writing the detail to a file rather than the terminal&lt;/li&gt;
&lt;li&gt;MUST use a distinct exit code for each important failure mode: checking an exit code is always easier than parsing output&lt;/li&gt;
&lt;li&gt;MUST put the most important information last, where the eye lands&lt;/li&gt;
&lt;li&gt;MUST group repeated errors of the same kind under one explanatory header instead of printing many similar lines&lt;/li&gt;
&lt;li&gt;MUST NOT silently rewrite the user’s input: when it accepts an alternative syntax, it says so and documents both&lt;/li&gt;
&lt;li&gt;SHOULD suggest the correction when user input is wrong and the intent is guessable&lt;/li&gt;
&lt;li&gt;SHOULD ask before running the suggestion rather than forcing it&lt;/li&gt;
&lt;li&gt;SHOULD make bug reports effortless by pre-filling as much context as possible into the issue URL&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Arguments and flags&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MUST use an argument-parsing library, the language built-in one or a good third-party one, instead of hand-rolling the parser&lt;/li&gt;
&lt;li&gt;MUST validate every input early and bail out before anything bad happens&lt;/li&gt;
&lt;li&gt;MUST give every flag a full-length form, and reserve single-letter flags for the common ones so the short namespace stays free&lt;/li&gt;
&lt;li&gt;MUST use the conventional names for the well-known flags a tool has: &lt;code&gt;-a/--all&lt;/code&gt;, &lt;code&gt;-d/--debug&lt;/code&gt;, &lt;code&gt;-f/--force&lt;/code&gt;, &lt;code&gt;-h/--help&lt;/code&gt;, &lt;code&gt;-n/--dry-run&lt;/code&gt;, &lt;code&gt;-o/--output&lt;/code&gt;, &lt;code&gt;-p/--port&lt;/code&gt;, &lt;code&gt;-q/--quiet&lt;/code&gt;, &lt;code&gt;-u/--user&lt;/code&gt;, &lt;code&gt;-V/--version&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;MUST support a &lt;code&gt;--version&lt;/code&gt; flag, and MUST NOT let &lt;code&gt;-v&lt;/code&gt; mean both verbose and version&lt;/li&gt;
&lt;li&gt;MUST allow &lt;code&gt;-&lt;/code&gt; to read from stdin or write to stdout when the input or output is a file&lt;/li&gt;
&lt;li&gt;SHOULD prefer flags to positional args: they read clearly and leave room to add input later&lt;/li&gt;
&lt;li&gt;SHOULD make arguments, flags and subcommands order-independent, so appending a flag to a recalled line still works&lt;/li&gt;
&lt;li&gt;SHOULD keep multiple positional args to one meaning, e.g. a list of same-typed files such as &lt;code&gt;rm *.txt&lt;/code&gt;; the exception is a memorable primary action like &lt;code&gt;cp &amp;lt;source&amp;gt; &amp;lt;destination&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SHOULD prompt for a missing argument when interactive, and never make the prompt mandatory&lt;/li&gt;
&lt;li&gt;SHOULD accept an explicit &lt;code&gt;none&lt;/code&gt; when a flag takes an optional value, rather than a blank value&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Interactivity and destructive actions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MUST let the user escape: Ctrl-C always works, and a wrapper around a program that swallows Ctrl-C says how to escape&lt;/li&gt;
&lt;li&gt;MUST only prompt when stdin is a TTY&lt;/li&gt;
&lt;li&gt;MUST have &lt;code&gt;--no-input&lt;/code&gt; to disable every prompt, and MUST fail with the flag to pass when input is required in that mode&lt;/li&gt;
&lt;li&gt;MUST NOT print a password as it is typed&lt;/li&gt;
&lt;li&gt;MUST confirm destructive actions interactively with &lt;code&gt;y&lt;/code&gt;/&lt;code&gt;yes&lt;/code&gt;, and require &lt;code&gt;-f&lt;/code&gt;/&lt;code&gt;--force&lt;/code&gt; when not interactive&lt;/li&gt;
&lt;li&gt;MUST make severe operations (deleting a whole remote application or server) hard to confirm by accident, asking for the name of the thing being deleted or accepting &lt;code&gt;--confirm=&amp;quot;name&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;MUST offer &lt;code&gt;--dry-run&lt;/code&gt; for moderate operations (deleting a directory or a remote resource, a bulk change) so the user can see what would happen&lt;/li&gt;
&lt;li&gt;SHOULD treat a config change that implicitly destroys something as severe&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Subcommands&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MUST be consistent across subcommands: same flag names for the same thing, similar output formatting&lt;/li&gt;
&lt;li&gt;MUST use the same two-level &lt;code&gt;noun verb&lt;/code&gt; shape across object types when the tool manages several, and the same verbs for the same operations&lt;/li&gt;
&lt;li&gt;MUST NOT have a catch-all subcommand that swallows unknown input, since that makes any future subcommand name a breaking change&lt;/li&gt;
&lt;li&gt;MUST NOT accept arbitrary subcommand prefixes as abbreviations; aliases are fine but must be explicit and stable&lt;/li&gt;
&lt;li&gt;MUST NOT have ambiguous or similarly named subcommands: &lt;code&gt;update&lt;/code&gt; and &lt;code&gt;upgrade&lt;/code&gt; side by side is confusing&lt;/li&gt;
&lt;li&gt;SHOULD split a complex tool into subcommands, and merge closely related tools into one command&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Performance and robustness&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MUST print something to the user within 100 ms; responsive beats fast&lt;/li&gt;
&lt;li&gt;MUST print before a network request so the command never looks broken while waiting&lt;/li&gt;
&lt;li&gt;MUST apply a timeout to every network operation, configurable, with a sane default&lt;/li&gt;
&lt;li&gt;MUST say something immediately on Ctrl-C and exit as soon as possible; when a second Ctrl-C would be destructive, say what it will do&lt;/li&gt;
&lt;li&gt;MUST be idempotent where possible, and MUST assume a previous run died before its clean-up&lt;/li&gt;
&lt;li&gt;MUST be recoverable: after a transient failure the user re-runs the same command and it resumes where it left off&lt;/li&gt;
&lt;li&gt;MUST apply a timeout to any clean-up code, so it cannot hang forever&lt;/li&gt;
&lt;li&gt;SHOULD assume misuse: scripted invocation, bad connections, concurrent instances, untested environments&lt;/li&gt;
&lt;li&gt;SHOULD retry transient failures with backoff and jitter&lt;/li&gt;
&lt;li&gt;SHOULD be crash-only: defer clean-up to the next run or design it out, so a failure can exit immediately&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Configuration and environment variables&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MUST make the default the right thing for most users; a setting nobody knows to pass has failed&lt;/li&gt;
&lt;li&gt;MUST apply configuration in precedence order: flags → running shell environment → project config (such as &lt;code&gt;.env&lt;/code&gt;) → user config → system config&lt;/li&gt;
&lt;li&gt;MUST follow the XDG Base Directory spec for user config (&lt;code&gt;~/.config/&amp;lt;tool&amp;gt;/&lt;/code&gt;) rather than scattering dotfiles in &lt;code&gt;$HOME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;MUST let any default be overridden in a config file, so an argument is not repeated on every call&lt;/li&gt;
&lt;li&gt;MUST ask for consent before automatically modifying configuration the tool does not own, and say exactly what it does&lt;/li&gt;
&lt;li&gt;MUST NOT commandeer widely used variable names&lt;/li&gt;
&lt;li&gt;MUST name environment variables with uppercase letters, digits and underscores only, never starting with a digit&lt;/li&gt;
&lt;li&gt;SHOULD use a flag for per-invocation settings (debug level, dry run) and a version-controlled file for settings stable across a project&lt;/li&gt;
&lt;li&gt;SHOULD honour the general-purpose variables: &lt;code&gt;DEBUG&lt;/code&gt;, &lt;code&gt;EDITOR&lt;/code&gt;, &lt;code&gt;HTTP_PROXY&lt;/code&gt;/&lt;code&gt;HTTPS_PROXY&lt;/code&gt;/&lt;code&gt;ALL_PROXY&lt;/code&gt;/&lt;code&gt;NO_PROXY&lt;/code&gt;, &lt;code&gt;TERM&lt;/code&gt;/&lt;code&gt;TERMINFO&lt;/code&gt;/&lt;code&gt;TERMCAP&lt;/code&gt;, &lt;code&gt;TMPDIR&lt;/code&gt;, &lt;code&gt;HOME&lt;/code&gt;, &lt;code&gt;PAGER&lt;/code&gt;, &lt;code&gt;LINES&lt;/code&gt;/&lt;code&gt;COLUMNS&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SHOULD read &lt;code&gt;.env&lt;/code&gt; where appropriate for settings tied to a directory&lt;/li&gt;
&lt;li&gt;SHOULD create a new config file rather than appending to an existing one, and delimit additions with a dated comment&lt;/li&gt;
&lt;li&gt;SHOULD aim for single-line environment variable values&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Security and privacy&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MUST NOT read secrets from flags, where they leak into &lt;code&gt;ps&lt;/code&gt; and shell history&lt;/li&gt;
&lt;li&gt;MUST NOT rely on environment variables for secrets&lt;/li&gt;
&lt;li&gt;MUST accept secrets from a file (&lt;code&gt;--password-file&lt;/code&gt;) or from stdin&lt;/li&gt;
&lt;li&gt;MUST NOT read or write files the user did not pass as arguments (internal state such as a cache excepted), or call a remote server, without saying so&lt;/li&gt;
&lt;li&gt;MUST offer a &lt;code&gt;login&lt;/code&gt; command for a tool with remote accounts, and treat the CLI’s API calls with the same security practices as the rest of the application&lt;/li&gt;
&lt;li&gt;MUST store a token or key, never raw credentials, in the OS keyring or a &lt;code&gt;0600&lt;/code&gt; file under &lt;code&gt;~/.config/&amp;lt;tool&amp;gt;/&lt;/code&gt;, so it can be revoked without touching the user’s primary login&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Telemetry&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MUST NOT phone home usage or crash data without consent&lt;/li&gt;
&lt;li&gt;MUST respect &lt;code&gt;DO_NOT_TRACK&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;MUST state what is collected, why, how it is anonymised and how long it is retained&lt;/li&gt;
&lt;li&gt;MUST NOT block on analytics&lt;/li&gt;
&lt;li&gt;SHOULD prefer instrumenting the docs and the downloads over instrumenting the binary&lt;/li&gt;
&lt;li&gt;SHOULD ask for consent once, at first run, and make withdrawing it as easy as giving it&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Naming and distribution&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MUST give the program a short, memorable, lowercase name that is not too generic and does not collide with an existing command&lt;/li&gt;
&lt;li&gt;MUST be easy to uninstall, with the instruction at the bottom of the install instructions&lt;/li&gt;
&lt;li&gt;SHOULD keep the name easy to type for something people run all day&lt;/li&gt;
&lt;li&gt;SHOULD distribute as a single binary when the language allows it&lt;/li&gt;
&lt;li&gt;SHOULD otherwise use the platform’s native package installer over scattering files that cannot easily be removed&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Compatibility and future-proofing&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MUST treat subcommands, args, flags, config files and env vars as interfaces, and keep changes additive where possible&lt;/li&gt;
&lt;li&gt;MUST warn in the program itself before a non-additive change, telling the user how to make their usage future-proof, and stop warning once they have&lt;/li&gt;
&lt;li&gt;MUST document deprecations with a version number and a replacement&lt;/li&gt;
&lt;li&gt;MUST test on every platform the tool claims to support, and list them in the docs&lt;/li&gt;
&lt;li&gt;MUST note platform-specific install steps and behavioural differences rather than leaving users to guess&lt;/li&gt;
&lt;li&gt;SHOULD pin what the tool depends on&lt;/li&gt;
&lt;li&gt;MAY change human-readable output freely; that is why &lt;code&gt;--plain&lt;/code&gt; and &lt;code&gt;--json&lt;/code&gt; exist for scripts&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MUST define the CLI’s purpose in one sentence&lt;/li&gt;
&lt;li&gt;MUST list every command with a one-line explanation&lt;/li&gt;
&lt;li&gt;MUST give each command a syntax block before anything else&lt;/li&gt;
&lt;li&gt;MUST give every key command at least one copy-paste-ready example&lt;/li&gt;
&lt;li&gt;MUST explain every flag: what it does, when to use it, what happens if it is skipped&lt;/li&gt;
&lt;li&gt;MUST state default values and show the output format with a sample&lt;/li&gt;
&lt;li&gt;MUST document the errors users will hit and the exact command that fixes each&lt;/li&gt;
&lt;li&gt;MUST outline the setup requirements: authentication, environment variables, system prerequisites, minimum versions&lt;/li&gt;
&lt;li&gt;MUST cross-reference related commands, pointing to the next logical step&lt;/li&gt;
&lt;li&gt;MUST use one term per concept and keep it identical to the product’s own wording&lt;/li&gt;
&lt;li&gt;MUST show commands and their output as text, never as images&lt;/li&gt;
&lt;li&gt;MUST run every example command in the docs as written before publishing&lt;/li&gt;
&lt;li&gt;MUST state the CLI version the docs match, and note features that only exist from a given version&lt;/li&gt;
&lt;li&gt;MUST keep the docs in version control and update them in the same commit as the CLI change&lt;/li&gt;
&lt;li&gt;MUST use the same public docs for internal developers&lt;/li&gt;
&lt;li&gt;SHOULD outline real-world use cases, not just the command list&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Testing and feedback&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MUST get the CLI in front of developers who did not write it, including outsiders and newcomers&lt;/li&gt;
&lt;li&gt;MUST have someone outside the team read the docs for the first time and follow them without guessing&lt;/li&gt;
&lt;li&gt;MUST listen to the default and &lt;code&gt;--plain&lt;/code&gt; output end to end through a screen reader (Orca, or &lt;code&gt;espeak-ng&lt;/code&gt; at the least)&lt;/li&gt;
&lt;li&gt;SHOULD let users report usability problems easily, and invite usability feedback from newcomers&lt;/li&gt;
&lt;li&gt;SHOULD be explicit with testers about what feedback is wanted, and accept the spontaneous kind&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Sources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://clig.dev/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; class=&quot;external-link&quot;&gt;Command Line Interface Guidelines&lt;/a&gt; by Aanand Prasad, Ben Firshman, Carl Tashian and Eva Parish, CC BY-SA 4.0: many rules here are adapted from it&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://devcenter.heroku.com/articles/cli-style-guide&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; class=&quot;external-link&quot;&gt;Heroku CLI Style Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/@jdxcode/12-factor-cli-apps-dd3c227a0e46&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; class=&quot;external-link&quot;&gt;12 Factor CLI Apps&lt;/a&gt; by Jeff Dickey&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gnu.org/prep/standards/html_node/Command_002dLine-Interfaces.html&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; class=&quot;external-link&quot;&gt;GNU Coding Standards: Standards for Command Line Interfaces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap12.html&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; class=&quot;external-link&quot;&gt;POSIX Utility Conventions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc2119&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; class=&quot;external-link&quot;&gt;RFC 2119&lt;/a&gt; and &lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc8174&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; class=&quot;external-link&quot;&gt;RFC 8174&lt;/a&gt;: requirement key words&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://specifications.freedesktop.org/basedir-spec/latest/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; class=&quot;external-link&quot;&gt;XDG Base Directory Specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://no-color.org/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; class=&quot;external-link&quot;&gt;NO_COLOR&lt;/a&gt; and &lt;a href=&quot;https://force-color.org/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; class=&quot;external-link&quot;&gt;FORCE_COLOR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://consoledonottrack.com/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; class=&quot;external-link&quot;&gt;Console Do Not Track&lt;/a&gt;: the &lt;code&gt;DO_NOT_TRACK&lt;/code&gt; variable&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>Standards</category><category>CLI</category><author>damian.buho@proton.me (Damián Búho)</author></item><item><title>Post: AI Stance</title><link>https://dbuho.me/post/ai-stance/?utm_source=tag-standards&amp;utm_medium=rss</link><guid isPermaLink="false">01M4EXHHXNN36X1HZCTY463WQY</guid><description>Inspired by Armin Ronacher&amp;#39;s AI Transparency Statement I use coding agents every day, but never use LLMs for writing or anything that&amp;#39;s meant to be read by humans. I occasionally make a throwaway picture (like an avatar). I do use them to fix idiotic ESL mistakes I sometimes make. I use … and — via the Compose key in Linux since the 2010s. I have a background in traditional publishing and believe that three dots (...) are not an ellipsis (…) and never will be.</description><pubDate>Tue, 23 Jun 2026 02:59:00 GMT</pubDate><content:encoded>&lt;p&gt;Inspired by &lt;a href=&quot;https://lucumr.pocoo.org/ai-transparency/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; class=&quot;external-link&quot;&gt;Armin Ronacher&amp;#39;s AI Transparency Statement&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I use coding agents every day, but never use LLMs for writing or anything that&amp;#39;s meant to be read by humans.
I occasionally make a throwaway picture (like an avatar).&lt;/p&gt;
&lt;p&gt;I do use them to fix idiotic &lt;abbr title=&quot;English as a second or foreign language&quot;&gt;ESL&lt;/abbr&gt; mistakes I sometimes make. I use … and — via the Compose key in Linux since the 2010s.
I have a background in traditional publishing and believe that three dots (...) are not an ellipsis (…) and never will be.&lt;/p&gt;
&lt;h2&gt;Ground rules&lt;/h2&gt;
&lt;h3&gt;Disclose for humans&lt;/h3&gt;
&lt;p&gt;Every human deserves to know the source of your information, and has the right to ignore an LLM answer without reading it. It&amp;#39;s a good rule even for non-AI applications; I am not reading your &amp;quot;russia today&amp;quot; quote, mate.&lt;/p&gt;
&lt;p&gt;So, an LLM response should be marked with the same effort as &amp;quot;trigger warnings&amp;quot; or at least &lt;a href=&quot;https://apastyle.apa.org/style-grammar-guidelines/citations/quotations&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; class=&quot;external-link&quot;&gt;use some quoting standard like APA&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I make an exception for code, because the clanker that did some menial task doesn&amp;#39;t deserve a &amp;quot;Co-Authored&amp;quot; byline.
Also, no one reads your code anyway (sad, but true).&lt;/p&gt;
&lt;h3&gt;Accepting full responsibility&lt;/h3&gt;
&lt;p&gt;An agent/model didn&amp;#39;t fuck up. You did.&lt;/p&gt;
&lt;h3&gt;Never give up control&lt;/h3&gt;
&lt;p&gt;Don&amp;#39;t trust them fully; always have a deterministic pipeline to check their work.&lt;/p&gt;
&lt;h2&gt;More personally&lt;/h2&gt;
&lt;p&gt;I dislike the misleading &amp;quot;AI&amp;quot; term and people who are &lt;em&gt;really&lt;/em&gt; into it.&lt;/p&gt;
&lt;p&gt;Although, I believe any technology can produce obnoxious zealots. Just look at crypto.&lt;/p&gt;
&lt;p&gt;Maybe people should look into who raised all of those assholes, instead of screaming at a chain of hashes or matrix multipliers.&lt;/p&gt;
&lt;p&gt;I accept LLMs as a genie that can&amp;#39;t be put back into the bottle. Holy wars about LLMs are boring.&lt;/p&gt;
&lt;p&gt;I do believe that companies behind so-called &amp;quot;SOTA models&amp;quot; are not to be trusted and LLMs should be self-hosted and sovereign.&lt;/p&gt;
&lt;p&gt;At the same time, the whole &amp;quot;they drink all our water&amp;quot; trope is a good way to detect virtue-signalling idiots.
Most of them can&amp;#39;t distinguish an artesian well from an Abyssinian one and have zero interest in the state of local aquifers.&lt;/p&gt;
&lt;h2&gt;Projectfile&lt;/h2&gt;
&lt;p&gt;I use the &lt;a href=&quot;https://projectfile.org/extensions/org/projectfile/ai/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; class=&quot;external-link&quot;&gt;&amp;quot;org.projectfile.ai&amp;quot; extension&lt;/a&gt; in my projectfile schema, which generates an &amp;quot;AI POLICY.md&amp;quot; document in all my projects.&lt;/p&gt;</content:encoded><category>LLM</category><category>Meta</category><category>Standards</category><author>damian.buho@proton.me (Damián Búho)</author></item><item><title>Post: Spotlight: human.json</title><link>https://dbuho.me/post/spotlight-humanjson/?utm_source=tag-standards&amp;utm_medium=rss</link><guid isPermaLink="false">01M293G9HFA4ASQY02ZR5M8009</guid><description>I have human.json on this site. human.json is a lightweight protocol for humans to assert authorship of their site content and vouch for the humanity of others. It uses URL ownership as identity, and trust propagates through a crawlable web of vouches between sites. https://codeberg.org/robida/human.json I like the idea of establishing trust between people in this slop era. I always felt like such conventions and standards are something that only a bunch of important grayscrotums in very important commitees can do, and human.json actually inspired me to design projectfile , first and foremost for myself, but also to put it out there.</description><pubDate>Mon, 25 May 2026 02:59:00 GMT</pubDate><content:encoded>&lt;p&gt;I have &lt;a href=&quot;https://dbuho.me/human.json&quot;&gt;human.json&lt;/a&gt; on this site.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;human.json is a lightweight protocol for humans to assert authorship of their site content and
vouch for the humanity of others. It uses URL ownership as identity, and trust propagates through a
crawlable web of vouches between sites.
&lt;a href=&quot;https://codeberg.org/robida/human.json&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; class=&quot;external-link bare-url&quot;&gt;https://codeberg.org/robida/human.json&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I like the idea of establishing trust between people in this slop era.&lt;/p&gt;
&lt;p&gt;I always felt like such conventions and standards are something that only a bunch of important
grayscrotums in very important commitees can do, and human.json actually inspired me to design
&lt;a href=&quot;https://projectfile.org&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; class=&quot;external-link&quot;&gt;projectfile&lt;/a&gt;, first and foremost for myself, but also to put it out there.&lt;/p&gt;
&lt;p&gt;Although, I believe that any kind of commentless JSON should be only used by Catholic nuns as
punishment tool, I also believe we need more initiatives like this one. Not only because it&amp;#39;s a
legitimate attempt to solve a problem, but also because we lately gave up a lot of ground to
committees of aforementioned grayscrotums (corporate or pseudocorporate), and the world kinda sucks
because of it.&lt;/p&gt;
&lt;p&gt;You can fuck the right off with your new vibe-coded habit tracker, but if you have an idea for a
protocol or a scheme that empowers other people to build, I salute you.
Even if it&amp;#39;s weird or obscure, any such idea is an open invitation to work together, and that&amp;#39;s
cool.&lt;/p&gt;
&lt;p&gt;P.S. Technically it was just a &amp;quot;Vouch&amp;quot; collection in my Payload CMS backend, and a little renderer
for my Astro frontend, so I am not sure that I&amp;#39;ll open a human.json consulting agency anytime soon.&lt;/p&gt;</content:encoded><category>Standards</category><category>Small Web</category><author>damian.buho@proton.me (Damián Búho)</author></item></channel></rss>