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

Validation & Rendering

govctl provides tools to validate governance artifacts, enforce completion gates, and render human-readable documentation.

Validation

Check All Artifacts

govctl check

This validates:

  • Schema conformance — All required fields present, correct types
  • Phase discipline — No invalid state transitions
  • Cross-referencesrefs and [[...]] annotations point to existing artifacts
  • Controlled-vocabulary tags — All artifact tags are registered in gov/config.toml [tags] allowed
  • Clause structure — Normative clauses in spec sections
  • Source code scanning[[RFC-0001]] annotations in source files are verified

Exit Codes

  • 0 — All validations passed
  • 1 — Validation errors found

Source Code Scanning

govctl scans source files for [[artifact-id]] annotations and verifies they reference existing, non-deprecated artifacts:

#![allow(unused)]
fn main() {
// Implements [[RFC-0001:C-VALIDATION]]
fn validate() { ... }

// Per [[ADR-0005]], we use semantic colors
}

Configure scanning in gov/config.toml:

[source_scan]
enabled = true
include = ["src/**/*.rs"]

include is the positive scan domain and uses Git gitignore path-pattern semantics. Project .gitignore files provide the baseline exclusions. Governance-specific exclusions and re-inclusions belong in .govignore files:

# Skip generated source evidence
generated/

# Restore one governed subtree excluded by .gitignore
!fixtures/
!fixtures/governed/

.govignore uses normal gitignore ordering and ! re-inclusion, and its rules take precedence over .gitignore. Re-including a descendant requires re-including each excluded parent directory. govctl prunes excluded directories before reading their contents.

An optional source_scan.pattern override must be a valid regular expression whose capture group 1 returns the complete artifact ID for every match. Unknown and outdated reference diagnostics report the normalized source path followed by a one-based line and byte column.

Controlled-Vocabulary Tags

Tags provide cross-cutting categorization across all governance artifacts. Every tag must be registered in a project-level allow list before use.

Managing the Tag Registry

# List all registered tags with usage counts
govctl tag list

# Register a new tag
govctl tag new caching

# Remove a tag (fails if any artifact still uses it)
govctl tag delete caching

Tagging Artifacts

Once a tag is registered, apply it to any artifact via the standard edit command with --add:

govctl rfc edit RFC-0010 tags --add caching
govctl adr edit ADR-0003 tags --add caching
govctl work edit WI-2026-01-17-001 tags --add caching

Filtering by Tag

List commands support --tag to filter by one or more tags (comma-separated, AND logic):

govctl rfc list --tag caching
govctl adr list --tag caching,performance
govctl work list --tag breaking-change

Tags are validated at govctl check time — any tag not in the allow list produces error E1105.

Verification Guards

Guards are executable completion checks that run automatically when a work item moves to done. They prevent work items from closing unless all configured checks pass.

How Guards Work

When you run govctl work move <WI-ID> done, govctl executes each guard defined in gov/config.toml:

[verification]
enabled = true
default_guards = ["GUARD-GOVCTL-CHECK"]

Each guard is a TOML file in gov/guard/:

#:schema ../schema/guard.schema.json

[govctl]
id = "GUARD-LIFECYCLE-TESTS"
title = "lifecycle tests pass"
refs = ["RFC-0000"]

[check]
command = "cargo test --test lifecycle_tests"
timeout_secs = 300

Guard Subcommands

Guards are first-class resources with their own CRUD verbs:

# Create a new guard
govctl guard new "My Lint Check"

# List all guards
govctl guard list

# Show guard definition
govctl guard show GUARD-MY-LINT

# Set guard fields
govctl guard edit GUARD-MY-LINT command --set "npm run lint"
govctl guard edit GUARD-MY-LINT timeout_secs --set 60

# Delete a guard (blocked if still referenced by work items or project defaults)
govctl guard delete GUARD-MY-LINT

Guard Fields

FieldRequiredDescription
idYesUnique guard identifier (e.g., GUARD-LINT)
titleYesHuman-readable description
refsNoRelated RFCs/ADRs
commandYesShell command to execute from project root
timeout_secsNoMax execution time (default: 300s)
patternNoRegex pattern that must match stdout+stderr

Guard Behavior

  • A guard passes when its command exits with code 0 (and matches pattern if specified)
  • A guard fails when the command exits non-zero, times out, or doesn’t match the pattern
  • All guards must pass before govctl work move <WI-ID> done succeeds

Running Guards Independently

Use govctl verify to run guards without moving a work item:

# Run all project default guards
govctl verify

# Run specific guards
govctl verify GUARD-CARGO-TEST GUARD-GOVCTL-CHECK

# Run guards required by a specific work item
govctl verify --work WI-2026-01-17-001

govctl work move <WI-ID> done runs the same effective required guards. Do not run govctl verify --work <WI-ID> immediately before that move; doing so executes the guards twice. Use independent verification for early feedback, diagnosis, or workflows that leave the Work Item active.

Per-Work-Item Guards

Project-level default_guards are only part of the picture. A work item can also require additional guards of its own:

[verification]
required_guards = ["GUARD-CLIPPY"]

This is useful when one work item needs an extra check that should not become a project-wide default.

The effective required guard set for a work item is:

  • the project-level default_guards when verification is enabled
  • plus the work item’s verification.required_guards
  • minus any explicitly waived guards

Choosing Guard Granularity

Treat default_guards as the intersection of checks required by every Work Item, not as a catalog of everything the project can verify. A default guard should be necessary even for documentation-only work, fast enough for every completion gate, stable, and independent of optional services.

