Push activity

Every push and merge, with the guard's answer

Push activity records each decision the push guard makes: who pushed or merged, the agent if one acted for them, which refs moved, and what the guard said. Agents' MCP sessions and writes are kept beside it.

Decisions

Allowed, denied, or the guard out of reach

Every push over HTTP or SSH, every merge, every tag a release makes, and every branch created, renamed or deleted in the web app is recorded with the refs it moved: old and new commit, new, deleted or forced. Then the decision: allowed, denied with the message the pusher saw, or unavailable, when the guard couldn't be reached and the push was refused. Its cause is recorded too, and never shown to the pusher. The agent and its person are named apart, so an agent's push is never taken for its person's own.

acme/invoices › Push activity
  • alicepushmain: 1a2b3c4 → 9c1d22aallowed
  • claude-code agent, for alicemergemain: 9c1d22a → 7e4f0b1main is a protected branch: agents can't update it (claude-code, acting for alice).denied
  • claude-code agent, for alicepushagent/export: 2b5c8e0 → 7e4f0b1forceallowed
  • bobpushrelease/next: new → 3d8e1f5the push guard couldn't be reached, push rejectedunavailable

Evaluate mode

What a ruleset would have refused

A ruleset in evaluate mode decides each push and merge but never refuses. What it would have refused is recorded on the push or merge itself, which went through, with the refusal it would have made. The ruleset's Insights read the same records, by its id, so renaming it keeps them.

acme/invoices › Push activity
bobmain: 9c1d22a0 → 3d8e1f55allowed

evaluateRuleset Signed main would have refused this (main): main requires signed commits: 3d8e1f55a0c2 isn't signed by a key registered to a Branchscope user.

Agents over MCP

Every session, and every write an agent tried

The Agents (MCP) tab lists each MCP session starting, and every write an agent called: opening, merging or closing a change, commenting, posting a status. Each names the agent, its person and the repository, with the first line of the answer and ok, refused or error. Reads aren't logged. A session is shown to the agent's person and site administrators; a write to anyone who can read its repository.

Push activity › Agents (MCP)
  • claude-code agent, for alice, via MCPconnectedok
  • claude-code agent, for alice, via MCPopen_change · acme/invoicesOpened #12 Export invoices as CSV (open; agent/export → main). The review is queued; get_review shows it when it's done.ok
  • claude-code agent, for alice, via MCPmerge_change · acme/invoicesmain is a protected branch: agents can't update it (claude-code, acting for alice).refused

Where to look

Per repository, per branch, or everything you can read

Each repository has an Activity tab, and a branch's menu opens only the pushes that moved it. Push activity in the sidebar covers every repository you can read; signed in, it shows yours: your own pushes and merges, and everything in your repositories. A repository's activity is for anyone who can read the repository, and no one else.

acme/invoices › Activity

Branchmain

alicemain: 1a2b3c4 → 9c1d22aallowed

Push activity

PushesAgents (MCP)

Pushes and merges by you, and in your repositories, with the push guard's decision. When the guard can't be reached, the push is rejected and the cause goes only to the git service's log.

API and webhooks

Read it from your own tools

GET /v1/activity and /v1/activity/agents list newest first, filtered by repo, actor, agent, since and until, and pushes by ref too; the SDK has them as activity.list and activity.listAgents. A repository's webhooks get each decision as push.checked, and each write over MCP as agent.action. Entries stay as long as the repository: they move with it when it's transferred, and go when it's deleted.

~
$ curl -H "Authorization: Bearer $BRANCHSCOPE_TOKEN" "https://api.branchscope.example/v1/activity?repo=acme/invoices&ref=main&agent=claude-code"
{
  "data": [
    { "repo": "acme/invoices", "source": "merge", "decision": "denied",
      "message": "main is a protected branch: agents can't update it (claude-code, acting for alice).\nPush another branch and open a change; a person merges it.",
      "refs": [{ "old": "9c1d22a0e4b7c3f1a8d2e6b9c0f4a7d1e3b5c8f2",
                 "new": "7e4f0b12c6a9d3e8f1b4a7c0d2e5f8a1b3c6d9e0", "ref": "refs/heads/main" }],
      "pusher": "alice", "agent": "claude-code", "evaluations": [] }
  ],
  "nextCursor": null
}

See what the guard decided

Open a repository's Activity, or Push activity in the sidebar, and every push and merge is there, with who made it and why it went through or didn't.