Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

RFC-0002: CLI Resource Model and Command Architecture

Version: 0.2.0 | Status: normative | Phase: impl


1. Summary

[RFC-0002:C-SUMMARY] Summary (Informative)

This RFC defines the resource-first command architecture for the govctl CLI. It establishes normative requirements for command structure, resource types, and verb semantics to ensure consistency and discoverability.

The design follows established patterns from Docker, kubectl, and other modern CLIs where commands are grouped by resource type (noun-first) rather than operation type (verb-first).

Scope: This RFC specifies the structural contract (which commands exist, how they’re organized, what resources they operate on). Implementation details (flag syntax, help text formatting, terminal colors) are left to ADRs.

Rationale: A stable command structure enables:

  1. Predictable UX across all resource types
  2. Agent/script automation via consistent patterns
  3. Scoped help and command discovery
  4. Future extensibility without namespace pollution

Since: v0.1.0


2. Specification

[RFC-0002:C-RESOURCE-MODEL] Resource-First Command Structure (Normative)

The govctl CLI MUST use a resource-first command structure of the form:

govctl <resource> <verb> [arguments] [flags]

Where:

  • <resource> is a governance artifact type (rfc, adr, work, clause, release)
  • <verb> is an operation on that resource (new, list, get, edit, delete, or resource-specific lifecycle operations)
  • [arguments] are positional parameters (typically IDs, titles, or values)
  • [flags] are optional modifiers (–filter, –output, –stdin, etc.)

Rationale:

The resource-first structure (noun-first) provides several advantages over verb-first (operation-first):

  1. Scoped Discovery: govctl rfc --help shows only RFC operations, not all 30+ global commands
  2. Namespace Clarity: govctl rfc finalize is unambiguous; govctl finalize requires knowing it only applies to RFCs
  3. Mental Model Alignment: Users think “I want to work with RFCs” then “What can I do?”, not “I want to finalize something, what can be finalized?”
  4. Extensibility: Adding govctl rfc validate doesn’t pollute the global namespace
  5. Industry Convention: Docker, kubectl, git, cargo all use resource-scoping or similar patterns

Exceptions:

Commands that operate across all resource types (init, check, status, render) remain at the global level as they don’t belong to a specific resource namespace.

Implementation Note:

For backwards compatibility during migration, verb-first aliases MAY be supported but MUST emit deprecation warnings. Full verb-first syntax MUST be removed in a major version release.

Since: v0.1.0

[RFC-0002:C-RESOURCES] Resource Types (Normative)

The following resource types MUST be supported as top-level command namespaces:

1. rfc - Request for Comments

Manages RFC specifications (normative documents defining system behavior).

  • ID Format: RFC-NNNN (e.g., RFC-0001)
  • Lifecycle: draft → normative → deprecated (per [[RFC-0001:C-RFC-STATUS]])
  • Phase: spec → impl → test → stable (per [[RFC-0001:C-RFC-PHASE]])

2. adr - Architecture Decision Record

Manages ADRs (records of architectural decisions).

  • ID Format: ADR-NNNN (e.g., ADR-0001)
  • Lifecycle: proposed → accepted → superseded, or proposed → rejected (per [[RFC-0001:C-ADR-STATUS]])

3. work - Work Item

Manages work items (tasks, features, bugs).

  • ID Format: WI-YYYY-MM-DD-NNN (e.g., WI-2026-01-19-001)
  • Lifecycle: queue → active → done, with cancellation at any stage (per [[RFC-0001:C-WORK-STATUS]])

4. clause - RFC Clause

Manages individual clauses within RFCs.

  • ID Format: RFC-NNNN:C-NAME (e.g., RFC-0001:C-SUMMARY)
  • Lifecycle: active → deprecated → superseded (per [[RFC-0001:C-CLAUSE-STATUS]])

Clause Namespace vs Storage:

Clauses remain at the CLI top-level namespace despite being child resources of RFCs because their ID format (RFC-NNNN:C-NAME) is self-scoping and unambiguous.

The CLI namespace is independent of filesystem layout. Implementations MAY store clause files nested under RFC directories (e.g., gov/rfc/RFC-0001/clauses/C-NAME.json) while maintaining the flat CLI command structure (govctl clause get RFC-0001:C-NAME).

