Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions docs/code/worker.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,24 @@ When a watched PR falls behind its base branch, the worker catches the branch up

This applies only to the agent's own PRs (the same watch list as review polling). Each base/head SHA pair is a durable event in `.devintern-code/queue.db`; new commits on the PR branch open a fresh event, so an exhausted attempt is retried after the next push. Failures retry up to `WEBHOOK_MAX_RETRIES` (default 3), including across worker restarts. Before acting, the worker requires the PR head SHA to remain unchanged for `WORKER_BASE_SYNC_QUIET_SECONDS` (default 30) and then re-fetches both SHAs. Recent or concurrent pushes defer the run without consuming an attempt; if a run defers several times in a row, the event is given up until the head or base moves again. GitHub's PR API can report an outdated `base.sha` for a while, so the resolver always merges the actual fetched tip of the base branch rather than trusting that field. Each resolve run is bounded by `WORKER_RESOLVE_TIMEOUT_SECONDS` (default 1800; `0` disables) — a hung resolver subprocess is killed and counted as a failed attempt, and runs left `in_progress` by a crashed or killed worker are marked failed at the next startup. The same merge logic is available manually for any PR via `devintern resolve-conflicts <pr-url>`.

### Syncing teammates' open PRs (`sync_team_prs`)

By default only the agent's own PRs are synced, as described above. To also keep human teammates' long-lived branches caught up with their base, enable team-PR sync:

Set `sync_team_prs = true` on the relevant `[[repos]]` entry in `workspace.toml`.

Behavior with the flag enabled:

- Only PRs authored by the repository's own team are synced: GitHub's `author_association` must be `OWNER`, `MEMBER`, `COLLABORATOR`, or `MAINTAIN`. PRs from outside contributors — and everything from forks — is never auto-synced; those branches remain their authors' to manage. The gate is checked both at discovery and again against the fresh per-PR payload before any run.
- Discovery polls each enabled repo's open-PR list every tick using conditional (ETag-cached) requests, so idle ticks stay rate-limit-free. The first sweep after startup fetches PR details once per open PR; afterwards only changed PRs cost requests. The list covers up to the first 100 open PRs per repo — while a repo sits at that page-size cap, the worker logs a warning, since PRs beyond it are invisible to discovery.
- Closed and merged PRs drop out of the open list on their own; draft PRs are never auto-synced (a draft signals work in progress).
- Review feedback handling stays an own-PR feature: other people's PRs are only ever caught up with their base, never addressed or replied to beyond the sync outcome.
- Everything else works exactly as for the agent's own PRs: quiet period, durable per-SHA events, retry limits, no force-pushes, and branch protection rules apply equally.

**Trust boundaries:** unlike the agent's own PRs, these branches are authored by other people, so their content is untrusted input. Enabling the flag therefore **requires a sandboxed agent**: the worker refuses to start when `AGENT_SANDBOX` is unset or `none` (see [Sandboxing the Agent](./configuration.md#sandboxing-the-agent)). What contains the rest: all resolution work happens inside a dedicated branch-scoped worktree under `/tmp/`, never in your checkout; fork PRs and drafts never enter the pipeline; merge pushes are lease-verified and never forced; and each resolver subprocess is killed at `WORKER_RESOLVE_TIMEOUT_SECONDS` (default 1800). What does *not* contain it: genuine conflict resolution hands a teammate's conflicted tree to the sandboxed coding agent — let branch protection decide what actually lands.

Sync activity on non-devintern PRs is fully auditable: the worker logs each foreign PR it starts/stops watching (`👀 … watching owner/repo#N (open PR) for base sync`) plus any PR skipped for a non-team author (`🚧 …`), and marks its sync lines with `(external PR)`; the resolver posts a comment on the PR describing what was merged; and every attempt is recorded as a `conflict_resolution` run in the [dashboard](./dashboard.md).

## Mention the bot on any PR

The worker also reacts to mentions on pull requests it did not create. When a teammate writes a comment like `@devintern address the review feedback` on any PR in the repository, the worker picks it up on the next poll and handles it through the same pipeline. Detection is a repository-wide sweep of new comments (two requests per interval, regardless of how many PRs are open), so mentions work without any webhook setup.
Expand Down
1 change: 1 addition & 0 deletions packages/code/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Added

- **Opt-in base sync for teammates' open PRs (`sync_team_prs` per workspace repo)**: setting it extends the worker's automatic merge-conflict/base-behind sync from just the agent's own PRs to open, non-draft PRs authored by the repository's own team (`author_association` OWNER/MEMBER/COLLABORATOR/MAINTAIN) — useful when teammates' long-lived branches fall behind their base. Enabling it requires `AGENT_SANDBOX`: the worker refuses to start otherwise. Outside contributors and fork PRs are never auto-synced; discovery uses ETag-cached open-PR list polling (rate-limit friendly, first 100 open PRs per repo); review feedback stays an own-PR feature; every foreign sync is logged and recorded as a `conflict_resolution` run. Default remains off
- **Workspace worker probes push access at startup**: each configured GitHub HTTPS remote gets a side-effect-free `git push --dry-run` against its bare clone, so an under-scoped token (fine-grained PAT without `Contents: Read and write`, or a `$GITHUB_TOKEN` that silently overrides the keyring login via `gh auth git-credential`) is reported as a clear startup warning instead of burning task pickups on 403 pushes

### Changed
Expand Down
Loading