forgejo-mcp/openspec/specs/branch-protection/spec.md
Christoph Görn 88cd866d0f
docs: 📝 archive branch-protection-management + co-locate demo (uc6)
Completes the OpenSpec lifecycle for the implementation merged in #196:
- openspec archive branch-protection-management -> live spec
  openspec/specs/branch-protection/spec.md (7 requirements).
- Change moved to changes/archive/2026-06-02-branch-protection-management/.
- Showboat demo moved next to the live spec
  (openspec/specs/branch-protection/branch-protection.demo.md); spec link fixed.

openspec validate --all --strict: 17/17. check-demos: 0 errors.

Closes forgejo-mcp-uc6.
2026-06-02 16:37:06 +02:00

5.9 KiB

branch-protection Specification

Purpose

TBD - created by archiving change branch-protection-management. Update Purpose after archive.

Requirements

Requirement: List branch protection rules (bounded)

The server SHALL provide a list_branch_protections tool that returns the branch protection rules of a repository given owner and repo. The tool SHALL expose caller-controlled page and limit bounds and the response SHALL be resumable by echoing the page that was returned, satisfying docs/design/output-bounding.md.

Scenario: List returns the repository's rules

  • WHEN list_branch_protections is called with a valid owner and repo
  • THEN the result SHALL contain the repository's branch protection rules as returned by GET /repos/{owner}/{repo}/branch_protections
  • AND each rule SHALL include at least its rule_name, branch_name, enable_status_check, status_check_contexts, and required_approvals

Scenario: Caller bounds the page size

  • WHEN list_branch_protections is called with limit set to N
  • THEN the request to Forgejo SHALL carry a page size of N
  • AND the response SHALL indicate the page returned so the caller can request the next page

Requirement: Get a branch protection rule

The server SHALL provide a get_branch_protection tool that returns a single rule given owner, repo, and the rule identifier (rule).

Scenario: Existing rule is returned

  • WHEN get_branch_protection is called with an owner, repo, and a rule that exists
  • THEN the result SHALL contain that rule's full protection state

Scenario: Missing rule yields an error

  • WHEN get_branch_protection is called with a rule that does not exist
  • THEN the tool SHALL return an error result rather than an empty success

Requirement: Create a branch protection rule

The server SHALL provide a create_branch_protection tool that creates a rule via POST /repos/{owner}/{repo}/branch_protections. The tool SHALL require owner, repo, and branch_name; rule_name SHALL be optional (Forgejo defaults it to branch_name). The tool SHALL round-trip status_check_contexts exactly.

Scenario: Create enforces status checks

  • WHEN create_branch_protection is called with enable_status_check true and status_check_contexts set to a list of contexts
  • THEN the request body sent to Forgejo SHALL contain enable_status_check: true and the exact status_check_contexts list
  • AND the result SHALL reflect the created rule with those contexts

Scenario: Create requires a branch name

  • WHEN create_branch_protection is called without branch_name
  • THEN the tool SHALL return an error result and SHALL NOT call Forgejo

Requirement: Edit a branch protection rule with PATCH semantics

The server SHALL provide an edit_branch_protection tool that updates a rule via PATCH /repos/{owner}/{repo}/branch_protections/{rule}. The tool SHALL only send fields the caller explicitly provides; fields the caller omits SHALL be left unchanged on the server.

Scenario: Editing one field leaves others untouched

  • WHEN edit_branch_protection is called with only required_approvals set to 2
  • THEN the request body sent to Forgejo SHALL set required_approvals to 2
  • AND the other protection fields the caller did not pass SHALL be sent as null (leave-unchanged), never as a concrete value such as false that would silently relax protection

Scenario: Editing status checks round-trips the contexts

  • WHEN edit_branch_protection is called with status_check_contexts set to a list
  • THEN the request body SHALL contain that exact list

Requirement: Delete a branch protection rule

The server SHALL provide a delete_branch_protection tool that removes a rule via DELETE /repos/{owner}/{repo}/branch_protections/{rule} and reports success.

Scenario: Existing rule is deleted

  • WHEN delete_branch_protection is called for a rule that exists
  • THEN Forgejo SHALL receive a delete request for that rule
  • AND the tool SHALL return a success result confirming removal

Requirement: Branch protections collection resource (bounded)

The server SHALL expose a resource-template forgejo://repo/{owner}/{repo}/branch_protections that returns the repository's protection rules as a read-only JSON document. The embedded list SHALL be bounded at EmbeddedListCap using the shared resource.Bounded helper, and when truncated SHALL carry the truncation sentinel and name list_branch_protections as the tool to fetch the remainder.

Scenario: Collection resource returns bounded rules

  • WHEN the resource forgejo://repo/{owner}/{repo}/branch_protections is read for a repo with rules
  • THEN the payload SHALL list the rules up to EmbeddedListCap
  • AND when more than EmbeddedListCap rules exist, the payload SHALL set a truncation indicator naming list_branch_protections

Scenario: Unknown repository maps to a not-found resource error

  • WHEN the collection resource is read for a repository that does not exist
  • THEN the handler SHALL return a resource error mapped from the Forgejo 404 response

Requirement: Single branch protection resource

The server SHALL expose a resource-template forgejo://repo/{owner}/{repo}/branch_protection/{rule} that returns one rule's protection state as a read-only JSON document.

Scenario: Single rule resource returns its state

  • WHEN the resource forgejo://repo/{owner}/{repo}/branch_protection/{rule} is read for an existing rule
  • THEN the payload SHALL contain that rule's protection state including status_check_contexts and required_approvals

Scenario: Malformed URI maps to an invalid-params error

  • WHEN a forgejo://repo/... branch-protection URI is read that does not match the template
  • THEN the handler SHALL return a resource error with the invalid-params code