README
¶
Vigil
Vigil is a command-line tool that checks project automation before it changes a repository. It helps people and coding agents see what a command will do, decide whether it is allowed, run it, and review the result.
In plain terms, Vigil helps answer:
- What will run?
- Why will it run?
- What is it allowed to access or change?
- What result did it produce?
- Did a command change the repository when it said it would not?
Vigil does not replace CI, deployment tooling, a secrets manager, or an operating-system sandbox. It is a local safety and evidence layer around the commands you already run.
- Official homepage: paycaltech.com/vigil
- Command help: paycaltech.com/vigil/help
- Source repository: github.com/PayCal-Technologies/vigil-public
- Created by PayCal Technologies
v0.2.0-beta.1is the current public prerelease candidate.v0.1.0remains the legacy bootstrap release and does not include every command, help page, completion target, or plugin/distribution workflow documented here.
What Vigil Includes
The standalone vigil binary includes:
- versioned JSON config files and migration commands;
- searchable command help, shell completions, and manpages;
- direct command execution by default, with shell execution only when requested;
- timeouts, cancellation, signal handling, and clear run states;
- detection when a read-only command changes tracked repository files;
- reviewed plans that stop running if the inputs changed after approval;
- machine-readable output, including JSON, JSONL, JUnit, SARIF, and GitHub annotations;
- setup, Git hook, support bundle, and local workflow commands;
- built-in packs that work without checking out the Vigil source code;
- repository boundary checks for packs and configuration;
- executable plugins that are pinned by digest and require explicit capability approval.
Repository Snapshot
| Signal | Value |
|---|---|
| Repository | vigil-public |
| Dependency manifests | go.mod |
| Test paths | Go *_test.go (35) |
| Vigil commands | 87 |
Generated by Vigil Scribe from local repository facts.
Install
Install the current public prerelease with Go:
go install github.com/PayCal-Technologies/vigil-public/cmd/vigil@v0.2.0-beta.1
To try the latest development version:
go install github.com/PayCal-Technologies/vigil-public/cmd/vigil@main
Or build this checkout locally:
go build -trimpath -o bin/vigil ./cmd/vigil
v0.2.0-beta.1 is the current public prerelease candidate. v0.1.0 is an
early bootstrap release with platform binaries, completions, a manpage, and
SHA256SUMS. It came before the newer archive, signing, SBOM, Sigstore,
attestation, Windows cross-build, expanded completion, help, and v1 gate
contract work.
The newer release workflow is designed to publish static macOS, Linux, and
Windows archives for amd64 and arm64. macOS binaries are Developer ID-signed and
notarized before final checksums are created. Each archive includes
README.md, LICENSE, the manpage, and completions for Bash, Zsh, Fish,
PowerShell, Elvish, Nushell, Xonsh, Tcsh, Clink, Yash, and Oil-family shells,
plus the public configuration, output, pack, plan, plugin protocol, index,
publisher, lock, and trust schemas. New release-workflow candidates also include
checksums, an SPDX SBOM, a Sigstore bundle, GitHub build-provenance
attestations, and v1-acceptance-gate.json.
Homebrew packaging automation exists, but it is not listed as an install command
until the project tap has a public, tested formula. Stable release automation
install-tests the generated formula before and after publication, then publishes
the matching formula to the project tap when
HOMEBREW_TAP_TOKEN is configured.
Release Status
v0.2.0-beta.1 is the current public prerelease candidate. GitHub release
immutability is enabled for future releases, but the existing v0.1.0 release
itself is not immutable. The beta source release documents and exercises the new
command surface, help system, expanded completion targets, Windows cross-build
metadata, schemas, and v1 gate contract. Signed archive, checksum, SBOM,
Sigstore, attestation, native-smoke, and Homebrew publication remain tied to the
release environment tag policy and secrets.
v1.0.0 is intentionally blocked until the external and operational acceptance
ledger is complete. In other words, Vigil will not cut a stable v1 release until
the required evidence is present. The stable v1 release gate fails closed and
emits v1-acceptance-gate.json listing the remaining evidence.
To verify a downloaded release produced by the current release workflow:
shasum -a 256 -c SHA256SUMS
gh attestation verify vigil_0.2.0-beta.1_linux_amd64.tar.gz \
--repo PayCal-Technologies/vigil-public
cosign verify-blob SHA256SUMS \
--bundle SHA256SUMS.sigstore.json \
--certificate-identity \
https://github.com/PayCal-Technologies/vigil-public/.github/workflows/release.yml@refs/tags/v0.2.0-beta.1 \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
For v0.1.0, verify only the published legacy checksums:
shasum -a 256 -c SHA256SUMS
Quick Start
This quick start requires v0.2.0-beta.1+ or main. The legacy v0.1.0
release does not include every command shown here.
vigil init
vigil config:validate
vigil --allow-mutation plan --output .vigil/plans/reviewed.json
vigil --allow-mutation apply .vigil/plans/reviewed.json
vigil --allow-mutation sentry
vigil sentry:apply .vigil/plans/sentry-reviewed.json
vigil workflow:local --dry-run
vigil workflow:local
vigil verify --json
Running vigil without a command prints help. In an interactive terminal, it
also offers guided setup.
Common compatibility aliases remain available:
| Beginner command | What it maps to |
|---|---|
vigil init |
vigil setup:wizard |
vigil list |
vigil commands |
vigil plan |
digest-bound configured workflow plan |
vigil apply |
execute an unchanged reviewed plan |
vigil sentry |
interactive Sentry Mode plan review |
vigil extensions:list |
list loaded packs |
vigil extensions:doctor |
validate loaded packs |
vigil plugins:list |
list locked executable plugins |
vigil plugins:doctor |
verify plugin identity, trust, and compatibility |
The extensions:* names are kept for compatibility. Packs are declarative
metadata. Plugins are separate executables with their own install and trust
flow.
Usage Examples
Most write commands require --allow-mutation. If a command is only previewing
or validating, it usually does not need that approval flag.
Beginner Examples
If I want to see what Vigil can do, I must run:
vigil
vigil list
If I want to set up Vigil for a project, I must run:
vigil init
If I want to check whether my config file is valid, I must run:
vigil config:validate
If I want to see what local workflow would run without changing anything, I must run:
vigil workflow:local --dry-run
If I want to run the configured local workflow, I must run:
vigil workflow:local
If I want to make a local support bundle for troubleshooting, I must run:
vigil support:bundle --dry-run
vigil --allow-mutation support:bundle
If I want to check whether Git hooks are ready, I must run:
vigil hooks:doctor
Moderate Examples
If I want to review a plan before executing it, I must run:
vigil --allow-mutation plan --output .vigil/plans/reviewed.json
vigil --allow-mutation apply .vigil/plans/reviewed.json
If I want an interactive Sentry Mode review before running a workflow, I must run:
vigil --allow-mutation sentry
vigil sentry:apply .vigil/plans/sentry-reviewed.json
If I want to save run logs and evidence for a workflow, I must run:
vigil --allow-mutation workflow:local --artifacts
If I want to run only checks with a specific tag, I must run:
vigil workflow:local --dry-run --tag pre-push
vigil workflow:local --tag pre-push
If I want to migrate an older config file, I must run:
vigil config:migrate
vigil --allow-mutation config:migrate --write
If I want to install Vigil Git hooks without overwriting existing hooks, I must run:
vigil hooks:install --dry-run
vigil --allow-mutation hooks:install --chain
If I want live progress while creating a support bundle, I must run:
vigil --allow-mutation support:bundle --stream=text
If I want machine-readable command details for automation, I must run:
vigil explain workflow:local --json
vigil list --json
Expert Examples
If I want JSONL progress events for a long local workflow, I must run:
vigil workflow:local --format=jsonl
If I want an agent-readable safety summary before an AI agent works, I must run:
vigil sentry:state
vigil sentry:state --json
If I want bounded parallel execution for eligible gates, I must run:
vigil workflow:local --dry-run --jobs=4
vigil workflow:local --jobs=4
If I want to test a candidate config file without replacing the default one, I must run:
vigil --config ./candidate.vigil.config.json config:validate --json
vigil --config ./candidate.vigil.config.json workflow:local --dry-run
If I want to inspect and verify installed packs, I must run:
vigil extensions:list --json
vigil extensions:doctor --json
If I want to install a local executable plugin, I must run:
vigil plugins:conformance --file ./vigil-plugin-example --json
vigil --allow-mutation plugins:install \
--file ./vigil-plugin-example \
--approve filesystem:read
vigil plugins:doctor --json
If I want to trust a publisher and install a plugin from a signed index, I must run:
vigil --allow-mutation plugins:trust-publisher \
--key ./publisher.pub \
--name "Example Publisher"
vigil plugins:index:verify --index https://example.test/vigil/index-v1.json
vigil --allow-mutation plugins:install \
--index https://example.test/vigil/index-v1.json \
--id example \
--version 1.2.3 \
--approve filesystem:read \
--stream=jsonl
If I want to make a fuller local support bundle for an internal review, I must run:
vigil --allow-mutation support:bundle \
--include-config \
--include-git-status \
--stream=text
If I want to verify a release archive from the newer release workflow, I must run:
shasum -a 256 -c SHA256SUMS
gh attestation verify vigil_0.2.0-beta.1_linux_amd64.tar.gz \
--repo PayCal-Technologies/vigil-public
cosign verify-blob SHA256SUMS \
--bundle SHA256SUMS.sigstore.json \
--certificate-identity \
https://github.com/PayCal-Technologies/vigil-public/.github/workflows/release.yml@refs/tags/v0.2.0-beta.1 \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
How Commands Run
A gate is one command that Vigil can run. In schema 3, gates run an executable and its arguments directly:
{
"name": "go test",
"command": "go",
"args": ["test", "./..."],
"read_only": true,
"tags": ["test", "pre-push"],
"timeout": "5m"
}
If a gate needs shell syntax such as pipes or redirects, opt in with
"shell": true:
{
"name": "report",
"command": "go test ./... | tee test.log",
"shell": true,
"read_only": false,
"timeout": "10m"
}
Gates can depend on other gates and can opt into bounded parallel execution:
{
"name": "integration tests",
"command": "go",
"args": ["test", "./integration/..."],
"read_only": true,
"depends_on": ["generated-code check"],
"parallel_group": "tests",
"continue_on_error": true,
"required": true,
"retry": {"max_attempts": 2, "delay": "1s", "on": ["failed"]},
"cwd": "services/api",
"environment": {"CI": "true"},
"artifacts": [
{"path": "reports/junit.xml", "kind": "junit", "media_type": "application/xml"}
],
"tags": ["network", "pre-push"],
"timeout": "5m"
}
Ungrouped gates run one after another. Only explicit read-only groups run at the
same time, bounded by --jobs. Tag filtering also includes required
dependencies. See the workflow graph contract.
Vigil streams command output while it runs and keeps bounded structured summaries. Each process has a default or per-gate timeout. Ctrl+C and SIGTERM cancel the active process group.
Saved local evidence is opt-in because writing logs changes the repository:
vigil --allow-mutation workflow:local --artifacts
The default ignored directory is .vigil/runs/<run-id>/. It contains a
mode-0600 manifest.json, digest-bearing plan.json, result.json, and
separate mode-0600 stdout/stderr logs per gate. The manifest follows
schemas/vigil-run-artifact-manifest-v1.schema.json and records the run ID,
standard file names, and log budgets. Each stream log is capped at 64 MiB and
ends with [truncated] if that bound is reached. The complete run shares a 512
MiB log budget; Vigil fails closed before opening a stream when it cannot
reserve a truncation marker. Structured gate results expose summary and log
truncation flags. A custom
in-repository artifact root must be Git-ignored; paths outside the repository
are allowed explicitly. Symlink redirection and paths inside Git metadata are
rejected.
To separate review from execution:
vigil --allow-mutation plan --output .vigil/plans/reviewed.json
vigil --allow-mutation apply .vigil/plans/reviewed.json
apply refuses to run if the config, repository HEAD, Git-visible workspace,
active registry, packs, or Vigil executable changed after review. See
reviewed plans.
Sentry Mode is the interactive review path:
vigil --allow-mutation sentry
vigil sentry:apply .vigil/plans/sentry-reviewed.json
sentry opens a terminal review of the planned gates. Read-only gates are shown
as safe to run. Mutating gates start on hold, and the reviewer can approve them
one by one before the reviewed plan is written. sentry:apply then checks that
the plan is still fresh and that every mutating gate has a Sentry review
approval. This gives teams a narrower alternative to approving every mutating
gate with a broad execution flag.
Execution states are:
ok
failed
skipped
cancelled
timed_out
mutation_detected
blocked
tool_missing
internal_error
Safety Model
read_only means the command is expected not to alter the Git-visible
repository workspace. Vigil compares repository fingerprints before and after
the command and reports mutation_detected when they differ.
It does not provide operating-system sandboxing. A command may still touch the network, databases, user caches, ignored files, files outside the repository, credential stores, or external services. Inspect command capabilities with:
vigil explain workflow:local --json
vigil list --json
Every command declares its access level, capabilities, implementation binding, host API, timeout, network behavior, required tools, stability, and output formats in one registry. Unknown or incomplete executable command definitions fail closed.
Commands that can write require explicit approval at the CLI boundary:
vigil github:init-ci
vigil --allow-mutation github:init-ci --write
vigil support:bundle --dry-run
vigil --allow-mutation support:bundle
Access values are:
| Access | Help | Meaning |
|---|---|---|
read |
r |
Does not declare repository or external changes. |
write |
w |
Writes unless an explicit read-only flag is active. |
conditional-write |
r/w |
Read-only by default; specific flags turn writing on. |
Configuration
Vigil looks upward from the current directory for vigil.config.json. Use
--config PATH to choose a different file.
vigil config:schema
vigil config:template --profile=go-tool
vigil config:init --profile=go-tool --write
vigil --config ./candidate.vigil.config.json config:validate --json
vigil config:migrate
vigil --allow-mutation config:migrate --write
The current config schema is 3. Migration keeps unknown top-level and nested
fields, refuses to downgrade future schemas, converts older command strings to
argv where safe, and marks shell-dependent older gates explicitly.
See config schema and compatibility policy.
Packs
Vigil uses three extension concepts:
- Built-in module: Go code compiled into Vigil.
- Pack: metadata that groups and governs built-in or future declarative commands.
- Plugin: a separately installed executable using subprocess protocol
1, a digest-bound repository lock, and local capability trust.
Official pack manifests are embedded in the binary. If the same thing is defined in more than one place, this precedence order applies:
core < embedded official < user < repository
User packs live under the platform config directory at vigil/packs, or at
VIGIL_USER_PACK_ROOT. Repository packs use the configured manifest_root.
extensions:doctor reports overrides. Vigil also enforces disabled IDs, kind
policy, privacy policy, duplicate IDs or commands, traversal checks, and symlink
escape checks.
vigil extensions:list --json
vigil extensions:doctor --json
Official packs cover accessibility, dependency checks, deployment verification, file iteration, GitHub CI generation, release policy, repository health, Scribe, security adapters, and test adapters.
Plugins
Plugins can be installed from local executables that you choose explicitly:
vigil --allow-mutation plugins:install \
--file ./vigil-plugin-example \
--approve filesystem:read
vigil plugins:list --json
vigil plugins:doctor --json
vigil plugins:conformance --file ./vigil-plugin-example --json
vigil --allow-mutation plugins:update --file ./vigil-plugin-example --approve-all
vigil --allow-mutation plugins:remove example
They can also be installed from an exact release in a locally trusted, threshold-signed index:
vigil --allow-mutation plugins:trust-publisher \
--key ./publisher.pub \
--name "Example Publisher"
vigil plugins:index:verify --index https://example.test/vigil/index-v1.json
vigil --allow-mutation plugins:install \
--index https://example.test/vigil/index-v1.json \
--id example \
--version 1.2.3 \
--approve filesystem:read
The repository lock pins the plugin version, executable digest, metadata digest, capabilities, commands, protocol, host API, acquisition type, signed index digest, signer IDs, and signature threshold. Local trust records capability approval, digest revocation, and publisher-key revocation. Only plugins that match policy, version, compatibility, and command-collision checks enter the typed registry.
Plugin subprocesses receive a cleared minimal environment, bounded JSON I/O, timeouts, and cancellation. Capability approval is not an operating-system sandbox: an approved executable still runs as the current OS user. Repositories can deny local plugins, require signed acquisition, allow specific IDs or publishers, and deny capabilities. See plugin model.
Plugin authors can run repeatable handshake checks without installing the
plugin, then exercise every declared command in a disposable repository with
--allow-mutation plugins:conformance --file PATH --execute. The
language-neutral reference fixture is checked on Linux and macOS.
Hooks
Vigil asks Git for the active hooks directory, including
core.hooksPath, worktrees, and .git files.
vigil hooks:doctor --json
vigil hooks:install --dry-run
vigil --allow-mutation hooks:install
vigil --allow-mutation hooks:install --chain
vigil hooks:uninstall --dry-run
vigil --allow-mutation hooks:uninstall
Existing hooks are never overwritten by default. --chain preserves the exact
existing hook and hooks:uninstall restores it.
Support Bundles
Support bundles are local-only and never upload automatically.
vigil support:bundle --dry-run
vigil --allow-mutation support:bundle
vigil --allow-mutation support:bundle --include-config --include-git-status
By default, bundles omit the full config, Git status, environment variables,
and collected secrets. They redact absolute paths and common secret patterns in
diagnostics, include a redaction report, use a content-derived ID, and are
written atomically with mode 0600.
Automation Contract
Exit codes are:
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Check failed |
| 2 | Usage or configuration error |
| 3 | Policy blocked execution |
| 4 | Required dependency missing |
| 5 | Timeout or cancellation |
| 6 | Mutation violation |
| 7 | Internal Vigil failure |
--json responses use common envelope schema 1. Workflows and aggregate
checks also support JSONL, JUnit, and GitHub annotations. File-oriented finding
checks support SARIF 2.1.0. See machine output
and the checked-in schemas.
Documentation
- Product contract
- Roadmap and release gates
- v1 contract freeze
- v1 acceptance matrix
- Support policy
- Architecture
- Workflow graph
- Mutation model
- Reviewed plans
- Threat model
- Pack model
- Plugin model
- Plugin authoring
- Plugin index publishing
- Config schema
- Exit codes
- Machine output
- Performance methodology
- Upgrade and rollback
- Troubleshooting
- RFC process
- v1 independent review briefs
- Deprecation policy
- Release process
- Release channels
- GitHub release readiness
- Changelog
Security reports must follow SECURITY.md.
License
Vigil is open source under the 0BSD license. See LICENSE.
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
vigil
command
|
|
|
vigil-plugin-publisher
command
|
|
|
vigil-release-archive
command
|
|
|
internal
|
|