5. release - Release Version

Manages release versions and changelogs.

  • ID Format: Semantic version (e.g., 1.0.0)
  • No lifecycle (immutable once created)

Resource Identification:

Each resource type MUST have a unique, predictable ID format that:

  1. Is stable across filesystem operations
  2. Can be referenced in other artifacts
  3. Clearly identifies the resource type without context
  4. Supports lexicographic sorting where meaningful
  5. Is case-sensitive (RFC-0001 ≠ rfc-0001)

Timestamp Format:

All timestamps in resource metadata (created, updated, started, completed) MUST use ISO 8601 date format (YYYY-MM-DD) in UTC timezone.

Future Extensions:

Additional resource types MAY be added via RFC amendment. New resource types MUST follow the same structural patterns defined in [[RFC-0002:C-CRUD-VERBS]].

Since: v0.1.0

[RFC-0002:C-CRUD-VERBS] Universal CRUD Verbs (Normative)

All resource types MUST support the following CRUD (Create, Read, Update, Delete) verbs where applicable:

1. new - Create Resource

Syntax: govctl <resource> new <arguments>

Creates a new instance of the resource. Required arguments vary by resource type but typically include a title or primary identifier.

MUST support for: rfc, adr, work, clause, release Behavior:

  • Generates unique ID if not provided
  • Initializes resource with default values
  • Creates necessary filesystem structure
  • Validates inputs per resource schema

2. list - List Resources

Syntax: govctl <resource> list [filter]

Lists all instances of the resource type. Optional filter narrows results.

MUST support for: rfc, adr, work, clause, release Behavior:

  • Returns tabular output by default
  • Supports filtering (exact match or substring)
  • Sorted by ID (lexicographic order)
  • MUST respect [[RFC-0002:C-OUTPUT-FORMAT]] flags

3. get - Read Resource

Syntax: govctl <resource> get <id> [field]

Retrieves a resource by ID. If field is specified, returns only that field value.

MUST support for: rfc, adr, work, clause Behavior:

  • Returns full resource if no field specified
  • Returns field value if field specified
  • MUST respect [[RFC-0002:C-OUTPUT-FORMAT]] flags
  • MUST error if resource or field does not exist

Field Name Stability:

Field names exposed via get <id> <field> MUST be stable identifiers defined by the resource schema. Field names MAY NOT be renamed without a major version bump of govctl.

4. edit - Update Resource

Syntax: govctl <resource> edit <id> <field> [value]

Updates a single field on a resource. Value can be provided as argument or via stdin.

MUST support for: rfc, adr, work, clause Behavior:

  • Simple fields: replace value
  • Array fields: special syntax (see ADR-0017 for implementation details)
  • MUST validate field names per resource schema
  • MUST validate values per field type
  • MUST support --stdin flag for multiline content

5. delete - Delete Resource

Syntax: govctl <resource> delete <id>

Removes a resource permanently.

MUST support for: work, clause MUST NOT support for: rfc, adr (use lifecycle verbs instead)

Deletion Safety Constraints:

For clauses:

  • MUST only allow deletion if containing RFC is in draft status
  • MUST verify no other artifacts reference the clause ID before deletion
  • MUST error with list of referencing artifacts if references exist

For work items:

  • MUST only allow deletion if status is queue
  • MUST verify no other artifacts reference the work item ID before deletion
  • MUST error with list of referencing artifacts if references exist

General Deletion Behavior:

  • SHOULD require confirmation unless --force flag provided
  • MUST be atomic (either fully succeeds or fully fails)

Rationale: Permanent deletion breaks referential integrity. These constraints ensure deletions are safe and don’t leave dangling references in the governance graph.

Consistency Requirements:

  1. All CRUD verbs MUST use the same flag names across resource types
  2. Error messages MUST follow the same format across all verbs
  3. Exit codes MUST be consistent (0 = success, non-zero = error)
  4. Stdin handling MUST work identically across all verbs that accept it

Forbidden Variations:

  • MUST NOT use different verb names for the same operation (e.g., “show” vs “get”)
  • MUST NOT reorder arguments between resource types (ID always comes before field)
  • MUST NOT have resource-specific flags for universal operations

Since: v0.1.0

