Problem
DMC's workspace-git abilities cover the happy path of an agent shipping a fresh branch: status, log, diff, pull, add, commit, push. None of them help an agent manage its own pull request backlog when reality moves faster than the agent.
Concrete failure pattern (observed today in chubes4/world-of-wordpress):
- Cycle 1 opens PR A touching files X, Y.
- Cycle 2 fires before A merges, opens PR B touching file X.
- Cycle 3 fires before A and B merge, sees both as open in perception, deliberately steers around X and Y to avoid conflict, ships an unrelated field note.
- Cycle 4 does the same. Cycle 5. Cycle 6.
Each cycle is making the correct local decision — don't conflict with your own open PRs — but the cumulative effect is the agent producing field notes during every cycle while the real work it actually wants to do is locked behind unmerged PRs that go stale.
The agent has no way to bring its own PRs home. It can detect a stale PR exists (perception surfaces open PRs). It cannot:
- Rebase a stale day-branch onto current
main so the conflict resolves.
- Reset a branch to drop merge-conflict-inducing commits (e.g. accumulated daily-memory chore commits that always conflict with main's newer daily memory).
- Force-push the rebased history back to the day-branch.
- Resolve simple text conflicts inline.
- Squash a noisy commit history into one substantive commit before the auto-merger picks it up.
A human had to do this work today by hand: rebase, cherry-pick the substantive commits, squash, force-push. That's exactly the kind of mechanical workflow an agent should own.
What this asks for
1. Three new low-level abilities
datamachine/workspace-git-rebase
Input: name (workspace handle), onto (base ref, default origin/<base-branch>), interactive (always false), strategy_option (e.g. theirs, ours, optional).
Behavior: git fetch origin && git rebase <onto> from the worktree path. If conflicts arise, return them in the output schema with file paths, conflict-marker counts, and a conflicts array. The ability does not auto-resolve; that's the agent's job using workspace_edit/workspace_write. After resolution the agent calls workspace_git_add and a new workspace_git_rebase_continue (or pass continue: true to the same ability) to resume.
Output: success, state (clean / conflicting), conflicts (array of files with marker counts), applied (commit count applied), pending (commit count still to apply).
datamachine/workspace-git-reset
Input: name, mode (one of soft, mixed, hard), target (ref or commit, default origin/<branch>).
Behavior: git reset --<mode> <target> from the worktree path. Hard reset requires an explicit allow_destructive: true flag.
Output: success, mode, previous_head, new_head, paths_affected (count, not list).
datamachine/workspace-git-push — extend existing ability
Add force_with_lease boolean parameter (default false). When true, the push uses --force-with-lease=<branch>:<expected-sha> where expected-sha is the remote tip the agent last observed. The expected SHA can be passed explicitly or computed by the ability from git ls-remote before the push.
Optional but safe: refuse force_with_lease against main regardless of any flag, the same way the existing allow_primary_mutation flag works.
2. A composite high-level ability
datamachine/workspace-pr-rebase
Input: name (worktree handle), pr (PR number or URL, optional — if omitted the ability resolves the PR from the worktree's pushed branch via the GitHub API), squash (boolean, default false), drop_paths (array of glob patterns — paths to drop during rebase rather than resolve, e.g. bundles/world-creator/memory/agent/daily/**).
Behavior:
- Resolve the worktree path and the PR's base branch via GitHub API.
git fetch origin <base>.
git rebase origin/<base> from the worktree.
- For each conflict file matching a
drop_paths glob: resolve by taking base (git checkout --theirs <file> and git add <file>) — i.e. drop the PR's version in favor of main's. Most useful for daily-memory chore conflicts.
- For each remaining conflict: return as a structured conflict for the agent to resolve manually with
workspace_edit/workspace_write + workspace_git_rebase (with continue: true).
- If
squash: true after a clean rebase: git reset --soft origin/<base>, then git commit -m \"<PR title>\" using the PR's title for the message. Body inherits from the PR.
git push --force-with-lease.
Output: success, state (clean / conflicting), dropped_paths (count), unresolved_conflicts (array), squashed (boolean), pushed (boolean), head_sha, pr_url.
This single ability replaces the manual workflow a human did today:
```text
git fetch origin
git checkout pr-branch
git reset --soft origin/main
(paths from drop_paths are now in working tree, agent ignores them via .gitignore-like skip)
git commit -m ""
git push --force-with-lease
```
3. Perception layer integration
The world plugin's World_Perception_Directive (and equivalent directives in other DM-hosted agents) should be able to consume the GitHub API and surface PR staleness state: for each open PR, is it ahead of base, behind base, or conflicting. Today the directive's branches section (in the world plugin) just lists open PRs without their freshness state.
That's a world-plugin concern, not a DMC concern — but DMC could expose a helper ability datamachine/workspace-pr-status (input: pr or branch, output: mergeable, behind, ahead, conflicting) that any perception layer can consume. That's a thin wrapper over gh api repos/.../pulls/<n> returning the relevant fields.
Why not just merge through the auto-merger
The world repo has an auto-merger (merge-world-creator-pr job in .github/workflows/world-creator.yml) that runs after each cycle. It uses gh pr merge and refuses to merge CONFLICTING PRs. That's correct safety behavior — the auto-merger shouldn't blindly merge conflicts.
The right answer is the agent itself resolves the conflict on its own branch, then the auto-merger merges the cleaned-up result. That's what these abilities enable.
Why a composite ability
The agent could compose git_rebase + git_add + git_reset + git_push --force-with-lease itself, but:
- The conflict-resolution loop is mechanical and well-defined. Agents should not burn turns on it.
- The composite ability can be idempotent — calling it twice on a clean PR is a no-op. Calling it twice during a conflict surfaces the same conflict.
- The composite ability can ship with safety rails the agent can't easily forget: never force-push to a base branch, always use
--force-with-lease (never bare --force), always squash if requested.
- The agent's mental model becomes "bring this PR home" instead of "fetch base, rebase, resolve conflicts, squash, force-push."
Scope notes
- DMC abilities only. No DM core changes required.
- The new low-level abilities follow the same pattern as the existing
workspace-git-* abilities — same ability category, same permission_callback, same WorkspaceTools registration shape.
- All four new abilities should register against the same modes the existing workspace-git abilities use (
chat, pipeline with requires_opt_in: true).
- Tool registration in
inc/Tools/WorkspaceTools.php follows the existing pattern.
AI assistance
- AI assistance: Yes
- Tool(s): Claude Code (Sonnet 4.5)
- Used for: Diagnosed the agent's PR backlog management gap by watching the World Creator cycles repeatedly avoid conflict surfaces and produce field-note filler. Designed the four-ability addition (
rebase, reset, push --force-with-lease, composite pr-rebase) plus the optional workspace-pr-status helper for perception integration. Chris specified that this is a DMC-level gap and that the agent should be able to bring its own PRs home autonomously.
Problem
DMC's workspace-git abilities cover the happy path of an agent shipping a fresh branch:
status,log,diff,pull,add,commit,push. None of them help an agent manage its own pull request backlog when reality moves faster than the agent.Concrete failure pattern (observed today in
chubes4/world-of-wordpress):Each cycle is making the correct local decision — don't conflict with your own open PRs — but the cumulative effect is the agent producing field notes during every cycle while the real work it actually wants to do is locked behind unmerged PRs that go stale.
The agent has no way to bring its own PRs home. It can detect a stale PR exists (perception surfaces open PRs). It cannot:
mainso the conflict resolves.A human had to do this work today by hand: rebase, cherry-pick the substantive commits, squash, force-push. That's exactly the kind of mechanical workflow an agent should own.
What this asks for
1. Three new low-level abilities
datamachine/workspace-git-rebaseInput:
name(workspace handle),onto(base ref, defaultorigin/<base-branch>),interactive(always false),strategy_option(e.g.theirs,ours, optional).Behavior:
git fetch origin && git rebase <onto>from the worktree path. If conflicts arise, return them in the output schema with file paths, conflict-marker counts, and aconflictsarray. The ability does not auto-resolve; that's the agent's job usingworkspace_edit/workspace_write. After resolution the agent callsworkspace_git_addand a newworkspace_git_rebase_continue(or passcontinue: trueto the same ability) to resume.Output:
success,state(clean / conflicting),conflicts(array of files with marker counts),applied(commit count applied),pending(commit count still to apply).datamachine/workspace-git-resetInput:
name,mode(one ofsoft,mixed,hard),target(ref or commit, defaultorigin/<branch>).Behavior:
git reset --<mode> <target>from the worktree path. Hard reset requires an explicitallow_destructive: trueflag.Output:
success,mode,previous_head,new_head,paths_affected(count, not list).datamachine/workspace-git-push— extend existing abilityAdd
force_with_leaseboolean parameter (default false). When true, the push uses--force-with-lease=<branch>:<expected-sha>whereexpected-shais the remote tip the agent last observed. The expected SHA can be passed explicitly or computed by the ability fromgit ls-remotebefore the push.Optional but safe: refuse
force_with_leaseagainstmainregardless of any flag, the same way the existingallow_primary_mutationflag works.2. A composite high-level ability
datamachine/workspace-pr-rebaseInput:
name(worktree handle),pr(PR number or URL, optional — if omitted the ability resolves the PR from the worktree's pushed branch via the GitHub API),squash(boolean, default false),drop_paths(array of glob patterns — paths to drop during rebase rather than resolve, e.g.bundles/world-creator/memory/agent/daily/**).Behavior:
git fetch origin <base>.git rebase origin/<base>from the worktree.drop_pathsglob: resolve by taking base (git checkout --theirs <file>andgit add <file>) — i.e. drop the PR's version in favor of main's. Most useful for daily-memory chore conflicts.workspace_edit/workspace_write+workspace_git_rebase(withcontinue: true).squash: trueafter a clean rebase:git reset --soft origin/<base>, thengit commit -m \"<PR title>\"using the PR's title for the message. Body inherits from the PR.git push --force-with-lease.Output:
success,state(clean / conflicting),dropped_paths(count),unresolved_conflicts(array),squashed(boolean),pushed(boolean),head_sha,pr_url.This single ability replaces the manual workflow a human did today:
```text
git fetch origin
git checkout pr-branch
git reset --soft origin/main
(paths from drop_paths are now in working tree, agent ignores them via .gitignore-like skip)
git commit -m ""
git push --force-with-lease
```
3. Perception layer integration
The world plugin's
World_Perception_Directive(and equivalent directives in other DM-hosted agents) should be able to consume the GitHub API and surface PR staleness state: for each open PR, is it ahead of base, behind base, or conflicting. Today the directive'sbranchessection (in the world plugin) just lists open PRs without their freshness state.That's a world-plugin concern, not a DMC concern — but DMC could expose a helper ability
datamachine/workspace-pr-status(input:prorbranch, output:mergeable,behind,ahead,conflicting) that any perception layer can consume. That's a thin wrapper overgh api repos/.../pulls/<n>returning the relevant fields.Why not just merge through the auto-merger
The world repo has an auto-merger (
merge-world-creator-prjob in.github/workflows/world-creator.yml) that runs after each cycle. It usesgh pr mergeand refuses to mergeCONFLICTINGPRs. That's correct safety behavior — the auto-merger shouldn't blindly merge conflicts.The right answer is the agent itself resolves the conflict on its own branch, then the auto-merger merges the cleaned-up result. That's what these abilities enable.
Why a composite ability
The agent could compose
git_rebase+git_add+git_reset+git_push --force-with-leaseitself, but:--force-with-lease(never bare--force), always squash if requested.Scope notes
workspace-git-*abilities — same ability category, same permission_callback, same WorkspaceTools registration shape.chat,pipelinewithrequires_opt_in: true).inc/Tools/WorkspaceTools.phpfollows the existing pattern.AI assistance
rebase,reset,push --force-with-lease, compositepr-rebase) plus the optionalworkspace-pr-statushelper for perception integration. Chris specified that this is a DMC-level gap and that the agent should be able to bring its own PRs home autonomously.