# CLI Tool Constitution (v1)

Derived from first principles. Paste into `.specify/memory/constitution.md` via
`/speckit.constitution`. Preserve the exact phrasing of each principle; do not
paraphrase into generalities.

Source: https://daita.io/blog/spec_kit_constitution_first_principles

## Principles

### 1. A CLI is a contract with humans and scripts

Every command has a stable, versioned interface. Flags are documented.
Exit codes are meaningful (0 success, non-zero failure, distinct codes for
distinct failure classes). Breaking flag changes require a major version bump.

### 2. Optimize for deletion, not extension

A subcommand must be small enough that one engineer can delete and rewrite
it in a day. Reject plugin frameworks, speculative abstraction layers, and
"configurable everything" designs until two concrete consumers demand them.

### 3. Make dependencies explicit

No implicit global state. No magic config file lookups across parent dirs
without the user asking. No import-time side effects. Every external
resource (network, filesystem, env var) the command touches is listed in
`--help`.

### 4. Fail loudly, exit predictably

Errors print to stderr, results print to stdout. No colored error banners
when stdout is not a TTY. Never swallow errors into "operation completed"
messages. A non-zero exit code is always paired with a human-readable
stderr message and, where relevant, a machine-readable error code.

### 5. Test the transformation, not the process runner

Unit tests cover the pure logic (parsing, transformation, formatting).
Integration tests drive the binary with a fixture filesystem and env.
"It compiles" is not a test. A green CI without a failing test for the
bug you just fixed is not green.

### 6. Composability over features

New behavior should compose with existing Unix tools (pipes, stdin, stdout,
exit codes) before becoming a new flag. If `mytool list | grep foo` works,
do not add `mytool list --filter foo`. Flags that duplicate pipe behavior
require a written justification.

### 7. Determinism by default

Same inputs produce same outputs. No timestamps in output unless requested.
No non-deterministic ordering. If randomness is needed, accept a `--seed`
flag.

### 8. Startup is fast, help is instant

`mytool --help` and `mytool <subcommand> --help` must return in under 100ms.
Lazy-load heavy dependencies. No network calls on startup. No "updating
metadata" banners without an explicit opt-in.

### 9. Commands are discoverable; local dev matches CI

Every repeatable action (build, test, lint, release) is a single named
command listed in one place. The command a developer runs locally is the
same command CI runs. If a new contributor cannot list every command in
30 seconds, the interface is broken.