[RFC-0002:C-LIFECYCLE-VERBS] Resource-Specific Lifecycle Verbs (Normative)

Resource-specific lifecycle verbs implement state transitions defined in [[RFC-0001]]. These verbs MUST be scoped to their resource namespace.

RFC Lifecycle Verbs:

  1. govctl rfc finalize <id> <normative|deprecated>

    • Implements [[RFC-0001:C-RFC-STATUS]] transitions
    • draft → normative or draft → deprecated
  2. govctl rfc advance <id> <spec|impl|test|stable>

    • Implements [[RFC-0001:C-RFC-PHASE]] transitions
    • Forward-only phase progression
  3. govctl rfc bump <id> <patch|minor|major> -m <message>

    • Version bumping per semantic versioning
    • Updates changelog automatically
    • Optional: --change <description> for additional changelog entries
  4. govctl rfc supersede <id> --by <replacement-id>

    • Marks RFC as superseded by another RFC
    • Both RFCs must exist

ADR Lifecycle Verbs:

  1. govctl adr accept <id>

    • Implements [[RFC-0001:C-ADR-STATUS]] proposed → accepted
  2. govctl adr reject <id>

    • Implements [[RFC-0001:C-ADR-STATUS]] proposed → rejected
  3. govctl adr supersede <id> --by <replacement-id>

    • Implements [[RFC-0001:C-ADR-STATUS]] accepted → superseded
    • Both ADRs must exist

Work Lifecycle Verbs:

  1. govctl work move <id> <queue|active|done|cancelled>
    • Implements [[RFC-0001:C-WORK-STATUS]] transitions
    • Validates gate conditions (e.g., acceptance criteria for done)
    • Updates timestamp fields automatically

Clause Lifecycle Verbs:

  1. govctl clause deprecate <id>

    • Implements [[RFC-0001:C-CLAUSE-STATUS]] active → deprecated
  2. govctl clause supersede <id> --by <replacement-id>

    • Implements [[RFC-0001:C-CLAUSE-STATUS]] active/deprecated → superseded
    • Both clauses must exist

Consistency Requirements:

  1. All lifecycle verbs MUST validate transitions per [[RFC-0001]]
  2. All lifecycle verbs MUST update timestamp fields where applicable
  3. All lifecycle verbs MUST be atomic (no partial state changes)
  4. All lifecycle verbs MUST support global --dry-run flag
  5. Invalid transitions MUST error with clear explanation of valid transitions

Rationale:

Lifecycle verbs are resource-specific because:

  • RFCs have status AND phase (two dimensions of state)
  • ADRs can be rejected (not applicable to RFCs)
  • Work items have gate conditions (acceptance criteria)
  • Each resource has different valid transitions

Scoping these verbs to resources makes their applicability explicit and prevents confusion.

Since: v0.1.0

[RFC-0002:C-OUTPUT-FORMAT] Output Format Control (Normative)

All commands that output resource data MUST support the --output (or -o) flag with the following format options:

Required Output Formats:

  1. table (default for human use)

    • Formatted tables with headers and aligned columns
    • MAY use colors when terminal supports them
    • MUST be readable in plain text (no control codes in non-TTY)
  2. json

    • Valid JSON output
    • Pretty-printed with 2-space indentation
    • MUST be parseable by standard JSON tools
  3. yaml

    • Valid YAML output
    • Formatted for readability
    • MUST be parseable by standard YAML tools
  4. toml

    • Valid TOML output (native format for ADRs and Work Items)
    • MUST be parseable by standard TOML tools
    • Only applicable where TOML is the source format
  5. plain

    • Plain text values with no formatting
    • One value per line for lists
    • Single value (no newline) for scalar fields
    • Suitable for shell scripting and piping

Applicability:

Commands MUST support output formats as follows:

  • get with no field: table, json, yaml, toml
  • get with field: plain (default), json, yaml
  • list: table (default), json, yaml

Commands MAY add format-specific flags (e.g., --format-json-compact) but MUST NOT remove or change behavior of standard formats.

Format Selection:

  1. Explicit --output <format> takes precedence
  2. If not specified:
    • For TTY: default is table
    • For non-TTY: default MUST be json
  3. Invalid format names MUST error with list of valid formats

Exceptions:

