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.
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.mdMUST 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.mdat all times. Any code change that alters externally visible behavior MUST updateSKILL.mdin the same commit. SKILL.mdMUST be written in natural language understandable by an LLM Agent with no prior context about the project.SKILL.mdMUST be created and approved before CLI implementation begins (contract-first).SKILL.mdMUST 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.
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
0on success and a non-zero code on any error. - Skills MUST NOT write partial results to
stdoutbefore an error; on failure,stdoutMUST be empty or contain only complete, valid output produced before the error condition.
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
--formatflag 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
--formatflag is given. When--formatis explicitly specified, the result MUST be wrapped in a valid document of that format. - The
--formatflag MUST accept lowercase values only (yaml,json,toml). Unknown format values MUST cause a non-zero exit with an error onstderr.
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.
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
--streamflag or be the documented default behavior of the command (stated inSKILL.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 tomlis requested, the Skill MUST exit with a non-zero code and print an error tostderrexplaining that TOML does not support streaming. - Each streamed record MUST be independently parseable without buffering the entire stream.
- Skills MUST flush
stdoutafter each complete record to ensure downstream consumers receive data promptly. - On error mid-stream, the Skill MUST write the error to
stderrand exit with a non-zero code. Any records already written tostdoutbefore 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.
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
--replflag. 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 tostderrso thatstdoutremains 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 tostdout. 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
stderrand wait for the next input. - The REPL MUST exit cleanly (code
0) on EOF (Ctrl-D) or when the user typesexitorquit. - 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, andtoml. - REPL mode MUST support the
--formatflag 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.mdif 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.
All Skills MUST provide a --help flag that outputs standardized usage
information.
Rules:
--helpoutput MUST be written tostdoutand the Skill MUST exit with code0.--helpis the canonical plain-text help channel. It MUST remain human- readable and MUST NOT emit YAML, JSON, or TOML.- Passing
--formatalongside--helpMUST NOT convert--helpinto a structured help surface. - Help text MUST follow this section order:
- NAME —
<skill-name>followed by a one-line summary. - SYNOPSIS — invocation syntax with placeholders for arguments
(e.g.,
skill-name [OPTIONS] <input>). - DESCRIPTION — one to three paragraphs explaining what the Skill does and when to use it.
- OPTIONS — table or list of all flags/arguments, each with type, default value, and one-line description.
- FORMATS — list of supported
--formatvalues and whether--stream/--replare supported. - EXAMPLES — at least two usage examples (one minimal, one with flags).
- EXIT CODES — table of exit codes and their meanings.
- NAME —
- Subcommands (if any) MUST each support
--helpwith the same section structure. - Skills MAY additionally provide a dedicated
helpsubcommand for structured help documents. When present, thehelpsubcommand MUST support--format yaml,--format json, and--format toml, with YAML as the default structured help format. - Plain-text
--helpoutput and any structuredhelpoutput 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
clapor 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.
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.mdunder 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.
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-gnuandaarch64-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.
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
clapcrate (with derive macros preferred for consistency). - Serialization/deserialization MUST use
serdewith format-specific crates:serde_yamlfor YAML,serde_jsonfor JSON,tomlfor TOML. - Error handling MUST use
anyhowfor application-level errors orthiserrorfor library-level typed errors. Rawunwrap()/expect()calls are prohibited in production code paths (allowed in tests). - Code MUST pass
cargo clippy -- -D warningswith 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.tomlwith 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.
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].nameinCargo.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.rsor be named descriptively (e.g.,cli_contract_test.rs).
SKILL.md required sections (in order):
- Description — one-paragraph summary of what the Skill does.
- Prerequisites — system dependencies, environment variables, auth requirements.
- Invocation — command syntax with all flags and arguments.
- Input — description of stdin or argument inputs and their formats.
- Output — description of stdout output format, including supported
--formatvalues (yaml/json/toml) and streaming behavior if applicable. - REPL Mode — (if supported) available REPL commands and behavior.
- Errors — exit codes and their meanings; example error messages.
- Examples — at least two end-to-end usage examples.
All Skills developed in this project MUST follow spec-driven development using the speckit methodology:
- Specify (
/speckit.specify): Define the Skill's purpose, user stories, and acceptance criteria inspec.md. User stories MUST be framed from the Agent's perspective (e.g., "As an Agent, I need to…"). - Plan (
/speckit.plan): Design the CLI interface, I/O contract, and implementation approach inplan.md. The Constitution Check MUST explicitly verify compliance with all six Core Principles before Phase 0 research. - Tasks (
/speckit.tasks): Break implementation into ordered tasks intasks.md. The Foundational phase MUST include:Cargo.tomlproject initializationSKILL.mdcreation and review (blocking prerequisite)clapCLI skeleton with--help,--format, and--versionflags
- Implement (
/speckit.implement): Execute tasks in order.SKILL.mdMUST be finalized before CLI logic is written (contract-first). - Validate: Run the Skill against all acceptance scenarios from
spec.mdusing the actual CLI binary. Test that:stdout/stderr/exit codes match the contract inSKILL.md- All three output formats (YAML, JSON, TOML) produce valid documents
--helpoutput follows the standardized section order- Structured
helpoutput (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 clippyandcargo fmt --checkpass
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.
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_DATEMUST 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.mdwith 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