- Fail-closed path no longer needs jq: the ask JSON is a printf literal,
and a host without jq asks instead of staying silent.
- A tool_name that is not a non-empty string asks (was: no opinion).
- Gate workflow_run_trigger, tag_create, release_create, and
file_write_branch when it lands on main/master, has no branch, or
empties a file (same effect as pr_merge / file_delete).
- Header claim narrowed: gitea-mcp spellings on any server name, not
other servers' spellings of the same operation.
- Tests run the hook as hooks.json does (bash <path>), assert exit 0 on
every case, and cover null/missing/wrong-type tool_name, last-segment
verb parsing and a PATH without jq. 13 new cases were red first.
Refs mathias/infra#508
Bump-Type: minor
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gitea-mcp authenticates by PAT pass-through, so an agent holds the
caller's full PAT scope, and repo_delete's confirm field is filled in by
the model. The infra-mcp README said client-side deny lists covered
destructive verbs; on 2026-10-01 none existed in any settings file.
PreToolUse hook on mcp__.*: repo_delete, file_delete, branch_delete,
pr_merge, tbd_ship, repo_update and repo_mirror_push get "ask". Matched
on the verb, not the server name, so the connector namespace or a
renamed registration cannot bypass it. Never emits allow; malformed
input fails closed.
Scope limit: MCP calls only. The Gitea REST API via Bash with the PAT
in env is not covered (recorded in infra ADR-0027).
Refs mathias/infra#508
Bump-Type: minor
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>