A language-agnostic constraint harness for any codebase — rules scoped repo-wide, or to a single service.
An HCR (Harness Constraint Record) is a single, versioned, machine-checkable
rule about your codebase. jigctl is the reference implementation CLI that reads
and validates HCRs stored under a repo's .hcr/ directory, configured by jig.toml.
Here is a complete HCR:
---
id: HCR-0001
title: Static lint check must pass before merge
scope: repo
regulates: maintainability
summary: Every changed package must pass the linter with zero warnings before a pull request can merge.
state: enforced
enforced_by:
- kind: command
run: "make lint"
timeout_secs: 120
severity: blocking
cadence: [on-change, ci]
---
Run `make lint` against any package you touch before opening a pull request.
Zero warnings are allowed — fix the code rather than suppressing the rule.Build the CLI from source inside a repository checkout. There are no published releases yet.
go build -o jigctl ./cmd/jigctlValidate your repo's records for well-formedness:
./jigctl validate .jigctl run provides a JSON contract via --format=json for tooling integration.
- Schema: Validates against
schema/run-output-v1.schema.json. - Versioning: The
schema_versionfield guarantees compatibility. Additive changes (new fields) are non-breaking; consumers should ignore unknown fields. - Channel Contract: A completed run always emits valid JSON on
stdout(even with 0 records). An invocation failure (e.g. bad format, an unknown--cadencevalue, or an empty--cadence=) or operational crash emits an emptystdout, writes the error tostderr, and exits with code2. - Execution & Cadence: The
--cadenceflag filters which bindings run. It accepts a comma-separated subset ofon-change,ci,scheduled,production, or the literalall. When--cadenceis not supplied, the default ison-change,ci. - Strict Mode: The
--strictflag fails the run (exit code1) on author-causedexpected-uncheckedomissions (e.g. bindings excluded because they lack the requested cadence). It does not gate bindings the invoker explicitly deselected via the--cadenceflag. - Context Budget: The
--only-failuresflag reduces payload size for consumers with constrained context budgets. The JSON contract carries each record's Markdown guidancebody. On a fully passing run, this makes the payload expensive: this repository emits ~35,406 bytes of JSON, of which ~15,110 bytes (43%) is unactionablebodyguidance attached to records that passed. The--only-failuresflag drops records that do not require action; the same passing run emits just 458 bytes, a 99% reduction.- The flag is opt-in and defaults to off. Default output is unchanged.
- It requires
--format=json. Using it with--format=human,--format=plain, or with no format at all is an invocation failure: emptystdout,jigctl: --only-failures requires --format=jsononstderr, and exit code2. - It filters the
records[]array to only those whose projection is actionable:violation,operational,invalid, orblocked-unchecked. Records projectingpassorexpected-unchecked(including bindings deselected via--cadence) are dropped entirely fromrecords[]. - The
summary.bindings_by_projectionstill counts expected-unchecked bindings without naming whether they were invoker-deselected or author-excluded. A consumer needing the deselected-vs-excluded distinction must read the unfiltered JSON (without--only-failures). - Filtering is record-level and all-or-nothing. A kept record retains all of its
bindings[], including any that individually passed. - The
summary,exit_code, anddiagnosticsfields are always computed over the entire run and are never affected by the filter. A consumer still learns how many records ran and how many passed from a document that carries none of them. - When nothing is actionable,
recordsis[]— an empty array, nevernull. - The filtered document validates against the unchanged
schema/run-output-v1.schema.json.schema_versionstays1.
Example:
./jigctl run . --format=json{
"schema_version": 1,
"command": "run",
"root": "/path/to/repo",
"exit_code": 0,
"diagnostics": [],
"summary": {
"records": 1,
"bindings": 1,
"bindings_by_projection": {
"pass": 1,
"violation": 0,
"expected-unchecked": 0,
"blocked-unchecked": 0,
"operational": 0,
"invalid": 0
},
"unwaived_findings": 0,
"files_with_unwaived_findings": 0
},
"records": []
}Example with --only-failures:
jigctl run . --allow-exec --format=json --only-failuresThis repo contains the HCR schema and the jigctl CLI.
Licensed under MIT.