Skip to content

Latest commit

 

History

History
408 lines (338 loc) · 18.8 KB

File metadata and controls

408 lines (338 loc) · 18.8 KB

rust-cli Constitution

Core Principles

I. CLI-First

Every Skill extension MUST be implemented as a standalone CLI program. The CLI is the primary and only required interface between the Agent and the Skill's functionality. Non-CLI interfaces (REST APIs, library imports, SDKs) are permitted as internal implementation details but MUST NOT be the integration surface exposed to the Agent.

Rules:

  • Each Skill MUST be invocable as a single CLI command.
  • Programs MUST NOT require a running daemon or background service to operate (except when explicitly running in REPL mode; see Principle III).
  • Skill programs MUST be self-contained and executable without modification to the host Agent environment beyond installation of declared dependencies.

Rationale: A CLI boundary keeps Skills universally portable across Agent implementations and prevents tight coupling between the Skill's internals and the Agent runtime.

II. Skill Contract (SKILL.md)

Every CLI-based Skill MUST ship with a SKILL.md file at the Skill root that defines the complete Agent integration contract. SKILL.md is the authoritative specification for how an Agent invokes and interprets the Skill.

Rules:

  • SKILL.md MUST document: invocation syntax, all accepted arguments/flags, input format (stdin or args), output format (stdout), error conditions (stderr), exit codes, and at least one usage example.
  • The Skill's observable behavior MUST match SKILL.md at all times. Any code change that alters externally visible behavior MUST update SKILL.md in the same commit.
  • SKILL.md MUST be written in natural language understandable by an LLM Agent with no prior context about the project.
  • SKILL.md MUST be created and approved before CLI implementation begins (contract-first).
  • SKILL.md MUST document supported output formats (YAML/JSON/TOML), streaming behavior (if applicable), and REPL mode (if supported).

Rationale: The Agent cannot inspect source code at invocation time. SKILL.md is the only reliable source of truth for correct invocation; stale or missing documentation causes silent Agent failures.

III. Text I/O Protocol

Skills MUST communicate with the Agent exclusively through text streams. This ensures debuggability, composability, and portability.

General rules:

  • Standard results MUST be written to stdout.
  • Errors, warnings, and diagnostic messages MUST be written to stderr.
  • Skills MUST exit with code 0 on success and a non-zero code on any error.
  • Skills MUST NOT write partial results to stdout before an error; on failure, stdout MUST be empty or contain only complete, valid output produced before the error condition.

III-A. Output Format Convention

The default serialization format for structured output is YAML. Skills MUST support format switching via a --format flag.

Rules:

  • The default output format (when no --format flag is provided) MUST be YAML.
  • Skills MUST support at least these three formats: --format yaml (default), --format json, --format toml.
  • Output MUST be valid, parseable documents in the selected format. No mixing of formats within a single invocation.
  • For simple scalar results (a single string, number, or boolean), Skills MAY output the raw value without serialization wrapping when no --format flag is given. When --format is explicitly specified, the result MUST be wrapped in a valid document of that format.
  • The --format flag MUST accept lowercase values only (yaml, json, toml). Unknown format values MUST cause a non-zero exit with an error on stderr.

Rationale: YAML is human-readable by default and naturally represents hierarchical data. JSON and TOML are widely supported in automation pipelines. A consistent --format flag eliminates per-Skill format negotiation.

III-B. Streaming Output Protocol

Some Skills produce output incrementally (e.g., progress updates, log tailing, long-running transformations). Streaming output MUST follow a well-defined framing protocol.

Rules:

  • Streaming mode MUST be activated explicitly via a --stream flag or be the documented default behavior of the command (stated in SKILL.md).
  • YAML streaming: Use YAML multi-document format — each record is a complete YAML document separated by --- on its own line. The stream ends with ... on its own line.
  • JSON streaming: Use NDJSON (Newline-Delimited JSON) — each record is a complete JSON object on a single line, terminated by \n.
  • TOML streaming: TOML has no multi-document convention. Streaming in TOML format is NOT supported. If --stream --format toml is requested, the Skill MUST exit with a non-zero code and print an error to stderr explaining that TOML does not support streaming.
  • Each streamed record MUST be independently parseable without buffering the entire stream.
  • Skills MUST flush stdout after each complete record to ensure downstream consumers receive data promptly.
  • On error mid-stream, the Skill MUST write the error to stderr and exit with a non-zero code. Any records already written to stdout before the error are considered valid and delivered.

Rationale: Standardized streaming framing allows Agents and downstream tools to parse incremental output without custom per-Skill logic.

III-C. REPL Mode Protocol

Skills MAY support an interactive REPL (Read-Eval-Print Loop) mode for exploratory or multi-turn usage. REPL mode is OPTIONAL per Skill.

