TL;DR
Spec-driven development is useful only while the code and its governing artifacts stay aligned. SpecGov is a local, MIT-licensed CLI and GitHub Action that maps implementation paths to requirements, ADRs, docs, or specs, then reports when a code change bypasses them.
This tutorial uses the stable v0.1.0 release to build a small manifest, run a local scan, simulate a pull request check, and add the same check to GitHub Actions. The workflow is advisory first, so a team can learn where its mappings are incomplete before making them blocking.
What you will build
By the end, a repository will have a .specgov.yml manifest that says which artifacts govern src/auth/**. SpecGov can then report a warning when a pull request changes src/auth/session.ts without changing a related specification or design document.
SpecGov does not replace a spec-authoring method. It works with existing Markdown contracts, ADRs, .specs folders, Kiro specs, and Spec Kit plans. It reads local files and Git metadata. The project documentation describes it as framework agnostic, PR native, advisory first, and private by default.
Prerequisites
You need:
- Node.js 20 or newer. The package declares
node >=20. - A Git repository with a few documentation or specification files.
- Git, if you want to run the pull request comparison locally.
- A GitHub repository if you want to add the Action.
The stable release is specgov@0.1.0, published under the MIT license. The current repository also contains newer pre-release work, so pin the version when you need repeatable behavior.
Install the stable CLI
You can install the published CLI globally:
npm install -g specgov@0.1.0
Or use it without changing the global environment:
npx specgov@0.1.0 --help
The CLI exposes init, scan, check-pr, trace, and drift. The first four are enough for a useful pull request gate. The v0.1.0 README documents the complete command surface and exit codes.
Add a small manifest
Create .specgov.yml at the repository root. Start with one high-value mapping instead of trying to govern every path immediately:
version: 1
mode: advisory
artifacts:
- path: "docs/**/*.md"
kind: documentation
owner: docs
- path: "adr/**/*.md"
kind: decision
owner: architecture
- path: ".specs/**/*.md"
kind: specification
owner: engineering
mappings:
- code: "src/auth/**"
specs:
- "docs/auth/**"
- "adr/auth/**"
- ".specs/features/auth/**"
description: Authentication behavior must stay aligned with its specs.
rules:
require_spec_impact_for_code_changes: true
require_lifecycle_status: false
require_owner_for_active_specs: false
stale_after_days: 180
ignore:
- "node_modules/**"
- "dist/**"
- ".git/**"
The artifacts entries tell SpecGov what belongs to the repository's governance layer. A mappings entry connects implementation paths to the artifacts that must move with them. The mapping is explicit: an unrelated changed document does not satisfy the rule by accident.
Keep mode: advisory while the manifest is new. Advisory mode reports warnings but returns success for those warnings. Strict mode returns exit code 1 when governance findings should block a pull request.
Run the local checks
First scan the repository and emit JSON for a script or CI job:
specgov scan --format json
Then simulate a pull request that changes an authentication file:
specgov check-pr --format json --changed-file src/auth/session.ts
With the manifest above and no related spec change, the result should contain a SPEC_IMPACT_MISSING warning. That warning is useful evidence, not a failure in advisory mode. It tells the author which code path changed and which spec roots should be considered.
For a human-readable report, omit --format json:
specgov check-pr --changed-file src/auth/session.ts
You can also create a trace index for automation:
specgov trace --out .specgov.trace.json
The exact report depends on your repository. The important verification is reproducible: run the same command against the same checkout and inspect the finding code, related files, status, and exit code.
Add the GitHub Action
Once the local mapping makes sense, add a workflow such as .github/workflows/specgov.yml:
name: SpecGov
on:
pull_request:
jobs:
specgov:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: paladini/specgov@v0.1.0
with:
mode: advisory
base-ref: ${{ github.event.pull_request.base.sha }}
head-ref: ${{ github.event.pull_request.head.sha }}
The repository's stable README uses the same action contract and recommends pinning the Action to a version tag for repeatable CI behavior. The checkout needs full history because the check compares the pull request's base and head references.
When the mapping has earned trust, change mode to strict for the paths you are ready to enforce. Treat that as a policy decision: a strict rule can block a pull request, so the mapped artifact roots must be maintained with the same care as source code.
Why this works
The useful abstraction is a small graph:
- Artifact globs identify the documents that can govern behavior.
- Code-to-spec mappings connect implementation paths to those artifacts.
- Git changes provide the pull request scope.
- SpecGov compares the scope with the mappings and emits Markdown or JSON evidence.
This is more precise than checking whether a repository contains a file named SPEC.md. It also avoids asking an agent or model to guess which document matters. The manifest makes the relationship explicit and reviewable.
Failure modes and limitations
An empty glob or a typo in a path can make a mapping look complete while matching nothing. Run scan and review its artifact list before enabling strict mode.
SpecGov does not prove that a requirement is correct, that an implementation satisfies the requirement semantically, or that a declared producer really authored an artifact. It reports structural relationships and policy findings. A passing scan is not a correctness guarantee.
The stable release is marked pre-release in its README, and the CLI, report shape, and Action inputs may change before a first mature release. Pin 0.1.0 in tutorials and workflows, then review changes before upgrading.
The security boundary is intentionally narrow. Version 0.1 runs locally or in the GitHub runner, does not require an API key, does not call a model, and does not upload repository contents. That does not make the surrounding runner trusted automatically. Review third-party Actions, protect workflow changes, and avoid exposing private reports in public logs.
FAQ
Does SpecGov require GitHub?
No. The CLI can run locally in any Git repository. GitHub Actions is an integration point for pull request review.
Does it support only one specification framework?
No. The stable release supports custom folders and mappings, including docs, ADRs, .specs, Kiro-style specs, and Spec Kit-style plans.
Should every repository start in strict mode?
No. Start advisory, fix empty or overly broad mappings, observe real findings, and make only trusted paths strict.
Does a warning mean the code is unsafe?
No. It means the configured governance relationship is incomplete for the changed path. A reviewer still needs to decide whether the code, artifact, or mapping should change.
Takeaway
Spec drift becomes actionable when a repository can state which artifacts govern which code paths. SpecGov turns that statement into a deterministic local check and a pull request report. Start with one mapping, keep it advisory, verify the findings, and tighten enforcement only when the repository's own evidence supports it.
AI assistance disclosure: I used AI assistance to organize this tutorial and edit its prose. The project behavior, commands, configuration, version, license, limitations, and verification results were checked against the public repository, the stable v0.1.0 tag, package metadata, and local test/build commands.
What is the first code-to-artifact mapping in your repository that would benefit from an advisory check?
Top comments (0)