[DEV-105] Make automatic conflict resolution in workspace mode configurable: run immediately or on a schedule (e.g. nightly) to reduce AI token spend - #96
Open
danii1 wants to merge 3 commits into
Conversation
…pace mode configurable: run immediately or on a schedule (e.g. nightly) to reduce AI token spend
…lict resolution off entirely [workspace].conflict_resolution = "disabled" now opts a workspace out of automatic base-sync on the agent's PRs: no detection, no queuing, no agent runs. Conflicted PRs stay conflicted until resolved by hand or via `devintern resolve-conflicts <pr-url>`. Review feedback and @mentions are unaffected, and the worker logs the disabled mode at startup.
# Conflicts: # packages/code/tests/workspace-config.test.ts
Contributor
Author
|
🔀 This branch had merge conflicts with |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Task: DEV-105
Summary: Make automatic conflict resolution in workspace mode configurable: run immediately or on a schedule (e.g. nightly) to reduce AI token spend
Implementation Details
I'll start by exploring the codebase to understand the existing conflict-resolution flow and scheduling patterns.
Now let me look at the supporting pieces: worker-state cursors, the webhook queue base-sync API, docs, and existing config tests.
I have a good picture now. Let me check a few remaining details: the automation-config tests,
exhaustBaseSyncEvent/hasProcessed, andparseEnvInteger.I now have the full picture. Let me plan the work:
Starting with the shared schedule parser in
automation-config.ts:Now add the shared validation helper and occurrence helper, and refactor
parseAutomationEntriesto use them:I introduced a duplicate-error issue:
stringValue("cron")and the helper both validate the raw values. Since the locals are no longer used, remove them:Now refactor
nextAutomationDueto delegate to the shared helper:It's in
automation-acquirer.ts:Now the workspace config parsing:
Now the parsing logic inside
parseWorkspaceConfig:Now the poller — the core of this task. First the imports and options:
Now the module-level constants and window-state type:
Now the class changes — state members,
start()logging,tick()sync, and the gate:Now add the window-management private methods at the end of the class:
Now wire it into the workspace worker:
Now the
workspace inittemplate:Now the tests. First, extend
makeAcquirerin the poller test file:Now add the scheduled-mode tests to the poller test file:
Now the workspace config tests:
Now add
nextScheduleOccurrence/parseCronOrIntervalScheduletests to the automation-config test file:Now the docs. First
workspaces.md— the sample config and a dedicated section:Now
worker.md— extend the "Merge conflicts on the agent's PRs" section:Now verify — typecheck and the relevant tests:
Typecheck passes. Run the tests directly with bun:
All 63 pass. Now the full suite plus lint and format:
Let me verify none of the lint warnings come from my changes:
One new warning from my refactor — the now-unused
CronExpressionParserimport inautomation-acquirer.ts:Now a final review of the full diff:
One comment in the gate is slightly inaccurate about what happens after a manual fix — the pending event isn't completed by polling, it's simply never executed because GitHub stops reporting a conflict:
Final verification — full typecheck, lint, format, and test run:
DEV-105 is implemented. All checks pass: typecheck 11/11, lint 0 errors, 1028 tests green.
What was built
Config (
workspace.toml,[workspace]—config.ts:63,config.ts:250):Validation reuses the
[[automations]]format via a new shared helperparseCronOrIntervalSchedule/nextScheduleOccurrence(automation-config.ts:15,automation-config.ts:109);parseAutomationEntrieswas refactored onto the same helper (identical error messages, multi-error collection preserved). Strict validation: invalid mode, missing/duplicate/invalid schedule keys, or schedule keys without scheduled mode all fail config load.Poller gate (
review-polling-acquirer.ts:630,syncConflictWindowat:743): the existingresolveConflictsseam is now gated on a durable window state (persisted as aworker:conflict-windowcursor). Outside the window, conflicts are still detected and queued as pending base-sync events — the agent is never invoked. When the scheduled occurrence arrives, a grace window (WORKER_RESOLVE_WINDOW_GRACE_MINUTES, default 60) opens and all queued conflicts resolve through the existing backoff/quiet-period/revalidation machinery. Windows missed while the worker was down catch up on the first tick after restart; each window gets a fresh defer budget; stale/merged PRs are skipped by the existing mergeability checks.On demand:
devintern resolve-conflicts <pr-url>is untouched — a manual fix means GitHub stops reportingdirty, so the queued event never triggers an agent run.Startup surfacing: the worker logs the active mode, e.g.
⏰ [poll:reviews] conflict resolution: scheduled (cron "0 3 * * *"); next window …orconflict resolution: auto(review-polling-acquirer.ts:820).Edge cases covered: human mid-review pushes → quiet period + never-force-push unchanged; shutdown mid-run → cursor + pending events survive restart; review feedback is never delayed by scheduled mode (only base-sync is gated).
Tests (+15): config parsing/validation (7), schedule helper (3), poller scheduled-mode behavior — queue-before-window, resolve-in-window, re-queue after grace, restart catch-up, manual-resolve interplay, startup mode logging (5). Docs: both
docs/code/workspaces.md(new "Automatic conflict resolution: auto vs scheduled" section incl. token-cost tradeoff) anddocs/code/worker.md(new "Scheduled conflict resolution" subsection), plus theworkspace inittemplate.This PR was automatically created by @devintern/code