Diffinery

codician/diffinerypublic

Open-source, agent-first GitHub and GitHub Actions alternative that runs on your own Cloudflare account: git hosting, pull requests, code review and drop-in GitHub Actions YAML on Workers, Durable Objects, R2 and Containers.

Docs: OpenRouter everywhere providers are listed, OIDC differences, per-repository job caps (#87)

#79 and #82 updated their own pages; this catches the rest. OIDC's
Differences from GitHub table still said sub never varied, the AWS
wildcard example now also matches pull_request and environment subjects,
the runners page didn't mention the 20-job cap, the dispatch endpoints
didn't mention the 429 at 500 unfinished runs, and the notifications,
audit log and agents overview listed two providers.


Claude-Session: https://claude.ai/code/session_016q5wwBFck8JHq14gHUM2CL

Co-authored-by: Claude <noreply@anthropic.com>
Canberk Demirci authored · GitHub committed signed1 parent 3b4bcbacommit ecf0293e66d75d9c0f56fce7ffda292911a64a6bBrowse files
6 files changed+11−12
Files (6)
modifiedapps/diffinery/docs/accounts/notifications.md+1−1View file
@@ -233,7 +233,7 @@
233233 | `token_created` | `[Diffinery] A personal access token was added to your account` (or `A token was created for the agent review-bot`) | Security | `security_alert` | A token was created for you or your agent, from the web UI, CLI or API |
234234 | `token_expiring` | `[Diffinery] Your token "ci-deploy" expires on <date>` | Security | `security_alert` | About 7 days before a token expires (once per token, for tokens that last more than 8 days) |
235235 | `agent_created` | `[Diffinery] A new agent was added: review-bot` | Security | `security_alert` | You created an agent |
236-| `model_key_added` | `[Diffinery] Your Anthropic API key was added to Diffinery` (or `OpenAI`) | Security | `security_alert` | You saved a model API key for [agent tasks](/docs/agents/tasks) |
236+| `model_key_added` | `[Diffinery] Your Anthropic API key was added to Diffinery` (or `OpenAI`, `OpenRouter`) | Security | `security_alert` | You saved a model API key for [agent tasks](/docs/agents/tasks) |
237237 | `push_blocked` | `[acme/website] Your push was blocked: possible secrets` | Security | `security_alert` | Push protection rejected your `git push`, or a commit made in the web editor, through the REST API or over MCP (subject `Your commit was blocked`). For an agent, its owner is told. |
238238 | `push_bypassed` | `[acme/website] Push protection was bypassed` | Security | `security_alert` | A repository admin pushed past push protection, or committed a flagged file through the commits API with `allow_secrets`; sent to that admin and the repository's admins |
239239 | `account_status` | `[Diffinery] Your account was disabled` or `Your account was enabled` | Security | `account` | A site administrator disabled your account, or enabled it again |
modifiedapps/diffinery/docs/actions/oidc.md+5−6View file
@@ -122,7 +122,7 @@
122122
123123 The token header is `{"alg": "ES256", "typ": "JWT", "kid": "..."}`.
124124
125-The `ref` (and therefore `sub`) for each event:
125+The `ref` for each event. It is also the end of `sub`, except in a job with `environment:` and in a `pull_request` run:
126126
127127 | Event | `ref` |
128128 |---|---|
@@ -175,7 +175,7 @@
175175 }
176176 ```
177177
178- To allow every branch and tag of the repository, use `"StringLike": { "diffinery.com:sub": "repo:acme/website:*" }` together with the `aud` check. Attach the permissions the workflow needs to the role.
178+ To allow every branch and tag of the repository, use `"StringLike": { "diffinery.com:sub": "repo:acme/website:*" }` together with the `aud` check. That pattern also matches `pull_request` runs and jobs in any environment, so a role that deploys should name one `ref:` or `environment:` subject instead. Attach the permissions the workflow needs to the role.
179179
180180 3. Use it from a workflow:
181181
@@ -350,13 +350,12 @@
350350 |---|---|---|
351351 | Issuer | `https://token.actions.githubusercontent.com` | `https://diffinery.com` |
352352 | Algorithm | RS256 | ES256 |
353-| `sub` | Varies by event (for example `repo:o/r:pull_request`, `repo:o/r:environment:prod`) | Always `repo:<owner>/<repo>:ref:<ref>`; pull requests use `refs/pull/<n>/merge` |
354-| Claims | Many, including `repository_id`, `workflow_ref`, `ref_type`, `environment`, `runner_environment` | Only the claims listed in [Claims](#claims) |
355-| Jobs with `environment:` | `environment` claim, and `sub` is `repo:o/r:environment:<name>` | No `environment` claim; `sub` is unchanged (see [Jobs that use an environment](#jobs-that-use-an-environment)) |
353+| `sub` | `environment:<name>`, `pull_request` or `ref:<ref>` form, and a customizable template | The same three forms; the template can't be customized |
354+| Claims | Many, including `workflow_ref`, `job_workflow_sha`, `runner_environment` | Only the claims listed in [Claims](#claims) |
356355 | `job_workflow_ref` | The reusable workflow's file when the job is in one | Always the run's top-level workflow |
357356 | Token lifetime | About 5 to 10 minutes | 10 minutes |
358357
359-When you port a trust policy from GitHub, change the issuer host (`token.actions.githubusercontent.com` to `diffinery.com`) in provider URLs and condition keys, and rewrite `sub` patterns to the `repo:<owner>/<repo>:ref:<ref>` form.
358+When you port a trust policy from GitHub, change the issuer host (`token.actions.githubusercontent.com` to `diffinery.com`) in provider URLs and condition keys, and keep your `sub` patterns as they are, unless they rely on a customized subject template.
360359
361360 ## Troubleshooting
362361
modifiedapps/diffinery/docs/actions/runners.md+1−1View file
@@ -71,7 +71,7 @@
7171 | Temp directory | `/workspace/_temp` (`RUNNER_TEMP`) |
7272 | Tool cache | `/opt/hostedtoolcache` (`RUNNER_TOOL_CACHE`, `AGENT_TOOLSDIRECTORY`) |
7373 | Locale | `LANG=C.UTF-8`, `LC_ALL=C.UTF-8` |
74-| Concurrency | Up to 100 hosted job containers run at once across diffinery.com |
74+| Concurrency | Up to 100 hosted job containers run at once across diffinery.com, and at most 20 from one repository; its further jobs stay queued until one of its own finishes. See [Limits](/docs/reference/limits) |
7575
7676 ### The Ubuntu 24.04 image
7777
modifiedapps/diffinery/docs/agents/overview.md+1−1View file
@@ -214,7 +214,7 @@
214214
215215 ## Agent tasks, agent review and Today
216216
217-- **[Agent tasks](/docs/agents/tasks)**: on a repository's **Tasks** tab, give one of your agents a goal. Diffinery runs Claude Code, Codex or your own command in a sandbox as that agent, with your own model API key (saved under **Settings → Model access**, and never placed in the sandbox), then pushes a branch and opens a pull request for review.
217+- **[Agent tasks](/docs/agents/tasks)**: on a repository's **Tasks** tab, give one of your agents a goal. Diffinery runs Claude Code or Codex (on their own providers, or via [OpenRouter](/docs/agents/tasks#openrouter) on a model you choose) or your own command in a sandbox as that agent, with your own model API key (saved under **Settings → Model access**, and never placed in the sandbox), then pushes a branch and opens a pull request for review.
218218 - **[Agent review](/docs/agents/review)**: one of your agents reviews pull requests for bugs, security issues and logic errors, like Cursor's Bugbot. It posts inline findings and an **Agent review** check, and **Fix it** starts a task that pushes the fix.
219219 - **[Today](/docs/agents/today)**: the first page after signing in, also `GET /api/v3/diffinery/today` and the `today` MCP tool. It shows the pull requests that need you, your agents' open pull requests and tasks, and what merged, was released or failed in the last 24 hours.
220220
modifiedapps/diffinery/docs/security/audit-log.md+1−1View file
@@ -78,7 +78,7 @@
7878 | `task.stop` | Someone stops a task (its starter, its agent or a repository admin) | `owner/repo#<task number>` | none |
7979 | `review.settings` | A repository admin turns [agent review](/docs/agents/review) on or off, or changes its settings | `owner/repo` | `enabled`, `agent`, `runtime`, `trigger`, `autofix`, `daily_limit` |
8080 | `review.request` | A person asks for an agent review with **Request agent review** or `POST /repos/{owner}/{repo}/pulls/{number}/diffinery/agent-review` | `owner/repo#<pull request number>` | none |
81-| `model_key.set`, `model_key.delete` | You save, replace or delete a model API key under **Settings → Model access** (or `PUT`/`DELETE /api/v3/diffinery/model-keys/{provider}`) | the provider (`anthropic` or `openai`) | `hint` (the key's last four characters) and `opted_in_at` (when you accepted the provider's terms) for `model_key.set` |
81+| `model_key.set`, `model_key.delete` | You save, replace or delete a model API key under **Settings → Model access** (or `PUT`/`DELETE /api/v3/diffinery/model-keys/{provider}`) | the provider (`anthropic`, `openai` or `openrouter`) | `hint` (the key's last four characters) and `opted_in_at` (when you accepted the provider's terms) for `model_key.set` |
8282
8383 ### Organizations and invitations
8484
modifiedapps/diffinery/src/docs/api-meta.ts+2−2View file
@@ -276,7 +276,7 @@
276276 },
277277 "POST /repos/{owner}/{repo}/dispatches": {
278278 summary: "Trigger a repository_dispatch event",
279- description: "Starts workflows on the default branch that run `on: repository_dispatch` with this type, and sends the `repository_dispatch` webhook. Fails with 422 on an empty repository.",
279+ description: "Starts workflows on the default branch that run `on: repository_dispatch` with this type, and sends the `repository_dispatch` webhook. Fails with 422 on an empty repository, and with 429 when the repository already has 500 unfinished workflow runs.",
280280 access: "write",
281281 status: 204,
282282 body: {
@@ -1058,7 +1058,7 @@
10581058 },
10591059 "POST /repos/{owner}/{repo}/actions/workflows/{workflow}/dispatches": {
10601060 summary: "Run a workflow (workflow_dispatch)",
1061- description: "`workflow` is the file path or name, URL-encoded, like `.github%2Fworkflows%2Fdeploy.yml` or `deploy.yml`. Returns the new run's id.",
1061+ description: "`workflow` is the file path or name, URL-encoded, like `.github%2Fworkflows%2Fdeploy.yml` or `deploy.yml`. Returns the new run's id. Fails with 429 when the repository already has 500 unfinished workflow runs.",
10621062 access: "write",
10631063 status: 201,
10641064 body: { ref: ["string", "Branch or tag to run on.", true], inputs: ["object", "Values for `on.workflow_dispatch.inputs`."] },