Gate proposed change
Contract
| Field | Bound contract |
|---|---|
| Trigger | A proposed commit, merge, or auto-merge must clear a machine boundary before it can land. |
| Authority | Read-only. No file, VCS, credential, paid, published, deployed, or remote mutation. The gate evaluates policy and returns a verdict; it never merges, commits, pushes, or writes. |
| Side effect | Chat output only: an allow or deny verdict with the matched paths and the trigger. The gate itself performs no merge. |
| Done | Denylist is evaluated before file count before allowlist with dot-aware matching under strict version-1 config validation, and a denied change names the exact matched paths. |
Not for
- Landing PRs: use gate-and-merge.
- Merging, committing, or pushing, this gate evaluates policy and returns a verdict only.
- Source or remote mutation: this skill is read-only.
Inputs
gate config: a YAML file withversion: 1, a requireddenylistarray of glob strings, an optionalmaxFilesnumber, and an optionalautoMergeAllowlistarray of glob strings. Must be supplied.action: one ofcommit,merge,auto-merge. Must be supplied; any other value is invalid.paths: the list of changed file paths in the proposed change. Must be supplied.
Procedure
- Validate the action is one of
commit,merge,auto-merge. Stop with an invalid-action error on any other value. Done when: the action is validated or an invalid-action error is returned. - Load and strictly validate the gate config:
- Parse the YAML.
- Require
versionto equal1; otherwise reject. - Require
denylistto be an array of strings; otherwise reject. - If
maxFilesis present, require it to be a finite number; otherwise reject. - If
autoMergeAllowlistis present, require it to be an array of strings; otherwise reject. - Stop with a config-validation error on any failure; do not evaluate. Done when: the config is validated or a config-validation error is returned.
- Evaluate the changed paths in this exact order, returning on the first hit:
- Denylist first. For each path, test it against every
denylistglob with dot-aware matching (a*segment matches names beginning with.). If one or more paths match, deny with triggerdenylist, listing the exact matched paths. - File count. If
maxFilesis set and the number of paths exceeds it, deny with triggerfile-count, listing all paths. - Auto-merge allowlist. Only when action is
auto-merge: for each path, require it to match at least oneautoMergeAllowlistglob with dot-aware matching. If any path matches none, deny with triggernot-allowlisted, listing the exact non-matching paths. Done when: the first matching condition returns a deny, or all conditions pass.
- Denylist first. For each path, test it against every
- If no condition denied, allow with trigger
ok. Done when: an allow or deny verdict is returned.
Failure and recovery
- Invalid action: stop; return the invalid value and the accepted set. No evaluation runs.
- Config not found or unparseable YAML: stop; return the file and parse error. No evaluation runs.
- Config schema invalid (wrong version, non-string-array denylist, non-number
maxFiles, non-string-arrayautoMergeAllowlist): stop; return the field and the constraint. No evaluation runs. - Empty paths list: no denylist hit,
0 <= maxFiles, and zero paths trivially satisfy the allowlist; result is allow with triggerok. Do not invent paths. - Partial-result rule: evaluation is all-or-nothing per condition; a deny on an earlier condition short-circuits all later conditions. The gate never mutates state, so there is no rollback; a failed validation leaves nothing to undo.
- The blocked/non-converged result is a deny verdict or a validation error, never a silent allow.
Output
A verdict record: allowed (boolean), trigger (one of ok, denylist, file-count, not-allowlisted), reason (human-readable), and matchedPaths (the exact paths responsible; empty when ok); the gate emits this record only; it performs no merge, commit, or write.