govctl status is exempt from output format requirements and always produces human-readable tabular output intended for interactive use only.

Consistency Requirements:

  1. JSON/YAML/TOML output MUST match the internal schema exactly
  2. Table format MAY omit fields for readability but MUST show all critical fields
  3. Plain format MUST output stable, parseable text (no decorations)
  4. Output format MUST NOT affect command semantics (same data, different representation)

Rationale:

Universal output format control enables:

  • Human readability (table)
  • Script automation (json/yaml)
  • Integration with standard tools (jq, yq)
  • Native format editing (toml for ADRs/work items)

This pattern follows kubectl and Docker conventions where -o json works on all read operations.

Since: v0.1.0

[RFC-0002:C-GLOBAL-COMMANDS] Global Commands (Normative)

The following commands operate across all resources and MUST remain at the global namespace level:

1. govctl init

Initializes a new govctl project in the current directory.

Syntax: govctl init [--force]

Behavior:

  • Creates gov/ directory structure
  • Generates gov/config.toml
  • Creates subdirectories for rfcs, adrs, work items
  • Optionally creates .claude/commands/ with workflow templates
  • MUST error if already initialized (unless --force)

2. govctl check

Validates all governance artifacts across the project.

Syntax: govctl check [--deny-warnings]

Behavior:

  • Validates RFCs, ADRs, clauses, work items
  • Checks state machine invariants
  • Verifies cross-references
  • Scans source code for references (if enabled in config)
  • Returns exit code 0 if valid, non-zero if errors
  • With --deny-warnings: treats warnings as errors

3. govctl status

Shows summary counts of all artifacts grouped by status.

Syntax: govctl status

Behavior:

  • Displays counts by status/phase for each resource type
  • Highlights active work items
  • Shows pending decisions (proposed ADRs, draft RFCs)
  • Uses colors in TTY mode for visual scanning
  • No output format flag (always human-readable table)

4. govctl render

Generates markdown documentation from source-of-truth TOML/JSON.

Syntax: govctl render [targets...] [--output-dir PATH] [--dry-run]

Behavior:

  • Renders RFCs from JSON to markdown (published)
  • Renders ADRs from TOML to markdown (local only)
  • Renders work items from TOML to markdown (local only)
  • Generates CHANGELOG.md from releases
  • Default: renders RFCs only
  • With targets: rfc, adr, work, changelog, all
  • MUST validate before rendering

5. govctl describe

Outputs machine-readable CLI metadata for agent/tool integration.

Syntax: govctl describe [--context]

Behavior:

  • Outputs JSON with command catalog
  • Includes workflow information
  • With --context: adds current project state and suggested actions
  • Enables AI agents to discover capabilities (per [[ADR-0015]])

Stability Contract:

The JSON schema of govctl describe output MUST be versioned. The schema version MUST be included in the output. Backward-incompatible changes to the schema require a major version bump of govctl.

This ensures agents and automation tools can rely on stable introspection.

6. govctl completions

Generates shell completion scripts.

Syntax: govctl completions <bash|zsh|fish|powershell>

Behavior:

  • Outputs completion script for specified shell
  • Can be sourced or installed per shell conventions

Rationale:

These commands are global because they:

  1. Operate on multiple resource types simultaneously
  2. Don’t fit the <resource> <verb> pattern semantically
  3. Are project-level operations, not resource-level
  4. Match user mental model of “project commands” vs “resource commands”

Future Additions:

New global commands MAY be added via RFC amendment. They MUST meet at least one criterion:

  1. Operate on multiple resource types
  2. Perform project-level initialization or cleanup
  3. Provide meta-information about the CLI itself

Since: v0.1.0


Changelog

v0.2.0 (2026-01-19)

Incorporate review feedback: add deletion safety constraints, field name stability, output format defaults, describe schema versioning, and editorial clarifications

Added

  • Added deletion safety constraints requiring draft RFCs and reference checks
  • Added field name stability guarantee for get command
  • Specified json as default output format for non-TTY
  • Added status command exception to output format requirements
  • Added describe command schema versioning contract
  • Clarified clause namespace vs filesystem storage independence
  • Added case-sensitivity and timestamp format requirements

v0.1.0 (2026-01-19)

Initial draft