Rules:

  • REPL mode MUST be activated via a --repl flag. The default mode (no flag) MUST remain non-interactive (one-shot execution via args/stdin).
  • REPL mode is primarily a human-oriented interaction surface. It MUST remain explicit and MUST NOT be the default interface assumed by an Agent unless the Agent intentionally opts into --repl.
  • The REPL prompt format MUST be: <skill-name>> (skill name followed by > and a single space), written to stderr so that stdout remains machine-parseable.
  • Each REPL input line is treated as a complete command. The Skill reads one line from stdin, processes it, and writes the result to stdout. The default REPL presentation MAY prioritize human readability rather than the one-shot command's default structured format.
  • After each result, the Skill MUST write the prompt again to stderr and wait for the next input.
  • The REPL MUST exit cleanly (code 0) on EOF (Ctrl-D) or when the user types exit or quit.
  • Errors for individual REPL commands MUST be written to stderr; the REPL MUST NOT exit on a per-command error — it MUST continue to accept input.
  • REPL help, whether shown automatically or via an in-session command, MUST be plain text only.
  • If the Skill supports explicit structured REPL output, it MUST use the same serialization contracts as one-shot mode for yaml, json, and toml.
  • REPL mode MUST support the --format flag set at invocation time when the Skill offers structured REPL output. Format switching mid-session is NOT required.
  • Skills MUST document REPL-supported commands in SKILL.md if REPL mode is offered.

Rationale: REPL mode enables human exploration and Agent multi-turn interactions without repeated process spawning. Writing prompts to stderr preserves stdout for machine-parseable output when structured formats are requested, while still allowing the default REPL experience to optimize for human readability.

III-D. Help Output Format

All Skills MUST provide a --help flag that outputs standardized usage information.

Rules:

  • --help output MUST be written to stdout and the Skill MUST exit with code 0.
  • --help is the canonical plain-text help channel. It MUST remain human- readable and MUST NOT emit YAML, JSON, or TOML.
  • Passing --format alongside --help MUST NOT convert --help into a structured help surface.
  • Help text MUST follow this section order:
    1. NAME<skill-name> followed by a one-line summary.
    2. SYNOPSIS — invocation syntax with placeholders for arguments (e.g., skill-name [OPTIONS] <input>).
    3. DESCRIPTION — one to three paragraphs explaining what the Skill does and when to use it.
    4. OPTIONS — table or list of all flags/arguments, each with type, default value, and one-line description.
    5. FORMATS — list of supported --format values and whether --stream / --repl are supported.
    6. EXAMPLES — at least two usage examples (one minimal, one with flags).
    7. EXIT CODES — table of exit codes and their meanings.
  • Subcommands (if any) MUST each support --help with the same section structure.
  • Skills MAY additionally provide a dedicated help subcommand for structured help documents. When present, the help subcommand MUST support --format yaml, --format json, and --format toml, with YAML as the default structured help format.
  • Plain-text --help output and any structured help output MUST be derived from the same command metadata source of truth and MUST stay semantically consistent with the actual command surface.
  • Help text MAY be rendered through clap or adjacent help-rendering code, but the metadata describing commands, flags, defaults, formats, and examples MUST come from the same definitions used by the CLI implementation.

Rationale: Standardized help output allows both humans and Agents to discover Skill capabilities without reading SKILL.md. A dedicated structured help path supports machine-readable introspection without compromising the human-readable role of --help, and shared metadata prevents drift between the two channels.

IV. Composability & Independence

Each Skill MUST be independently installable, invocable, and testable without depending on other Skills at runtime.

Rules:

  • Skills MUST NOT import or invoke other Skills' code at runtime.
  • Shared utilities MUST be vendored or declared as an explicit crate dependency, not assumed present from a co-installed Skill.
  • Each Skill MUST declare all runtime dependencies explicitly in Cargo.toml.
  • A Skill MUST be fully testable in isolation without any other Skill installed.
  • Skills MAY call external services or system commands, but MUST document these external dependencies in SKILL.md under a "Prerequisites" section.

Rationale: Independent Skills can be installed, updated, and replaced without cascading breakage. This mirrors the Unix philosophy and enables safe parallel development of multiple Skills.

V. Simplicity & Portability

Skills MUST favor minimal dependencies and standard tooling. Every added dependency or abstraction MUST be justified against the concrete value it delivers.

Rules:

  • Skills MUST compile to a single static binary for the target platform (use cargo build --release). The binary MUST be runnable without requiring a Rust toolchain on the target machine.
  • Skills MUST target at minimum: x86_64-unknown-linux-gnu and aarch64-apple-darwin (macOS ARM). Additional targets are OPTIONAL.
  • YAGNI: Do not add features, flags, or abstractions not required by the current Skill specification.
  • Each external crate dependency MUST be justified; prefer Rust standard library equivalents where they exist and are not materially more complex.
  • Skills targeting Agent environments MUST avoid GUI, desktop notification, or other non-headless OS integrations.

Rationale: A single compiled binary eliminates runtime dependency issues and makes distribution trivial. Minimal dependencies reduce compile times and attack surface.

VI. Rust Implementation

All CLI Skills MUST be implemented in Rust. This ensures consistent performance, memory safety, and a uniform toolchain across all Skills in the project.