Keep reusable checks narrow and name them for the risk domain they cover, such as lifecycle tests, schema tests, or CLI parsing tests. Add those guards to affected Work Items:

govctl work edit WI-2026-01-17-001 verification.required_guards --add GUARD-LIFECYCLE-TESTS

Full test suites, full lint suites, integration tests, and other expensive aggregate checks should remain available as guards, but normally be required only by Work Items that change shared infrastructure or cross multiple risk domains. One-off diagnostic commands do not need Guard artifacts.

Repeated waivers are not a substitute for correct scope. If many unrelated Work Items waive the same default guard, remove it from default_guards and require it only where its risk applies.

Guard Waivers

If a guard must be waived for a specific work item, record that explicitly with a reason:

[[verification.waivers]]
guard = "GUARD-CARGO-TEST"
reason = "Flaky on CI runner image; tracked in issue #123"

Waivers are scoped to a single work item. They do not disable verification globally, and they should be treated as an exception that must be explained.

Rendering

Render governance artifacts to markdown for documentation.

Render All

govctl render            # RFCs to docs/rfc/
govctl render adr        # ADRs to docs/adr/
govctl render work       # Work items to docs/work/
govctl render all        # Everything
govctl render changelog  # CHANGELOG.md

Render Single Items

govctl rfc render RFC-0010
govctl adr render ADR-0005
govctl work render WI-2026-01-17-001

View Without Writing Files

The show commands render styled markdown to stdout without writing files:

govctl rfc show RFC-0010
govctl adr show ADR-0005
govctl work show WI-2026-01-17-001
govctl clause show RFC-0010:C-SCOPE

Hash Signatures

Rendered markdown includes a SHA-256 signature for tampering detection:

<!-- SIGNATURE: sha256:abc123... -->

If the source changes, the signature won’t match — indicating the rendered doc is stale.

Project Status

govctl status

Shows RFC/ADR/work item counts by status, phase breakdown, and active work items.

govctl search cache
govctl search "work item" --type work
govctl search RFC-0002 --output json
govctl search migration --tag cli -n 5
govctl search cache --reindex

Search is project-wide discovery across RFCs, clauses, ADRs, work items, and verification guards. Use repeated --type flags to restrict artifact kinds and repeated --tag flags to require all listed tags.

Supported output formats are table (default), json, and plain. If govctl persists a search index, it lives under .govctl/ as derived local state. The command establishes index freshness before returning results; --reindex forces a full rebuild.

CLI Self-Description

govctl provides a machine-readable command catalog for agent discoverability:

govctl describe
govctl describe --context   # Adds counts and non-terminal project state

The output includes a schema version and derives its command tree from the running CLI. Context mode omits terminal artifact details and offers only read-only discovery commands; use resource show commands or installed skills for deeper guidance.

Self-Update

Update govctl to the latest release:

govctl self-update          # Download and replace binary
govctl self-update --check  # Check for newer version without downloading

Supports GITHUB_TOKEN environment variable for authenticated API requests.

Agent Integration

Install or update govctl’s user-scoped integration through the agent runtime’s native plugin mechanism:

govctl agent doctor all
govctl agent install claude
govctl agent install codex
govctl agent update all

doctor is read-only. install preserves existing Codex reviewer-role files; update refreshes govctl’s installed role files. Start a new agent session after installation or update so the runtime reloads its integration. Both runtimes load bundled skills and hooks from their native plugin. Claude also loads Markdown reviewer agents from that plugin; Codex reviewer agents are standalone TOML roles managed by the same command.

Claude and Codex load separate hook manifests so each client receives fields and output in its native protocol. At session start, govctl uses normal upward project discovery and injects compact active-work and loop context only when the working directory belongs to a governed project. It stays silent in unmanaged directories and reports damaged governance state as non-blocking recovery context.

Before a direct edit to lifecycle-managed artifacts, the hook advises using the resource-specific CLI when it can express the change. The edit is never blocked: direct editing remains the recovery path for unsupported operations, followed by govctl check. The plugin does not run project-wide validation at the end of every turn.

Use init-skills only when a project-local or custom-directory copy is needed:

govctl init-skills --format claude
govctl init-skills --format codex
govctl init-skills --dir /path/to/agent-config

This direct projection does not register a native user plugin. It writes bundled workflow skills, writer/helper skills, and reviewer agents to the resolved destination.

Schema Migration

When the governance schema evolves between govctl versions, artifact files may need format upgrades:

govctl migrate

This upgrades TOML artifact file formats (e.g., adding #:schema headers or normalizing schema metadata) with transactional safety — changes are staged, backed up, and committed atomically.

govctl migrate vs the /migrate Workflow

These are related but serve different purposes:

govctl migrate/migrate skill
WhatUpgrade existing govctl artifacts to current formatAdopt govctl in an existing project
WhenAfter updating govctl versionWhen starting governance in a brownfield repo
EffectSyncs TOML artifacts, schemas, ignore configuration, and local support filesDiscovers decisions, backfills ADRs, annotates source
RiskLow — transactional, reversibleMedium — requires human review of generated ADRs

Run govctl migrate when govctl reports an outdated schema version, missing or stale bundled schema files, or missing govctl-managed local-state .gitignore entries such as .govctl.lock and .govctl/. Schema versions below 3 require migration with a compatible earlier govctl version before upgrading. Legacy RFC or clause JSON storage is rejected explicitly. Use the /migrate skill when bringing an existing project under governance for the first time.