Docs: workflow scheduler, deploys that spare running jobs, agent review cross-links (#72)
Covers #65, #66, #68 and #70: the scheduler's own timer and its admin status endpoint, deploys that leave running jobs alone, runs whose jobs were all skipped, and agent review limits, audit entries, email and links. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016q5wwBFck8JHq14gHUM2CL
Canberk Demirci authored · GitHub committed signed1 parent 9c9b881commit 83c1b97aff96ae9014bab508dad7497581b789e3Browse files
11 files changed+65−14
Files (11)
- apps/diffinery/docs/accounts/notifications.md+3−2
- apps/diffinery/docs/actions/overview.md+3−3
- apps/diffinery/docs/admin/site-administration.md+22−1
- apps/diffinery/docs/agents/overview.md+2−1
- apps/diffinery/docs/concepts.md+1−1
- apps/diffinery/docs/index.md+2−1
- apps/diffinery/docs/reference/limits.md+22−4
- apps/diffinery/docs/repositories/branch-protection.md+2−0
- apps/diffinery/docs/security/audit-log.md+2−0
- apps/diffinery/docs/self-hosting/configuration.md+1−1
- apps/diffinery/src/docs/api-meta.ts+5−0
modifiedapps/diffinery/docs/accounts/notifications.md+3−2View file
| @@ -45,8 +45,8 @@ | ||
| 45 | 45 | |
| 46 | 46 | | Group | Emails | Can be turned off | Default | |
| 47 | 47 | | --- | --- | --- | --- | |
| 48 | -| Security | New sign-in from a browser or device not seen before (and every email-recovery sign-in), passkey added or removed, access token created or about to expire, agent added, push blocked or push protection bypassed, account disabled or enabled | No | On | | |
| 49 | -| Account | Invitations, welcome, sign-in links, test email | No | On | | |
| 48 | +| Security | New sign-in from a browser or device not seen before (and every email-recovery sign-in), passkey added or removed, access token created or about to expire, agent added, model API key added, push blocked or push protection bypassed, account disabled or enabled | No | On | | |
| 49 | +| Account | Invitations, welcome, sign-in links, test email, agent review's daily limit reached | No | On | | |
| 50 | 50 | | Participating | Issues and pull requests you opened, commented on, reviewed, were assigned, were asked to review, were @mentioned in or subscribed to: new issues and pull requests, comments, reviews, pushes, merges, closes, reopens, assignments and review requests | Yes | On | |
| 51 | 51 | | Watching | Everything else in repositories you watch with **All activity** | Yes | On | |
| 52 | 52 | | Actions | Workflow runs you started (failed runs only, unless you turn off **Only failed runs**), and scheduled runs in repositories you watch | Yes | On, failures only | |
| @@ -240,6 +240,7 @@ | ||
| 240 | 240 | | `invite` | `@diffy invited you to join the acme organization on Diffinery` | Account | `invitation` | Someone invited your email address (organization, repository or instance) | |
| 241 | 241 | | `welcome` | `Welcome to Diffinery, @diffy` | Account | `account` | You created your account from an invite | |
| 242 | 242 | | `signin_link` | `[Diffinery] Your one-time sign-in link` | Account | `account` | A site administrator created a sign-in link for you | |
| 243 | +| `review_limit_reached` | `[acme/website] Agent review reached its daily limit` | Account | `your_activity` | [Agent review](/docs/agents/review) on a repository whose reviews use your model key reached its daily limit (at most once a day per repository) | | |
| 243 | 244 | | `test` | `[Diffinery] Test email` | Account | `account` | You clicked **Send me a test email** (or used the API) | |
| 244 | 245 | | `invite_accepted` | `[Diffinery] @diffy accepted your invitation` | Organizations | `account` | Someone accepted an invite you created | |
| 245 | 246 | | `access_request` | `[Diffinery] newcomer@example.com asked for access` | Organizations | `admin` | A person waiting for an invite requested access (sent to site administrators) | |
modifiedapps/diffinery/docs/actions/overview.md+3−3View file
| @@ -111,7 +111,7 @@ | ||
| 111 | 111 | 3. **The run is orchestrated durably** by a Cloudflare Workflow. It walks the job graph from `needs`: each job starts as soon as the jobs it needs have finished, without waiting for unrelated jobs. The orchestration survives restarts of the platform, and each wait for a job lasts at most 6 hours. |
| 112 | 112 | 4. **Each job is evaluated** just before it starts: its `if:` condition and its matrix. A job whose condition is false is recorded as `skipped`; without a status function in its `if:`, a job is also skipped when any job above it in the `needs` chain failed, was cancelled or was skipped. A matrix job becomes one job per combination (at most 256), started up to `max-parallel` at a time, and each combination gets its own `name`, `runs-on`, `timeout-minutes`, `continue-on-error` and job `concurrency` group, evaluated with its `matrix` values. A job with a `concurrency` group waits as `pending` while another job of the group runs. |
| 113 | 113 | 5. **Each hosted job gets its own container.** A fresh Cloudflare Container (Ubuntu 24.04, linux/amd64) starts with a job token that is valid only for that job. The runner agent inside fetches the job definition (for a job with `environment:`, this is when the environment's branch policy is checked and its secrets and variables are added), runs the steps in order, streams the log back as it goes, and reports each step's result and the job's conclusion. The container stops when the job ends. Jobs for self-hosted runners wait until a `diffinery runner` with matching labels claims them instead. |
| 114 | -6. **The run finishes** when every job is done. Its conclusion is `failure` if any job failed or timed out (except jobs with `continue-on-error: true`), otherwise `cancelled` if the run was cancelled or any job was cancelled, otherwise `success`. Skipped jobs don't make a run fail. | |
| 114 | +6. **The run finishes** when every job is done. Its conclusion is `failure` if any job failed or timed out (except jobs with `continue-on-error: true`), otherwise `cancelled` if the run was cancelled or any job was cancelled, otherwise `skipped` if every job was skipped, otherwise `success`. Skipped jobs don't make a run fail. As on GitHub, a `workflow_run` job with `if: github.event.workflow_run.conclusion == 'success'` is skipped after a run whose jobs were all skipped. | |
| 115 | 115 | |
| 116 | 116 | ### Timeouts |
| 117 | 117 | |
| @@ -138,7 +138,7 @@ | ||
| 138 | 138 | | `success` | Every step succeeded (steps with `continue-on-error: true` may have failed). | |
| 139 | 139 | | `failure` | A step failed, the job could not start, or (for runs) a job without `continue-on-error: true` failed. | |
| 140 | 140 | | `cancelled` | Someone cancelled the run, a newer run or job in the same concurrency group replaced it, or a sibling matrix job failed or timed out with `fail-fast` on. | |
| 141 | -| `skipped` | The job's `if:` condition was false. | | |
| 141 | +| `skipped` | The job's `if:` condition was false, or (for runs) every job was skipped. | | |
| 142 | 142 | | `timed_out` | (Jobs) Diffinery waited 6 hours for the job without a result. | |
| 143 | 143 | |
| 144 | 144 | ## The Actions tab |
| @@ -316,7 +316,7 @@ | ||
| 316 | 316 | |
| 317 | 317 | Click **Cancel run** on the run page, run `diffinery run cancel <run-id>`, call `POST /actions/runs/{run_id}/cancel`, or use the `cancel_workflow` MCP tool. You need write access. |
| 318 | 318 | |
| 319 | -Cancelling stops every unfinished job's container and marks those jobs `cancelled` with the reason `Cancelled by <login>`. Jobs that haven't started yet and have no status function in their `if:` are skipped; a job with `if: always()` or `if: cancelled()` still runs, as on GitHub. The run's conclusion is `cancelled`. | |
| 319 | +Cancelling stops every unfinished job's container at once and marks those jobs `cancelled` with the reason `Cancelled by <login>`. Jobs that haven't started yet and have no status function in their `if:` are skipped; a job with `if: always()` or `if: cancelled()` still runs, as on GitHub. The run's conclusion is `cancelled`. | |
| 320 | 320 | |
| 321 | 321 | ## Re-run a run |
| 322 | 322 |
modifiedapps/diffinery/docs/admin/site-administration.md+22−1View file
| @@ -158,8 +158,29 @@ | ||
| 158 | 158 | | `POST /api/v3/diffinery/admin/emails/samples` | Send every template to yourself now, or only some with `{"only": ["signin", "invite-org"]}`. Returns `to`, `sent`, `total` and each result. | site administrator, with an `admin` token for all repositories or a browser session | |
| 159 | 159 | | `GET /api/v3/diffinery/emails?all=1` | Everyone's recent emails (without `all=1`, only yours). Also takes `kind`, `since` and `per_page` (up to 500). | site administrator for `all=1` | |
| 160 | 160 | |
| 161 | -The sample IDs are `pr-opened`, `issue-opened`, `comment`, `review-approved`, `review-changes`, `review-requested`, `assigned`, `pushed`, `merged`, `closed`, `reopened`, `run-failed`, `signin`, `passkey-added`, `passkey-removed`, `token-created`, `token-expiring`, `agent-created`, `model-key-added`, `push-bypassed`, `push-blocked`, `commit-blocked`, `account-disabled`, `account-enabled`, `invite-org`, `invite-repo`, `invite-accepted`, `welcome`, `signin-link`, `access-request`, `org-member`, `repo-access`, `repo-created`, `repo-deleted`, `repo-transferred` and `test`. | |
| 161 | +The sample IDs are `pr-opened`, `issue-opened`, `comment`, `review-approved`, `review-changes`, `review-requested`, `assigned`, `pushed`, `merged`, `closed`, `reopened`, `run-failed`, `signin`, `passkey-added`, `passkey-removed`, `token-created`, `token-expiring`, `agent-created`, `model-key-added`, `review-limit`, `push-bypassed`, `push-blocked`, `commit-blocked`, `account-disabled`, `account-enabled`, `invite-org`, `invite-repo`, `invite-accepted`, `welcome`, `signin-link`, `access-request`, `org-member`, `repo-access`, `repo-created`, `repo-deleted`, `repo-transferred` and `test`. | |
| 162 | 162 | |
| 163 | +## Workflow scheduler | |
| 164 | + | |
| 165 | +Scheduled workflows are started by Diffinery's own timer, every 5 minutes, which also catches up checks that came late (see [Scheduled workflows](/docs/actions/events#schedule)). When a scheduled run doesn't start, read the scheduler's state to tell a timer that stopped from a run that failed to start: | |
| 166 | + | |
| 167 | +```bash | |
| 168 | +diffinery api GET /diffinery/admin/scheduler | |
| 169 | +``` | |
| 170 | + | |
| 171 | +```json | |
| 172 | +{ "tick_minutes": 5, "last_tick_at": "2026-10-13T17:30:01.204Z", "covered_until": "2026-10-13T17:30:00.000Z", "next_tick_at": "2026-10-13T17:35:00.000Z" } | |
| 173 | +``` | |
| 174 | + | |
| 175 | +| Field | Meaning | | |
| 176 | +| --- | --- | | |
| 177 | +| `tick_minutes` | Minutes between checks (`SCHEDULE_TICK_MINUTES`, default 5) | | |
| 178 | +| `last_tick_at` | When the last check finished, or `null` before the first | | |
| 179 | +| `covered_until` | The last minute whose schedules have been started | | |
| 180 | +| `next_tick_at` | When the next check is due, or `null` if the timer isn't set (the cron trigger sets it again within 5 minutes) | | |
| 181 | + | |
| 182 | +A `last_tick_at` far behind the time means checks are failing; look in the Worker's logs for `schedule tick failed`. Site administrators only, with any token scope. How it works is in [Architecture](/docs/self-hosting/architecture#workflow-schedules). | |
| 183 | + | |
| 163 | 184 | ## Administration from the CLI |
| 164 | 185 | |
| 165 | 186 | The CLI (needs Node.js 22 or later) covers invites and, through `diffinery api`, any API endpoint: |
modifiedapps/diffinery/docs/agents/overview.md+2−1View file
| @@ -211,9 +211,10 @@ | ||
| 211 | 211 | |
| 212 | 212 | To cut off one running copy without disabling the agent, revoke just its token. |
| 213 | 213 | |
| 214 | -## Agent tasks and Today | |
| 214 | +## Agent tasks, agent review and Today | |
| 215 | 215 | |
| 216 | 216 | - **[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 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. | |
| 217 | 218 | - **[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. |
| 218 | 219 | |
| 219 | 220 | ## Set up a coding agent |
modifiedapps/diffinery/docs/concepts.md+1−1View file
| @@ -45,7 +45,7 @@ | ||
| 45 | 45 | - A workflow run whose code came from an agent (the agent triggered it, pushed the branch last, or opened the pull request, and re-runs and `workflow_run` followers of such a run) acts as the agent, so a workflow can't carry agent-written code past these rules. |
| 46 | 46 | - It can import from GitHub only into an organization it or its owner administers, its imports never bypass push protection, and they skip variables, secret names and environments. |
| 47 | 47 | |
| 48 | -Agents work through the [MCP server](/docs/agents/mcp), the REST API, the CLI and Git. Diffinery can also run one for you: an [agent task](/docs/agents/tasks) gives one of your agents a goal and runs Claude Code, Codex or your own command with your own model key, then opens a pull request. [Today](/docs/agents/today), the first page after signing in, shows what needs you and what your agents are doing. See [Agents](/docs/agents/overview). | |
| 48 | +Agents work through the [MCP server](/docs/agents/mcp), the REST API, the CLI and Git. Diffinery can also run one for you: an [agent task](/docs/agents/tasks) gives one of your agents a goal and runs Claude Code, Codex or your own command with your own model key, then opens a pull request, and [agent review](/docs/agents/review) has one review pull requests for bugs. [Today](/docs/agents/today), the first page after signing in, shows what needs you and what your agents are doing. See [Agents](/docs/agents/overview). | |
| 49 | 49 | |
| 50 | 50 | ### People imported from GitHub |
| 51 | 51 |
modifiedapps/diffinery/docs/index.md+2−1View file
| @@ -16,6 +16,7 @@ | ||
| 16 | 16 | | Connect an AI agent | [Agents](/docs/agents/overview) and [MCP](/docs/agents/mcp) | |
| 17 | 17 | | Give an agent a goal and get a pull request back, with your own model key | [Agent tasks](/docs/agents/tasks) | |
| 18 | 18 | | See what needs you and what your agents did since yesterday | [Today](/docs/agents/today) | |
| 19 | +| Have one of your agents review pull requests for bugs, like Bugbot | [Agent review](/docs/agents/review) | | |
| 19 | 20 | | Script against Diffinery | [REST API guide](/docs/reference/rest-api), [REST API reference](/docs/api) and [CLI reference](/docs/reference/cli) | |
| 20 | 21 | | Run your own instance | [Deploy Diffinery](/docs/self-hosting/deploy) | |
| 21 | 22 | |
| @@ -25,7 +26,7 @@ | ||
| 25 | 26 | - **Pull requests and issues.** Draft pull requests, reviews with line comments, required approvals and checks, merge, squash and rebase, an `intent` field that tells reviewers what a change is meant to do, and a merge queue. See [Pull requests](/docs/collaboration/pull-requests) and [Merge queue](/docs/collaboration/merge-queue). |
| 26 | 27 | - **Actions.** Workflow YAML compatible with GitHub Actions: the same triggers, expressions, matrices, `needs`, outputs, reusable workflows, secrets, variables, OIDC, service containers and Docker. Jobs run in Cloudflare Containers, or on your own machines with self-hosted runners. See [Compatibility with GitHub Actions](/docs/actions/compatibility). |
| 27 | 28 | - **Container registry.** Push and pull images at `diffinery.com/<owner>/<name>` instead of ghcr.io. See [Container registry](/docs/packages/container-registry). |
| 28 | -- **Agents as first-class accounts.** Agents have their own logins and tokens, act on behalf of a person or an organization, and work through MCP, the REST API, git or the CLI. Guardrails keep a human in the loop: unless a branch protection rule allows it, agents can't push to or merge into the default branch or protected branches, and their pull requests need a human approval. [Agent tasks](/docs/agents/tasks) run Claude Code, Codex or your own command in a sandbox with your own model key and open a pull request, and [Today](/docs/agents/today) shows what needs you and what your agents did. See [Agents](/docs/agents/overview). | |
| 29 | +- **Agents as first-class accounts.** Agents have their own logins and tokens, act on behalf of a person or an organization, and work through MCP, the REST API, git or the CLI. Guardrails keep a human in the loop: unless a branch protection rule allows it, agents can't push to or merge into the default branch or protected branches, and their pull requests need a human approval. [Agent tasks](/docs/agents/tasks) run Claude Code, Codex or your own command in a sandbox with your own model key and open a pull request, [agent review](/docs/agents/review) has one of them review pull requests, and [Today](/docs/agents/today) shows what needs you and what your agents did. See [Agents](/docs/agents/overview). | |
| 29 | 30 | - **Security by default.** Passkeys instead of passwords, invite-only sign-up, branch protection, push protection that blocks leaked credentials, encrypted secrets and an audit log. See [Security overview](/docs/security/overview). |
| 30 | 31 | |
| 31 | 32 | ## How Diffinery runs |
modifiedapps/diffinery/docs/reference/limits.md+22−4View file
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | --- |
| 2 | 2 | title: Limits |
| 3 | -description: Every hard limit in Diffinery and where it applies: sign-in, tokens, API, search, archives, releases, git, Actions, sandboxes, agent tasks, packages, imports, email. | |
| 3 | +description: Every hard limit in Diffinery and where it applies: sign-in, tokens, API, search, archives, releases, git, Actions, sandboxes, agent tasks, agent review, packages, imports, email. | |
| 4 | 4 | --- |
| 5 | 5 | |
| 6 | 6 | This page lists the fixed limits built into Diffinery: sizes, counts, timeouts and lifetimes. Use it when a push, a workflow, an upload or an API call fails with a size or count error, or when you plan something large. Values come from the code of the running version. Where a limit comes from Cloudflare rather than from Diffinery, the table says so. |
| @@ -170,10 +170,11 @@ | ||
| 170 | 170 | | Reusable workflows per run | 20 calls | "a run can call at most 20 reusable workflows" | |
| 171 | 171 | | `workflow_run` chains | 3 levels | A run started by `workflow_run` that is itself three links down a chain triggers nothing (A starts B starts C starts D; D's runs start nothing). | |
| 172 | 172 | | Schedule granularity | 5 minutes | Scheduled workflows are checked every 5 minutes. A cron that fires more often still runs at most once per 5-minute window. Only workflows on the default branch of repositories that aren't archived are scheduled. | |
| 173 | +| Schedule catch-up | 60 minutes | A check that comes late, or fails, is caught up by the next one, up to an hour back. Each schedule starts once per check, however many of its minutes the check covers. | | |
| 173 | 174 | | Starting a job | 3 retries | Starting a job's container is retried 3 times with exponential backoff from 10 seconds before the job fails with "Could not start a runner". | |
| 174 | 175 | | Hosted runner size | Cloudflare Containers `standard-2` | Each `runs-on: ubuntu-latest` job runs in its own container of this instance type. | |
| 175 | 176 | | Hosted job containers at once | 100 | `max_instances` of the runner container class. | |
| 176 | -| Jobs during a deploy | 14 minutes | When Diffinery is redeployed, a running hosted job keeps going for up to 14 minutes after its container is asked to stop, then is cancelled. | | |
| 177 | +| Jobs during a deploy | Not interrupted | A deploy doesn't replace the container of a running hosted job: it finishes on the version it started with. If the platform replaces a job's container anyway, the job keeps going for up to 13 minutes, then is cancelled. | | |
| 177 | 178 | | Service container health check | 15 minutes | How long a job waits for a `services:` container's health check to pass. | |
| 178 | 179 | | Log line length | 16,384 characters | Longer lines are cut and end with `…`. | |
| 179 | 180 | | Log shown in the web UI | 20,000 lines | The job page shows the first 20,000 lines and links to the full log. | |
| @@ -227,6 +228,22 @@ | ||
| 227 | 228 | |
| 228 | 229 | See [Agent tasks](/docs/agents/tasks). For the Today view's limits (repositories active in the last 30 days, at most 100 of them, 50 open pull requests each), see [Today](/docs/agents/today). |
| 229 | 230 | |
| 231 | +## Agent review | |
| 232 | + | |
| 233 | +| Limit | Value | Details | | |
| 234 | +| --- | --- | --- | | |
| 235 | +| Review length | 30 minutes | The review stops and its **Agent review** check fails with "The review didn't finish". | | |
| 236 | +| Model requests per review | 200 | The model proxy answers `429` to the next request and stops the review; its check fails. | | |
| 237 | +| Automatic reviews per pull request | 10 in 24 hours | Later pushes get an action-required check; people with write access can still ask. | | |
| 238 | +| Reviews per pull request | 20 in 24 hours, asked for or automatic | The check asks for action, and asking returns `429`. | | |
| 239 | +| Reviews per repository | 50 in 24 hours by default, settable from 1 to 1000 (`daily_limit`) | The check asks for action, asking returns `429`, and the admin whose key reviews use gets a `review_limit_reached` email at most once a day. | | |
| 240 | +| Inline findings per review | 25 | Findings outside the changed lines go in the review's summary. | | |
| 241 | +| Changed files in the prompt | 300 | The rest are summed up as `… and N more`. | | |
| 242 | +| Review rules in the prompt | 48 KiB | Of the base branch's `REVIEW.md` and `.cursor/BUGBOT.md` files. | | |
| 243 | +| Autofix tasks per pull request | 3 | Only for pull requests whose author has write access. | | |
| 244 | + | |
| 245 | +See [Agent review](/docs/agents/review). | |
| 246 | + | |
| 230 | 247 | ## Container registry |
| 231 | 248 | |
| 232 | 249 | | Limit | Value | Applies to | |
| @@ -296,7 +313,8 @@ | ||
| 296 | 313 | | Runner containers | `standard-2`, up to 100 instances | `containers[RunnerContainer]`. | |
| 297 | 314 | | Sandbox containers | `standard-1`, up to 50 instances | `containers[SandboxContainer]`. | |
| 298 | 315 | | Import containers | `standard-4`, up to 20 instances | `containers[ImportContainer]`: one container per Git transfer of an import. | |
| 299 | -| Container rollout grace period | 3,600 seconds | `rollout_active_grace_period` for every container class. | | |
| 316 | +| Container rollout grace period | 23,400 seconds for runners, 25,200 for imports, 3,600 for sandboxes | `rollout_active_grace_period`. A deploy doesn't replace a container younger than this, so running jobs (6 hours at most) and import transfers finish first. | | |
| 300 | 317 | | Event queue | Batches of up to 50 messages (2 seconds), 8 retries | `diffinery-events`, dead-letter queue `diffinery-events-dlq`. | |
| 301 | 318 | | Mail queue | Batches of up to 20 messages (2 seconds), 8 retries | `diffinery-mail`, dead-letter queue `diffinery-mail-dlq`. The consumer itself gives up after 6 attempts. | |
| 302 | -| Cron trigger | Every 5 minutes | `*/5 * * * *`: scheduled workflows, token expiry reminders, email log pruning, container registry cleanup and cancelling draft imports older than 7 days. | | |
| 319 | +| Workflow scheduler | Every 5 minutes | `SchedulerDO`'s own alarm (`SCHEDULE_TICK_MINUTES`, 1 to 60) starts scheduled workflows, up to 16 repositories at a time. | | |
| 320 | +| Cron trigger | Every 5 minutes | `*/5 * * * *`: token expiry reminders, email log pruning, container registry cleanup, cancelling draft imports older than 7 days, and setting the scheduler's alarm if it isn't set. | |
modifiedapps/diffinery/docs/repositories/branch-protection.md+2−0View file
| @@ -85,6 +85,8 @@ | ||
| 85 | 85 | 3. Reports from agents never count, whoever they are and whatever the binding says. |
| 86 | 86 | 4. Of the reports left, any failure fails the check, and any report that has not finished keeps it pending. The check passes only when every counted report passed. |
| 87 | 87 | |
| 88 | +A required check named **Agent review** is bound to Diffinery's own reviewer (`diffinery-agent-review`), so only [agent review](/docs/agents/review) can pass it. | |
| 89 | + | |
| 88 | 90 | For commit statuses, only each reporter's latest status for a context is used, so one account's later status cannot replace another account's. |
| 89 | 91 | |
| 90 | 92 | A required check with no counted report blocks the merge with `required check '<name>' has not run`. That includes a check that only an agent reported. Make sure the workflow or CI system runs for every pull request into the protected branch. |
modifiedapps/diffinery/docs/security/audit-log.md+2−0View file
| @@ -76,6 +76,8 @@ | ||
| 76 | 76 | | `task.start` | Someone starts an [agent task](/docs/agents/tasks) | `owner/repo#<task number>` | `agent`, `runtime` | |
| 77 | 77 | | `task.message`, `task.retry` | The person who started a task sends a follow-up or retries it | `owner/repo#<task number>` | none | |
| 78 | 78 | | `task.stop` | Someone stops a task (its starter, its agent or a repository admin) | `owner/repo#<task number>` | none | |
| 79 | +| `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` | | |
| 80 | +| `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 | | |
| 79 | 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` | |
| 80 | 82 | |
| 81 | 83 | ### Organizations and invitations |
modifiedapps/diffinery/docs/self-hosting/configuration.md+1−1View file
| @@ -115,7 +115,7 @@ | ||
| 115 | 115 | | `upload_source_maps` | `true` | Readable stack traces in the logs. | |
| 116 | 116 | | `limits.cpu_ms` | `300000` | Up to 5 minutes of CPU time per request (large pushes, diffs and merges). | |
| 117 | 117 | | `containers` | `RunnerContainer`: `standard-2`, `max_instances: 100`; `SandboxContainer`: `standard-1`, `max_instances: 50`; `ImportContainer`: `standard-4`, `max_instances: 20`; `rollout_active_grace_period`: 23400 for runners and 25200 for imports (longer than a job or transfer can run, so a deploy never replaces a running one), 3600 for sandboxes | All three build `containers/runner/Dockerfile` with `containers/runner` as context. Raise `max_instances` for more concurrent jobs, sandboxes or import transfers. | |
| 118 | -| `triggers.crons` | `["*/5 * * * *"]` | Scheduled workflows, token expiry reminders, email log pruning, registry cleanup, and cancelling draft imports older than 7 days. | | |
| 118 | +| `triggers.crons` | `["*/5 * * * *"]` | Token expiry reminders, email log pruning, registry cleanup, cancelling draft imports older than 7 days, and setting the workflow scheduler's alarm if it isn't set. Scheduled workflows run from that alarm, not from the cron trigger. | | |
| 119 | 119 | |
| 120 | 120 | ## The dev environment |
| 121 | 121 |
modifiedapps/diffinery/src/docs/api-meta.ts+5−0View file
| @@ -1290,6 +1290,11 @@ | ||
| 1290 | 1290 | }, |
| 1291 | 1291 | "POST /diffinery/emails/test": { summary: "Send yourself a test email", access: "account" }, |
| 1292 | 1292 | "GET /diffinery/admin/email": { summary: "Email delivery status", description: "Whether sending is configured, and counts for the last 24 hours.", access: "site-admin" }, |
| 1293 | + "GET /diffinery/admin/scheduler": { | |
| 1294 | + summary: "Workflow scheduler state", | |
| 1295 | + description: "`tick_minutes`, `last_tick_at` (when the last check finished), `covered_until` (the last minute whose schedules were started) and `next_tick_at` (null when the timer isn't set). Tells a scheduler that stopped ticking from a run that failed to start.", | |
| 1296 | + access: "site-admin", | |
| 1297 | + }, | |
| 1293 | 1298 | "POST /diffinery/admin/emails/samples": { summary: "Send yourself every email template", access: "site-admin", body: { only: ["string[]", "Only these sample ids."] } }, |
| 1294 | 1299 | |
| 1295 | 1300 | // ------------------------------------------------------------ tokens, agents and sandboxes |