Winch Labs

Extending

The rule manifest

A custom rule is two files sharing a basename:

.garboard/rules/
  instance_size.json    # manifest — identity, severity, the docs line
  instance_size.wasm    # module   — the check itself

The manifest

{
  "id": "instance_size",
  "severity": "warn",
  "title": "Oversized instance class",
  "docs": "https://acme.dev/rules/instance-size",
  "description": "Finance signed off on sizes up to db.m5.4xlarge."
}
Field Required Rules
id yes [a-z0-9_.-], 3–64 characters, must not start with custom. — the prefix is added for you
severity yes critical, warn or info — the gate’s existing tiers, no new ones
title yes Fallback title when a finding omits one
docs yes An http(s) URL — the line a reader follows from the pull request comment
description no Free text for the settings UI

Unknown fields are an error. A typo’d "severty" that silently defaulted would be a rule running at the wrong tier, and finding that out from a production pull request is the wrong time.

The manifest owns identity, not the module

Severity and rule id are read from the manifest and stamped onto every finding the module returns.

Two consequences, both deliberate:

  • A module cannot escalate its own severity between uploads. The tier is a property of the rule as configured, reviewable in a diff, not something the code decides at run time.
  • A module cannot report under a built-in’s id. Findings always appear as custom.<id> — for the manifest above, custom.instance_size.

This is why docs is required rather than optional. A custom finding appears in someone’s pull request alongside built-in ones, and the reader deserves somewhere to go that explains your rule. A rule that cannot explain itself is noise with your name on it.

Where the files live

Committed to .garboard/rules/ in the repository they apply to. garboard gate picks them up automatically — --rules defaults to <path>/.garboard/rules and is skipped when that directory is absent, so a repository without custom rules needs no flag.

Committing them is what keeps CI offline: the rule travels with the code it checks.