Rules:

  • The implementation language for all Skill CLI programs is Rust (stable channel, latest stable release or one version behind).
  • CLI argument parsing MUST use the clap crate (with derive macros preferred for consistency).
  • Serialization/deserialization MUST use serde with format-specific crates: serde_yaml for YAML, serde_json for JSON, toml for TOML.
  • Error handling MUST use anyhow for application-level errors or thiserror for library-level typed errors. Raw unwrap()/expect() calls are prohibited in production code paths (allowed in tests).
  • Code MUST pass cargo clippy -- -D warnings with no suppressions unless explicitly justified in a code comment.
  • Code MUST be formatted with cargo fmt (default rustfmt configuration).
  • Each Skill MUST include a Cargo.toml with accurate [package] metadata: name, version, edition, description.

Rationale: A single mandatory language eliminates polyglot complexity, enables shared CI/CD pipelines, and guarantees memory safety. The mandated crate choices (clap, serde, anyhow/thiserror) form a minimal, battle-tested foundation that avoids per-Skill tooling debates.

Skill Structure Standards

Every CLI Skill project MUST follow this canonical directory layout:

<skill-name>/
├── SKILL.md             # Agent integration contract (REQUIRED)
├── Cargo.toml           # Rust package manifest (REQUIRED)
├── src/
│   ├── main.rs          # CLI entrypoint with clap (REQUIRED)
│   ├── lib.rs           # Core logic (RECOMMENDED for testability)
│   └── ...              # Additional modules as needed
├── tests/
│   └── cli_test.rs      # CLI integration/contract tests (REQUIRED)
└── README.md            # Human-facing documentation (RECOMMENDED)

Naming conventions:

  • Skill directory names MUST use lowercase kebab-case (e.g., search-web, run-sql-query).
  • The Cargo package name ([package].name in Cargo.toml) MUST match the directory name.
  • The compiled binary name MUST match the package name.
  • Test files under tests/ MUST use snake_case and end with _test.rs or be named descriptively (e.g., cli_contract_test.rs).

SKILL.md required sections (in order):

  1. Description — one-paragraph summary of what the Skill does.
  2. Prerequisites — system dependencies, environment variables, auth requirements.
  3. Invocation — command syntax with all flags and arguments.
  4. Input — description of stdin or argument inputs and their formats.
  5. Output — description of stdout output format, including supported --format values (yaml/json/toml) and streaming behavior if applicable.
  6. REPL Mode — (if supported) available REPL commands and behavior.
  7. Errors — exit codes and their meanings; example error messages.
  8. Examples — at least two end-to-end usage examples.

Development Workflow

All Skills developed in this project MUST follow spec-driven development using the speckit methodology:

  1. Specify (/speckit.specify): Define the Skill's purpose, user stories, and acceptance criteria in spec.md. User stories MUST be framed from the Agent's perspective (e.g., "As an Agent, I need to…").
  2. Plan (/speckit.plan): Design the CLI interface, I/O contract, and implementation approach in plan.md. The Constitution Check MUST explicitly verify compliance with all six Core Principles before Phase 0 research.
  3. Tasks (/speckit.tasks): Break implementation into ordered tasks in tasks.md. The Foundational phase MUST include:
    • Cargo.toml project initialization
    • SKILL.md creation and review (blocking prerequisite)
    • clap CLI skeleton with --help, --format, and --version flags
  4. Implement (/speckit.implement): Execute tasks in order. SKILL.md MUST be finalized before CLI logic is written (contract-first).
  5. Validate: Run the Skill against all acceptance scenarios from spec.md using the actual CLI binary. Test that:
    • stdout/stderr/exit codes match the contract in SKILL.md
    • All three output formats (YAML, JSON, TOML) produce valid documents
    • --help output follows the standardized section order
    • Structured help output (if supported) stays consistent with --help
    • REPL mode (if supported) handles input/output/errors correctly, including plain-text REPL help and any explicit structured formats
    • cargo clippy and cargo fmt --check pass

Testing discipline:

  • CLI contract/integration tests (invoking the compiled binary as a subprocess) are REQUIRED for all Skills and MUST be written before implementation.
  • Unit tests for internal logic (#[cfg(test)] modules) are RECOMMENDED.
  • Tests MUST cover all three output formats for at least one command.

Governance

This Constitution governs all CLI-based Skill development under the rust-cli project. It supersedes any conflicting guidance in individual feature plans, README files, or verbal conventions.

Amendment procedure:

  • Amendments MUST be proposed with a written rationale and impact assessment.
  • A MAJOR version bump is required for: removal or redefinition of a Core Principle, or backward-incompatible changes to the Skill Structure Standards.
  • A MINOR version bump is required for: new principle or section added, or material expansion of existing guidance.
  • A PATCH version bump is required for: clarifications, wording improvements, and typo fixes.
  • LAST_AMENDED_DATE MUST be updated to today's date on every change.

Compliance:

  • All PRs MUST include a Constitution Check in the plan (see plan-template.md).
  • Any deviation from a principle MUST be documented in the Complexity Tracking table of the relevant plan.md with explicit justification for why the deviation is necessary and what simpler alternative was rejected.
  • Agents loading this Skill MUST apply these principles when generating any CLI-based Skill for the user.

Version: 1.2.0 | Ratified: 2026-03-27 | Last Amended: 2026-03-28