Skip to content

feat(cli): add list subcommand to query and inspect active canons #38

Open

Description

@jimbojw

Problem & Motivation

The relationship between Canons and Files is an $M \times N$ bipartite graph:

  • A single canon may govern many files across the repository.
  • A single file may be governed by multiple overlapping canons (global, scoped, or tag-based).

As a repository accumulates canons across monorepo packages, developers and AI coding assistants need a fast, deterministic, zero-token CLI interface to inspect this graph in both directions without manual glob evaluation:

  1. Repository Inventory: "What canons exist across this project, and what are their scopes and tags?"
  2. Contextual Applicability ($F \rightarrow C$): "Which canons govern the specific file(s) I am editing right now?"
  3. Blast Radius / Impact Analysis ($C \rightarrow F$): "If I author or edit canon X, which repository files will it govern?"
  4. Graph Health & Coverage: "Are there orphaned canons matching zero files? Are there critical source files completely uncovered by canons?"

As the anchor issue for CLI initial capabilities, this issue defines the read-only query and inspection suite, establishing full conformance with the dogfood CLI ergonomics canons (packages/cli/.canons/).


Command Capabilities & Invocation Ergonomics

1. Basic Inventory (All Canons)

Scans for **/.canons/**/*.md and outputs the repository inventory:

$ canon-clerk list
ID                               SCOPE             PATHS       TITLE
canons-must-be-atomic            global            **/*.md     Canons Must Be Atomic
scripts-must-echo-traces         .agents/skills/   **/*.sh     Scripts Must Echo Command Traces
cli-must-separate-data-from-diag packages/cli/     **/*.ts     CLI Must Separate Data From Diagnostics

2. Contextual Applicability ($F \rightarrow C$: Files to Canons)

Determines which canons pass Stage 0 deterministic path filtering for one or more files:

# Query by specific path
$ canon-clerk list --path packages/cli/src/index.ts

# Query by currently staged git files
$ canon-clerk list --staged

# Unix pipeline composition via stdin (per cli-commands-accepting-collections-must-support-stdin)
$ git diff --name-only origin/main...HEAD | canon-clerk list --stdin

3. Blast Radius & Reverse Query ($C \rightarrow F$: Canon to Files)

Projects a canon's path globs and scope boundaries onto the active repository to list governed files:

# List all files governed by a specific canon ID
$ canon-clerk list --files --canon cli-must-separate-data-from-diagnostics

# List all files governed by a tag across packages
$ canon-clerk list --files --tag cli-ergonomics

4. Graph Health & Integrity Diagnostics

Provides audit capabilities to maintain repository hygiene:

# Dead/Orphan Canons: Canons whose paths: match 0 repository files (e.g. stale globs after refactors)
$ canon-clerk list --orphans

# Uncovered Surface Area: Source files matching 0 active canons
$ canon-clerk list --files --uncovered

Output Formats & Pipeline Contracts

The command strictly complies with our dogfood CLI ergonomics canons:

  1. Delimiter-Separated Output (cli-list-commands-must-emit-delimiter-separated-lines):

    • When output is piped (non-interactive / non-TTY), canon-clerk list emits plain newline-delimited IDs (or clean tab-separated lines) without ANSI color escapes or table box-drawing characters:
      $ canon-clerk list --path packages/cli/src/index.ts | xargs -n1 ...
    • Formatted tables with column headers are reserved for interactive TTYs or explicit --table opt-in.
  2. Machine-Readable JSON (cli-output-commands-must-support-json):

    • --json emits the canonicalized schema for programmatic agent consumption:
      $ canon-clerk list --json
      [
        {
          "id": "cli-must-separate-data-from-diagnostics",
          "title": "CLI Must Separate Data From Diagnostics",
          "filePath": "packages/cli/.canons/cli-must-separate-data-from-diagnostics.md",
          "scope": "packages/cli",
          "paths": ["packages/cli/**/*.ts"],
          "tags": ["cli-ergonomics"],
          "inspect": ["diff"]
        }
      ]
  3. Deterministic Sorting (cli-collection-outputs-must-be-stably-sorted):

    • Canon collections are sorted lexicographically by id.
    • File collections are sorted lexicographically by relative repository path.
  4. Query Exit Codes (cli-queries-must-exit-zero-on-empty-results):

    • If a query returns 0 matching canons or 0 matching files, the command emits empty output and exits 0. (Exit codes $>0$ are strictly reserved for execution failures per cli-must-signal-failure-via-exit-codes).
  5. Diagnostic Separation (cli-must-separate-data-from-diagnostics):

    • Data payload (tables, TSV, JSON) writes exclusively to stdout.
    • Informational notices, warnings, and error diagnostics write exclusively to stderr.

Acceptance Criteria

  • Discovery & Derivation: Discover **/.canons/**/*.md and derive metadata (id, title, paths, tags, inspect) per SPEC.md Section 4.
  • Path Filtering ($F \rightarrow C$): Support --path <filepath>, --staged, and --stdin for Stage 0 matching.
  • Reverse Query ($C \rightarrow F$): Support --files --canon <id> and --files --tag <tag>.
  • Health Diagnostics: Support --orphans (unmatched canons) and --files --uncovered (unmatched files).
  • Output Ergonomics:
    • Auto-detect TTY: formatted table for terminals; clean newline/TSV for pipes.
    • Support --json with canonicalized schema.
    • Stable lexicographical sorting on all collections.
    • Exit code 0 on empty query results.
  • Help & Examples: Provide runnable, copy-pasteable usage examples in --help per cli-commands-must-provide-runnable-examples.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    scope: cliCLI binary and command-line execution.type: featNew user-facing functionality (triggers SemVer minor release).

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      ⌂ Proxy